| 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 |