@SuppressWarnings("deprecation") // InputMethodSubtype.getLocale() deprecated in API 24
  private void recordKeyboardLocaleUma() {
    InputMethodManager imm =
        (InputMethodManager) mAppContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    List<InputMethodInfo> ims = imm.getEnabledInputMethodList();
    ArrayList<String> uniqueLanguages = new ArrayList<>();
    for (InputMethodInfo method : ims) {
      List<InputMethodSubtype> submethods = imm.getEnabledInputMethodSubtypeList(method, true);
      for (InputMethodSubtype submethod : submethods) {
        if (submethod.getMode().equals("keyboard")) {
          String language = submethod.getLocale().split("_")[0];
          if (!uniqueLanguages.contains(language)) {
            uniqueLanguages.add(language);
          }
        }
      }
    }
    RecordHistogram.recordCountHistogram("InputMethod.ActiveCount", uniqueLanguages.size());

    InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype();
    Locale systemLocale = Locale.getDefault();
    if (currentSubtype != null && currentSubtype.getLocale() != null && systemLocale != null) {
      String keyboardLanguage = currentSubtype.getLocale().split("_")[0];
      boolean match = systemLocale.getLanguage().equalsIgnoreCase(keyboardLanguage);
      RecordHistogram.recordBooleanHistogram("InputMethod.MatchesSystemLanguage", match);
    }
  }
  /**
   * Handle all necessary tasks that can be delayed until initialization completes.
   *
   * @param activityCreationTimeMs The time of creation for the activity this toolbar belongs to.
   * @param activityName Simple class name for the activity this toolbar belongs to.
   */
  public void onDeferredStartup(final long activityCreationTimeMs, final String activityName) {
    // Record startup performance statistics
    long elapsedTime = SystemClock.elapsedRealtime() - activityCreationTimeMs;
    if (elapsedTime < RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS) {
      ThreadUtils.postOnUiThreadDelayed(
          new Runnable() {
            @Override
            public void run() {
              onDeferredStartup(activityCreationTimeMs, activityName);
            }
          },
          RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS - elapsedTime);
    }
    RecordHistogram.recordTimesHistogram(
        "MobileStartup.ToolbarFirstDrawTime." + activityName,
        mToolbar.getFirstDrawTime() - activityCreationTimeMs,
        TimeUnit.MILLISECONDS);

    long firstFocusTime = mToolbar.getLocationBar().getFirstUrlBarFocusTime();
    if (firstFocusTime != 0) {
      RecordHistogram.recordCustomTimesHistogram(
          "MobileStartup.ToolbarFirstFocusTime." + activityName,
          firstFocusTime - activityCreationTimeMs,
          MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS,
          MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS,
          TimeUnit.MILLISECONDS,
          50);
    }
  }
Esempio n. 3
0
  private static void recordShareHistograms(int count, int filterType) {
    RecordHistogram.recordEnumeratedHistogram(
        "Android.DownloadManager.Share.FileTypes", filterType, DownloadFilter.FILTER_BOUNDARY);

    RecordHistogram.recordLinearCountHistogram(
        "Android.DownloadManager.Share.Count", count, 1, 20, 20);
  }
 private void recordDeferredStartupStats() {
   RecordHistogram.recordLongTimesHistogram(
       "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
       mDeferredStartupDuration,
       TimeUnit.MILLISECONDS);
   RecordHistogram.recordLongTimesHistogram(
       "UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration",
       mMaxTaskDuration,
       TimeUnit.MILLISECONDS);
   RecordHistogram.recordLongTimesHistogram(
       "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime",
       SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
       TimeUnit.MILLISECONDS);
   LocaleManager.getInstance().recordStartupMetrics();
 }
 @SmallTest
 @Feature({"Webapps"})
 public void testUmaThemeColorCustom() {
   assertEquals(
       1,
       RecordHistogram.getHistogramValueCountForTesting(
           WebappUma.HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
           WebappUma.SPLASHSCREEN_COLOR_STATUS_CUSTOM));
 }
