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