492 lines
26 KiB
Diff
492 lines
26 KiB
Diff
From: Ryan Archer <ryan.bradley.archer@gmail.com>
|
|
Date: Wed, 2 Aug 2017 01:41:28 -0400
|
|
Subject: Add an always-incognito mode
|
|
|
|
More specifically, add a preference that causes all new tabs and all
|
|
clicked links to launch as incognito.
|
|
Make sure initial incognito status is correctly recognized.
|
|
Enable incognito custom tabs and fix crashes for incognito/custom tab intents (credits to @uazo)
|
|
---
|
|
chrome/android/chrome_java_sources.gni | 1 +
|
|
.../java/res/xml/privacy_preferences.xml | 5 ++
|
|
.../AlwaysIncognitoLinkInterceptor.java | 74 +++++++++++++++++++
|
|
.../chrome/browser/ChromeTabbedActivity.java | 6 +-
|
|
.../chrome/browser/app/ChromeActivity.java | 4 +
|
|
.../AppMenuPropertiesDelegateImpl.java | 6 ++
|
|
.../ChromeContextMenuPopulator.java | 9 ++-
|
|
.../CustomTabIntentDataProvider.java | 5 +-
|
|
.../browser/init/StartupTabPreloader.java | 11 ++-
|
|
.../privacy/settings/PrivacySettings.java | 4 +-
|
|
.../browser/tabmodel/ChromeTabCreator.java | 16 +++-
|
|
.../tabmodel/TabModelSelectorBase.java | 8 ++
|
|
.../browser/tabmodel/TabPersistentStore.java | 10 +++
|
|
.../webapps/WebappIntentDataProvider.java | 14 ++++
|
|
.../flags/android/chrome_feature_list.cc | 2 +-
|
|
.../strings/android_chrome_strings.grd | 7 ++
|
|
16 files changed, 172 insertions(+), 10 deletions(-)
|
|
create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java
|
|
|
|
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
|
|
--- a/chrome/android/chrome_java_sources.gni
|
|
+++ b/chrome/android/chrome_java_sources.gni
|
|
@@ -3,6 +3,7 @@
|
|
# found in the LICENSE file.
|
|
|
|
chrome_java_sources = [
|
|
+ "java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java",
|
|
"java/src/com/google/android/apps/chrome/appwidget/bookmarks/BookmarkThumbnailWidgetProvider.java",
|
|
"java/src/org/chromium/chrome/browser/ActivityTabProvider.java",
|
|
"java/src/org/chromium/chrome/browser/AfterStartupTaskUtils.java",
|
|
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
|
|
--- a/chrome/android/java/res/xml/privacy_preferences.xml
|
|
+++ b/chrome/android/java/res/xml/privacy_preferences.xml
|
|
@@ -18,6 +18,11 @@
|
|
android:summary="@string/preload_pages_summary"
|
|
android:persistent="false"
|
|
android:order="1"/>
|
|
+ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
|
|
+ android:key="always_incognito"
|
|
+ android:title="@string/always_incognito_title"
|
|
+ android:summary="@string/always_incognito_summary"
|
|
+ android:defaultValue="false" />
|
|
<Preference
|
|
android:fragment="org.chromium.chrome.browser.privacy.settings.DoNotTrackSettings"
|
|
android:key="do_not_track"
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java b/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java
|
|
@@ -0,0 +1,74 @@
|
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
+
|
|
+package org.chromium.chrome.browser;
|
|
+
|
|
+import android.content.SharedPreferences;
|
|
+
|
|
+import org.chromium.chrome.browser.tab.EmptyTabObserver;
|
|
+import org.chromium.chrome.browser.tab.Tab;
|
|
+import org.chromium.chrome.browser.tab.TabImpl;
|
|
+import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
|
|
+import org.chromium.chrome.browser.tab.TabLaunchType;
|
|
+import org.chromium.chrome.browser.tabmodel.TabModel;
|
|
+import org.chromium.content_public.browser.LoadUrlParams;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.HashSet;
|
|
+import java.util.Map;
|
|
+import java.util.Set;
|
|
+/**
|
|
+ * A {@link TabObserver} that implements the always-incognito preference behavior for links. When the preference is set
|
|
+ * to true, it intercepts links opened within observed {@link Tab}s and opens them in new incognito <code>Tab</code>s instead.
|
|
+ */
|
|
+public class AlwaysIncognitoLinkInterceptor extends EmptyTabObserver {
|
|
+
|
|
+ public static final String PREF_ALWAYS_INCOGNITO = "always_incognito";
|
|
+
|
|
+ private final SharedPreferences alwaysIncognitoContainer;
|
|
+ private final Map<Tab, String> lastUrls;
|
|
+ private final Set<Tab> revertingTabs;
|
|
+
|
|
+ public AlwaysIncognitoLinkInterceptor(final SharedPreferences alwaysIncognitoContainer) {
|
|
+
|
|
+ assert alwaysIncognitoContainer != null;
|
|
+
|
|
+ this.alwaysIncognitoContainer = alwaysIncognitoContainer;
|
|
+ lastUrls = new HashMap<Tab, String>();
|
|
+ revertingTabs = new HashSet<Tab>();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onDestroyed(final Tab tab)
|
|
+ {
|
|
+ lastUrls.remove(tab);
|
|
+ revertingTabs.remove(tab);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onUpdateUrl(final Tab tab, final String url) {
|
|
+
|
|
+ if (tab == null) return;
|
|
+ if (url == null) return;
|
|
+ if (tab.isIncognito()) return;
|
|
+ if (alwaysIncognitoContainer == null) return;
|
|
+
|
|
+ final String lastUrl = lastUrls.put(tab, url);
|
|
+
|
|
+ if (!alwaysIncognitoContainer.getBoolean(PREF_ALWAYS_INCOGNITO, false)) return;
|
|
+ if (revertingTabs.contains(tab)) {
|
|
+ revertingTabs.remove(tab);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ((ChromeTabbedActivity)tab.getWindowAndroid().getActivity().get()).getTabCreator(true).createNewTab(new LoadUrlParams(url), TabLaunchType.FROM_LINK, tab);
|
|
+
|
|
+ if ((url.equals(lastUrl)) || (!tab.canGoBack())) {
|
|
+ // this call was triggered by a reload
|
|
+ } else {
|
|
+ revertingTabs.add(tab);
|
|
+ tab.goBack();
|
|
+ }
|
|
+ }
|
|
+}
|
|
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
|
|
@@ -49,6 +49,7 @@ import org.chromium.base.supplier.OneshotSupplierImpl;
|
|
import org.chromium.base.supplier.Supplier;
|
|
import org.chromium.base.task.PostTask;
|
|
import org.chromium.chrome.R;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate;
|
|
import org.chromium.chrome.browser.IntentHandler.TabOpenType;
|
|
import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout;
|
|
@@ -1601,8 +1602,9 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
|
|
Bundle savedInstanceState = getSavedInstanceState();
|
|
|
|
// We determine the model as soon as possible so every systems get initialized coherently.
|
|
- boolean startIncognito = savedInstanceState != null
|
|
- && savedInstanceState.getBoolean("is_incognito_selected", false);
|
|
+ boolean startIncognito = ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false)
|
|
+ || (savedInstanceState != null
|
|
+ && savedInstanceState.getBoolean("is_incognito_selected", false));
|
|
int index = savedInstanceState != null ? savedInstanceState.getInt(WINDOW_INDEX, 0) : 0;
|
|
|
|
mNextTabPolicySupplier = new ChromeNextTabPolicySupplier(mOverviewModeBehaviorSupplier);
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
|
|
@@ -85,6 +85,7 @@ import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial;
|
|
import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager;
|
|
import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager.ContextualSearchTabPromotionDelegate;
|
|
import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
|
|
import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides;
|
|
import org.chromium.chrome.browser.device.DeviceClassManager;
|
|
@@ -1569,6 +1570,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
|
|
throw new IllegalStateException(
|
|
"Attempting to access TabCreator before initialization");
|
|
}
|
|
+ if (ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false)) {
|
|
+ return mIncognitoTabCreator;
|
|
+ }
|
|
return incognito ? mIncognitoTabCreator : mRegularTabCreator;
|
|
}
|
|
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
|
|
@@ -523,6 +523,12 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
|
|
}
|
|
|
|
private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean isIncognito) {
|
|
+ if (ContextUtils.getAppSharedPreferences().getBoolean("always_incognito", false)) {
|
|
+ final MenuItem newTabOption = menu.findItem(R.id.new_tab_menu_id);
|
|
+ if (newTabOption != null)
|
|
+ newTabOption.setVisible(false);
|
|
+ }
|
|
+
|
|
// We have to iterate all menu items since same menu item ID may be associated with more
|
|
// than one menu items.
|
|
boolean isMenuGroupTabsVisible = TabUiFeatureUtilities.isTabGroupsAndroidEnabled()
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
|
|
@@ -29,7 +29,9 @@ import androidx.annotation.VisibleForTesting;
|
|
import org.chromium.base.ContextUtils;
|
|
import org.chromium.base.metrics.RecordHistogram;
|
|
import org.chromium.base.supplier.Supplier;
|
|
+import org.chromium.base.ContextUtils;
|
|
import org.chromium.chrome.R;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
|
|
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item;
|
|
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator.ContextMenuUma.Action;
|
|
@@ -376,7 +378,12 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
|
|
if (FirstRunStatus.getFirstRunFlowComplete() && !isEmptyUrl(mParams.getUrl())
|
|
&& UrlUtilities.isAcceptedScheme(mParams.getUrl())) {
|
|
if (mMode == ContextMenuMode.NORMAL) {
|
|
- linkGroup.add(createListItem(Item.OPEN_IN_NEW_TAB));
|
|
+ if (ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false)
|
|
+ && !mItemDelegate.isIncognito()) {
|
|
+ // disallow open in new tab
|
|
+ } else
|
|
+ linkGroup.add(createListItem(Item.OPEN_IN_NEW_TAB));
|
|
+
|
|
if (!mItemDelegate.isIncognito() && mItemDelegate.isIncognitoSupported()) {
|
|
linkGroup.add(createListItem(Item.OPEN_IN_INCOGNITO_TAB));
|
|
}
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
|
|
@@ -48,6 +48,9 @@ import org.chromium.components.browser_ui.widget.TintedDrawable;
|
|
import org.chromium.components.embedder_support.util.UrlConstants;
|
|
import org.chromium.device.mojom.ScreenOrientationLockType;
|
|
|
|
+import org.chromium.base.ContextUtils;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
+
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.ArrayList;
|
|
@@ -796,7 +799,7 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
|
|
|
|
@Override
|
|
public boolean isIncognito() {
|
|
- return false;
|
|
+ return ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false);
|
|
}
|
|
|
|
@Nullable
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
|
|
@@ -38,6 +38,9 @@ import org.chromium.ui.base.PageTransition;
|
|
import org.chromium.ui.base.WindowAndroid;
|
|
import org.chromium.url.GURL;
|
|
|
|
+import org.chromium.base.ContextUtils;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
+
|
|
/**
|
|
* This class attempts to preload the tab if the url is known from the intent when the profile
|
|
* is created. This is done to improve startup latency.
|
|
@@ -195,9 +198,11 @@ public class StartupTabPreloader implements ProfileManager.Observer, Destroyable
|
|
Intent intent = mIntentSupplier.get();
|
|
GURL url = UrlFormatter.fixupUrl(getUrlFromIntent(intent));
|
|
|
|
+ boolean isIncognito = ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false);
|
|
+
|
|
ChromeTabCreator chromeTabCreator =
|
|
- (ChromeTabCreator) mTabCreatorManager.getTabCreator(false);
|
|
- WebContents webContents = WebContentsFactory.createWebContents(false, false);
|
|
+ (ChromeTabCreator) mTabCreatorManager.getTabCreator(isIncognito);
|
|
+ WebContents webContents = WebContentsFactory.createWebContents(isIncognito, false);
|
|
|
|
mLoadUrlParams = new LoadUrlParams(url.getValidSpecOrEmpty());
|
|
String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(intent);
|
|
@@ -211,7 +216,7 @@ public class StartupTabPreloader implements ProfileManager.Observer, Destroyable
|
|
// Create a detached tab, but don't add it to the tab model yet. We'll do that
|
|
// later if the loadUrlParams etc... match.
|
|
mTab = TabBuilder.createLiveTab(false)
|
|
- .setIncognito(false)
|
|
+ .setIncognito(isIncognito)
|
|
.setLaunchType(TabLaunchType.FROM_EXTERNAL_APP)
|
|
.setWindow(mWindowAndroid)
|
|
.setWebContents(webContents)
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
|
|
@@ -46,9 +46,11 @@ public class PrivacySettings
|
|
private static final String PREF_SECURE_DNS = "secure_dns";
|
|
private static final String PREF_DO_NOT_TRACK = "do_not_track";
|
|
private static final String PREF_CLEAR_BROWSING_DATA = "clear_browsing_data";
|
|
+ private static final String PREF_ALWAYS_INCOGNITO = "always_incognito";
|
|
private static final String[] NEW_PRIVACY_PREFERENCE_ORDER = {PREF_CLEAR_BROWSING_DATA,
|
|
PREF_CAN_MAKE_PAYMENT, PREF_NETWORK_PREDICTIONS,
|
|
- PREF_SECURE_DNS, PREF_DO_NOT_TRACK
|
|
+ PREF_SECURE_DNS, PREF_DO_NOT_TRACK,
|
|
+ PREF_ALWAYS_INCOGNITO
|
|
};
|
|
|
|
private ManagedPreferenceDelegate mManagedPreferenceDelegate;
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
|
|
@@ -39,6 +39,10 @@ import org.chromium.ui.base.PageTransition;
|
|
import org.chromium.ui.base.WindowAndroid;
|
|
import org.chromium.url.GURL;
|
|
|
|
+import org.chromium.base.ContextUtils;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
+import org.chromium.chrome.browser.tab.TabObserver;
|
|
+
|
|
/**
|
|
* This class creates various kinds of new tabs and adds them to the right {@link TabModel}.
|
|
*/
|
|
@@ -60,6 +64,7 @@ public class ChromeTabCreator extends TabCreator {
|
|
private final ChromeActivity mActivity;
|
|
private final StartupTabPreloader mStartupTabPreloader;
|
|
private final boolean mIncognito;
|
|
+ private final TabObserver mExtraLogic;
|
|
|
|
private WindowAndroid mNativeWindow;
|
|
private TabModel mTabModel;
|
|
@@ -78,6 +83,10 @@ public class ChromeTabCreator extends TabCreator {
|
|
mNativeWindow = nativeWindow;
|
|
mTabDelegateFactorySupplier = tabDelegateFactory;
|
|
mIncognito = incognito;
|
|
+ if (!mIncognito)
|
|
+ mExtraLogic = new AlwaysIncognitoLinkInterceptor(ContextUtils.getAppSharedPreferences());
|
|
+ else
|
|
+ mExtraLogic = null;
|
|
mOverviewNTPCreator = overviewNTPCreator;
|
|
mAsyncTabParamsManager = asyncTabParamsManager;
|
|
}
|
|
@@ -231,6 +240,8 @@ public class ChromeTabCreator extends TabCreator {
|
|
if (creationState == TabCreationState.LIVE_IN_FOREGROUND && !openInForeground) {
|
|
creationState = TabCreationState.LIVE_IN_BACKGROUND;
|
|
}
|
|
+ if (mExtraLogic != null)
|
|
+ tab.addObserver(mExtraLogic);
|
|
mTabModel.addTab(tab, position, type, creationState);
|
|
return tab;
|
|
} finally {
|
|
@@ -265,6 +276,8 @@ public class ChromeTabCreator extends TabCreator {
|
|
@TabCreationState
|
|
int creationState = openInForeground ? TabCreationState.LIVE_IN_FOREGROUND
|
|
: TabCreationState.LIVE_IN_BACKGROUND;
|
|
+ if (mExtraLogic != null)
|
|
+ tab.addObserver(mExtraLogic);
|
|
mTabModel.addTab(tab, position, type, creationState);
|
|
return true;
|
|
}
|
|
@@ -308,7 +321,6 @@ public class ChromeTabCreator extends TabCreator {
|
|
// TODO(crbug.com/1081924): Clean up the launches from SearchActivity/Chrome.
|
|
public Tab launchUrlFromExternalApp(String url, String referer, String headers, String appId,
|
|
boolean forceNewTab, Intent intent, long intentTimestamp) {
|
|
- assert !mIncognito;
|
|
boolean isLaunchedFromChrome = TextUtils.equals(appId, mActivity.getPackageName());
|
|
|
|
if (forceNewTab && !isLaunchedFromChrome) {
|
|
@@ -417,6 +429,8 @@ public class ChromeTabCreator extends TabCreator {
|
|
.setSerializedCriticalPersistedTabData(serializedCriticalPersistedTabData)
|
|
.build();
|
|
}
|
|
+ if (mExtraLogic != null)
|
|
+ tab.addObserver(mExtraLogic);
|
|
|
|
if (state.isIncognito() != mIncognito) {
|
|
throw new IllegalStateException("Incognito state mismatch. TabState: "
|
|
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
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
|
|
@@ -256,7 +256,15 @@ public abstract class TabModelSelectorBase implements TabModelSelector, Incognit
|
|
public void markTabStateInitialized() {
|
|
if (mTabStateInitialized) return;
|
|
mTabStateInitialized = true;
|
|
+
|
|
for (TabModelSelectorObserver listener : mObservers) listener.onTabStateInitialized();
|
|
+
|
|
+ if (mStartIncognito) {
|
|
+ // profile is not set in always-incognito mode in TabModelSelectorProfileSupplier
|
|
+ // so force it
|
|
+ selectModel(false); // restore model so next call always set incognito mode
|
|
+ selectModel(true);
|
|
+ }
|
|
}
|
|
|
|
@Override
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
|
|
@@ -16,6 +16,7 @@ import androidx.annotation.VisibleForTesting;
|
|
import androidx.core.util.AtomicFile;
|
|
|
|
import org.chromium.base.Callback;
|
|
+import org.chromium.base.ContextUtils;
|
|
import org.chromium.base.Log;
|
|
import org.chromium.base.ObserverList;
|
|
import org.chromium.base.StreamUtil;
|
|
@@ -49,6 +50,8 @@ import org.chromium.components.embedder_support.util.UrlUtilities;
|
|
import org.chromium.content_public.browser.LoadUrlParams;
|
|
import org.chromium.content_public.browser.UiThreadTaskTraits;
|
|
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
+
|
|
import java.io.BufferedInputStream;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
@@ -595,6 +598,13 @@ public class TabPersistentStore extends TabPersister {
|
|
}
|
|
}
|
|
|
|
+ if (ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false)) {
|
|
+ if (!isIncognito) {
|
|
+ Log.w(TAG, "Failed to restore tab: not in incognito mode.");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
TabModel model = mTabModelSelector.getModel(isIncognito);
|
|
|
|
if (model.isIncognito() != isIncognito) {
|
|
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
|
|
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
|
|
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
|
|
@@ -19,6 +19,9 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProv
|
|
import org.chromium.chrome.browser.flags.ActivityType;
|
|
import org.chromium.components.browser_ui.widget.TintedDrawable;
|
|
|
|
+import org.chromium.base.ContextUtils;
|
|
+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
|
|
+
|
|
/**
|
|
* Stores info about a web app.
|
|
*/
|
|
@@ -32,6 +35,8 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
|
|
private final @ActivityType int mActivityType;
|
|
private final Intent mIntent;
|
|
|
|
+ private boolean mIsIncognito = false;
|
|
+
|
|
/**
|
|
* Returns the toolbar color to use if a custom color is not specified by the webapp.
|
|
*/
|
|
@@ -51,6 +56,10 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
|
|
mWebappExtras = webappExtras;
|
|
mWebApkExtras = webApkExtras;
|
|
mActivityType = (webApkExtras != null) ? ActivityType.WEB_APK : ActivityType.WEBAPP;
|
|
+
|
|
+ if (ContextUtils.getAppSharedPreferences().getBoolean(AlwaysIncognitoLinkInterceptor.PREF_ALWAYS_INCOGNITO, false)) {
|
|
+ mIsIncognito = true;
|
|
+ }
|
|
}
|
|
|
|
@Override
|
|
@@ -138,6 +147,11 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
|
|
return mWebApkExtras;
|
|
}
|
|
|
|
+ @Override
|
|
+ public boolean isIncognito() {
|
|
+ return mIsIncognito;
|
|
+ }
|
|
+
|
|
@Override
|
|
public int getDefaultOrientation() {
|
|
return mWebappExtras.orientation;
|
|
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
|
|
--- a/chrome/browser/flags/android/chrome_feature_list.cc
|
|
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
|
|
@@ -374,7 +374,7 @@ const base::Feature kCCTExternalLinkHandling{"CCTExternalLinkHandling",
|
|
base::FEATURE_ENABLED_BY_DEFAULT};
|
|
|
|
const base::Feature kCCTIncognito{"CCTIncognito",
|
|
- base::FEATURE_DISABLED_BY_DEFAULT};
|
|
+ base::FEATURE_ENABLED_BY_DEFAULT};
|
|
|
|
const base::Feature kCCTPostMessageAPI{"CCTPostMessageAPI",
|
|
base::FEATURE_ENABLED_BY_DEFAULT};
|
|
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
|
|
@@ -832,6 +832,13 @@ Your Google account may have other forms of browsing history like searches and a
|
|
<message name="IDS_CLEAR_BROWSING_HISTORY_SUMMARY" desc="A text for the basic tab explaining browsing history.">
|
|
Clears history and autocompletions in the address bar.
|
|
</message>
|
|
+ <!-- always incognito -->
|
|
+ <message name="IDS_ALWAYS_INCOGNITO_TITLE" desc="Title for always incognito mode">
|
|
+ Open links in incognito tabs always
|
|
+ </message>
|
|
+ <message name="IDS_ALWAYS_INCOGNITO_SUMMARY" desc="Summary for always incognito mode">
|
|
+ Opens links in incognito tabs when you click on new tab or on a link
|
|
+ </message>
|
|
<message name="IDS_CLEAR_BROWSING_HISTORY_SUMMARY_SIGNED_IN" desc="A text explaining other forms of activity for signed in users.">
|
|
Clears history and autocompletions in the address bar. Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK"><link></ph>myactivity.google.com<ph name="END_LINK"></link></ph>.
|
|
</message>
|
|
--
|
|
2.17.1
|
|
|