Esempio n. 6
0
 private List<SnippetListItem> readRecommendationsArray(JsonReader reader) throws IOException {
   List<SnippetListItem> listSnippetItems = new ArrayList<SnippetListItem>();
   mNumArticles = 0;
   reader.beginArray();
   while (reader.hasNext()) {
     readSnippetGroup(listSnippetItems, reader);
   }
   reader.endArray();
   RecordHistogram.recordSparseSlowlyHistogram("NewTabPage.Snippets.NumArticles", mNumArticles);
   return listSnippetItems;
 }
Esempio n. 7
0
  @Override
  public void didCommitProvisionalLoadForFrame(
      long frameId, boolean isMainFrame, String url, int transitionType) {
    if (isMainFrame && UmaUtils.isRunningApplicationStart()) {
      // Currently it takes about 2000ms to commit a navigation if the measurement
      // begins very early in the browser start. How many buckets (b) are needed to
      // explore the _typical_ values with granularity 100ms and a maximum duration
      // of 1 minute?
      //   s^{n+1} / s^{n} = 2100 / 2000
      //   s = 1.05
      //   s^b = 60000
      //   b = ln(60000) / ln(1.05) ~= 225
      RecordHistogram.recordCustomTimesHistogram(
          "Startup.FirstCommitNavigationTime",
          SystemClock.uptimeMillis() - UmaUtils.getMainEntryPointTime(),
          1,
          60000 /* 1 minute */,
          TimeUnit.MILLISECONDS,
          225);
      UmaUtils.setRunningApplicationStart(false);
    }

    if (isMainFrame) {
      mTab.setIsTabStateDirty(true);
      mTab.updateTitle();
    }

    RewindableIterator<TabObserver> observers = mTab.getTabObservers();
    while (observers.hasNext()) {
      observers
          .next()
          .onDidCommitProvisionalLoadForFrame(mTab, frameId, isMainFrame, url, transitionType);
    }

    observers.rewind();
    while (observers.hasNext()) {
      observers.next().onUrlUpdated(mTab);
    }

    if (!isMainFrame) return;
    mTab.handleDidCommitProvisonalLoadForFrame(url, transitionType);
  }
  /**
   * Handle application level deferred startup tasks that can be lazily done after all the necessary
   * initialization has been completed. Any calls requiring network access should probably go here.
   *
   * <p>Keep these tasks short and break up long tasks into multiple smaller tasks, as they run on
   * the UI thread and are blocking. Remember to follow RAIL guidelines, as much as possible, and
   * that most devices are quite slow, so leave enough buffer.
   */
  @UiThread
  public void initDeferredStartupForApp() {
    if (mDeferredStartupInitializedForApp) return;
    mDeferredStartupInitializedForApp = true;
    ThreadUtils.assertOnUiThread();

    RecordHistogram.recordLongTimesHistogram(
        "UMA.Debug.EnableCrashUpload.DeferredStartUptime2",
        SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
        TimeUnit.MILLISECONDS);

    mDeferredTasks.add(
        new Runnable() {
          @Override
          public void run() {
            // Punt all tasks that may block on disk off onto a background thread.
            initAsyncDiskTask();

            AfterStartupTaskUtils.setStartupComplete();

            PartnerBrowserCustomizations.setOnInitializeAsyncFinished(
                new Runnable() {
                  @Override
                  public void run() {
                    String homepageUrl = HomepageManager.getHomepageUri(mAppContext);
                    LaunchMetrics.recordHomePageLaunchMetrics(
                        HomepageManager.isHomepageEnabled(mAppContext),
                        NewTabPage.isNTPUrl(homepageUrl),
                        homepageUrl);
                  }
                });

            PartnerBookmarksShim.kickOffReading(mAppContext);

            PowerMonitor.create(mAppContext);

            ShareHelper.clearSharedImages();

            OfflinePageUtils.clearSharedOfflineFiles(mAppContext);
          }
        });

    mDeferredTasks.add(
        new Runnable() {
          @Override
          public void run() {
            // Clear any media notifications that existed when Chrome was last killed.
            MediaCaptureNotificationService.clearMediaNotifications(mAppContext);

            startModerateBindingManagementIfNeeded();

            recordKeyboardLocaleUma();
          }
        });

    mDeferredTasks.add(
        new Runnable() {
          @Override
          public void run() {
            // Start or stop Physical Web
            PhysicalWeb.onChromeStart();
          }
        });

    final ChromeApplication application = (ChromeApplication) mAppContext;

    mDeferredTasks.add(
        new Runnable() {
          @Override
          public void run() {
            // Starts syncing with GSA.
            application.createGsaHelper().startSync();
          }
        });

    ProcessInitializationHandler.getInstance().initializeDeferredStartupTasks();
  }
 private static void recordBooleanHistogram(String name, boolean value) {
   if (!sReportingDisabledForTests) {
     RecordHistogram.recordBooleanHistogram(name, value);
   }
 }
 private void recordPassphraseDialogDismissal(int result) {
   RecordHistogram.recordEnumeratedHistogram(
       "Sync.PassphraseDialogDismissed", result, PASSPHRASE_DIALOG_LIMIT);
 }
