blob: 61a13b9becd8cec8082494ca95bb43cf12303cd4 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.app.flags;
import android.text.TextUtils;
import org.chromium.base.annotations.RemovableInRelease;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.firstrun.FirstRunUtils;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.CachedFieldTrialParameter;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.lens.LensFeature;
import org.chromium.chrome.browser.merchant_viewer.MerchantViewerConfig;
import org.chromium.chrome.browser.notifications.chime.ChimeFeatures;
import org.chromium.chrome.browser.page_annotations.PageAnnotationsServiceConfig;
import org.chromium.chrome.browser.paint_preview.StartupPaintPreviewHelper;
import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceConfig;
import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils;
import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
import org.chromium.chrome.browser.tasks.tab_management.PriceTrackingUtilities;
import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
import java.util.ArrayList;
import java.util.List;
/**
* Caches the flags that Chrome might require before native is loaded in a later next run.
*/
public class ChromeCachedFlags {
private boolean mIsFinishedCachingNativeFlags;
private static final ChromeCachedFlags INSTANCE = new ChromeCachedFlags();
/**
* A list of field trial parameters that will be cached when starting minimal browser mode. See
* {@link #cacheMinimalBrowserFlags()}.
*/
private static final List<CachedFieldTrialParameter> MINIMAL_BROWSER_FIELD_TRIALS =
new ArrayList<CachedFieldTrialParameter>() {
{
// This is used by CustomTabsConnection implementation, which does not
// necessarily start chrome.
add(CustomTabActivity.EXPERIMENTS_FOR_AGSA_PARAMS);
}
};
/**
* @return The {@link ChromeCachedFlags} singleton.
*/
public static ChromeCachedFlags getInstance() {
return INSTANCE;
}
/**
* Caches flags that are needed by Activities that launch before the native library is loaded
* and stores them in SharedPreferences. Because this function is called during launch after the
* library has loaded, they won't affect the next launch until Chrome is restarted.
*/
public void cacheNativeFlags() {
if (mIsFinishedCachingNativeFlags) return;
FirstRunUtils.cacheFirstRunPrefs();
// Workaround for crbug.com/1223545: Do not use Arrays.asList().
List<String> featuresToCache = new ArrayList<String>() {
{
add(ChromeFeatureList.ANDROID_PARTNER_CUSTOMIZATION_PHENOTYPE);
add(ChromeFeatureList.APP_MENU_MOBILE_SITE_OPTION);
add(ChromeFeatureList.APP_TO_WEB_ATTRIBUTION);
add(ChromeFeatureList.BOOKMARK_BOTTOM_SHEET);
add(ChromeFeatureList.CCT_INCOGNITO);
add(ChromeFeatureList.CCT_INCOGNITO_AVAILABLE_TO_THIRD_PARTY);
add(ChromeFeatureList.CCT_REMOVE_REMOTE_VIEW_IDS);
add(ChromeFeatureList.CLIPBOARD_SUGGESTION_CONTENT_HIDDEN);
add(ChromeFeatureList.CLOSE_TAB_SUGGESTIONS);
add(ChromeFeatureList.CRITICAL_PERSISTED_TAB_DATA);
add(ChromeFeatureList.COMMAND_LINE_ON_NON_ROOTED);
add(ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID);
add(ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE);
add(ChromeFeatureList.DYNAMIC_COLOR_ANDROID);
add(ChromeFeatureList.EARLY_LIBRARY_LOAD);
add(ChromeFeatureList.IMMERSIVE_UI_MODE);
add(ChromeFeatureList.INSTANT_START);
add(ChromeFeatureList.INTEREST_FEED_V2);
add(ChromeFeatureList.LENS_CAMERA_ASSISTED_SEARCH);
add(ChromeFeatureList.NEW_WINDOW_APP_MENU);
add(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK);
add(ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS);
add(ChromeFeatureList.PAINT_PREVIEW_DEMO);
add(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP);
add(ChromeFeatureList.PRIORITIZE_BOOTSTRAP_TASKS);
add(ChromeFeatureList.READ_LATER);
add(ChromeFeatureList.START_SURFACE_ANDROID);
add(ChromeFeatureList.STORE_HOURS);
add(ChromeFeatureList.SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT);
add(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID);
add(ChromeFeatureList.TAB_GROUPS_ANDROID);
add(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID);
add(ChromeFeatureList.TAB_TO_GTS_ANIMATION);
add(ChromeFeatureList.THEME_REFACTOR_ANDROID);
add(ChromeFeatureList.TOOLBAR_USE_HARDWARE_BITMAP_DRAW);
add(ChromeFeatureList.USE_CHIME_ANDROID_SDK);
}
};
CachedFeatureFlags.cacheNativeFlags(featuresToCache);
CachedFeatureFlags.cacheAdditionalNativeFlags();
List<CachedFieldTrialParameter> fieldTrialsToCache =
new ArrayList<CachedFieldTrialParameter>() {
{
add(ChimeFeatures.ALWAYS_REGISTER);
add(ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_INFOBAR_LIMIT);
add(ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_INFOBAR_PERIOD);
add(ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_SESSION_TIME_MS);
add(LensFeature.DISABLE_LENS_CAMERA_ASSISTED_SEARCH_ON_INCOGNITO);
add(LensFeature.ENABLE_LENS_CAMERA_ASSISTED_SEARCH_ON_LOW_END_DEVICE);
add(LensFeature.ENABLE_LENS_CAMERA_ASSISTED_SEARCH_ON_TABLET);
add(LensFeature.SEARCH_BOX_START_VARIANT_LENS_CAMERA_ASSISTED_SEARCH);
add(LensFeature.MIN_AGSA_VERSION_LENS_CAMERA_ASSISTED_SEARCH);
add(MerchantViewerConfig.DEFAULT_TRUST_SIGNALS_MESSAGE_DELAY);
add(MerchantViewerConfig.TRUST_SIGNALS_MESSAGE_USE_RATING_BAR);
add(MerchantViewerConfig.TRUST_SIGNALS_MESSAGE_WINDOW_DURATION_SECONDS);
add(MerchantViewerConfig.TRUST_SIGNALS_SHEET_USE_PAGE_TITLE);
add(PageAnnotationsServiceConfig.PAGE_ANNOTATIONS_BASE_URL);
add(ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS);
add(StartSurfaceConfiguration.HOME_BUTTON_ON_GRID_TAB_SWITCHER);
add(StartSurfaceConfiguration.NEW_SURFACE_FROM_HOME_BUTTON);
add(StartSurfaceConfiguration.OMNIBOX_FOCUSED_ON_NEW_TAB);
add(StartSurfaceConfiguration.SHOW_TABS_IN_MRU_ORDER);
add(StartSurfaceConfiguration.START_SURFACE_EXCLUDE_MV_TILES);
add(StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH_NO_TAB);
add(StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY);
add(StartSurfaceConfiguration.START_SURFACE_OPEN_NTP_INSTEAD_OF_START);
add(StartSurfaceConfiguration.SHOW_NTP_TILES_ON_OMNIBOX);
add(StartSurfaceConfiguration.START_SURFACE_VARIATION);
add(StartSurfaceConfiguration.SUPPORT_ACCESSIBILITY);
add(StartupPaintPreviewHelper.ACCESSIBILITY_SUPPORT_PARAM);
add(CommerceSubscriptionsServiceConfig.STALE_TAB_LOWER_BOUND_SECONDS);
add(CommerceSubscriptionsServiceConfig.SUBSCRIPTIONS_SERVICE_BASE_URL);
add(PriceTrackingUtilities.ENABLE_PRICE_NOTIFICATION);
add(PriceTrackingUtilities.ENABLE_PRICE_TRACKING);
add(TabContentManager.ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION);
add(TabUiFeatureUtilities.ENABLE_LAUNCH_BUG_FIX);
add(TabUiFeatureUtilities.ENABLE_LAUNCH_POLISH);
add(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP);
add(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP_ADAPTIVE);
add(TabUiFeatureUtilities.ENABLE_TAB_GROUP_AUTO_CREATION);
add(TabUiFeatureUtilities.ZOOMING_MIN_MEMORY);
add(TabUiFeatureUtilities.ZOOMING_MIN_SDK);
add(TabUiFeatureUtilities.SKIP_SLOW_ZOOMING);
add(TabUiFeatureUtilities.TAB_GRID_LAYOUT_ANDROID_NEW_TAB_TILE);
add(TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO);
}
};
tryToCatchMissingParameters(fieldTrialsToCache);
CachedFeatureFlags.cacheFieldTrialParameters(fieldTrialsToCache);
CachedFeatureFlags.onEndCheckpoint();
mIsFinishedCachingNativeFlags = true;
}
@RemovableInRelease
private void tryToCatchMissingParameters(List<CachedFieldTrialParameter> listed) {
// All instances of CachedFieldTrialParameter should be manually passed to
// CachedFeatureFlags.cacheFieldTrialParameters(). The following checking is a best-effort
// attempt to try to catch accidental omissions. It cannot replace the list because some
// instances might not be instantiated if the classes they belong to are not accessed yet.
List<String> omissions = new ArrayList<>();
for (CachedFieldTrialParameter trial : CachedFieldTrialParameter.getAllInstances()) {
if (listed.contains(trial)) continue;
if (MINIMAL_BROWSER_FIELD_TRIALS.contains(trial)) continue;
omissions.add(trial.getFeatureName() + ":" + trial.getParameterName());
}
assert omissions.isEmpty()
: "The following trials are not correctly cached: "
+ TextUtils.join(", ", omissions);
}
/**
* Caches flags that are enabled in minimal browser mode and must take effect on startup but
* are set via native code. This function needs to be called in minimal browser mode to mark
* these field trials as active, otherwise histogram data recorded in minimal browser mode
* won't be tagged with their corresponding field trial experiments.
*/
public void cacheMinimalBrowserFlags() {
CachedFeatureFlags.cacheMinimalBrowserFlagsTimeFromNativeTime();
// TODO(crbug.com/995355): Move other related flags from cacheNativeFlags() to here.
List<String> featuresToCache = new ArrayList<String>() {
{
add(ChromeFeatureList.EXPERIMENTS_FOR_AGSA);
add(ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD);
add(ChromeFeatureList.SERVICE_MANAGER_FOR_BACKGROUND_PREFETCH);
}
};
CachedFeatureFlags.cacheNativeFlags(featuresToCache);
CachedFeatureFlags.cacheFieldTrialParameters(MINIMAL_BROWSER_FIELD_TRIALS);
}
}