[go: nahoru, domu]

blob: ad6e5679ee99480fc1f0399bc0e5b888804091be [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// 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 androidx.annotation.AnyThread;
import androidx.annotation.VisibleForTesting;
import org.jni_zero.CalledByNative;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.FieldTrialList;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.build.BuildConfig;
import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.back_press.BackPressManager;
import org.chromium.chrome.browser.back_press.MinimizeAppAndCloseTabBackPressHandler;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
import org.chromium.chrome.browser.customtabs.features.branding.BrandingController;
import org.chromium.chrome.browser.feed.FeedPlaceholderLayout;
import org.chromium.chrome.browser.firstrun.FirstRunUtils;
import org.chromium.chrome.browser.flags.CachedFieldTrialParameter;
import org.chromium.chrome.browser.flags.CachedFlag;
import org.chromium.chrome.browser.flags.CachedFlagUtils;
import org.chromium.chrome.browser.flags.CachedFlagsSafeMode;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.hub.HubFieldTrial;
import org.chromium.chrome.browser.new_tab_url.DseNewTabUrlManager;
import org.chromium.chrome.browser.notifications.chime.ChimeFeatures;
import org.chromium.chrome.browser.omaha.VersionNumberGetter;
import org.chromium.chrome.browser.omnibox.OmniboxFeatures;
import org.chromium.chrome.browser.optimization_guide.OptimizationGuidePushNotificationManager;
import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
import org.chromium.chrome.browser.preferences.ChromeSharedPreferences;
import org.chromium.chrome.browser.recent_tabs.RestoreTabsFeatureHelper;
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
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 static final ChromeCachedFlags INSTANCE = new ChromeCachedFlags();
private boolean mIsFinishedCachingNativeFlags;
private static String sReachedCodeProfilerTrialGroup;
/**
* 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 =
List.of(
// This is used by CustomTabsConnection implementation, which does not
// necessarily start chrome.
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();
CachedFlagUtils.cacheNativeFlags(ChromeFeatureList.sFlagsCachedFullBrowser);
cacheAdditionalNativeFlags();
List<CachedFieldTrialParameter> fieldTrialsToCache =
List.of(
BrandingController.BRANDING_CADENCE_MS,
BrandingController.MAX_BLANK_TOOLBAR_TIMEOUT_MS,
BrandingController.USE_TEMPORARY_STORAGE,
BrandingController.ANIMATE_TOOLBAR_ICON_TRANSITION,
ChimeFeatures.ALWAYS_REGISTER,
FeedPlaceholderLayout.ENABLE_INSTANT_START_ANIMATION,
HubFieldTrial.FLOATING_ACTION_BUTTON,
HubFieldTrial.PANE_SWITCHER_USES_TEXT,
HubFieldTrial.SUPPORTS_OTHER_TABS,
HubFieldTrial.SUPPORTS_SEARCH,
HubFieldTrial.SUPPORTS_BOOKMARKS,
OptimizationGuidePushNotificationManager.MAX_CACHE_SIZE,
OmniboxFeatures.ENABLE_MODERNIZE_VISUAL_UPDATE_ON_TABLET,
OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_ACTIVE_COLOR_ON_OMNIBOX,
OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_MERGE_CLIPBOARD_ON_NTP,
OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_SMALL_BOTTOM_MARGIN,
OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_SMALLER_MARGINS,
OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_SMALLEST_MARGINS,
CustomTabIntentDataProvider.AUTO_TRANSLATE_ALLOW_ALL_FIRST_PARTIES,
CustomTabIntentDataProvider.AUTO_TRANSLATE_PACKAGE_NAME_ALLOWLIST,
CustomTabIntentDataProvider.THIRD_PARTIES_DEFAULT_POLICY,
CustomTabIntentDataProvider.DENYLIST_ENTRIES,
CustomTabIntentDataProvider.ALLOWLIST_ENTRIES,
DseNewTabUrlManager.EEA_COUNTRY_ONLY,
DseNewTabUrlManager.SWAP_OUT_NTP,
WarmupManager.SPARE_TAB_INITIALIZE_RENDERER,
RestoreTabsFeatureHelper.RESTORE_TABS_PROMO_SKIP_FEATURE_ENGAGEMENT,
StartSurfaceConfiguration.IS_DOODLE_SUPPORTED,
StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_SECONDS,
StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_ON_TABLET_SECONDS,
StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_USE_MODEL,
StartSurfaceConfiguration.SHOW_TABS_IN_MRU_ORDER,
StartSurfaceConfiguration.SIGNIN_PROMO_NTP_COUNT_LIMIT,
StartSurfaceConfiguration
.SIGNIN_PROMO_NTP_SINCE_FIRST_TIME_SHOWN_LIMIT_HOURS,
StartSurfaceConfiguration.SIGNIN_PROMO_NTP_RESET_AFTER_HOURS,
StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH_NO_TAB,
StartSurfaceConfiguration.START_SURFACE_OPEN_NTP_INSTEAD_OF_START,
StartSurfaceConfiguration.START_SURFACE_OPEN_START_AS_HOMEPAGE,
StartSurfaceConfiguration.SURFACE_POLISH_OMNIBOX_COLOR,
StartSurfaceConfiguration.SURFACE_POLISH_MOVE_DOWN_LOGO,
StartSurfaceConfiguration.SURFACE_POLISH_LESS_BRAND_SPACE,
StartSurfaceConfiguration.SURFACE_POLISH_SCROLLABLE_MVT,
StartSurfaceConfiguration.SURFACE_POLISH_USE_MAGIC_SPACE,
TabUiFeatureUtilities.ANIMATION_START_TIMEOUT_MS,
TabUiFeatureUtilities.ZOOMING_MIN_MEMORY,
TabUiFeatureUtilities.SKIP_SLOW_ZOOMING,
TabManagementFieldTrial.DELAY_TEMP_STRIP_TIMEOUT_MS,
VersionNumberGetter.MIN_SDK_VERSION,
MinimizeAppAndCloseTabBackPressHandler.SYSTEM_BACK,
BackPressManager.TAB_HISTORY_RECOVER,
BackPressManager.START_UP_MOVE_TO_BACK);
tryToCatchMissingParameters(fieldTrialsToCache);
CachedFlagUtils.cacheFieldTrialParameters(fieldTrialsToCache);
CachedFlagsSafeMode.getInstance().onEndCheckpoint();
mIsFinishedCachingNativeFlags = true;
}
private void tryToCatchMissingParameters(List<CachedFieldTrialParameter> listed) {
if (!BuildConfig.ENABLE_ASSERTS) return;
// 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() {
cacheMinimalBrowserFlagsTimeFromNativeTime();
CachedFlagUtils.cacheNativeFlags(ChromeFeatureList.sFlagsCachedInMinimalBrowser);
CachedFlagUtils.cacheFieldTrialParameters(MINIMAL_BROWSER_FIELD_TRIALS);
}
/**
* Caches a predetermined list of flags that must take effect on startup but are set via native
* code.
*
* Do not add new simple boolean flags here, add them to {@link #cacheNativeFlags} instead.
*/
public static void cacheAdditionalNativeFlags() {
cacheReachedCodeProfilerTrialGroup();
// Propagate REACHED_CODE_PROFILER feature value to LibraryLoader. This can't be done in
// LibraryLoader itself because it lives in //base and can't depend on ChromeFeatureList.
LibraryLoader.setReachedCodeProfilerEnabledOnNextRuns(
ChromeFeatureList.isEnabled(ChromeFeatureList.REACHED_CODE_PROFILER),
ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
ChromeFeatureList.REACHED_CODE_PROFILER, "sampling_interval_us", 0));
// Similarly, propagate the BACKGROUND_THREAD_POOL feature value to LibraryLoader.
LibraryLoader.setBackgroundThreadPoolEnabledOnNextRuns(
ChromeFeatureList.isEnabled(ChromeFeatureList.BACKGROUND_THREAD_POOL));
// Propagate the CACHE_ACTIVITY_TASKID feature value to ApplicationStatus.
ApplicationStatus.setCachingEnabled(
ChromeFeatureList.isEnabled(ChromeFeatureList.CACHE_ACTIVITY_TASKID));
}
/** Caches the trial group of the reached code profiler feature to be using on next startup. */
private static void cacheReachedCodeProfilerTrialGroup() {
// Make sure that the existing value is saved in a static variable before overwriting it.
if (sReachedCodeProfilerTrialGroup == null) {
getReachedCodeProfilerTrialGroup();
}
ChromeSharedPreferences.getInstance()
.writeString(
ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP,
FieldTrialList.findFullName(ChromeFeatureList.REACHED_CODE_PROFILER));
}
/**
* @return The trial group of the reached code profiler.
*/
@CalledByNative
public static String getReachedCodeProfilerTrialGroup() {
if (sReachedCodeProfilerTrialGroup == null) {
sReachedCodeProfilerTrialGroup =
ChromeSharedPreferences.getInstance()
.readString(ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP, "");
}
return sReachedCodeProfilerTrialGroup;
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
static void cacheMinimalBrowserFlagsTimeFromNativeTime() {
ChromeSharedPreferences.getInstance()
.writeLong(
ChromePreferenceKeys.FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS,
System.currentTimeMillis());
}
public static long getLastCachedMinimalBrowserFlagsTimeMillis() {
return ChromeSharedPreferences.getInstance()
.readLong(
ChromePreferenceKeys.FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS,
0);
}
@CalledByNative
@AnyThread
static boolean isEnabled(String featureName) {
CachedFlag cachedFlag = ChromeFeatureList.sAllCachedFlags.get(featureName);
assert cachedFlag != null;
return cachedFlag.isEnabled();
}
}