Esempio n. 11
0
 /**
  * Records metrics related to downloading a page. Should be called after a tap on the download
  * page button.
  *
  * @param tab The Tab containing the page being downloaded.
  */
 public static void recordDownloadPageMetrics(Tab tab) {
   RecordHistogram.recordPercentageHistogram(
       "OfflinePages.SavePage.PercentLoaded", tab.getProgress());
 }
  /**
   * Handle application level deferred startup tasks that can be lazily done after all the necessary
   * initialization has been completed. Any calls requiring network access should probably go here.
   */
  @UiThread
  public void onDeferredStartupForApp() {
    if (mDeferredStartupComplete) return;
    ThreadUtils.assertOnUiThread();

    long startDeferredStartupTime = SystemClock.uptimeMillis();

    RecordHistogram.recordLongTimesHistogram(
        "UMA.Debug.EnableCrashUpload.DeferredStartUptime",
        startDeferredStartupTime - UmaUtils.getMainEntryPointTime(),
        TimeUnit.MILLISECONDS);
    mLocaleManager.recordStartupMetrics();

    // Punt all tasks that may block the UI thread off onto a background thread.
    new AsyncTask<Void, Void, Void>() {
      @Override
      protected Void doInBackground(Void... params) {
        try {
          TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
          long asyncTaskStartTime = SystemClock.uptimeMillis();
          boolean crashDumpDisabled =
              CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
          if (!crashDumpDisabled) {
            RecordHistogram.recordLongTimesHistogram(
                "UMA.Debug.EnableCrashUpload.Uptime2",
                asyncTaskStartTime - UmaUtils.getMainEntryPointTime(),
                TimeUnit.MILLISECONDS);
            PrivacyPreferencesManager.getInstance().enablePotentialCrashUploading();
            MinidumpUploadService.tryUploadAllCrashDumps(mAppContext);
          }
          CrashFileManager crashFileManager = new CrashFileManager(mAppContext.getCacheDir());
          crashFileManager.cleanOutAllNonFreshMinidumpFiles();

          MinidumpUploadService.storeBreakpadUploadStatsInUma(
              ChromePreferenceManager.getInstance(mAppContext));

          // Force a widget refresh in order to wake up any possible zombie widgets.
          // This is needed to ensure the right behavior when the process is suddenly
          // killed.
          BookmarkWidgetProvider.refreshAllWidgets(mAppContext);

          // Initialize whether or not precaching is enabled.
          PrecacheLauncher.updatePrecachingEnabled(mAppContext);

          if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_WEBAPK)) {
            WebApkVersionManager.updateWebApksIfNeeded();
          }

          removeSnapshotDatabase();

          cacheIsChromeDefaultBrowser();

          RecordHistogram.recordLongTimesHistogram(
              "UMA.Debug.EnableCrashUpload.DeferredStartUpDurationAsync",
              SystemClock.uptimeMillis() - asyncTaskStartTime,
              TimeUnit.MILLISECONDS);

          return null;
        } finally {
          TraceEvent.end("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
        }
      }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    AfterStartupTaskUtils.setStartupComplete();

    PartnerBrowserCustomizations.setOnInitializeAsyncFinished(
        new Runnable() {
          @Override
          public void run() {
            String homepageUrl = HomepageManager.getHomepageUri(mAppContext);
            LaunchMetrics.recordHomePageLaunchMetrics(
                HomepageManager.isHomepageEnabled(mAppContext),
                NewTabPage.isNTPUrl(homepageUrl),
                homepageUrl);
          }
        });

    // TODO(aruslan): http://b/6397072 This will be moved elsewhere
    PartnerBookmarksShim.kickOffReading(mAppContext);

    PowerMonitor.create(mAppContext);

    ShareHelper.clearSharedImages(mAppContext);

    // Clear any media notifications that existed when Chrome was last killed.
    MediaCaptureNotificationService.clearMediaNotifications(mAppContext);

    startModerateBindingManagementIfNeeded();

    recordKeyboardLocaleUma();

    ChromeApplication application = (ChromeApplication) mAppContext;
    // Starts syncing with GSA.
    application.createGsaHelper().startSync();

    application.initializeSharedClasses();

    // Start or stop Physical Web
    PhysicalWeb.onChromeStart(application);

    mDeferredStartupComplete = true;

    RecordHistogram.recordLongTimesHistogram(
        "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
        SystemClock.uptimeMillis() - startDeferredStartupTime,
        TimeUnit.MILLISECONDS);
  }
  @Override
  public Notification build() {
    // A note about RemoteViews and updating notifications. When a notification is passed to the
    // {@code NotificationManager} with the same tag and id as a previous notification, an
    // in-place update will be performed. In that case, the actions of all new
    // {@link RemoteViews} will be applied to the views of the old notification. This is safe
    // for actions that overwrite old values such as setting the text of a {@code TextView}, but
    // care must be taken for additive actions. Especially in the case of
    // {@link RemoteViews#addView} the result could be to append new views below stale ones. In
    // that case {@link RemoteViews#removeAllViews} must be called before adding new ones.
    RemoteViews compactView = new RemoteViews(mContext.getPackageName(), R.layout.web_notification);
    RemoteViews bigView = new RemoteViews(mContext.getPackageName(), R.layout.web_notification_big);

    float fontScale = mContext.getResources().getConfiguration().fontScale;
    bigView.setInt(R.id.body, "setMaxLines", calculateMaxBodyLines(fontScale));
    int scaledPadding =
        calculateScaledPadding(fontScale, mContext.getResources().getDisplayMetrics());
    String formattedTime = "";

    // Temporarily allowing disk access. TODO: Fix. See http://crbug.com/577185
    StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
    StrictMode.allowThreadDiskWrites();
    try {
      long time = SystemClock.elapsedRealtime();
      formattedTime = DateFormat.getTimeFormat(mContext).format(new Date());
      RecordHistogram.recordTimesHistogram(
          "Android.StrictMode.NotificationUIBuildTime",
          SystemClock.elapsedRealtime() - time,
          TimeUnit.MILLISECONDS);
    } finally {
      StrictMode.setThreadPolicy(oldPolicy);
    }

    for (RemoteViews view : new RemoteViews[] {compactView, bigView}) {
      view.setTextViewText(R.id.time, formattedTime);
      view.setTextViewText(R.id.title, mTitle);
      view.setTextViewText(R.id.body, mBody);
      view.setTextViewText(R.id.origin, mOrigin);
      view.setImageViewBitmap(R.id.icon, getNormalizedLargeIcon());
      view.setViewPadding(R.id.title, 0, scaledPadding, 0, 0);
      view.setViewPadding(R.id.body_container, 0, scaledPadding, 0, scaledPadding);
      addWorkProfileBadge(view);

      int smallIconId = useMaterial() ? R.id.small_icon_overlay : R.id.small_icon_footer;
      view.setViewVisibility(smallIconId, View.VISIBLE);
      if (mSmallIconBitmap != null) {
        view.setImageViewBitmap(smallIconId, mSmallIconBitmap);
      } else {
        view.setImageViewResource(smallIconId, mSmallIconId);
      }
    }
    addActionButtons(bigView);
    configureSettingsButton(bigView);

    // Note: this is not a NotificationCompat builder so be mindful of the
    // API level of methods you call on the builder.
    Notification.Builder builder = new Notification.Builder(mContext);
    builder.setTicker(mTickerText);
    builder.setContentIntent(mContentIntent);
    builder.setDeleteIntent(mDeleteIntent);
    builder.setDefaults(mDefaults);
    builder.setVibrate(mVibratePattern);
    builder.setWhen(mTimestamp);
    builder.setOnlyAlertOnce(!mRenotify);
    builder.setContent(compactView);

    // Some things are duplicated in the builder to ensure the notification shows correctly on
    // Wear devices and custom lock screens.
    builder.setContentTitle(mTitle);
    builder.setContentText(mBody);
    builder.setSubText(mOrigin);
    builder.setLargeIcon(getNormalizedLargeIcon());
    setSmallIconOnBuilder(builder, mSmallIconId, mSmallIconBitmap);
    for (Action action : mActions) {
      addActionToBuilder(builder, action);
    }
    if (mSettingsAction != null) {
      addActionToBuilder(builder, mSettingsAction);
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      // Notification.Builder.setPublicVersion was added in Android L.
      builder.setPublicVersion(createPublicNotification(mContext));
    }

    Notification notification = builder.build();
    notification.bigContentView = bigView;
    return notification;
  }
