Commit 68b6254c authored by tedchoc's avatar tedchoc Committed by Commit bot

Disable UI options that allow new tabs before FRE.

Prior to completing the FRE on Android, we should disallow
UI options that allow creating new tabs in Chrome.

This disables "Web Search" from the action mode menu and
also the various "Open in X" menu options.

BUG=671149

Review-Url: https://codereview.chromium.org/2559573002
Cr-Commit-Position: refs/heads/master@{#437670}
parent 53796c72
...@@ -11,6 +11,7 @@ import android.view.Menu; ...@@ -11,6 +11,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader;
import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.search_engines.TemplateUrlService;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
...@@ -37,6 +38,16 @@ public class ChromeActionModeCallback implements ActionMode.Callback { ...@@ -37,6 +38,16 @@ public class ChromeActionModeCallback implements ActionMode.Callback {
@Override @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) { public boolean onCreateActionMode(ActionMode mode, Menu menu) {
notifyContextualActionBarVisibilityChanged(true); notifyContextualActionBarVisibilityChanged(true);
int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT
| ActionModeCallbackHelper.MENU_ITEM_SHARE;
// Disable options that expose additional Chrome functionality prior to the FRE being
// completed (i.e. creation of a new tab).
if (FirstRunStatus.getFirstRunFlowComplete()) {
allowedActionModes |= ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH;
}
mHelper.setAllowedMenuItems(allowedActionModes);
mHelper.onCreateActionMode(mode, menu); mHelper.onCreateActionMode(mode, menu);
return true; return true;
} }
......
...@@ -369,7 +369,7 @@ public class ChromeTabbedActivity extends ChromeActivity implements OverviewMode ...@@ -369,7 +369,7 @@ public class ChromeTabbedActivity extends ChromeActivity implements OverviewMode
ChromePreferenceManager preferenceManager = ChromePreferenceManager.getInstance(this); ChromePreferenceManager preferenceManager = ChromePreferenceManager.getInstance(this);
// Promos can only be shown when we start with ACTION_MAIN intent and // Promos can only be shown when we start with ACTION_MAIN intent and
// after FRE is complete. // after FRE is complete.
if (!mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete(this)) { if (!mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete()) {
// Only show promos on the second oppurtunity. This is because we show FRE on the // Only show promos on the second oppurtunity. This is because we show FRE on the
// first oppurtunity, and we don't want to show such content back to back. // first oppurtunity, and we don't want to show such content back to back.
if (preferenceManager.getPromosSkippedOnFirstStart()) { if (preferenceManager.getPromosSkippedOnFirstStart()) {
......
...@@ -86,7 +86,7 @@ public class EmbedContentViewActivity extends FullScreenActivity { ...@@ -86,7 +86,7 @@ public class EmbedContentViewActivity extends FullScreenActivity {
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
boolean retVal = super.onCreateOptionsMenu(menu); boolean retVal = super.onCreateOptionsMenu(menu);
if (!FirstRunStatus.getFirstRunFlowComplete(this)) return retVal; if (!FirstRunStatus.getFirstRunFlowComplete()) return retVal;
return true; return true;
} }
......
...@@ -15,6 +15,7 @@ import android.webkit.MimeTypeMap; ...@@ -15,6 +15,7 @@ import android.webkit.MimeTypeMap;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma; import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma;
import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.search_engines.TemplateUrlService;
...@@ -272,6 +273,16 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { ...@@ -272,6 +273,16 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
} }
} }
// Hide all items that could spawn additional tabs until FRE has been completed.
if (!FirstRunStatus.getFirstRunFlowComplete()) {
menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(false);
menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false);
menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false);
menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false);
menu.findItem(R.id.contextmenu_search_by_image).setVisible(false);
menu.findItem(R.id.menu_id_open_in_chrome).setVisible(false);
}
if (mMode == FULLSCREEN_TAB_MODE) { if (mMode == FULLSCREEN_TAB_MODE) {
removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST); removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST);
} else if (mMode == CUSTOM_TAB_MODE) { } else if (mMode == CUSTOM_TAB_MODE) {
......
...@@ -260,7 +260,7 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD ...@@ -260,7 +260,7 @@ public class FirstRunActivity extends AppCompatActivity implements FirstRunPageD
UmaUtils.recordForegroundStartTime(); UmaUtils.recordForegroundStartTime();
stopProgressionIfNotAcceptedTermsOfService(); stopProgressionIfNotAcceptedTermsOfService();
if (!mFreProperties.getBoolean(EXTRA_USE_FRE_FLOW_SEQUENCER)) { if (!mFreProperties.getBoolean(EXTRA_USE_FRE_FLOW_SEQUENCER)) {
if (FirstRunStatus.getFirstRunFlowComplete(this)) { if (FirstRunStatus.getFirstRunFlowComplete()) {
// This is a parallel flow that needs to be refreshed/re-fired. // This is a parallel flow that needs to be refreshed/re-fired.
// Signal the FRE flow completion and re-launch the original intent. // Signal the FRE flow completion and re-launch the original intent.
completeFirstRunExperience(); completeFirstRunExperience();
......
...@@ -86,7 +86,7 @@ public abstract class FirstRunFlowSequencer { ...@@ -86,7 +86,7 @@ public abstract class FirstRunFlowSequencer {
@VisibleForTesting @VisibleForTesting
protected boolean isFirstRunFlowComplete() { protected boolean isFirstRunFlowComplete() {
return FirstRunStatus.getFirstRunFlowComplete(mActivity); return FirstRunStatus.getFirstRunFlowComplete();
} }
@VisibleForTesting @VisibleForTesting
...@@ -263,13 +263,13 @@ public abstract class FirstRunFlowSequencer { ...@@ -263,13 +263,13 @@ public abstract class FirstRunFlowSequencer {
fromIntent != null && TextUtils.equals(fromIntent.getAction(), Intent.ACTION_MAIN); fromIntent != null && TextUtils.equals(fromIntent.getAction(), Intent.ACTION_MAIN);
if (!fromChromeIcon && ToSAckedReceiver.checkAnyUserHasSeenToS(context)) return null; if (!fromChromeIcon && ToSAckedReceiver.checkAnyUserHasSeenToS(context)) return null;
final boolean baseFreComplete = FirstRunStatus.getFirstRunFlowComplete(context); final boolean baseFreComplete = FirstRunStatus.getFirstRunFlowComplete();
if (!baseFreComplete) { if (!baseFreComplete) {
if (forLightweightFre if (forLightweightFre
&& CommandLine.getInstance().hasSwitch( && CommandLine.getInstance().hasSwitch(
ChromeSwitches.ENABLE_LIGHTWEIGHT_FIRST_RUN_EXPERIENCE)) { ChromeSwitches.ENABLE_LIGHTWEIGHT_FIRST_RUN_EXPERIENCE)) {
if (!FirstRunStatus.shouldSkipWelcomePage(context) if (!FirstRunStatus.shouldSkipWelcomePage()
&& !FirstRunStatus.getLightweightFirstRunFlowComplete(context)) { && !FirstRunStatus.getLightweightFirstRunFlowComplete()) {
return createLightweightFirstRunIntent(context, fromChromeIcon); return createLightweightFirstRunIntent(context, fromChromeIcon);
} }
} else { } else {
......
...@@ -58,7 +58,7 @@ public final class FirstRunSignInProcessor { ...@@ -58,7 +58,7 @@ public final class FirstRunSignInProcessor {
SigninManager signinManager = SigninManager.get(activity.getApplicationContext()); SigninManager signinManager = SigninManager.get(activity.getApplicationContext());
signinManager.onFirstRunCheckDone(); signinManager.onFirstRunCheckDone();
boolean firstRunFlowComplete = FirstRunStatus.getFirstRunFlowComplete(activity); boolean firstRunFlowComplete = FirstRunStatus.getFirstRunFlowComplete();
// We skip signin and the FRE if // We skip signin and the FRE if
// - FRE is disabled, or // - FRE is disabled, or
// - FRE hasn't been completed, but the user has already seen the ToS in the Setup Wizard. // - FRE hasn't been completed, but the user has already seen the ToS in the Setup Wizard.
...@@ -129,7 +129,7 @@ public final class FirstRunSignInProcessor { ...@@ -129,7 +129,7 @@ public final class FirstRunSignInProcessor {
Log.e(TAG, "Attempt to pass-through without completed FRE"); Log.e(TAG, "Attempt to pass-through without completed FRE");
// Things went wrong -- we want the user to go through the full FRE. // Things went wrong -- we want the user to go through the full FRE.
FirstRunStatus.setFirstRunFlowComplete(activity, false); FirstRunStatus.setFirstRunFlowComplete(false);
setFirstRunFlowSignInComplete(activity, false); setFirstRunFlowSignInComplete(activity, false);
setFirstRunFlowSignInAccountName(activity, null); setFirstRunFlowSignInAccountName(activity, null);
setFirstRunFlowSignInSetup(activity, false); setFirstRunFlowSignInSetup(activity, false);
...@@ -207,7 +207,7 @@ public final class FirstRunSignInProcessor { ...@@ -207,7 +207,7 @@ public final class FirstRunSignInProcessor {
* @param data Resulting FRE properties bundle * @param data Resulting FRE properties bundle
*/ */
public static void finalizeFirstRunFlowState(Context context, Bundle data) { public static void finalizeFirstRunFlowState(Context context, Bundle data) {
FirstRunStatus.setFirstRunFlowComplete(context, true); FirstRunStatus.setFirstRunFlowComplete(true);
setFirstRunFlowSignInAccountName(context, setFirstRunFlowSignInAccountName(context,
data.getString(FirstRunActivity.RESULT_SIGNIN_ACCOUNT_NAME)); data.getString(FirstRunActivity.RESULT_SIGNIN_ACCOUNT_NAME));
setFirstRunFlowSignInSetup( setFirstRunFlowSignInSetup(
...@@ -221,7 +221,7 @@ public final class FirstRunSignInProcessor { ...@@ -221,7 +221,7 @@ public final class FirstRunSignInProcessor {
public static void updateSigninManagerFirstRunCheckDone(Context context) { public static void updateSigninManagerFirstRunCheckDone(Context context) {
SigninManager manager = SigninManager.get(context); SigninManager manager = SigninManager.get(context);
if (manager.isSignInAllowed()) return; if (manager.isSignInAllowed()) return;
if (!FirstRunStatus.getFirstRunFlowComplete(context)) return; if (!FirstRunStatus.getFirstRunFlowComplete()) return;
if (!getFirstRunFlowSignInComplete(context)) return; if (!getFirstRunFlowSignInComplete(context)) return;
manager.onFirstRunCheckDone(); manager.onFirstRunCheckDone();
} }
......
...@@ -21,10 +21,9 @@ public class FirstRunStatus { ...@@ -21,10 +21,9 @@ public class FirstRunStatus {
/** /**
* Sets the "main First Run Experience flow complete" preference. * Sets the "main First Run Experience flow complete" preference.
* @param context Any context
* @param isComplete Whether the main First Run Experience flow is complete * @param isComplete Whether the main First Run Experience flow is complete
*/ */
public static void setFirstRunFlowComplete(Context context, boolean isComplete) { public static void setFirstRunFlowComplete(boolean isComplete) {
ContextUtils.getAppSharedPreferences() ContextUtils.getAppSharedPreferences()
.edit() .edit()
.putBoolean(FIRST_RUN_FLOW_COMPLETE, isComplete) .putBoolean(FIRST_RUN_FLOW_COMPLETE, isComplete)
...@@ -35,11 +34,9 @@ public class FirstRunStatus { ...@@ -35,11 +34,9 @@ public class FirstRunStatus {
* Returns whether the main First Run Experience flow is complete. * Returns whether the main First Run Experience flow is complete.
* Note: that might NOT include "intro"/"what's new" pages, but it always * Note: that might NOT include "intro"/"what's new" pages, but it always
* includes ToS and Sign In pages if necessary. * includes ToS and Sign In pages if necessary.
* @param context Any context
*/ */
public static boolean getFirstRunFlowComplete(Context context) { public static boolean getFirstRunFlowComplete() {
return ContextUtils.getAppSharedPreferences() return ContextUtils.getAppSharedPreferences().getBoolean(FIRST_RUN_FLOW_COMPLETE, false);
.getBoolean(FIRST_RUN_FLOW_COMPLETE, false);
} }
/** /**
...@@ -54,16 +51,15 @@ public class FirstRunStatus { ...@@ -54,16 +51,15 @@ public class FirstRunStatus {
/** /**
* Checks whether the welcome page should be skipped from the main First Run Experience. * Checks whether the welcome page should be skipped from the main First Run Experience.
*/ */
public static boolean shouldSkipWelcomePage(Context context) { public static boolean shouldSkipWelcomePage() {
return ContextUtils.getAppSharedPreferences().getBoolean(SKIP_WELCOME_PAGE, false); return ContextUtils.getAppSharedPreferences().getBoolean(SKIP_WELCOME_PAGE, false);
} }
/** /**
* Sets the "lightweight First Run Experience flow complete" preference. * Sets the "lightweight First Run Experience flow complete" preference.
* @param context Any context
* @param isComplete Whether the lightweight First Run Experience flow is complete * @param isComplete Whether the lightweight First Run Experience flow is complete
*/ */
public static void setLightweightFirstRunFlowComplete(Context context, boolean isComplete) { public static void setLightweightFirstRunFlowComplete(boolean isComplete) {
ContextUtils.getAppSharedPreferences() ContextUtils.getAppSharedPreferences()
.edit() .edit()
.putBoolean(LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, isComplete) .putBoolean(LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, isComplete)
...@@ -72,9 +68,8 @@ public class FirstRunStatus { ...@@ -72,9 +68,8 @@ public class FirstRunStatus {
/** /**
* Returns whether the "lightweight First Run Experience flow" is complete. * Returns whether the "lightweight First Run Experience flow" is complete.
* @param context Any context
*/ */
public static boolean getLightweightFirstRunFlowComplete(Context context) { public static boolean getLightweightFirstRunFlowComplete() {
return ContextUtils.getAppSharedPreferences().getBoolean( return ContextUtils.getAppSharedPreferences().getBoolean(
LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, false); LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, false);
} }
......
...@@ -78,7 +78,7 @@ public class LightweightFirstRunActivity extends FirstRunActivity { ...@@ -78,7 +78,7 @@ public class LightweightFirstRunActivity extends FirstRunActivity {
@Override @Override
public void completeFirstRunExperience() { public void completeFirstRunExperience() {
FirstRunStatus.setLightweightFirstRunFlowComplete(LightweightFirstRunActivity.this, true); FirstRunStatus.setLightweightFirstRunFlowComplete(true);
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtras(mFreProperties); intent.putExtras(mFreProperties);
finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, intent); finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, intent);
......
...@@ -104,6 +104,6 @@ public class ToSAndUMAFirstRunFragment extends FirstRunPage { ...@@ -104,6 +104,6 @@ public class ToSAndUMAFirstRunFragment extends FirstRunPage {
@Override @Override
public boolean shouldSkipPageOnCreate(Context appContext) { public boolean shouldSkipPageOnCreate(Context appContext) {
return FirstRunStatus.shouldSkipWelcomePage(appContext); return FirstRunStatus.shouldSkipWelcomePage();
} }
} }
...@@ -12,6 +12,7 @@ import android.test.suitebuilder.annotation.MediumTest; ...@@ -12,6 +12,7 @@ import android.test.suitebuilder.annotation.MediumTest;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.KeyEvent; import android.view.KeyEvent;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
...@@ -21,6 +22,7 @@ import org.chromium.chrome.R; ...@@ -21,6 +22,7 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
import org.chromium.chrome.browser.download.DownloadTestBase; import org.chromium.chrome.browser.download.DownloadTestBase;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModel;
...@@ -39,7 +41,9 @@ import java.util.concurrent.atomic.AtomicReference; ...@@ -39,7 +41,9 @@ import java.util.concurrent.atomic.AtomicReference;
/** /**
* Context menu related tests * Context menu related tests
*/ */
@CommandLineFlags.Add(ChromeSwitches.GOOGLE_BASE_URL + "=http://example.com/") @CommandLineFlags.Add({
ChromeSwitches.GOOGLE_BASE_URL + "=http://example.com/",
ChromeSwitches.HERB_FLAVOR_DISABLED_SWITCH})
public class ContextMenuTest extends DownloadTestBase { public class ContextMenuTest extends DownloadTestBase {
private static final String TEST_PATH = private static final String TEST_PATH =
"/chrome/test/data/android/contextmenu/context_menu_test.html"; "/chrome/test/data/android/contextmenu/context_menu_test.html";
...@@ -61,11 +65,24 @@ public class ContextMenuTest extends DownloadTestBase { ...@@ -61,11 +65,24 @@ public class ContextMenuTest extends DownloadTestBase {
mTestUrl = mTestServer.getURL(TEST_PATH); mTestUrl = mTestServer.getURL(TEST_PATH);
deleteTestFiles(); deleteTestFiles();
super.setUp(); super.setUp();
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
FirstRunStatus.setFirstRunFlowComplete(true);
}
});
} }
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
mTestServer.stopAndDestroyServer(); mTestServer.stopAndDestroyServer();
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
FirstRunStatus.setFirstRunFlowComplete(false);
}
});
deleteTestFiles(); deleteTestFiles();
super.tearDown(); super.tearDown();
} }
......
...@@ -33,7 +33,7 @@ public class FirstRunIntegrationTest extends ChromeTabbedActivityTestBase { ...@@ -33,7 +33,7 @@ public class FirstRunIntegrationTest extends ChromeTabbedActivityTestBase {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@RetryOnFailure @RetryOnFailure
public void testExitFirstRunExperience() throws InterruptedException { public void testExitFirstRunExperience() throws InterruptedException {
if (FirstRunStatus.getFirstRunFlowComplete(getActivity())) { if (FirstRunStatus.getFirstRunFlowComplete()) {
return; return;
} }
......
...@@ -11,6 +11,7 @@ import org.chromium.base.ThreadUtils; ...@@ -11,6 +11,7 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabWindowManager.TabModelSelectorFactory; import org.chromium.chrome.browser.tabmodel.TabWindowManager.TabModelSelectorFactory;
...@@ -74,12 +75,24 @@ public class ContextMenuLoadUrlParamsTest extends ChromeTabbedActivityTestBase { ...@@ -74,12 +75,24 @@ public class ContextMenuLoadUrlParamsTest extends ChromeTabbedActivityTestBase {
} }
}); });
super.setUp(); super.setUp();
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
FirstRunStatus.setFirstRunFlowComplete(true);
}
});
mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
} }
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
FirstRunStatus.setFirstRunFlowComplete(false);
}
});
mTestServer.stopAndDestroyServer(); mTestServer.stopAndDestroyServer();
super.tearDown(); super.tearDown();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment