| Index: chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
 | 
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
 | 
| index 66d20a5a0a2f54ce6622f13bbcea356a99573abd..4b31f5b46c35bce9c94e4e4084e87a97b51f0b5f 100644
 | 
| --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
 | 
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
 | 
| @@ -27,6 +27,7 @@ import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
 | 
|  import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoUtils;
 | 
|  import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma;
 | 
|  import org.chromium.chrome.browser.profiles.Profile;
 | 
| +import org.chromium.chrome.browser.searchwidget.SearchWidgetProvider;
 | 
|  import org.chromium.chrome.browser.util.IntentUtils;
 | 
|  
 | 
|  import java.lang.ref.WeakReference;
 | 
| @@ -46,6 +47,24 @@ import java.util.concurrent.Callable;
 | 
|   * The activity might be run more than once, e.g. 1) for ToS and sign-in, and 2) for intro.
 | 
|   */
 | 
|  public class FirstRunActivity extends AsyncInitializationActivity implements FirstRunPageDelegate {
 | 
| +    /** Alerted about various events when FirstRunActivity performs them. */
 | 
| +    public interface FirstRunActivityObserver {
 | 
| +        /** See {@link #onFlowIsKnown}. */
 | 
| +        void onFlowIsKnown();
 | 
| +
 | 
| +        /** See {@link #acceptTermsOfService}. */
 | 
| +        void onAcceptTermsOfService();
 | 
| +
 | 
| +        /** See {@link #jumpToPage}. */
 | 
| +        void onJumpToPage(int position);
 | 
| +
 | 
| +        /** Called when First Run is completed. */
 | 
| +        void onUpdateCachedEngineName();
 | 
| +
 | 
| +        /** See {@link #abortFirstRunExperience}. */
 | 
| +        void onAbortFirstRunExperience();
 | 
| +    }
 | 
| +
 | 
|      protected static final String TAG = "FirstRunActivity";
 | 
|  
 | 
|      // Incoming parameters:
 | 
| @@ -95,6 +114,8 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|      @VisibleForTesting
 | 
|      static FirstRunGlue sGlue = new FirstRunGlueImpl();
 | 
|  
 | 
| +    private static FirstRunActivityObserver sObserver;
 | 
| +
 | 
|      private boolean mShowWelcomePage = true;
 | 
|  
 | 
|      private String mResultSignInAccountName;
 | 
| @@ -241,6 +262,7 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|                      skipPagesIfNecessary();
 | 
|                  }
 | 
|  
 | 
| +                if (sObserver != null) sObserver.onFlowIsKnown();
 | 
|                  recordFreProgressHistogram(mFreProgressStates.get(0));
 | 
|              }
 | 
|          };
 | 
| @@ -391,6 +413,7 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|          finishAllTheActivities(getLocalClassName(), Activity.RESULT_CANCELED, intent);
 | 
|  
 | 
|          sendPendingIntentIfNecessary(false);
 | 
| +        if (sObserver != null) sObserver.onAbortFirstRunExperience();
 | 
|      }
 | 
|  
 | 
|      @Override
 | 
| @@ -442,6 +465,10 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|          resultData.putExtras(mFreProperties);
 | 
|          finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, resultData);
 | 
|  
 | 
| +        // Update the search engine name cached by the widget.
 | 
| +        SearchWidgetProvider.updateCachedEngineName();
 | 
| +        if (sObserver != null) sObserver.onUpdateCachedEngineName();
 | 
| +
 | 
|          sendPendingIntentIfNecessary(true);
 | 
|      }
 | 
|  
 | 
| @@ -464,7 +491,9 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|  
 | 
|      @Override
 | 
|      public boolean didAcceptTermsOfService() {
 | 
| -        return sGlue.didAcceptTermsOfService(getApplicationContext());
 | 
| +        boolean result = sGlue.didAcceptTermsOfService(getApplicationContext());
 | 
| +        if (sObserver != null) sObserver.onAcceptTermsOfService();
 | 
| +        return result;
 | 
|      }
 | 
|  
 | 
|      @Override
 | 
| @@ -546,6 +575,8 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|       * @param position A page index to transition to.
 | 
|       */
 | 
|      private boolean jumpToPage(int position) {
 | 
| +        if (sObserver != null) sObserver.onJumpToPage(position);
 | 
| +
 | 
|          if (mShowWelcomePage && !didAcceptTermsOfService()) {
 | 
|              return position == 0;
 | 
|          }
 | 
| @@ -603,9 +634,9 @@ public class FirstRunActivity extends AsyncInitializationActivity implements Fir
 | 
|          CustomTabActivity.showInfoPage(this, getString(url));
 | 
|      }
 | 
|  
 | 
| -    /** Returns whether or not First Run is ready for interaction. */
 | 
|      @VisibleForTesting
 | 
| -    public boolean isPostNativePageSequenceCreated() {
 | 
| -        return mPostNativePageSequenceCreated;
 | 
| +    public static void setObserverForTest(FirstRunActivityObserver observer) {
 | 
| +        assert sObserver == null;
 | 
| +        sObserver = observer;
 | 
|      }
 | 
|  }
 | 
| 
 |