Esempio n. 14
0
  @Override
  public void renderProcessGone(boolean processWasOomProtected) {
    Log.i(
        TAG,
        "renderProcessGone() for tab id: "
            + mTab.getId()
            + ", oom protected: "
            + Boolean.toString(processWasOomProtected)
            + ", already needs reload: "
            + Boolean.toString(mTab.needsReload()));
    // Do nothing for subsequent calls that happen while the tab remains crashed. This
    // can occur when the tab is in the background and it shares the renderer with other
    // tabs. After the renderer crashes, the WebContents of its tabs are still around
    // and they still share the RenderProcessHost. When one of the tabs reloads spawning
    // a new renderer for the shared RenderProcessHost and the new renderer crashes
    // again, all tabs sharing this renderer will be notified about the crash (including
    // potential background tabs that did not reload yet).
    if (mTab.needsReload() || mTab.isShowingSadTab()) return;

    // This will replace TabRendererCrashStatus if numbers line up.
    int appState = ApplicationStatus.getStateForApplication();
    boolean applicationRunning = (appState == ApplicationState.HAS_RUNNING_ACTIVITIES);
    boolean applicationPaused = (appState == ApplicationState.HAS_PAUSED_ACTIVITIES);
    @TabRendererExitStatus int rendererExitStatus = TAB_RENDERER_EXIT_STATUS_MAX;
    if (processWasOomProtected) {
      if (applicationRunning) {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_OOM_PROTECTED_IN_RUNNING_APP;
      } else if (applicationPaused) {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_OOM_PROTECTED_IN_PAUSED_APP;
      } else {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_OOM_PROTECTED_IN_BACKGROUND_APP;
      }
    } else {
      if (applicationRunning) {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_NOT_PROTECTED_IN_RUNNING_APP;
      } else if (applicationPaused) {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_NOT_PROTECTED_IN_PAUSED_APP;
      } else {
        rendererExitStatus = TAB_RENDERER_EXIT_STATUS_NOT_PROTECTED_IN_BACKGROUND_APP;
      }
    }
    RecordHistogram.recordEnumeratedHistogram(
        "Tab.RendererExitStatus", rendererExitStatus, TAB_RENDERER_EXIT_STATUS_MAX);

    int activityState =
        ApplicationStatus.getStateForActivity(mTab.getWindowAndroid().getActivity().get());
    int rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_MAX;
    if (!processWasOomProtected
        || activityState == ActivityState.PAUSED
        || activityState == ActivityState.STOPPED
        || activityState == ActivityState.DESTROYED) {
      // The tab crashed in background or was killed by the OS out-of-memory killer.
      // setNeedsReload(true);
      mTab.setNeedsReload(true);
      if (applicationRunning) {
        rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_HIDDEN_IN_FOREGROUND_APP;
      } else {
        rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_HIDDEN_IN_BACKGROUND_APP;
      }
    } else {
      rendererCrashStatus = TAB_RENDERER_CRASH_STATUS_SHOWN_IN_FOREGROUND_APP;
      mTab.showSadTab();
      // This is necessary to correlate histogram data with stability counts.
      UmaSessionStats.logRendererCrash();
    }
    RecordHistogram.recordEnumeratedHistogram(
        "Tab.RendererCrashStatus", rendererCrashStatus, TAB_RENDERER_CRASH_STATUS_MAX);

    mTab.handleTabCrash();

    boolean sadTabShown = mTab.isShowingSadTab();
    RewindableIterator<TabObserver> observers = mTab.getTabObservers();
    while (observers.hasNext()) {
      observers.next().onCrash(mTab, sadTabShown);
    }
  }