Skip to content
forked from chromium/chromium

Commit f296f15

Browse files
csagan5chirayudesai
authored andcommitted
Add an always-incognito mode
Add a preference that causes all new tabs and all clicked links to launch in incognito. Make sure initial incognito status is correctly recognized. Enable incognito custom tabs and fix crashes for incognito/custom tab intents Use a native flag to correctly start new tabs on app startup Add history, recents, offlinepages and send to home screen support for always incognito. History, recent tabs and offline pages require the INCOGNITO_TAB_HISTORY_ENABLED flag turned on. IncognitoPlaceholder is also deactivated, both in the phone and tablet version. The relative tests are also present. based on the original work by Ryan Archer <ryan.bradley.archer@gmail.com> Major contributions by uazo. See also: bromite/bromite#1427 License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
1 parent fb5fdbd commit f296f15

65 files changed

Lines changed: 719 additions & 77 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

chrome/android/chrome_java_resources.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ chrome_java_resources = [
652652
"java/res/xml/main_preferences.xml",
653653
"java/res/xml/manage_sync_preferences.xml",
654654
"java/res/xml/phone_as_a_security_key_accessory_filter.xml",
655+
"java/res/xml/incognito_preferences.xml",
655656
"java/res/xml/privacy_preferences.xml",
656657
"java/res/xml/search_widget_info.xml",
657658
"java/res/xml/tracing_preferences.xml",

chrome/android/chrome_java_sources.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# found in the LICENSE file.
44

55
chrome_java_sources = [
6+
"java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java",
67
"java/src/com/google/android/apps/chrome/appwidget/bookmarks/BookmarkThumbnailWidgetProvider.java",
78
"java/src/org/chromium/chrome/browser/ActivityTabProvider.java",
89
"java/src/org/chromium/chrome/browser/ActivityUtils.java",
@@ -914,6 +915,7 @@ chrome_java_sources = [
914915
"java/src/org/chromium/chrome/browser/privacy/settings/IncognitoLockSettings.java",
915916
"java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImpl.java",
916917
"java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java",
918+
"java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java",
917919
"java/src/org/chromium/chrome/browser/provider/BaseColumns.java",
918920
"java/src/org/chromium/chrome/browser/provider/BookmarkColumns.java",
919921
"java/src/org/chromium/chrome/browser/provider/ChromeBrowserProviderImpl.java",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
This file is part of Bromite.
4+
5+
Bromite is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
Bromite is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with Bromite. If not, see <https://www.gnu.org/licenses/>.
17+
-->
18+
19+
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
20+
xmlns:app="http://schemas.android.com/apk/res-auto">
21+
22+
<org.chromium.components.browser_ui.settings.ChromeSwitchPreference
23+
android:key="always_incognito"
24+
android:title="@string/always_incognito_title"
25+
android:summary="@string/always_incognito_summary"
26+
android:defaultValue="false" />
27+
<org.chromium.components.browser_ui.settings.ChromeSwitchPreference
28+
android:key="incognito_history"
29+
android:title="@string/incognito_history_enabled_title"
30+
android:summary="@string/incognito_history_enabled_summary"
31+
android:defaultValue="false" />
32+
<org.chromium.components.browser_ui.settings.ChromeSwitchPreference
33+
android:key="incognito_save_site_setting"
34+
android:title="@string/incognito_save_site_setting_enabled_title"
35+
android:summary="@string/incognito_save_site_setting_enabled_summary"
36+
android:defaultValue="false" />
37+
</PreferenceScreen>

chrome/android/java/res/xml/privacy_preferences.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ found in the LICENSE file.
4040
android:key="secure_dns"
4141
android:title="@string/settings_secure_dns_title"
4242
android:fragment="org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings"/>
43+
<Preference
44+
android:key="incognito_settings"
45+
android:title="@string/incognito_settings_title"
46+
android:summary="@string/incognito_settings_summary"
47+
android:fragment="org.chromium.chrome.browser.privacy.settings.IncognitoSettings"/>
4348
<Preference
4449
android:fragment="org.chromium.chrome.browser.privacy.settings.DoNotTrackSettings"
4550
android:key="do_not_track"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package org.chromium.chrome.browser;
6+
7+
import android.content.SharedPreferences;
8+
import org.chromium.base.ContextUtils;
9+
10+
import org.chromium.components.user_prefs.UserPrefs;
11+
import org.chromium.components.prefs.PrefService;
12+
import org.chromium.chrome.browser.profiles.Profile;
13+
import org.chromium.chrome.browser.preferences.Pref;
14+
import org.chromium.base.Log;
15+
16+
import androidx.annotation.Nullable;
17+
18+
/**
19+
* A {@link TabObserver} that implements the always-incognito preference behavior for links.
20+
*/
21+
public class AlwaysIncognitoLinkInterceptor {
22+
23+
private static final String TAG = "AlwaysIncognito";
24+
public static final String PREF_ALWAYS_INCOGNITO = "always_incognito";
25+
26+
private static @Nullable Boolean cachedIsAlwaysIncognito = null;
27+
28+
public static boolean isAlwaysIncognito() {
29+
if (cachedIsAlwaysIncognito != null) return cachedIsAlwaysIncognito;
30+
cachedIsAlwaysIncognito = ContextUtils.getAppSharedPreferences()
31+
.getBoolean(PREF_ALWAYS_INCOGNITO, false);
32+
return cachedIsAlwaysIncognito;
33+
}
34+
35+
public static void setAlwaysIncognito(boolean enabled) {
36+
UserPrefs.get(Profile.getLastUsedRegularProfile())
37+
.setBoolean(Pref.ALWAYS_INCOGNITO_ENABLED, enabled);
38+
39+
SharedPreferences.Editor sharedPreferenceEditor = ContextUtils.getAppSharedPreferences().edit();
40+
sharedPreferenceEditor.putBoolean("always_incognito", enabled);
41+
sharedPreferenceEditor.apply();
42+
}
43+
44+
public static void migrateSettingToNative() {
45+
if (isAlwaysIncognito()) {
46+
PrefService prefService = UserPrefs.get(Profile.getLastUsedRegularProfile());
47+
if (!prefService.getBoolean(Pref.ALWAYS_INCOGNITO_ENABLED)) {
48+
Log.i(TAG, "Pref migration from java to native");
49+
prefService.setBoolean(Pref.ALWAYS_INCOGNITO_ENABLED, true);
50+
}
51+
}
52+
}
53+
}

chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.chromium.build.annotations.UsedByReflection;
5959
import org.chromium.cc.input.BrowserControlsState;
6060
import org.chromium.chrome.R;
61+
import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
6162
import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate;
6263
import org.chromium.chrome.browser.IntentHandler.TabOpenType;
6364
import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout;
@@ -578,8 +579,9 @@ public void initializeCompositor() {
578579
mTabModelOrchestrator.onNativeLibraryReady(getTabContentManager());
579580

580581
// For saving non-incognito tab closures for Recent Tabs.
582+
boolean alwaysIncognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito();
581583
mHistoricalTabModelObserver =
582-
new HistoricalTabModelObserver(mTabModelSelector.getModel(false));
584+
new HistoricalTabModelObserver(mTabModelSelector.getModel(alwaysIncognito));
583585

584586
if (TabUiFeatureUtilities.isTabletGridTabSwitcherEnabled(this)) {
585587
mTabModelSelector.addObserver(new TabModelSelectorObserver() {
@@ -1904,8 +1906,9 @@ protected void createTabModels() {
19041906
Bundle savedInstanceState = getSavedInstanceState();
19051907

19061908
// We determine the model as soon as possible so every systems get initialized coherently.
1907-
boolean startIncognito = savedInstanceState != null
1908-
&& savedInstanceState.getBoolean(IS_INCOGNITO_SELECTED, false);
1909+
boolean startIncognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()
1910+
|| (savedInstanceState != null
1911+
&& savedInstanceState.getBoolean(IS_INCOGNITO_SELECTED, false));
19091912

19101913
mNextTabPolicySupplier = new ChromeNextTabPolicySupplier(mLayoutStateProviderSupplier);
19111914

chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
9494
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManagerHandler;
9595
import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule;
96+
import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
9697
import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
9798
import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides;
9899
import org.chromium.chrome.browser.device.DeviceClassManager;
@@ -1808,6 +1809,9 @@ public TabCreator getTabCreator(boolean incognito) {
18081809
throw new IllegalStateException(
18091810
"Attempting to access TabCreator before initialization");
18101811
}
1812+
if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) {
1813+
incognito = true;
1814+
}
18111815
return mTabCreatorManagerSupplier.get().getTabCreator(incognito);
18121816
}
18131817

chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.chromium.base.supplier.OneshotSupplier;
3535
import org.chromium.chrome.R;
3636
import org.chromium.chrome.browser.ActivityTabProvider;
37+
import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
3738
import org.chromium.chrome.browser.banners.AppMenuVerbiage;
3839
import org.chromium.chrome.browser.bookmarks.BookmarkFeatures;
3940
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
@@ -99,6 +100,10 @@
99100
import java.util.List;
100101
import java.util.Map;
101102

103+
import org.chromium.components.prefs.PrefService;
104+
import org.chromium.components.user_prefs.UserPrefs;
105+
import org.chromium.chrome.browser.preferences.Pref;
106+
102107
/**
103108
* Base implementation of {@link AppMenuPropertiesDelegate} that handles hiding and showing menu
104109
* items based on activity state.
@@ -560,6 +565,13 @@ private int getInstanceCount() {
560565
}
561566

562567
private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean isIncognito) {
568+
boolean always_incognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito();
569+
if (always_incognito) {
570+
final MenuItem newTabOption = menu.findItem(R.id.new_tab_menu_id);
571+
if (newTabOption != null)
572+
newTabOption.setVisible(false);
573+
}
574+
563575
// We have to iterate all menu items since same menu item ID may be associated with more
564576
// than one menu items.
565577
boolean isOverviewModeMenu = menuGroup == MenuGroup.OVERVIEW_MODE_MENU;
@@ -636,7 +648,15 @@ private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean
636648
}
637649

638650
if (item.getItemId() == R.id.recent_tabs_menu_id) {
639-
item.setVisible(!isIncognito);
651+
if (always_incognito) {
652+
PrefService prefService =
653+
UserPrefs.get(Profile.getLastUsedRegularProfile());
654+
boolean historyEnabledInIncognito =
655+
prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED);
656+
item.setVisible(historyEnabledInIncognito);
657+
}
658+
else
659+
item.setVisible(!isIncognito);
640660
}
641661
if (item.getItemId() == R.id.menu_group_tabs) {
642662
item.setVisible(isMenuGroupTabsVisible);
@@ -876,7 +896,9 @@ protected boolean shouldShowHomeScreenMenuItem(boolean isChromeScheme, boolean i
876896
// is not persisted when adding to the homescreen.
877897
// * If creating shortcuts it not supported by the current home screen.
878898
return WebappsUtils.isAddToHomeIntentSupported() && !isChromeScheme && !isFileScheme
879-
&& !isContentScheme && !isIncognito && !url.isEmpty();
899+
&& !isContentScheme && !url.isEmpty()
900+
&& (!isIncognito ||
901+
AlwaysIncognitoLinkInterceptor.isAlwaysIncognito());
880902
}
881903

882904
/**

chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.chromium.base.metrics.RecordHistogram;
3131
import org.chromium.base.supplier.Supplier;
3232
import org.chromium.chrome.R;
33+
import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
3334
import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
3435
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item;
3536
import org.chromium.chrome.browser.contextmenu.ContextMenuCoordinator.ListItemType;
@@ -364,6 +365,9 @@ public List<Pair<Integer, ModelList>> buildContextMenu() {
364365
boolean hasSaveImage = false;
365366
mShowEphemeralTabNewLabel = null;
366367

368+
boolean always_incognito =
369+
AlwaysIncognitoLinkInterceptor.isAlwaysIncognito();
370+
367371
List<Pair<Integer, ModelList>> groupedItems = new ArrayList<>();
368372

369373
if (mParams.isAnchor()) {
@@ -382,6 +386,7 @@ public List<Pair<Integer, ModelList>> buildContextMenu() {
382386
linkGroup.add(createListItem(Item.OPEN_IN_NEW_TAB_IN_GROUP));
383387
}
384388
}
389+
385390
if (!mItemDelegate.isIncognito() && mItemDelegate.isIncognitoSupported()) {
386391
linkGroup.add(createListItem(Item.OPEN_IN_INCOGNITO_TAB));
387392
}
@@ -406,7 +411,7 @@ public List<Pair<Integer, ModelList>> buildContextMenu() {
406411
}
407412
}
408413
if (FirstRunStatus.getFirstRunFlowComplete()) {
409-
if (!mItemDelegate.isIncognito()
414+
if ((always_incognito || !mItemDelegate.isIncognito())
410415
&& UrlUtilities.isDownloadableScheme(mParams.getLinkUrl())) {
411416
linkGroup.add(createListItem(Item.SAVE_LINK_AS));
412417
}

chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,6 @@ public class CustomTabActivityLifecycleUmaTracker
6868
private boolean mIsInitialResume = true;
6969

7070
private void recordIncognitoLaunchReason() {
71-
IncognitoCustomTabIntentDataProvider incognitoProvider =
72-
(IncognitoCustomTabIntentDataProvider) mIntentDataProvider;
73-
74-
@IntentHandler.IncognitoCCTCallerId
75-
int incognitoCCTCallerId = incognitoProvider.getFeatureIdForMetricsCollection();
76-
RecordHistogram.recordEnumeratedHistogram("CustomTabs.IncognitoCCTCallerId",
77-
incognitoCCTCallerId, IntentHandler.IncognitoCCTCallerId.NUM_ENTRIES);
78-
79-
// Record which 1P app launched Incognito CCT.
80-
if (incognitoCCTCallerId == IntentHandler.IncognitoCCTCallerId.GOOGLE_APPS) {
81-
String sendersPackageName = incognitoProvider.getSendersPackageName();
82-
@IntentHandler.ExternalAppId
83-
int externalId = IntentHandler.mapPackageToExternalAppId(sendersPackageName);
84-
if (externalId != IntentHandler.ExternalAppId.OTHER) {
85-
RecordHistogram.recordEnumeratedHistogram("CustomTabs.ClientAppId.Incognito",
86-
externalId, IntentHandler.ExternalAppId.NUM_ENTRIES);
87-
} else {
88-
// Using package name didn't give any meaningful insight on who launched the
89-
// Incognito CCT, falling back to check if they provided EXTRA_APPLICATION_ID.
90-
externalId =
91-
IntentHandler.determineExternalIntentSource(incognitoProvider.getIntent());
92-
RecordHistogram.recordEnumeratedHistogram("CustomTabs.ClientAppId.Incognito",
93-
externalId, IntentHandler.ExternalAppId.NUM_ENTRIES);
94-
}
95-
}
9671
}
9772

9873
private void recordUserAction() {

0 commit comments

Comments
 (0)