From f109246e4767da708f9f114da2bba744a26052ec Mon Sep 17 00:00:00 2001 From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Sat, 1 Sep 2018 12:12:06 +0200 Subject: [PATCH] Remove WIP patches --- wip/Add-Always-Incognito-option.patch | 267 ------- wip/CAF-incognito-only.patch | 974 -------------------------- 2 files changed, 1241 deletions(-) delete mode 100644 wip/Add-Always-Incognito-option.patch delete mode 100644 wip/CAF-incognito-only.patch diff --git a/wip/Add-Always-Incognito-option.patch b/wip/Add-Always-Incognito-option.patch deleted file mode 100644 index f4e02b18..00000000 --- a/wip/Add-Always-Incognito-option.patch +++ /dev/null @@ -1,267 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 2 May 2018 01:24:39 +0200 -Subject: Add Always Incognito option - ---- - chrome/android/java/res/menu/custom_tabs_menu.xml | 12 ++++++++ - chrome/android/java/res/menu/main_menu.xml | 12 ++++++++ - .../chromium/chrome/browser/ChromeActivity.java | 4 +++ - .../chrome/browser/ChromeTabbedActivity.java | 4 +++ - .../org/chromium/chrome/browser/IntentHandler.java | 8 ++--- - .../chrome/browser/LaunchIntentDispatcher.java | 7 +++++ - .../browser/appmenu/AppMenuPropertiesDelegate.java | 35 ++++++++++++++++++++++ - .../CustomTabAppMenuPropertiesDelegate.java | 2 ++ - .../browser/preferences/PrefServiceBridge.java | 17 +++++++++++ - .../java/strings/android_chrome_strings.grd | 10 +++++++ - 10 files changed, 106 insertions(+), 5 deletions(-) - -diff --git a/chrome/android/java/res/menu/custom_tabs_menu.xml b/chrome/android/java/res/menu/custom_tabs_menu.xml ---- a/chrome/android/java/res/menu/custom_tabs_menu.xml -+++ b/chrome/android/java/res/menu/custom_tabs_menu.xml -@@ -62,6 +62,18 @@ - - - -+ -+ -+ -+ -+ -+ -+ - -diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml ---- a/chrome/android/java/res/menu/main_menu.xml -+++ b/chrome/android/java/res/menu/main_menu.xml -@@ -72,6 +72,18 @@ - - - -+ -+ -+ -+ -+ -+ -+ - - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java -@@ -1905,6 +1905,10 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - RecordUserAction.record("MobileMenuSettings"); - } else if (id == R.id.show_menu) { - showAppMenuForKeyboardEvent(); -+ } else if (id == R.id.enable_always_incognito_id || id == R.id.enable_always_incognito_check_id) { -+ final boolean alwaysIncognito = PrefServiceBridge.getInstance().alwaysIncognitoEnabled(); -+ PrefServiceBridge.getInstance().setAlwaysIncognitoEnabled(!alwaysIncognito); -+ RecordUserAction.record("MobileMenuRequestEnableAlwaysIncognito"); - } else if (id == R.id.find_in_page_id) { - if (mFindToolbarManager == null) return false; - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java -@@ -1753,6 +1753,10 @@ public class ChromeTabbedActivity - reportNewTabShortcutUsed(true); - getTabCreator(true).launchNTP(); - } -+ } else if (id == R.id.enable_always_incognito_id || id == R.id.enable_always_incognito_check_id) { -+ final boolean alwaysIncognito = PrefServiceBridge.getInstance().alwaysIncognitoEnabled(); -+ PrefServiceBridge.getInstance().setAlwaysIncognitoEnabled(!alwaysIncognito); -+ RecordUserAction.record("MobileMenuRequestEnableAlwaysIncognito"); - } else if (id == R.id.all_bookmarks_menu_id) { - if (currentTab != null) { - getCompositorViewHolder().hideKeyboard(() -> { -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java -@@ -732,7 +732,6 @@ public class IntentHandler { - // Determine if this intent came from a trustworthy source (either Chrome or Google - // first party applications). - boolean isInternal = isIntentChromeOrFirstParty(intent); -- boolean isFromChrome = wasIntentSenderChrome(intent); - - // "Open new incognito tab" is currently limited to Chrome. - // -@@ -741,11 +740,10 @@ public class IntentHandler { - // from the list. In this case, we do not apply our Chrome token as the user has the - // option to select apps outside of our control, so we rely on this in memory check - // instead. -- if (!isFromChrome -- && IntentUtils.safeGetBooleanExtra( -+ if (IntentUtils.safeGetBooleanExtra( - intent, EXTRA_OPEN_NEW_INCOGNITO_TAB, false) -- && (getPendingIncognitoUrl() == null -- || !getPendingIncognitoUrl().equals(intent.getDataString()))) { -+ && getPendingIncognitoUrl() != null -+ && getPendingIncognitoUrl().equals(intent.getDataString())) { - return true; - } - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java -@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.instantapps.InstantAppsHandler; - import org.chromium.chrome.browser.metrics.MediaNotificationUma; - import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; - import org.chromium.chrome.browser.notifications.NotificationPlatformBridge; -+import org.chromium.chrome.browser.preferences.PrefServiceBridge; - import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; - import org.chromium.chrome.browser.searchwidget.SearchActivity; - import org.chromium.chrome.browser.tab.Tab; -@@ -185,6 +186,12 @@ public class LaunchIntentDispatcher implements IntentHandler.IntentHandlerDelega - boolean incognito = - mIntent.getBooleanExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false); - -+ if (!incognito) { -+ incognito = PrefServiceBridge.getInstance().alwaysIncognitoEnabled(); -+ if (incognito) { -+ mIntent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); -+ } -+ } - // Check if a web search Intent is being handled. - IntentHandler intentHandler = new IntentHandler(this, mActivity.getPackageName()); - String url = IntentHandler.getUrlFromIntent(mIntent); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java -@@ -211,6 +211,8 @@ public class AppMenuPropertiesDelegate { - && !TextUtils.isEmpty(url); - prepareAddToHomescreenMenuItem(menu, currentTab, canShowHomeScreenMenuItem); - -+ updateEnableAlwaysIncognitoMenuItem(menu, currentTab); -+ - updateRequestDesktopSiteMenuItem(menu, currentTab, true /* can show */); - - updateEnableJavascriptMenuItem(menu, currentTab); -@@ -410,6 +412,39 @@ public class AppMenuPropertiesDelegate { - } - - /** -+ * Updates the enable Always Incognito item's state. -+ * -+ * @param menu {@link Menu} for enable always incognito -+ * @param currentTab Current tab being displayed. -+ */ -+ protected void updateEnableAlwaysIncognitoMenuItem( -+ Menu menu, Tab currentTab) { -+ MenuItem enableMenuRow = menu.findItem(R.id.enable_always_incognito_row_menu_id); -+ MenuItem enableMenuLabel = menu.findItem(R.id.enable_always_incognito_id); -+ MenuItem enableMenuCheck = menu.findItem(R.id.enable_always_incognito_check_id); -+ -+ // Hide enable always incognito on all chrome:// pages and the NTP. -+ String url = currentTab.getUrl(); -+ boolean isChromeScheme = url.startsWith(UrlConstants.CHROME_URL_PREFIX) -+ || url.startsWith(UrlConstants.CHROME_NATIVE_URL_PREFIX); -+ -+ boolean itemVisible = !isChromeScheme && !currentTab.isNativePage(); -+ enableMenuRow.setVisible(itemVisible); -+ if (!itemVisible) return; -+ -+ boolean alwaysIncognito = PrefServiceBridge.getInstance().alwaysIncognitoEnabled(); -+ -+ // Mark the checkbox if always incognito is activated on this tab. -+ enableMenuCheck.setChecked(alwaysIncognito); -+ -+ // This title doesn't seem to be displayed by Android, but it is used to set up -+ // accessibility text in {@link AppMenuAdapter#setupMenuButton}. -+ enableMenuLabel.setTitleCondensed(alwaysIncognito -+ ? mActivity.getString(R.string.menu_enable_always_incognito_on) -+ : mActivity.getString(R.string.menu_enable_always_incognito_off)); -+ } -+ -+ /** - * Updates the request desktop site item's state. - * - * @param menu {@link Menu} for request desktop site. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java -@@ -163,6 +163,8 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat - } - } - -+ updateEnableAlwaysIncognitoMenuItem(menu, currentTab); -+ - updateRequestDesktopSiteMenuItem(menu, currentTab, requestDesktopSiteVisible); - updateEnableJavascriptMenuItem(menu, currentTab); - prepareAddToHomescreenMenuItem(menu, currentTab, addToHomeScreenVisible); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java -@@ -57,6 +57,8 @@ public class PrefServiceBridge { - private static final String CONTEXTUAL_SEARCH_DISABLED = "false"; - private static final String CONTEXTUAL_SEARCH_ENABLED = "true"; - -+ private static boolean alwaysIncognito = false; -+ - /** - * Structure that holds all the version information about the current Chrome browser. - */ -@@ -359,6 +361,14 @@ public class PrefServiceBridge { - } - - /** -+ * @return true if always-incognito is enabled. -+ * The default is false. -+ */ -+ public boolean alwaysIncognitoEnabled() { -+ return alwaysIncognito; -+ } -+ -+ /** - * @return true if background sync is managed by policy. - */ - public boolean isBackgroundSyncManaged() { -@@ -422,6 +432,13 @@ public class PrefServiceBridge { - } - - /** -+ * Enable or disable always-incognito mode. -+ */ -+ public void setAlwaysIncognitoEnabled(boolean enabled) { -+ alwaysIncognito = enabled; -+ } -+ -+ /** - * Enable or disable background sync. - */ - public void setBackgroundSyncEnabled(boolean enabled) { -diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd ---- a/chrome/android/java/strings/android_chrome_strings.grd -+++ b/chrome/android/java/strings/android_chrome_strings.grd -@@ -2502,6 +2502,16 @@ To obtain new licenses, connect to the internet and play your downloaded content - Turn on JavaScript - - -+ -+ Always Incognito -+ -+ -+ Turn off Always Incognito -+ -+ -+ Turn on Always Incognito -+ -+ - - Desktop site - --- -2.7.4 - diff --git a/wip/CAF-incognito-only.patch b/wip/CAF-incognito-only.patch deleted file mode 100644 index 934728e2..00000000 --- a/wip/CAF-incognito-only.patch +++ /dev/null @@ -1,974 +0,0 @@ -commit 56ab68688e7d2c7734e6190bf602dd584eae3222 -Author: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat Dec 9 23:03:50 2017 +0100 - - Incognito-only mode ported from CAF - Some rework was needed, almost nothing applied cleanly. - See below for the description of the two commits that were merged in this one. - - Browser setting to switch to incognito only mode - - - Added a setting to switch to incognito only mode in - privacy settings - - Upon enabling or disabling the switch, the browser will - restart in the respective mode (regular or incognito only) - - Change-Id: Ic42daa3e9bfdc0fcb4029d9df16ed57c5776d966 - - Fix issues seen in full incognito mode - - - Fixes crashes seen in incognito mode. - - Allow Custom Tabs, Web Apps to use the incognito only mode. - - Ensure we notify the user of the incognito mode in the notification bar and remove the notification when all - incognito tabs are closed. - - Ensure the status bar for Custom Tabs and Web Apps are grey to give a visual notification to use. - - Ensure the tabs are correctly ref counted for Custom Tabs, Web Apps when using incognito only mode. - - CR-Fixed: SWE-8867, SWE-8802 - - Change-Id: I95a77016e7562d82359c7780771da4c7bb73aa06 - -diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml -index ce7db92..a85aea3 100644 ---- a/chrome/android/java/res/xml/privacy_preferences.xml -+++ b/chrome/android/java/res/xml/privacy_preferences.xml -@@ -31,6 +31,10 @@ - android:title="@string/network_predictions_title" - android:summary="@string/network_predictions_summary" - android:persistent="false" /> -+ - 0)) { -+ profile.destroyWhenAppropriate(); -+ IncognitoNotificationManager.dismissIncognitoNotification(); -+ } -+ -+ } -+ -+ @Override -+ protected void onDestroyInternal() { -+ handleTabClose(); -+ } - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java -index afc92bed..39caa0b 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java -@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.profiles.Profile; - import org.chromium.chrome.browser.widget.ControlContainer; - import org.chromium.content_public.browser.WebContents; - import org.chromium.content_public.browser.WebContentsObserver; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - - import java.net.InetAddress; - import java.net.MalformedURLException; -@@ -289,8 +290,9 @@ public final class WarmupManager { - public void createSpareWebContents() { - ThreadUtils.assertOnUiThread(); - if (!LibraryLoader.isInitialized()) return; -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); - if (mSpareWebContents != null || SysUtils.isLowEndDevice()) return; -- mSpareWebContents = WebContentsFactory.createWebContentsWithWarmRenderer(false, false); -+ mSpareWebContents = WebContentsFactory.createWebContentsWithWarmRenderer(incognitoOnly, false); - mObserver = new RenderProcessGoneObserver(); - mSpareWebContents.addObserver(mObserver); - mWebContentsCreationTimeMs = SystemClock.elapsedRealtime(); -@@ -316,7 +318,7 @@ public final class WarmupManager { - */ - public WebContents takeSpareWebContents(boolean incognito, boolean initiallyHidden) { - ThreadUtils.assertOnUiThread(); -- if (incognito || initiallyHidden) return null; -+ if ((incognito != mSpareWebContents.isIncognito()) || initiallyHidden) return null; - WebContents result = mSpareWebContents; - if (result == null) return null; - mSpareWebContents = null; -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java -index e48a3e8..5435958 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java -@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.UrlConstants; - import org.chromium.chrome.browser.banners.AppBannerManager; - import org.chromium.chrome.browser.bookmarks.BookmarkBridge; - import org.chromium.chrome.browser.download.DownloadUtils; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; - import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; - import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils; -@@ -175,6 +176,8 @@ public class AppMenuPropertiesDelegate { - - MenuItem allBookmarksMenuItem = menu.findItem(R.id.all_bookmarks_menu_id); - // Hide 'History' in incognito only browser -+ boolean isIncognitoOnlyBrowser = IncognitoOnlyModeUtil.getInstance() -+ .isIncognitoOnlyBrowser(); - menu.findItem(R.id.open_history_menu_id).setVisible(!isIncognitoOnlyBrowser); - - allBookmarksMenuItem.setTitle(mActivity.getString(R.string.menu_bookmarks)); -@@ -201,7 +204,7 @@ public class AppMenuPropertiesDelegate { - // is not persisted when adding to the homescreen. - // * If creating shortcuts it not supported by the current home screen. - boolean canShowHomeScreenMenuItem = ShortcutHelper.isAddToHomeIntentSupported() -- && !isChromeScheme && !isFileScheme && !isContentScheme && !isIncognito -+ && !isChromeScheme && !isFileScheme && !isContentScheme && (!isIncognito || isIncognitoOnlyBrowser) - && !TextUtils.isEmpty(url); - prepareAddToHomescreenMenuItem(menu, currentTab, canShowHomeScreenMenuItem); - -@@ -224,7 +227,8 @@ public class AppMenuPropertiesDelegate { - } - - if (isOverviewMenu) { -- if (isIncognito) { -+ if (isIncognito -+ && !(IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled())) { - // Hide normal close all tabs item. - menu.findItem(R.id.close_all_tabs_menu_id).setVisible(false); - // Enable close incognito tabs only if there are incognito tabs. -@@ -244,6 +248,7 @@ public class AppMenuPropertiesDelegate { - } - - boolean incognitoMenuItemVisible = !isBottomSheetNtpMenu || !isIncognito; -+ incognitoMenuItemVisible &= !(IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled()); - // Disable new incognito tab when it is blocked (e.g. by a policy). - // findItem(...).setEnabled(...)" is not enough here, because of the inflated - // main_menu.xml contains multiple items with the same id in different groups -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java -index 03edf2d..fb2cc2e 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java -@@ -33,6 +33,7 @@ import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; - import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer; - import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; - import org.chromium.chrome.browser.partnercustomizations.HomepageManager; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.tabmodel.TabModel; - import org.chromium.chrome.browser.tabmodel.TabModelSelector; -@@ -328,8 +329,10 @@ public class StackLayout extends Layout implements Animatable 0); -+ return (!mTabModel.isIncognito() -+ && !IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled()) -+ || (!mIsDying && mTabModel.getCount() > 0); - } - - private float getDefaultDiscardDirection() { -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java -index 25f1fd7..6257c82 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java -@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler - import org.chromium.chrome.browser.compositor.overlays.SceneOverlay; - import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer; - import org.chromium.chrome.browser.compositor.scene_layer.TabStripSceneLayer; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.tabmodel.TabCreatorManager; - import org.chromium.chrome.browser.tabmodel.TabModel; -@@ -377,7 +378,8 @@ public class StripLayoutHelperManager implements SceneOverlay { - mModelSelectorButton.setIncognito(mIsIncognito); - if (mTabModelSelector != null) { - boolean isVisible = mTabModelSelector.getModel(true).getCount() != 0; -- mModelSelectorButton.setVisible(isVisible); -+ mModelSelectorButton.setVisible(isVisible -+ && !IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled()); - - float endMargin = isVisible - ? MODEL_SELECTOR_BUTTON_WIDTH_DP + MODEL_SELECTOR_BUTTON_END_PADDING_DP -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java -index 43b556f..2b92e83 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java -@@ -59,9 +59,13 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; - import org.chromium.chrome.browser.compositor.layouts.LayoutManager; - import org.chromium.chrome.browser.datausage.DataUseTabUIManager; - import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; - import org.chromium.chrome.browser.fullscreen.BrowserStateBrowserControlsVisibilityDelegate; - import org.chromium.chrome.browser.gsa.GSAState; -+import org.chromium.chrome.browser.incognito.IncognitoNotificationManager; -+import org.chromium.chrome.browser.incognito.IncognitoNotificationService; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.metrics.PageLoadMetrics; - import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; - import org.chromium.chrome.browser.page_info.PageInfoPopup; -@@ -334,7 +338,12 @@ public class CustomTabActivity extends ChromeActivity { - if (mConnection.shouldHideDomainForSession(mSession)) { - getToolbarManager().setUrlBarHidden(true); - } -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); - int toolbarColor = mIntentDataProvider.getToolbarColor(); -+ if (incognitoOnly) { -+ toolbarColor = ApiCompatibilityUtils.getColor(getResources(), -+ R.color.incognito_primary_color); -+ } - getToolbarManager().updatePrimaryColor(toolbarColor, false); - if (!mIntentDataProvider.isOpenedByChrome()) { - getToolbarManager().setShouldUpdateToolbarPrimaryColor(false); -@@ -390,7 +399,8 @@ public class CustomTabActivity extends ChromeActivity { - mConnection.cancelSpeculation(mSession); - } - -- getTabModelSelector().getModel(false).addObserver(mTabModelObserver); -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ getTabModelSelector().getModel(incognitoOnly).addObserver(mTabModelObserver); - - boolean successfulStateRestore = false; - // Attempt to restore the previous tab state if applicable. -@@ -412,7 +422,7 @@ public class CustomTabActivity extends ChromeActivity { - } else { - mMainTab = createMainTab(); - } -- getTabModelSelector().getModel(false).addTab(mMainTab, 0, mMainTab.getLaunchType()); -+ getTabModelSelector().getModel(incognitoOnly).addTab(mMainTab, 0, mMainTab.getLaunchType()); - } - - // This cannot be done before because we want to do the reparenting only -@@ -550,7 +560,9 @@ public class CustomTabActivity extends ChromeActivity { - getIntent(), IntentHandler.EXTRA_TAB_ID, Tab.INVALID_TAB_ID); - int parentTabId = IntentUtils.safeGetIntExtra( - getIntent(), IntentHandler.EXTRA_PARENT_TAB_ID, Tab.INVALID_TAB_ID); -- Tab tab = new Tab(assignedTabId, parentTabId, false, getWindowAndroid(), -+ -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ Tab tab = new Tab(assignedTabId, parentTabId, incognitoOnly, getWindowAndroid(), - TabLaunchType.FROM_EXTERNAL_APP, null, null); - if (getIntent().getIntExtra( - CustomTabIntentDataProvider.EXTRA_BROWSER_LAUNCH_SOURCE, ACTIVITY_TYPE_OTHER) -@@ -588,12 +600,12 @@ public class CustomTabActivity extends ChromeActivity { - webContentsStateOnLaunch = WEBCONTENTS_STATE_TRANSFERRED_WEBCONTENTS; - webContents.resumeLoadingCreatedWebContents(); - } else { -- webContents = WarmupManager.getInstance().takeSpareWebContents(false, false); -+ webContents = WarmupManager.getInstance().takeSpareWebContents(IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(), false); - if (webContents != null) { - webContentsStateOnLaunch = WEBCONTENTS_STATE_SPARE_WEBCONTENTS; - } else { - webContents = -- WebContentsFactory.createWebContentsWithWarmRenderer(false, false); -+ WebContentsFactory.createWebContentsWithWarmRenderer(IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(), false); - webContentsStateOnLaunch = WEBCONTENTS_STATE_NO_WEBCONTENTS; - } - } -@@ -835,6 +847,13 @@ public class CustomTabActivity extends ChromeActivity { - if (getAppMenuHandler() != null) getAppMenuHandler().hideAppMenu(); - - super.finish(); -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ if (incognitoOnly) { -+ int incognitoCount = IncognitoNotificationService.getIncognitoTabCount(); -+ if (incognitoCount == 0) { -+ IncognitoNotificationManager.dismissIncognitoNotification(); -+ } -+ } - if (mIntentDataProvider != null && mIntentDataProvider.shouldAnimateOnFinish()) { - mShouldOverridePackage = true; - overridePendingTransition(mIntentDataProvider.getAnimationEnterRes(), -@@ -853,7 +872,8 @@ public class CustomTabActivity extends ChromeActivity { - public final void finishAndClose(boolean reparenting) { - if (mIsClosing) return; - mIsClosing = true; -- if (!reparenting) { -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ if (!reparenting && !incognitoOnly) { - // Closing the activity destroys the renderer as well. Re-create a spare renderer some - // time after, so that we have one ready for the next tab open. This does not increase - // memory consumption, as the current renderer goes away. We create a renderer as a lot -@@ -1025,7 +1045,8 @@ public class CustomTabActivity extends ChromeActivity { - protected void setStatusBarColor(Tab tab, int color) { - // Intentionally do nothing as CustomTabActivity explicitly sets status bar color. Except - // for Custom Tabs opened by Chrome. -- if (mIntentDataProvider.isOpenedByChrome()) super.setStatusBarColor(tab, color); -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ if (mIntentDataProvider.isOpenedByChrome() && !incognitoOnly) super.setStatusBarColor(tab, color); - } - - /** -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java -index f9e91ad..3e9bd1c 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java -@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.incognito; - - import android.annotation.TargetApi; - import android.app.Activity; -+import android.util.SparseArray; - import android.app.ActivityManager; - import android.app.ActivityManager.AppTask; - import android.app.ActivityManager.RecentTaskInfo; -@@ -24,15 +25,21 @@ import org.chromium.base.ContextUtils; - import org.chromium.base.ThreadUtils; - import org.chromium.base.VisibleForTesting; - import org.chromium.base.library_loader.LibraryProcessType; -+import org.chromium.chrome.browser.ChromeActivity; -+import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.ChromeTabbedActivity; - import org.chromium.chrome.browser.TabState; -+import org.chromium.chrome.browser.customtabs.CustomTabActivity; - import org.chromium.chrome.browser.document.ChromeLauncherActivity; - import org.chromium.chrome.browser.document.DocumentUtils; - import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.tabmodel.AsyncTabParams; -+import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager; - import org.chromium.chrome.browser.tabmodel.TabWindowManager; - import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy; - import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; - import org.chromium.content.browser.BrowserStartupController; -+import org.chromium.chrome.browser.webapps.WebappActivity; - - import java.io.File; - import java.lang.ref.WeakReference; -@@ -189,7 +196,9 @@ public class IncognitoNotificationService extends IntentService { - for (int i = 0; i < runningActivities.size(); i++) { - Activity activity = runningActivities.get(i).get(); - if (activity == null) continue; -- if (!(activity instanceof ChromeTabbedActivity)) continue; -+ if (!(activity instanceof ChromeTabbedActivity || -+ activity instanceof CustomTabActivity || -+ activity instanceof WebappActivity)) continue; - - ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity; - if (tabbedActivity.isActivityDestroyed()) continue; -@@ -205,7 +214,7 @@ public class IncognitoNotificationService extends IntentService { - BottomSheet.SHEET_STATE_PEEK, false); - } - -- tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs( -+ chromeActivity.getTabModelSelector().getModel(true).closeAllTabs( - false, false); - } - } -@@ -229,4 +238,30 @@ public class IncognitoNotificationService extends IntentService { - return deletionSuccessful; - } - -+ public static int getIncognitoTabCount() { -+ int count = 0; -+ List> runningActivities = -+ ApplicationStatus.getRunningActivities(); -+ for (int i = 0; i < runningActivities.size(); i++) { -+ Activity activity = runningActivities.get(i).get(); -+ if (activity == null) continue; -+ if (!(activity instanceof ChromeTabbedActivity || -+ activity instanceof CustomTabActivity || -+ activity instanceof WebappActivity)) continue; -+ -+ ChromeActivity chromeActivity = (ChromeActivity) activity; -+ if (chromeActivity.isActivityDestroyed()) continue; -+ -+ count += chromeActivity.getTabModelSelector().getModel(true).getCount(); -+ } -+ // Count tabs that are moving between activities (e.g. a tab that was recently reparented -+ // and hasn't been attached to its new activity yet). -+ SparseArray asyncTabParams = AsyncTabParamsManager.getAsyncTabParams(); -+ for (int i = 0; i < asyncTabParams.size(); i++) { -+ Tab tab = asyncTabParams.valueAt(i).getTabToReparent(); -+ if (tab != null && tab.isIncognito()) count++; -+ } -+ return count; -+ } -+ - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoOnlyModeUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoOnlyModeUtil.java -new file mode 100644 -index 0000000..f6b17e7 ---- /dev/null -+++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoOnlyModeUtil.java -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (c) 2016, The Linux Foundation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are -+ * met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials provided -+ * with the distribution. -+ * * Neither the name of The Linux Foundation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+package org.chromium.chrome.browser.incognito; -+ -+import org.chromium.base.CommandLine; -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.ChromeSwitches; -+import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager; -+ -+/** -+ * Utility class for incognito only mode -+ */ -+public class IncognitoOnlyModeUtil { -+ private static IncognitoOnlyModeUtil sInstance; -+ -+ private IncognitoOnlyModeUtil() {} -+ -+ public static IncognitoOnlyModeUtil getInstance() { -+ if (sInstance == null) { -+ sInstance = new IncognitoOnlyModeUtil(); -+ } -+ return sInstance; -+ } -+ /** -+ * @return whether incognito only browser -+ */ -+ public boolean isIncognitoOnlyBrowser() { -+ return CommandLine.getInstance().hasSwitch(ChromeSwitches.INCOGNITO_ONLY_MODE); -+ } -+ -+ /** -+ * @return whether incognito only mode preference is enabled -+ */ -+ public boolean isIncognitoOnlyPreferenceEnabled() { -+ return PrivacyPreferencesManager.getInstance(ContextUtils.getApplicationContext()). -+ isIncognitoOnlyEnabled(); -+ } -+ -+ /** -+ * @return whether incognito only browser or incognito only mode preference is enabled -+ */ -+ public boolean isIncognitoOnlyModeEnabled() { -+ return isIncognitoOnlyBrowser() || isIncognitoOnlyPreferenceEnabled(); -+ } -+ -+} -\ No newline at end of file -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java -index e594c57..def79eb 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java -@@ -20,6 +20,7 @@ import android.widget.FrameLayout; - import org.chromium.base.ApiCompatibilityUtils; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.WindowDelegate; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.ntp.NewTabPage; - import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; - import org.chromium.chrome.browser.util.MathUtils; -@@ -271,7 +272,8 @@ public class LocationBarPhone extends LocationBarLayout { - - boolean showIncognitoBadge = - getToolbarDataProvider() != null && getToolbarDataProvider().isIncognito(); -- mIncognitoBadge.setVisibility(showIncognitoBadge ? VISIBLE : GONE); -+ mIncognitoBadge.setVisibility(showIncognitoBadge -+ && !IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled() ? VISIBLE : GONE); - updateIncognitoBadgePadding(); - } - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java -index 0d78e7c..b1b9f67 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java -@@ -4,6 +4,8 @@ - - package org.chromium.chrome.browser.preferences.privacy; - -+import android.app.AlertDialog; -+import android.content.DialogInterface; - import android.os.Bundle; - import android.preference.CheckBoxPreference; - import android.preference.Preference; -@@ -18,8 +20,11 @@ import org.chromium.base.SysUtils; - import org.chromium.base.metrics.RecordHistogram; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.ChromeFeatureList; -+import org.chromium.chrome.browser.ApplicationLifetime; -+import org.chromium.chrome.browser.ChromeSwitches; - import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; - import org.chromium.chrome.browser.help.HelpAndFeedback; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.physicalweb.PhysicalWeb; - import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference; - import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate; -@@ -41,6 +46,7 @@ public class PrivacyPreferences extends PreferenceFragment - private static final String PREF_SAFE_BROWSING = "safe_browsing"; - private static final String PREF_CONTEXTUAL_SEARCH = "contextual_search"; - private static final String PREF_NETWORK_PREDICTIONS = "network_predictions"; -+ private static final String PREF_INCOGNITO_ONLY = "incognito_only"; - private static final String PREF_DO_NOT_TRACK = "do_not_track"; - private static final String PREF_USAGE_AND_CRASH_REPORTING = "usage_and_crash_reports"; - private static final String PREF_PHYSICAL_WEB = "physical_web"; -@@ -129,6 +135,18 @@ public class PrivacyPreferences extends PreferenceFragment - recordNetworkPredictionEnablingUMA((boolean) newValue); - } else if (PREF_NAVIGATION_ERROR.equals(key)) { - PrefServiceBridge.getInstance().setResolveNavigationErrorEnabled((boolean) newValue); -+ } else if (PREF_INCOGNITO_ONLY.equals(key)) { -+ incognitoOnlyPreferenceDialog(preference, (boolean) newValue).show(); -+ } -+ -+ boolean isIncognitoOnlyBrowser = IncognitoOnlyModeUtil.getInstance() -+ .isIncognitoOnlyBrowser(); -+ ChromeBaseCheckBoxPreference incognitoOnlyPref = -+ (ChromeBaseCheckBoxPreference) findPreference(PREF_INCOGNITO_ONLY); -+ if (isIncognitoOnlyBrowser) { -+ preferenceScreen.removePreference(incognitoOnlyPref); -+ } else { -+ incognitoOnlyPref.setOnPreferenceChangeListener(this); - } - - return true; -@@ -189,6 +207,13 @@ public class PrivacyPreferences extends PreferenceFragment - doNotTrackPref.setSummary(prefServiceBridge.isDoNotTrackEnabled() ? textOn : textOff); - } - -+ Preference incognitoOnlyPref = findPreference(PREF_INCOGNITO_ONLY); -+ if (incognitoOnlyPref != null) { -+ boolean isIncognitoOnlyEnabled = privacyPrefManager.isIncognitoOnlyEnabled(); -+ incognitoOnlyPref.setChecked(isIncognitoOnlyEnabled); -+ incognitoOnlyPref.setSummary(isIncognitoOnlyEnabled ? textOn : textOff); -+ } -+ - Preference contextualPref = findPreference(PREF_CONTEXTUAL_SEARCH); - if (contextualPref != null) { - boolean isContextualSearchEnabled = !prefServiceBridge.isContextualSearchDisabled(); -@@ -254,4 +279,38 @@ public class PrivacyPreferences extends PreferenceFragment - } - return false; - } -+ -+ private AlertDialog incognitoOnlyPreferenceDialog(final Preference preference, -+ final boolean isChecked) { -+ AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) -+ .setTitle(isChecked ? R.string.incognito_only_turn_on_title -+ : R.string.incognito_only_turn_off_title) -+ .setMessage(isChecked ? R.string.incognito_only_turn_on_confirmation -+ : R.string.incognito_only_turn_off_confirmation) -+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { -+ @Override -+ public void onClick(DialogInterface dialog, int id) { -+ ((ChromeBaseCheckBoxPreference) preference).setChecked(!isChecked); -+ dialog.dismiss(); -+ } -+ }) -+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { -+ @Override -+ public void onClick(DialogInterface dialog, int which) { -+ PrivacyPreferencesManager.getInstance(getActivity()). -+ setIncognitoOnlyEnabled((boolean) isChecked); -+ dialog.dismiss(); -+ ApplicationLifetime.terminate(true); -+ } -+ }) -+ .setOnCancelListener(new DialogInterface.OnCancelListener() { -+ @Override -+ public void onCancel(DialogInterface dialog) { -+ ((ChromeBaseCheckBoxPreference) preference).setChecked(!isChecked); -+ } -+ }) -+ .create(); -+ -+ return dialog; -+ } - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java -index 4ddbd4d..9e2a163 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java -@@ -38,6 +38,7 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage - private static final String PREF_BANDWIDTH_NO_CELLULAR_OLD = "prefetch_bandwidth_no_cellular"; - private static final String ALLOW_PRERENDER_OLD = "allow_prefetch"; - private static final String PREF_PHYSICAL_WEB = "physical_web"; -+ private static final String INCOGNITO_ONLY_PREFERENCE = "incognito_only_preference"; - private static final int PHYSICAL_WEB_OFF = 0; - private static final int PHYSICAL_WEB_ON = 1; - private static final int PHYSICAL_WEB_ONBOARDING = 2; -@@ -339,4 +340,23 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage - int state = mSharedPreferences.getInt(PREF_PHYSICAL_WEB, PHYSICAL_WEB_ONBOARDING); - return (state == PHYSICAL_WEB_ON); - } -+ -+ /** -+ * Check whether Incognito Only preference is enabled -+ * -+ * @return whether Incognito Only preference is enabled, false by default -+ */ -+ public boolean isIncognitoOnlyEnabled() { -+ return mSharedPreferences.getBoolean(INCOGNITO_ONLY_PREFERENCE, false); -+ } -+ -+ /** -+ * Sets the Incognito Only preference, which enables the browser to switch to incognito only -+ * mode -+ * -+ * @param enabled A boolean indicating whether to switch to incognito only mode. -+ */ -+ public void setIncognitoOnlyEnabled(boolean enabled) { -+ mSharedPreferences.edit().putBoolean(INCOGNITO_ONLY_PREFERENCE, enabled).apply(); -+ } - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java -index 344a2ed..d54accf 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java -@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; - import org.chromium.chrome.browser.preferences.LocationSettings; - import org.chromium.chrome.browser.preferences.PrefServiceBridge; - import org.chromium.chrome.browser.preferences.PreferenceUtils; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - - import java.util.ArrayList; - import java.util.List; -@@ -110,6 +111,13 @@ public class SiteSettingsPreferences extends PreferenceFragment - } - - private void configurePreferences() { -+ // Remove 'All sites' menu for incognito only browser -+ boolean isIncognitoOnlyBrowser = IncognitoOnlyModeUtil.getInstance() -+ .isIncognitoOnlyBrowser(); -+ if (isIncognitoOnlyBrowser) { -+ getPreferenceScreen().removePreference(findPreference(ALL_SITES_KEY)); -+ } -+ - if (mMediaSubMenu) { - // The Media sub-menu only contains Protected Content and Autoplay, so remove all other - // menus. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarController.java -index d90ccc3..ddc30f2 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarController.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/undo/UndoBarController.java -@@ -9,6 +9,7 @@ import android.content.Context; - import org.chromium.base.metrics.RecordHistogram; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.device.DeviceClassManager; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.snackbar.Snackbar; - import org.chromium.chrome.browser.snackbar.SnackbarManager; - import org.chromium.chrome.browser.tab.Tab; -@@ -64,7 +65,8 @@ public class UndoBarController implements SnackbarManager.SnackbarController { - mTabModelObserver = new EmptyTabModelObserver() { - private boolean disableUndo() { - return AccessibilityUtil.isAccessibilityEnabled() -- || DeviceClassManager.enableAccessibilityLayout(); -+ || DeviceClassManager.enableAccessibilityLayout() -+ || IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); - } - - @Override -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java -index c3e7aa0..b1d758c 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java -@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.tabmodel; - import org.chromium.base.ObserverList; - import org.chromium.base.ThreadUtils; - import org.chromium.chrome.browser.incognito.IncognitoNotificationManager; -+import org.chromium.chrome.browser.incognito.IncognitoNotificationService; - import org.chromium.chrome.browser.profiles.Profile; - import org.chromium.chrome.browser.tab.Tab; - -@@ -82,7 +83,7 @@ public class IncognitoTabModel implements TabModel { - - // Only delete the incognito profile if there are no incognito tabs open in any tab - // model selector as the profile is shared between them. -- if (profile != null && !mDelegate.doIncognitoTabsExist()) { -+ if (profile != null && !(IncognitoNotificationService.getIncognitoTabCount() > 0)) { - IncognitoNotificationManager.dismissIncognitoNotification(); - - profile.destroyWhenAppropriate(); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java -index 5221244..c976cd4 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java -@@ -5,6 +5,7 @@ - package org.chromium.chrome.browser.tabmodel; - - import org.chromium.base.ObserverList; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; - import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; -@@ -40,7 +41,8 @@ public abstract class TabModelSelectorBase implements TabModelSelector { - for (int i = 0; i < models.length; i++) { - tabModels.add(models[i]); - } -- mActiveModelIndex = startIncognito ? INCOGNITO_TAB_MODEL_INDEX : NORMAL_TAB_MODEL_INDEX; -+ mActiveModelIndex = (startIncognito || -+ IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled()) ? INCOGNITO_TAB_MODEL_INDEX : NORMAL_TAB_MODEL_INDEX; - mTabModels = Collections.unmodifiableList(tabModels); - - TabModelObserver tabModelObserver = new EmptyTabModelObserver() { -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java -index e69d43c..71893ff 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelSelector.java -@@ -14,6 +14,7 @@ import android.os.Build; - import org.chromium.base.ContextUtils; - import org.chromium.base.VisibleForTesting; - import org.chromium.chrome.browser.document.DocumentUtils; -+import org.chromium.chrome.browser.incognito.IncognitoNotificationService; - import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.tab.TabIdManager; - import org.chromium.chrome.browser.tabmodel.IncognitoTabModel.IncognitoTabModelDelegate; -@@ -105,7 +106,7 @@ public class DocumentTabModelSelector extends TabModelSelectorBase implements Ta - public boolean doIncognitoTabsExist() { - // TODO(dfalcantara): Devices in document mode do not trigger the TabWindowManager. - // Revisit this when we have a Samsung L multi-instance device. -- return mIncognitoTabModel.getCount() > 0; -+ return IncognitoNotificationService.getIncognitoTabCount() > 0; - } - }, mActivityDelegate); - initializeTabIdCounter(); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java -index 26bb763..b01a165 100644 ---- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java -@@ -52,6 +52,7 @@ import org.chromium.chrome.browser.customtabs.CustomTabsConnection; - import org.chromium.chrome.browser.document.ChromeLauncherActivity; - import org.chromium.chrome.browser.document.DocumentUtils; - import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; -+import org.chromium.chrome.browser.incognito.IncognitoOnlyModeUtil; - import org.chromium.chrome.browser.tab.EmptyTabObserver; - import org.chromium.chrome.browser.tab.Tab; - import org.chromium.chrome.browser.tab.TabDelegateFactory; -@@ -814,6 +815,12 @@ public class WebappActivity extends SingleTabActivity { - mBrandColor = (int) mWebappInfo.themeColor(); - } - -+ boolean incognitoOnly = IncognitoOnlyModeUtil.getInstance().isIncognitoOnlyModeEnabled(); -+ if (incognitoOnly) { -+ mBrandColor = ApiCompatibilityUtils.getColor(getResources(), -+ R.color.incognito_primary_color); -+ } -+ - int taskDescriptionColor = - ApiCompatibilityUtils.getColor(getResources(), R.color.default_primary_color); - -diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd -index a81975d..f14b395 100644 ---- a/chrome/android/java/strings/android_chrome_strings.grd -+++ b/chrome/android/java/strings/android_chrome_strings.grd -@@ -225,6 +225,26 @@ CHAR-LIMIT guidelines: - Retry - - -+ -+ -+ "Incognito Only" mode -+ -+ -+ Browse using only incognito tabs -+ -+ -+ Enable "Incognito Only" mode -+ -+ -+ Disable "Incognito Only" mode -+ -+ -+ Browser will <b>restart</b> in incognito-only mode. All opened tabs will be closed. -+ -+ -+ Browser will <b>restart</b> in regular mode. All opened tabs will be closed. -+ -+ - - - Settings -diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni -index ba24b98..a576f9d 100644 ---- a/chrome/android/java_sources.gni -+++ b/chrome/android/java_sources.gni -@@ -491,6 +491,7 @@ chrome_java_sources = [ - "java/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGenerator.java", - "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java", - "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java", -+ "java/src/org/chromium/chrome/browser/incognito/IncognitoOnlyModeUtil.java", - "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java", - "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java", - "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java",