OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.firstrun; | 5 package org.chromium.chrome.browser.firstrun; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.app.Fragment; | 8 import android.app.Fragment; |
9 import android.app.PendingIntent; | 9 import android.app.PendingIntent; |
10 import android.app.PendingIntent.CanceledException; | 10 import android.app.PendingIntent.CanceledException; |
11 import android.content.Intent; | 11 import android.content.Intent; |
12 import android.os.Bundle; | 12 import android.os.Bundle; |
13 import android.text.TextUtils; | 13 import android.text.TextUtils; |
14 | 14 |
15 import org.chromium.base.ApplicationStatus; | 15 import org.chromium.base.ApplicationStatus; |
16 import org.chromium.base.Log; | 16 import org.chromium.base.Log; |
17 import org.chromium.base.VisibleForTesting; | 17 import org.chromium.base.VisibleForTesting; |
18 import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; | 18 import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; |
19 import org.chromium.chrome.R; | 19 import org.chromium.chrome.R; |
20 import org.chromium.chrome.browser.ChromeApplication; | 20 import org.chromium.chrome.browser.ChromeApplication; |
21 import org.chromium.chrome.browser.customtabs.CustomTabActivity; | 21 import org.chromium.chrome.browser.customtabs.CustomTabActivity; |
22 import org.chromium.chrome.browser.customtabs.CustomTabsConnection; | 22 import org.chromium.chrome.browser.customtabs.CustomTabsConnection; |
23 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | 23 import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
24 import org.chromium.chrome.browser.init.AsyncInitializationActivity; | 24 import org.chromium.chrome.browser.init.AsyncInitializationActivity; |
25 import org.chromium.chrome.browser.metrics.UmaUtils; | 25 import org.chromium.chrome.browser.metrics.UmaUtils; |
26 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; | 26 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; |
27 import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoU
tils; | 27 import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoU
tils; |
28 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU
ma; | 28 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU
ma; |
29 import org.chromium.chrome.browser.profiles.Profile; | 29 import org.chromium.chrome.browser.profiles.Profile; |
30 import org.chromium.chrome.browser.searchwidget.SearchWidgetProvider; | |
31 import org.chromium.chrome.browser.util.IntentUtils; | 30 import org.chromium.chrome.browser.util.IntentUtils; |
32 | 31 |
33 import java.lang.ref.WeakReference; | 32 import java.lang.ref.WeakReference; |
34 import java.lang.reflect.Constructor; | 33 import java.lang.reflect.Constructor; |
35 import java.util.ArrayList; | 34 import java.util.ArrayList; |
36 import java.util.HashSet; | 35 import java.util.HashSet; |
37 import java.util.List; | 36 import java.util.List; |
38 import java.util.Set; | 37 import java.util.Set; |
39 import java.util.concurrent.Callable; | 38 import java.util.concurrent.Callable; |
40 | 39 |
41 /** | 40 /** |
42 * Handles the First Run Experience sequences shown to the user launching Chrome
for the first time. | 41 * Handles the First Run Experience sequences shown to the user launching Chrome
for the first time. |
43 * It supports only a simple format of FRE: | 42 * It supports only a simple format of FRE: |
44 * [Welcome] | 43 * [Welcome] |
45 * [Intro pages...] | 44 * [Intro pages...] |
46 * [Sign-in page] | 45 * [Sign-in page] |
47 * The activity might be run more than once, e.g. 1) for ToS and sign-in, and 2)
for intro. | 46 * The activity might be run more than once, e.g. 1) for ToS and sign-in, and 2)
for intro. |
48 */ | 47 */ |
49 public class FirstRunActivity extends AsyncInitializationActivity implements Fir
stRunPageDelegate { | 48 public class FirstRunActivity extends AsyncInitializationActivity implements Fir
stRunPageDelegate { |
50 /** Alerted about various events when FirstRunActivity performs them. */ | |
51 public interface FirstRunActivityObserver { | |
52 /** See {@link #onFlowIsKnown}. */ | |
53 void onFlowIsKnown(); | |
54 | |
55 /** See {@link #acceptTermsOfService}. */ | |
56 void onAcceptTermsOfService(); | |
57 | |
58 /** See {@link #jumpToPage}. */ | |
59 void onJumpToPage(int position); | |
60 | |
61 /** Called when First Run is completed. */ | |
62 void onUpdateCachedEngineName(); | |
63 | |
64 /** See {@link #abortFirstRunExperience}. */ | |
65 void onAbortFirstRunExperience(); | |
66 } | |
67 | |
68 protected static final String TAG = "FirstRunActivity"; | 49 protected static final String TAG = "FirstRunActivity"; |
69 | 50 |
70 // Incoming parameters: | 51 // Incoming parameters: |
71 public static final String EXTRA_COMING_FROM_CHROME_ICON = "Extra.ComingFrom
ChromeIcon"; | 52 public static final String EXTRA_COMING_FROM_CHROME_ICON = "Extra.ComingFrom
ChromeIcon"; |
72 public static final String EXTRA_USE_FRE_FLOW_SEQUENCER = "Extra.UseFreFlowS
equencer"; | 53 public static final String EXTRA_USE_FRE_FLOW_SEQUENCER = "Extra.UseFreFlowS
equencer"; |
73 public static final String EXTRA_START_LIGHTWEIGHT_FRE = "Extra.StartLightwe
ightFRE"; | 54 public static final String EXTRA_START_LIGHTWEIGHT_FRE = "Extra.StartLightwe
ightFRE"; |
74 public static final String EXTRA_CHROME_LAUNCH_INTENT = "Extra.FreChromeLaun
chIntent"; | 55 public static final String EXTRA_CHROME_LAUNCH_INTENT = "Extra.FreChromeLaun
chIntent"; |
75 public static final String EXTRA_FINISH_ON_TOUCH_OUTSIDE = "Extra.FreFinishO
nTouchOutside"; | 56 public static final String EXTRA_FINISH_ON_TOUCH_OUTSIDE = "Extra.FreFinishO
nTouchOutside"; |
76 | 57 |
77 static final String SHOW_WELCOME_PAGE = "ShowWelcome"; | 58 static final String SHOW_WELCOME_PAGE = "ShowWelcome"; |
(...skipping 29 matching lines...) Expand all Loading... |
107 private static final int FRE_PROGRESS_COMPLETED_NOT_SIGNED_IN = 5; | 88 private static final int FRE_PROGRESS_COMPLETED_NOT_SIGNED_IN = 5; |
108 private static final int FRE_PROGRESS_MAX = 6; | 89 private static final int FRE_PROGRESS_MAX = 6; |
109 private static final EnumeratedHistogramSample sMobileFreProgressMainIntentH
istogram = | 90 private static final EnumeratedHistogramSample sMobileFreProgressMainIntentH
istogram = |
110 new EnumeratedHistogramSample("MobileFre.Progress.MainIntent", FRE_P
ROGRESS_MAX); | 91 new EnumeratedHistogramSample("MobileFre.Progress.MainIntent", FRE_P
ROGRESS_MAX); |
111 private static final EnumeratedHistogramSample sMobileFreProgressViewIntentH
istogram = | 92 private static final EnumeratedHistogramSample sMobileFreProgressViewIntentH
istogram = |
112 new EnumeratedHistogramSample("MobileFre.Progress.ViewIntent", FRE_P
ROGRESS_MAX); | 93 new EnumeratedHistogramSample("MobileFre.Progress.ViewIntent", FRE_P
ROGRESS_MAX); |
113 | 94 |
114 @VisibleForTesting | 95 @VisibleForTesting |
115 static FirstRunGlue sGlue = new FirstRunGlueImpl(); | 96 static FirstRunGlue sGlue = new FirstRunGlueImpl(); |
116 | 97 |
117 private static FirstRunActivityObserver sObserver; | |
118 | |
119 private boolean mShowWelcomePage = true; | 98 private boolean mShowWelcomePage = true; |
120 | 99 |
121 private String mResultSignInAccountName; | 100 private String mResultSignInAccountName; |
122 private boolean mResultShowSignInSettings; | 101 private boolean mResultShowSignInSettings; |
123 | 102 |
124 private boolean mFlowIsKnown; | 103 private boolean mFlowIsKnown; |
125 private boolean mPostNativePageSequenceCreated; | 104 private boolean mPostNativePageSequenceCreated; |
126 private boolean mNativeSideIsInitialized; | 105 private boolean mNativeSideIsInitialized; |
127 private Set<FirstRunPage> mPagesToNotifyOfNativeInit; | 106 private Set<FirstRunPage> mPagesToNotifyOfNativeInit; |
128 private boolean mDeferredCompleteFRE; | 107 private boolean mDeferredCompleteFRE; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 | 234 |
256 mPagerAdapter = | 235 mPagerAdapter = |
257 new FirstRunPagerAdapter(getFragmentManager(), mPages, m
FreProperties); | 236 new FirstRunPagerAdapter(getFragmentManager(), mPages, m
FreProperties); |
258 stopProgressionIfNotAcceptedTermsOfService(); | 237 stopProgressionIfNotAcceptedTermsOfService(); |
259 mPager.setAdapter(mPagerAdapter); | 238 mPager.setAdapter(mPagerAdapter); |
260 | 239 |
261 if (mNativeSideIsInitialized) { | 240 if (mNativeSideIsInitialized) { |
262 skipPagesIfNecessary(); | 241 skipPagesIfNecessary(); |
263 } | 242 } |
264 | 243 |
265 if (sObserver != null) sObserver.onFlowIsKnown(); | |
266 recordFreProgressHistogram(mFreProgressStates.get(0)); | 244 recordFreProgressHistogram(mFreProgressStates.get(0)); |
267 } | 245 } |
268 }; | 246 }; |
269 mFirstRunFlowSequencer.start(); | 247 mFirstRunFlowSequencer.start(); |
270 | 248 |
271 recordFreProgressHistogram(FRE_PROGRESS_STARTED); | 249 recordFreProgressHistogram(FRE_PROGRESS_STARTED); |
272 } | 250 } |
273 | 251 |
274 @Override | 252 @Override |
275 public void finishNativeInitialization() { | 253 public void finishNativeInitialization() { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 384 } |
407 | 385 |
408 @Override | 386 @Override |
409 public void abortFirstRunExperience() { | 387 public void abortFirstRunExperience() { |
410 Intent intent = new Intent(); | 388 Intent intent = new Intent(); |
411 if (mFreProperties != null) intent.putExtras(mFreProperties); | 389 if (mFreProperties != null) intent.putExtras(mFreProperties); |
412 intent.putExtra(RESULT_CLOSE_APP, true); | 390 intent.putExtra(RESULT_CLOSE_APP, true); |
413 finishAllTheActivities(getLocalClassName(), Activity.RESULT_CANCELED, in
tent); | 391 finishAllTheActivities(getLocalClassName(), Activity.RESULT_CANCELED, in
tent); |
414 | 392 |
415 sendPendingIntentIfNecessary(false); | 393 sendPendingIntentIfNecessary(false); |
416 if (sObserver != null) sObserver.onAbortFirstRunExperience(); | |
417 } | 394 } |
418 | 395 |
419 @Override | 396 @Override |
420 public void completeFirstRunExperience() { | 397 public void completeFirstRunExperience() { |
421 if (!mNativeSideIsInitialized) { | 398 if (!mNativeSideIsInitialized) { |
422 mDeferredCompleteFRE = true; | 399 mDeferredCompleteFRE = true; |
423 return; | 400 return; |
424 } | 401 } |
425 if (!TextUtils.isEmpty(mResultSignInAccountName)) { | 402 if (!TextUtils.isEmpty(mResultSignInAccountName)) { |
426 boolean defaultAccountName = | 403 boolean defaultAccountName = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 DataReductionProxyUma | 435 DataReductionProxyUma |
459 .dataReductionProxyUIAction(DataReductionProxyUma.ACTION
_FRE_DISABLED); | 436 .dataReductionProxyUIAction(DataReductionProxyUma.ACTION
_FRE_DISABLED); |
460 DataReductionPromoUtils.saveFrePromoOptOut(true); | 437 DataReductionPromoUtils.saveFrePromoOptOut(true); |
461 } | 438 } |
462 } | 439 } |
463 | 440 |
464 Intent resultData = new Intent(); | 441 Intent resultData = new Intent(); |
465 resultData.putExtras(mFreProperties); | 442 resultData.putExtras(mFreProperties); |
466 finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, resultDa
ta); | 443 finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, resultDa
ta); |
467 | 444 |
468 // Update the search engine name cached by the widget. | |
469 SearchWidgetProvider.updateCachedEngineName(); | |
470 if (sObserver != null) sObserver.onUpdateCachedEngineName(); | |
471 | |
472 sendPendingIntentIfNecessary(true); | 445 sendPendingIntentIfNecessary(true); |
473 } | 446 } |
474 | 447 |
475 @Override | 448 @Override |
476 public void refuseSignIn() { | 449 public void refuseSignIn() { |
477 sSigninChoiceHistogram.record(SIGNIN_NO_THANKS); | 450 sSigninChoiceHistogram.record(SIGNIN_NO_THANKS); |
478 mResultSignInAccountName = null; | 451 mResultSignInAccountName = null; |
479 mResultShowSignInSettings = false; | 452 mResultShowSignInSettings = false; |
480 } | 453 } |
481 | 454 |
482 @Override | 455 @Override |
483 public void acceptSignIn(String accountName) { | 456 public void acceptSignIn(String accountName) { |
484 mResultSignInAccountName = accountName; | 457 mResultSignInAccountName = accountName; |
485 } | 458 } |
486 | 459 |
487 @Override | 460 @Override |
488 public void askToOpenSignInSettings() { | 461 public void askToOpenSignInSettings() { |
489 mResultShowSignInSettings = true; | 462 mResultShowSignInSettings = true; |
490 } | 463 } |
491 | 464 |
492 @Override | 465 @Override |
493 public boolean didAcceptTermsOfService() { | 466 public boolean didAcceptTermsOfService() { |
494 boolean result = sGlue.didAcceptTermsOfService(getApplicationContext()); | 467 return sGlue.didAcceptTermsOfService(getApplicationContext()); |
495 if (sObserver != null) sObserver.onAcceptTermsOfService(); | |
496 return result; | |
497 } | 468 } |
498 | 469 |
499 @Override | 470 @Override |
500 public void acceptTermsOfService(boolean allowCrashUpload) { | 471 public void acceptTermsOfService(boolean allowCrashUpload) { |
501 // If default is true then it corresponds to opt-out and false correspon
ds to opt-in. | 472 // If default is true then it corresponds to opt-out and false correspon
ds to opt-in. |
502 UmaUtils.recordMetricsReportingDefaultOptIn(!DEFAULT_METRICS_AND_CRASH_R
EPORTING); | 473 UmaUtils.recordMetricsReportingDefaultOptIn(!DEFAULT_METRICS_AND_CRASH_R
EPORTING); |
503 sGlue.acceptTermsOfService(allowCrashUpload); | 474 sGlue.acceptTermsOfService(allowCrashUpload); |
504 FirstRunStatus.setSkipWelcomePage(true); | 475 FirstRunStatus.setSkipWelcomePage(true); |
505 flushPersistentData(); | 476 flushPersistentData(); |
506 stopProgressionIfNotAcceptedTermsOfService(); | 477 stopProgressionIfNotAcceptedTermsOfService(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 Log.e(TAG, "Unable to send PendingIntent.", e); | 539 Log.e(TAG, "Unable to send PendingIntent.", e); |
569 } | 540 } |
570 } | 541 } |
571 | 542 |
572 /** | 543 /** |
573 * Transitions to a given page. | 544 * Transitions to a given page. |
574 * @return Whether the transition to a given page was allowed. | 545 * @return Whether the transition to a given page was allowed. |
575 * @param position A page index to transition to. | 546 * @param position A page index to transition to. |
576 */ | 547 */ |
577 private boolean jumpToPage(int position) { | 548 private boolean jumpToPage(int position) { |
578 if (sObserver != null) sObserver.onJumpToPage(position); | |
579 | |
580 if (mShowWelcomePage && !didAcceptTermsOfService()) { | 549 if (mShowWelcomePage && !didAcceptTermsOfService()) { |
581 return position == 0; | 550 return position == 0; |
582 } | 551 } |
583 if (position >= mPagerAdapter.getCount()) { | 552 if (position >= mPagerAdapter.getCount()) { |
584 completeFirstRunExperience(); | 553 completeFirstRunExperience(); |
585 return false; | 554 return false; |
586 } | 555 } |
587 mPager.setCurrentItem(position, false); | 556 mPager.setCurrentItem(position, false); |
588 recordFreProgressHistogram(mFreProgressStates.get(position)); | 557 recordFreProgressHistogram(mFreProgressStates.get(position)); |
589 return true; | 558 return true; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 return constructor.newInstance(); | 596 return constructor.newInstance(); |
628 } | 597 } |
629 }; | 598 }; |
630 } | 599 } |
631 | 600 |
632 @Override | 601 @Override |
633 public void showInfoPage(int url) { | 602 public void showInfoPage(int url) { |
634 CustomTabActivity.showInfoPage(this, getString(url)); | 603 CustomTabActivity.showInfoPage(this, getString(url)); |
635 } | 604 } |
636 | 605 |
| 606 /** Returns whether or not First Run is ready for interaction. */ |
637 @VisibleForTesting | 607 @VisibleForTesting |
638 public static void setObserverForTest(FirstRunActivityObserver observer) { | 608 public boolean isPostNativePageSequenceCreated() { |
639 assert sObserver == null; | 609 return mPostNativePageSequenceCreated; |
640 sObserver = observer; | |
641 } | 610 } |
642 } | 611 } |
OLD | NEW |