/**
   * Ensures correctness of the visibilityDetermined() calls, that should be always preceded by
   * setInForeground().
   */
  @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
  @LargeTest
  @Feature({"ProcessManagement"})
  public void testVisibilityDetermined() throws Exception {
    // Create a tab in foreground and wait until it is loaded.
    final Tab fgTab =
        ChromeApplication.getDocumentTabModelSelector()
            .getTabById(launchViaViewIntent(false, URL_1, "Page 1"));
    int initialNavigationPid = fgTab.getContentViewCore().getCurrentRenderProcessId();
    // Ensure the following calls happened:
    //  - FG - setInForeground(true) - when the tab is created in the foreground
    //  - DETERMINED - visibilityDetermined() - after the initial navigation is committed
    assertEquals("FG;DETERMINED;", mBindingManager.getVisibilityCalls(initialNavigationPid));

    // Navigate to about:version which requires a different renderer.
    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                fgTab.loadUrl(new LoadUrlParams(ABOUT_VERSION_PATH));
              }
            });
    ChromeTabUtils.waitForTabPageLoaded(fgTab, ABOUT_VERSION_PATH);
    int secondNavigationPid = fgTab.getContentViewCore().getCurrentRenderProcessId();
    assertTrue(secondNavigationPid != initialNavigationPid);
    // Ensure the following calls happened:
    //  - BG - setInForeground(false) - when the renderer is created for uncommited frame
    //  - FG - setInForeground(true) - when the frame is swapped in on commit
    //  - DETERMINED - visibilityDetermined() - after the navigation is committed
    assertEquals("BG;FG;DETERMINED;", mBindingManager.getVisibilityCalls(secondNavigationPid));

    // Open a tab in the background and load it.
    final Tab bgTab =
        ChromeApplication.getDocumentTabModelSelector()
            .getTabById(launchViaLaunchDocumentInstanceInBackground(false, URL_2, "Page 2"));
    int bgNavigationPid = bgTab.getContentViewCore().getCurrentRenderProcessId();
    // Ensure the following calls happened:
    //  - BG - setInForeground(false) - when tab is created in the background
    //  - DETERMINED - visibilityDetermined() - after the navigation is committed
    assertEquals("BG;DETERMINED;", mBindingManager.getVisibilityCalls(bgNavigationPid));
  }
コード例 #2
0
  /**
   * 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);
  }
  /**
   * Verifies that a renderer that crashes in foreground has the correct visibility when recreated.
   */
  @LargeTest
  @Feature({"ProcessManagement"})
  public void testCrashInForeground() throws Exception {
    // Create a tab in foreground and wait until it is loaded.
    final Tab tab =
        ChromeApplication.getDocumentTabModelSelector()
            .getTabById(launchViaViewIntent(false, URL_1, "Page 1"));

    // Kill the renderer and wait for the crash to be noted by the browser process.
    assertTrue(
        ChildProcessLauncher.crashProcessForTesting(
            tab.getContentViewCore().getCurrentRenderProcessId()));

    assertTrue(
        "Renderer crash wasn't noticed by the browser.",
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return tab.getContentViewCore().getCurrentRenderProcessId() == 0;
              }
            }));

    // Reload the tab, respawning the renderer.
    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                tab.reload();
              }
            });

    // Wait until the process is spawned and its visibility is determined.
    assertTrue(
        "Process for the crashed tab was not respawned.",
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return tab.getContentViewCore().getCurrentRenderProcessId() != 0;
              }
            }));

    assertTrue(
        "isInForeground() was not called for the process.",
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return mBindingManager.wasSetInForegroundCalled(
                    tab.getContentViewCore().getCurrentRenderProcessId());
              }
            }));

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                // Verify the visibility of the renderer.
                assertTrue(
                    mBindingManager.isInForeground(
                        tab.getContentViewCore().getCurrentRenderProcessId()));
              }
            });
  }
  /**
   * Verifies that the .setProcessInForeground() signal is called correctly as the tabs are created
   * and switched.
   */
  @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
  @LargeTest
  @Feature({"ProcessManagement"})
  public void testTabSwitching() throws Exception {
    // Create two tabs and wait until they are loaded, so that their renderers are around.
    final Tab[] tabs = new Tab[2];
    final int[] tabIds = new int[2];
    final DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector();
    tabIds[0] = launchViaViewIntent(false, URL_1, "Page 1");
    tabIds[1] = launchViaLaunchDocumentInstanceInBackground(false, URL_2, "Page 2");

    final TabModel tabModel = selector.getCurrentModel();
    tabs[0] = selector.getTabById(tabIds[0]);
    tabs[1] = selector.getTabById(tabIds[1]);

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                // Make sure that the renderers were spawned.
                assertTrue(tabs[0].getContentViewCore().getCurrentRenderProcessId() > 0);
                assertTrue(tabs[1].getContentViewCore().getCurrentRenderProcessId() > 0);

                // Verify that the renderer of the foreground tab was signalled as visible.
                assertTrue(
                    mBindingManager.isInForeground(
                        tabs[0].getContentViewCore().getCurrentRenderProcessId()));
                // Verify that the renderer of the tab loaded in background was signalled as not
                // visible.
                assertTrue(
                    mBindingManager.isInBackground(
                        tabs[1].getContentViewCore().getCurrentRenderProcessId()));
              }
            });

    // Wait until the activity of tabs[1] is resumed.
    assertTrue(
        "Activity was not resumed.",
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                // Switch to the tab that crashed in background.
                // http://crbug.com/509866: TabModelUtils#setIndex() sometimes fails. So we need to
                // call it repeatedly.
                getInstrumentation()
                    .runOnMainSync(
                        new Runnable() {
                          @Override
                          public void run() {
                            TabModelUtils.setIndex(
                                tabModel, TabModelUtils.getTabIndexById(tabModel, tabs[1].getId()));
                          }
                        });

                return ApplicationStatus.getStateForActivity(((DocumentTab) tabs[1]).getActivity())
                    == ActivityState.RESUMED;
              }
            }));

    // Verify that the renderer visibility was flipped.
    assertTrue(
        mBindingManager.isInBackground(tabs[0].getContentViewCore().getCurrentRenderProcessId()));
    assertTrue(
        mBindingManager.isInForeground(tabs[1].getContentViewCore().getCurrentRenderProcessId()));
  }