Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CrOS Bluetooth] Create BluetoothPowerController.
Create BluetoothPowerController to manage setting the Bluetooth adapter state, saving the state to prefs, and applying the pref on device startup or user login. The logic in this class is largely taken from the BluetoothPowerController in ash/system/bluetooth, except CrosBluetoothConfig APIs are used instead of BluetoothAdapter and ash-specific SessionManager methods are replaced with UserManager equivalents. For design doc, see go/cros-bluetooth-revamp-power-controller. Bug: 1010321 Change-Id: I17c6e1a03d6368c8caf74e69f78b4e28cae37892 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3263257 Commit-Queue: Gordon Seto <gordonseto@google.com> Reviewed-by: Kyle Horimoto <khorimoto@chromium.org> Reviewed-by: Xiyuan Xia <xiyuan@chromium.org> Reviewed-by: Chad Duffin <chadduffin@chromium.org> Cr-Commit-Position: refs/heads/main@{#940471}
- Loading branch information
Gordon Seto
authored and
Chromium LUCI CQ
committed
Nov 10, 2021
1 parent
d7362e0
commit 293e498
Showing
13 changed files
with
672 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
include_rules = [ | ||
"+ash/constants", | ||
"+components/device_event_log", | ||
"+components/user_manager", | ||
"+components/session_manager/core", | ||
"+components/sync_preferences/testing_pref_service_syncable.h", | ||
"+components/user_manager", | ||
"+device/bluetooth", | ||
"+mojo/public", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
chromeos/services/bluetooth_config/bluetooth_power_controller.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright 2021 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. | ||
|
||
#ifndef CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_H_ | ||
#define CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_H_ | ||
|
||
class PrefService; | ||
|
||
namespace chromeos { | ||
namespace bluetooth_config { | ||
|
||
// Sets the Bluetooth power state and saves the state to prefs. Also initializes | ||
// the Bluetooth power state during system startup and user session startup. | ||
// | ||
// Classes that wish to set the Bluetooth adapter state and save that value to | ||
// prefs should use this class. Classes that do not want to persist the state to | ||
// prefs should use AdapterStateController instead. | ||
class BluetoothPowerController { | ||
public: | ||
virtual ~BluetoothPowerController() = default; | ||
|
||
// Changes the Bluetooth power setting to |enabled|, persisting |enabled| to | ||
// user prefs if a user is logged in. If no user is logged in, the pref is | ||
// persisted to local state. | ||
virtual void SetBluetoothEnabledState(bool enabled) = 0; | ||
|
||
// Sets the PrefServices used to save and retrieve the Bluetooth power state. | ||
virtual void SetPrefs(PrefService* primary_profile_prefs_, | ||
PrefService* local_state) = 0; | ||
}; | ||
|
||
} // namespace bluetooth_config | ||
} // namespace chromeos | ||
|
||
#endif // CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_H_ |
184 changes: 184 additions & 0 deletions
184
chromeos/services/bluetooth_config/bluetooth_power_controller_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
// Copyright 2021 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. | ||
|
||
#include "chromeos/services/bluetooth_config/bluetooth_power_controller_impl.h" | ||
|
||
#include "ash/constants/ash_pref_names.h" | ||
#include "chromeos/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h" | ||
#include "components/device_event_log/device_event_log.h" | ||
#include "components/prefs/pref_registry_simple.h" | ||
#include "components/prefs/pref_service.h" | ||
#include "components/user_manager/user_manager.h" | ||
|
||
namespace chromeos { | ||
namespace bluetooth_config { | ||
namespace { | ||
|
||
// Decides whether to apply Bluetooth setting based on user type. | ||
// Returns true if the user type represents a human individual, currently this | ||
// includes: regular, child, supervised, or active directory. The other types | ||
// do not represent human account so those account should follow system-wide | ||
// Bluetooth setting instead. | ||
bool ShouldApplyUserBluetoothSetting(user_manager::UserType user_type) { | ||
return user_type == user_manager::USER_TYPE_REGULAR || | ||
user_type == user_manager::USER_TYPE_CHILD || | ||
user_type == user_manager::USER_TYPE_ACTIVE_DIRECTORY; | ||
} | ||
|
||
} // namespace | ||
|
||
// static | ||
void BluetoothPowerControllerImpl::RegisterLocalStatePrefs( | ||
PrefRegistrySimple* registry) { | ||
registry->RegisterBooleanPref(prefs::kSystemBluetoothAdapterEnabled, | ||
/*default_value=*/false); | ||
} | ||
|
||
// static | ||
void BluetoothPowerControllerImpl::RegisterProfilePrefs( | ||
PrefRegistrySimple* registry) { | ||
registry->RegisterBooleanPref(prefs::kUserBluetoothAdapterEnabled, | ||
/*default_value=*/false); | ||
} | ||
|
||
BluetoothPowerControllerImpl::BluetoothPowerControllerImpl( | ||
AdapterStateController* adapter_state_controller) | ||
: adapter_state_controller_(adapter_state_controller) {} | ||
|
||
BluetoothPowerControllerImpl::~BluetoothPowerControllerImpl() = default; | ||
|
||
void BluetoothPowerControllerImpl::SetBluetoothEnabledState(bool enabled) { | ||
if (primary_profile_prefs_) { | ||
BLUETOOTH_LOG(EVENT) << "Saving Bluetooth power state of " << enabled | ||
<< " to user prefs."; | ||
|
||
primary_profile_prefs_->SetBoolean(ash::prefs::kUserBluetoothAdapterEnabled, | ||
enabled); | ||
} else if (local_state_) { | ||
BLUETOOTH_LOG(EVENT) << "Saving Bluetooth power state of " << enabled | ||
<< " to local state."; | ||
|
||
local_state_->SetBoolean(ash::prefs::kSystemBluetoothAdapterEnabled, | ||
enabled); | ||
} else { | ||
BLUETOOTH_LOG(ERROR) | ||
<< "SetBluetoothEnabledState() called before preferences were set"; | ||
} | ||
SetAdapterState(enabled); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::SetPrefs(PrefService* primary_profile_prefs, | ||
PrefService* local_state) { | ||
InitLocalStatePrefService(local_state); | ||
InitPrimaryUserPrefService(primary_profile_prefs); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::InitLocalStatePrefService( | ||
PrefService* local_state) { | ||
// Return early if |local_state_| has already been initialized or | ||
// |local_state| is invalid. | ||
if (local_state_ || !local_state) | ||
return; | ||
|
||
local_state_ = local_state; | ||
|
||
// Apply the local state pref if no user has logged in (still in login | ||
// screen). | ||
if (!user_manager::UserManager::Get()->GetActiveUser()) | ||
ApplyBluetoothLocalStatePref(); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::ApplyBluetoothLocalStatePref() { | ||
if (local_state_->FindPreference(prefs::kSystemBluetoothAdapterEnabled) | ||
->IsDefaultValue()) { | ||
// If the device has not had the local state Bluetooth pref, set the pref | ||
// according to whatever the current Bluetooth power is. | ||
BLUETOOTH_LOG(EVENT) << "Saving current power state of " | ||
<< adapter_state_controller_->GetAdapterState() | ||
<< " to local state."; | ||
SaveCurrentPowerStateToPrefs(local_state_, | ||
prefs::kSystemBluetoothAdapterEnabled); | ||
return; | ||
} | ||
|
||
bool enabled = | ||
local_state_->GetBoolean(prefs::kSystemBluetoothAdapterEnabled); | ||
BLUETOOTH_LOG(EVENT) << "Applying local state pref Bluetooth power: " | ||
<< enabled; | ||
SetAdapterState(enabled); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::InitPrimaryUserPrefService( | ||
PrefService* primary_profile_prefs) { | ||
primary_profile_prefs_ = primary_profile_prefs; | ||
if (!primary_profile_prefs_) { | ||
return; | ||
} | ||
|
||
DCHECK_EQ(user_manager::UserManager::Get()->GetActiveUser(), | ||
user_manager::UserManager::Get()->GetPrimaryUser()); | ||
|
||
if (!has_attempted_apply_primary_user_pref_) { | ||
ApplyBluetoothPrimaryUserPref(); | ||
has_attempted_apply_primary_user_pref_ = true; | ||
} | ||
} | ||
|
||
void BluetoothPowerControllerImpl::ApplyBluetoothPrimaryUserPref() { | ||
absl::optional<user_manager::UserType> user_type = | ||
user_manager::UserManager::Get()->GetActiveUser()->GetType(); | ||
|
||
// Apply the Bluetooth pref only for regular users (i.e. users representing | ||
// a human individual). We don't want to apply Bluetooth pref for other users | ||
// e.g. kiosk, guest etc. For non-human users, Bluetooth power should be left | ||
// to the current power state. | ||
if (!user_type || !ShouldApplyUserBluetoothSetting(*user_type)) { | ||
BLUETOOTH_LOG(EVENT) << "Not applying primary user pref because user has " | ||
"no type or is not a regular user."; | ||
return; | ||
} | ||
|
||
if (!primary_profile_prefs_ | ||
->FindPreference(prefs::kUserBluetoothAdapterEnabled) | ||
->IsDefaultValue()) { | ||
bool enabled = | ||
primary_profile_prefs_->GetBoolean(prefs::kUserBluetoothAdapterEnabled); | ||
BLUETOOTH_LOG(EVENT) << "Applying primary user pref Bluetooth power: " | ||
<< enabled; | ||
SetAdapterState(enabled); | ||
return; | ||
} | ||
|
||
// If the user has not had the Bluetooth pref yet, set the user pref | ||
// according to whatever the current Bluetooth power is, except for | ||
// new users (first login on the device) always set the new pref to true. | ||
if (user_manager::UserManager::Get()->IsCurrentUserNew()) { | ||
BLUETOOTH_LOG(EVENT) << "Setting Bluetooth power to enabled for new user."; | ||
SetBluetoothEnabledState(true); | ||
return; | ||
} | ||
|
||
BLUETOOTH_LOG(EVENT) << "Saving current power state of " | ||
<< adapter_state_controller_->GetAdapterState() | ||
<< " to user prefs."; | ||
SaveCurrentPowerStateToPrefs(primary_profile_prefs_, | ||
prefs::kUserBluetoothAdapterEnabled); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::SetAdapterState(bool enabled) { | ||
BLUETOOTH_LOG(EVENT) << "Setting adapter state to " | ||
<< (enabled ? "enabled " : "disabled"); | ||
adapter_state_controller_->SetBluetoothEnabledState(enabled); | ||
} | ||
|
||
void BluetoothPowerControllerImpl::SaveCurrentPowerStateToPrefs( | ||
PrefService* prefs, | ||
const char* pref_name) { | ||
prefs->SetBoolean(pref_name, | ||
IsBluetoothEnabledOrEnabling( | ||
adapter_state_controller_->GetAdapterState())); | ||
} | ||
|
||
} // namespace bluetooth_config | ||
} // namespace chromeos |
68 changes: 68 additions & 0 deletions
68
chromeos/services/bluetooth_config/bluetooth_power_controller_impl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2021 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. | ||
|
||
#ifndef CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_IMPL_H_ | ||
#define CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_IMPL_H_ | ||
|
||
#include "chromeos/services/bluetooth_config/bluetooth_power_controller.h" | ||
|
||
#include "chromeos/services/bluetooth_config/adapter_state_controller.h" | ||
#include "components/user_manager/user_type.h" | ||
|
||
class PrefRegistrySimple; | ||
|
||
namespace chromeos { | ||
namespace bluetooth_config { | ||
|
||
// Concrete BluetoothPowerController implementation that uses prefs to save and | ||
// apply the Bluetooth power state. | ||
class BluetoothPowerControllerImpl : public BluetoothPowerController { | ||
public: | ||
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); | ||
static void RegisterProfilePrefs(PrefRegistrySimple* registry); | ||
|
||
explicit BluetoothPowerControllerImpl( | ||
AdapterStateController* adapter_state_controller); | ||
~BluetoothPowerControllerImpl() override; | ||
|
||
private: | ||
// BluetoothPowerController: | ||
void SetBluetoothEnabledState(bool enabled) override; | ||
void SetPrefs(PrefService* primary_profile_prefs, | ||
PrefService* local_state) override; | ||
|
||
void InitLocalStatePrefService(PrefService* local_state); | ||
|
||
// At login screen startup, applies the local state Bluetooth power setting | ||
// or sets the default pref value if the device doesn't have the setting yet. | ||
void ApplyBluetoothLocalStatePref(); | ||
|
||
void InitPrimaryUserPrefService(PrefService* primary_profile_prefs); | ||
|
||
// At primary user session startup, applies the user's Bluetooth power setting | ||
// or sets the default pref value if the user doesn't have the setting yet. | ||
void ApplyBluetoothPrimaryUserPref(); | ||
|
||
// Sets the Bluetooth power state. | ||
void SetAdapterState(bool enabled); | ||
|
||
// Saves to prefs the current Bluetooth power state. | ||
void SaveCurrentPowerStateToPrefs(PrefService* prefs, const char* pref_name); | ||
|
||
// Remembers whether we have ever attempted to apply the primary user's | ||
// Bluetooth setting. If this variable is true, we will ignore any active | ||
// user change event since we know that the primary user's Bluetooth setting | ||
// has been attempted to be applied. | ||
bool has_attempted_apply_primary_user_pref_ = false; | ||
|
||
PrefService* primary_profile_prefs_ = nullptr; | ||
PrefService* local_state_ = nullptr; | ||
|
||
AdapterStateController* adapter_state_controller_; | ||
}; | ||
|
||
} // namespace bluetooth_config | ||
} // namespace chromeos | ||
|
||
#endif // CHROMEOS_SERVICES_BLUETOOTH_CONFIG_BLUETOOTH_POWER_CONTROLLER_IMPL_H_ |
Oops, something went wrong.