此功能允许关闭 Google Chrome 后继续运行后台,控制此功能的开关是
// Set to true if background mode is enabled on this browser.
//更改此值可以修改默认开启关闭
inline constexpr char kBackgroundModeEnabled[] = "background_mode.enabled";
chrome\browser\background\background_mode_manager.cc
// static
void BackgroundModeManager::RegisterPrefs(PrefRegistrySimple* registry) {
//更改此值可以修改默认开启关闭
registry->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true);
}
1、此功能前端代码
chrome\browser\resources\settings\system_page\system_page.html
<if expr="not is_macosx and not chromeos_lacros">
<settings-toggle-button
pref="{{prefs.background_mode.enabled}}" //监听prefs变化
label="$i18n{backgroundAppsLabel}">
</settings-toggle-button>
<div class="hr"></div>
</if>
2、c++对应kBackgroundModeEnabled监听实现代码
chrome\browser\background\background_mode_manager.cc
///
// BackgroundModeManager, public
BackgroundModeManager::BackgroundModeManager(
const base::CommandLine& command_line,
ProfileAttributesStorage* profile_storage)
: profile_storage_(profile_storage), task_runner_(CreateTaskRunner()) {
// We should never start up if there is no browser process or if we are
// currently quitting.
CHECK(g_browser_process);
CHECK(!browser_shutdown::IsTryingToQuit());
// Add self as an observer for the ProfileAttributesStorage so we know when
// profiles are deleted and their names change.
// This observer is never unregistered because the BackgroundModeManager
// outlives the profile storage.
profile_storage_->AddObserver(this);
// Listen for the background mode preference changing.
if (g_browser_process->local_state()) { // Skip for unit tests
pref_registrar_.Init(g_browser_process->local_state());
pref_registrar_.Add(
prefs::kBackgroundModeEnabled, //监听prefs变化,控制功能开启关闭
base::BindRepeating(
&BackgroundModeManager::OnBackgroundModeEnabledPrefChanged,
base::Unretained(this)));
}
}
3、允许前端更改prefs值需要加白在
chrome\browser\extensions\api\settings_private\prefs_util.cc
const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys(){
// System settings.
(*s_allowlist)[::prefs::kBackgroundModeEnabled] =
settings_api::PrefType::kBoolean;
}
=========================================================================
注意:以下是前端更改prefs过程
前端通过chrome.settingsPrivate.setPref接口 通过mojom发送给主进程chrome\browser\extensions\api\settings_private\settings_private_api.h接口进行设置。
c++如何定义一个chrome.settingsPrivate接口给前端调用呢?
1、接口定义chrome\common\extensions\api\settings_private.idl
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Use the <code>chrome.settingsPrivate</code> API to get or set preferences
// from the settings UI. Access is restricted to a set of allowed user facing
// preferences.
namespace settingsPrivate {
enum PrefType { BOOLEAN, NUMBER, STRING, URL, LIST, DICTIONARY };
enum ControlledBy {
DEVICE_POLICY,
USER_POLICY,
OWNER,
PRIMARY_USER,
EXTENSION,
// Preferences are controlled by the parent of the child user.
PARENT,
// Preferences are controlled neither by parent nor the child user.
// Preference values are hard-coded values and can not be changed.
CHILD_RESTRICTION
};
enum Enforcement {
// Value cannot be changed by user.
ENFORCED,
// Value can be changed, but the administrator recommends a default.
RECOMMENDED,
// Value is protected by a code that only parents can access. The logic to
// require the code is NOT automatically added to a preference using this
// enforcement. This is only used to display the correct pref indicator.
PARENT_SUPERVISED
};
dictionary PrefObject {
// The key for the pref.
DOMString key;
// The type of the pref (e.g., boolean, string, etc.).
PrefType type;
// The current value of the pref.
any? value;
// The policy source of the pref; an undefined value means there is no
// policy.
ControlledBy? controlledBy;
// The owner name if controlledBy == OWNER.
// The primary user name if controlledBy == PRIMARY_USER.
// The extension name if controlledBy == EXTENSION.
DOMString? controlledByName;
// The policy enforcement of the pref; must be specified if controlledBy is
// also present.
Enforcement? enforcement;
// The recommended value if enforcement == RECOMMENDED.
any? recommendedValue;
// If enforcement == ENFORCED this optionally specifies preference values
// that are still available for selection by the user. If set, must contain
// at least 2 distinct values, as must contain |value| and
// |recommendedValue| (if present).
any[]? userSelectableValues;
// If true, user control of the preference is disabled for reasons unrelated
// to controlledBy (e.g. no signed-in profile is present). A false value is
// a no-op.
boolean? userControlDisabled;
// The extension ID if controlledBy == EXTENSION.
DOMString? extensionId;
// Whether the controlling extension can be disabled if controlledBy ==
// EXTENSION.
boolean? extensionCanBeDisabled;
};
callback OnPrefSetCallback = void (boolean success);
callback GetAllPrefsCallback = void (PrefObject[] prefs);
callback GetPrefCallback = void (PrefObject pref);
callback GetDefaultZoomCallback = void (double zoom);
callback SetDefaultZoomCallback = void (boolean success);
interface Functions {
// Sets a pref value.
// |name|: The name of the pref.
// |value|: The new value of the pref.
// |pageId|: An optional user metrics identifier.
// |callback|: The callback for whether the pref was set or not.
[supportsPromises] static void setPref(DOMString name,
any value,
optional DOMString pageId,
optional OnPrefSetCallback callback);
// Gets an array of all the prefs.
[supportsPromises] static void getAllPrefs(GetAllPrefsCallback callback);
// Gets the value of a specific pref.
[supportsPromises] static void getPref(DOMString name,
GetPrefCallback callback);
// Gets the default page zoom factor. Possible values are currently between
// 0.25 and 5. For a full list, see zoom::kPresetZoomFactors.
[supportsPromises] static void getDefaultZoom(
GetDefaultZoomCallback callback);
// Sets the page zoom factor. Must be less than 0.001 different than a value
// in zoom::kPresetZoomFactors.
[supportsPromises] static void setDefaultZoom(
double zoom,
optional SetDefaultZoomCallback callback);
};
interface Events {
// Fired when a set of prefs has changed.
//
// |prefs| The prefs that changed.
static void onPrefsChanged(PrefObject[] prefs);
};
};
2、c++settingsPrivate接口实现
chrome\browser\extensions\api\settings_private\settings_private_api.h
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_API_H_
#include "extensions/browser/extension_function.h"
namespace extensions {
// Implements the chrome.settingsPrivate.setPref method.
class SettingsPrivateSetPrefFunction : public ExtensionFunction {
public:
SettingsPrivateSetPrefFunction() {}
SettingsPrivateSetPrefFunction(const SettingsPrivateSetPrefFunction&) =
delete;
SettingsPrivateSetPrefFunction& operator=(
const SettingsPrivateSetPrefFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("settingsPrivate.setPref", SETTINGSPRIVATE_SETPREF)
protected:
~SettingsPrivateSetPrefFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
// Implements the chrome.settingsPrivate.getAllPrefs method.
class SettingsPrivateGetAllPrefsFunction : public ExtensionFunction {
public:
SettingsPrivateGetAllPrefsFunction() {}
SettingsPrivateGetAllPrefsFunction(
const SettingsPrivateGetAllPrefsFunction&) = delete;
SettingsPrivateGetAllPrefsFunction& operator=(
const SettingsPrivateGetAllPrefsFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("settingsPrivate.getAllPrefs",
SETTINGSPRIVATE_GETALLPREFS)
protected:
~SettingsPrivateGetAllPrefsFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
// Implements the chrome.settingsPrivate.getPref method.
class SettingsPrivateGetPrefFunction : public ExtensionFunction {
public:
SettingsPrivateGetPrefFunction() {}
SettingsPrivateGetPrefFunction(const SettingsPrivateGetPrefFunction&) =
delete;
SettingsPrivateGetPrefFunction& operator=(
const SettingsPrivateGetPrefFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("settingsPrivate.getPref", SETTINGSPRIVATE_GETPREF)
protected:
~SettingsPrivateGetPrefFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
// Implements the chrome.settingsPrivate.getDefaultZoom method.
class SettingsPrivateGetDefaultZoomFunction : public ExtensionFunction {
public:
SettingsPrivateGetDefaultZoomFunction() {}
SettingsPrivateGetDefaultZoomFunction(
const SettingsPrivateGetDefaultZoomFunction&) = delete;
SettingsPrivateGetDefaultZoomFunction& operator=(
const SettingsPrivateGetDefaultZoomFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("settingsPrivate.getDefaultZoom",
SETTINGSPRIVATE_GETDEFAULTZOOMFUNCTION)
protected:
~SettingsPrivateGetDefaultZoomFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
// Implements the chrome.settingsPrivate.setDefaultZoom method.
class SettingsPrivateSetDefaultZoomFunction : public ExtensionFunction {
public:
SettingsPrivateSetDefaultZoomFunction() {}
SettingsPrivateSetDefaultZoomFunction(
const SettingsPrivateSetDefaultZoomFunction&) = delete;
SettingsPrivateSetDefaultZoomFunction& operator=(
const SettingsPrivateSetDefaultZoomFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("settingsPrivate.setDefaultZoom",
SETTINGSPRIVATE_SETDEFAULTZOOMFUNCTION)
protected:
~SettingsPrivateSetDefaultZoomFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_API_H_
3、在extensions\browser\extension_function_histogram_value.h中定义函数ID
注意extensions\browser\extension_function_histogram_value.h中与chrome\browser\extensions\api\settings_private\settings_private_api.h中类名的对应关系,否则关联失败。//SETTINGSPRIVATE_SETPREF 应是类名(SettingsPrivateSetPrefFunction)去掉Function之后大写!!!!!
4、该类注册在out\Debug\gen\chrome\browser\extensions\api\generated_api_registration.cc
[自动生成的代码,不需要手动添加]
namespace extensions {
namespace api {
// static
void ChromeGeneratedFunctionRegistry::RegisterAll(ExtensionFunctionRegistry* registry)
{
{
&NewExtensionFunction<SettingsPrivateSetPrefFunction>,
SettingsPrivateSetPrefFunction::static_function_name(),
SettingsPrivateSetPrefFunction::static_histogram_value(),
},
........................................
}
5、注册api地方 chrome\browser\extensions\chrome_extensions_browser_api_provider.cc
namespace extensions {
ChromeExtensionsBrowserAPIProvider::ChromeExtensionsBrowserAPIProvider() =
default;
ChromeExtensionsBrowserAPIProvider::~ChromeExtensionsBrowserAPIProvider() =
default;
void ChromeExtensionsBrowserAPIProvider::RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) {
// Preferences.
registry->RegisterFunction<GetPreferenceFunction>();
registry->RegisterFunction<SetPreferenceFunction>();
registry->RegisterFunction<ClearPreferenceFunction>();
// Generated APIs from Chrome.
api::ChromeGeneratedFunctionRegistry::RegisterAll(registry);
}
} // namespace extensions
6、前端获取prefs实现
base::Value::List SettingsPrivateDelegate::GetAllPrefs() {
base::Value::List prefs;
//GetAllowlistedKeys()定义在
//chrome\browser\extensions\api\settings_private\prefs_util.cc
//所以要给前端添加新的prefs监听 要在此处加白,否则前端获取不到该prefs值
const TypedPrefMap& keys = prefs_util_->GetAllowlistedKeys();
for (const auto& it : keys) {
if (absl::optional<base::Value::Dict> pref = GetPref(it.first); pref) {
prefs.Append(std::move(*pref));
}
}
return prefs;
}
7、最后将settings_private.idl 放到chrome\common\extensions\api\api_sources.gni
中,然后进行编译即可。