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 2a8bbbc7d112ab5fa67f635f74152bf5068cc710..a2bbef179d142f361bd24fee3fc7b7c520972b6b 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 |
@@ -59,6 +59,8 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
static final String SHOW_SIGNIN_PAGE = "ShowSignIn"; |
static final String SHOW_DATA_REDUCTION_PAGE = "ShowDataReduction"; |
+ static final String POST_NATIVE_SETUP_NEEDED = "PostNativeSetupNeeded"; |
+ |
// Outgoing results: |
public static final String RESULT_CLOSE_APP = "Close App"; |
public static final String RESULT_SIGNIN_ACCOUNT_NAME = "ResultSignInTo"; |
@@ -98,6 +100,7 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
private String mResultSignInAccountName; |
private boolean mResultShowSignInSettings; |
+ private boolean mPostNativePageSequenceCreated; |
private boolean mNativeSideIsInitialized; |
private ProfileDataCache mProfileDataCache; |
@@ -105,6 +108,8 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
protected Bundle mFreProperties; |
+ private Runnable mSetUpPropertiesPostNative; |
+ |
private List<Callable<FirstRunPage>> mPages; |
private List<Integer> mFreProgressStates; |
@@ -125,27 +130,49 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
if (mShowWelcomePage) { |
mPages.add(pageOf(ToSAndUMAFirstRunFragment.class)); |
mFreProgressStates.add(FRE_PROGRESS_WELCOME_SHOWN); |
+ } else { |
+ // Otherwise, if we're skipping past the welcome page, then init the |
+ // native process and determine if data reduction proxy and signin |
+ // pages should be shown - which both depend on native code. |
+ createPostNativePageSequence(); |
} |
+ } |
+ |
+ private void createPostNativePageSequence() { |
+ if (mPostNativePageSequenceCreated) return; |
+ ensureBrowserProcessInitialized(); |
+ if (mFreProperties.getBoolean(POST_NATIVE_SETUP_NEEDED) |
+ && mSetUpPropertiesPostNative != null) { |
+ mSetUpPropertiesPostNative.run(); |
+ mFreProperties.remove(POST_NATIVE_SETUP_NEEDED); |
+ } |
+ |
+ boolean notifyAdapter = false; |
// An optional Data Saver page. |
if (mFreProperties.getBoolean(SHOW_DATA_REDUCTION_PAGE)) { |
mPages.add(pageOf(DataReductionProxyFirstRunFragment.class)); |
mFreProgressStates.add(FRE_PROGRESS_DATA_SAVER_SHOWN); |
+ notifyAdapter = true; |
} |
// An optional sign-in page. |
if (mFreProperties.getBoolean(SHOW_SIGNIN_PAGE)) { |
mPages.add(pageOf(AccountFirstRunFragment.class)); |
mFreProgressStates.add(FRE_PROGRESS_SIGNIN_SHOWN); |
+ notifyAdapter = true; |
+ } |
+ |
+ if (notifyAdapter && mPagerAdapter != null) { |
+ mPagerAdapter.notifyDataSetChanged(); |
} |
+ mPostNativePageSequenceCreated = true; |
} |
// Activity: |
@Override |
protected void onCreate(Bundle savedInstanceState) { |
- initializeBrowserProcess(); |
- |
super.onCreate(savedInstanceState); |
if (savedInstanceState != null) { |
@@ -170,13 +197,14 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
new FirstRunFlowSequencer(this, mFreProperties) { |
@Override |
- public void onFlowIsKnown(Bundle freProperties) { |
+ public void onFlowIsKnown(Bundle freProperties, Runnable setUpPropertiesPostNative) { |
if (freProperties == null) { |
completeFirstRunExperience(); |
return; |
} |
mFreProperties = freProperties; |
+ mSetUpPropertiesPostNative = setUpPropertiesPostNative; |
mShowWelcomePage = mFreProperties.getBoolean(SHOW_WELCOME_PAGE); |
createPageSequence(); |
@@ -226,6 +254,12 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
@Override |
protected void onStart() { |
super.onStart(); |
+ // Since the FRE may be shown before any tab is shown, mark that this is the point at |
+ // which Chrome went to foreground. This is needed as otherwise an assert will be hit |
+ // in UmaUtils.getForegroundStartTime() when recording the time taken to load the first |
+ // page (which happens after native has been initialized possibly while FRE is still |
+ // active). |
+ UmaUtils.recordForegroundStartTime(); |
stopProgressionIfNotAcceptedTermsOfService(); |
if (!mFreProperties.getBoolean(EXTRA_USE_FRE_FLOW_SEQUENCER)) { |
if (FirstRunStatus.getFirstRunFlowComplete(this)) { |
@@ -290,6 +324,7 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
@Override |
public void completeFirstRunExperience() { |
+ ensureBrowserProcessInitialized(); |
if (!TextUtils.isEmpty(mResultSignInAccountName)) { |
boolean defaultAccountName = |
sGlue.isDefaultAccountName(getApplicationContext(), mResultSignInAccountName); |
@@ -360,6 +395,13 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
@Override |
public void acceptTermsOfService(boolean allowCrashUpload) { |
+ // At this point, we're advancing past the first page, which has no native |
+ // dependencies to further pages in the sequence, if any. These require |
+ // native to be initialized and will be added by the call below if needed. |
+ // Additionally, the calls later in this function also require native |
+ // to be initialized. |
+ createPostNativePageSequence(); |
+ |
// If default is true then it corresponds to opt-out and false corresponds to opt-in. |
UmaUtils.recordMetricsReportingDefaultOptIn(!DEFAULT_METRICS_AND_CRASH_REPORTING); |
sGlue.acceptTermsOfService(allowCrashUpload); |
@@ -461,17 +503,17 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD |
while (currentPageIndex < mPagerAdapter.getCount()) { |
FirstRunPage currentPage = (FirstRunPage) mPagerAdapter.getItem(currentPageIndex); |
if (!currentPage.shouldSkipPageOnCreate(getApplicationContext())) return; |
+ // If we're advancing to the next page, ensure to init the post native page |
+ // sequence - as every page except the first requires that to be initialized. |
+ // This is a no-op if it has already been done. |
+ createPostNativePageSequence(); |
if (!jumpToPage(currentPageIndex + 1)) return; |
currentPageIndex = mPager.getCurrentItem(); |
} |
} |
- private void initializeBrowserProcess() { |
- // The Chrome browser process must be started here because this Activity |
- // may be started explicitly for tests cases, from Android notifications or |
- // when the application is restoring a FRE fragment after Chrome being killed. |
- // This should happen before super.onCreate() because it might recreate a fragment, |
- // and a fragment might depend on the native library. |
+ private void ensureBrowserProcessInitialized() { |
+ if (mNativeSideIsInitialized) return; |
Ted C
2016/12/01 21:59:06
Should we just make this Activity an AsyncInitiali
Alexei Svitkine (slow)
2016/12/02 18:34:54
This seems like a reasonable thing to do, but it s
Ted C
2016/12/02 21:34:52
I'm not 100% dead set on making it an AsyncInitial
Alexei Svitkine (slow)
2016/12/02 22:42:32
In my local testing, I did not see a considerable
Yusuf
2016/12/02 23:31:23
This is turning more into a UX discussion at this
Ted C
2016/12/02 23:47:33
Lower end devices are very, very slow at loading l
|
try { |
ChromeBrowserInitializer.getInstance(this).handleSynchronousStartup(); |
mNativeSideIsInitialized = true; |