Index: chrome/browser/chromeos/policy/device_local_account_policy_service.cc |
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc |
index df918a8701f2c3edabe8b145021a0867cd81794f..dbffdc3761e85dc2aa3aa888bdac60fa7bb3a78d 100644 |
--- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc |
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc |
@@ -4,16 +4,25 @@ |
#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" |
+#include <vector> |
+ |
+#include "base/bind.h" |
#include "base/logging.h" |
#include "base/message_loop.h" |
+#include "chrome/browser/chromeos/policy/device_local_account.h" |
#include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" |
+#include "chrome/browser/chromeos/settings/cros_settings.h" |
+#include "chrome/browser/chromeos/settings/cros_settings_names.h" |
+#include "chrome/browser/chromeos/settings/cros_settings_provider.h" |
+#include "chrome/browser/chromeos/settings/device_settings_service.h" |
#include "chrome/browser/policy/cloud/cloud_policy_client.h" |
#include "chrome/browser/policy/cloud/cloud_policy_constants.h" |
#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" |
#include "chrome/browser/policy/cloud/device_management_service.h" |
-#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" |
#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" |
+#include "chrome/common/chrome_notification_types.h" |
#include "chromeos/dbus/session_manager_client.h" |
+#include "content/public/browser/notification_details.h" |
#include "policy/policy_constants.h" |
namespace em = enterprise_management; |
@@ -21,18 +30,16 @@ namespace em = enterprise_management; |
namespace policy { |
DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker( |
+ const std::string& user_id, |
scoped_ptr<DeviceLocalAccountPolicyStore> store) |
- : store_(store.Pass()), |
+ : user_id_(user_id), |
+ store_(store.Pass()), |
core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType, |
store_->account_id()), |
store_.get()) {} |
DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {} |
-const std::string& DeviceLocalAccountPolicyBroker::account_id() const { |
- return store_->account_id(); |
-} |
- |
void DeviceLocalAccountPolicyBroker::Connect( |
scoped_ptr<CloudPolicyClient> client) { |
core_.Connect(client.Pass()); |
@@ -63,18 +70,27 @@ std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const { |
return display_name; |
} |
+DeviceLocalAccountPolicyService::PolicyBrokerWrapper::PolicyBrokerWrapper() |
+ : broker(NULL) { |
Mattias Nissler (ping if slow)
2013/05/15 08:46:40
nit: this file doesn't put newlines for empty func
bartfab (slow)
2013/05/17 11:14:28
Done.
|
+} |
+ |
DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService( |
chromeos::SessionManagerClient* session_manager_client, |
- chromeos::DeviceSettingsService* device_settings_service) |
+ chromeos::DeviceSettingsService* device_settings_service, |
+ chromeos::CrosSettings* cros_settings) |
: session_manager_client_(session_manager_client), |
device_settings_service_(device_settings_service), |
- device_management_service_(NULL) { |
- device_settings_service_->AddObserver(this); |
- DeviceSettingsUpdated(); |
+ cros_settings_(cros_settings), |
+ device_management_service_(NULL), |
+ cros_settings_callback_factory_(this) { |
+ cros_settings_->AddSettingsObserver( |
+ chromeos::kAccountsPrefDeviceLocalAccounts, this); |
+ UpdateAccountList(); |
} |
DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() { |
- device_settings_service_->RemoveObserver(this); |
+ cros_settings_->RemoveSettingsObserver( |
+ chromeos::kAccountsPrefDeviceLocalAccounts, this); |
DeleteBrokers(&policy_brokers_); |
} |
@@ -84,11 +100,10 @@ void DeviceLocalAccountPolicyService::Connect( |
device_management_service_ = device_management_service; |
// Connect the brokers. |
- for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); |
- broker != policy_brokers_.end(); ++broker) { |
- DCHECK(!broker->second->core()->client()); |
- broker->second->Connect( |
- CreateClientForAccount(broker->second->account_id()).Pass()); |
+ for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); |
+ it != policy_brokers_.end(); ++it) { |
+ DCHECK(!it->second.broker->core()->client()); |
+ it->second.broker->Connect(CreateClient().Pass()); |
} |
} |
@@ -97,28 +112,30 @@ void DeviceLocalAccountPolicyService::Disconnect() { |
device_management_service_ = NULL; |
// Disconnect the brokers. |
- for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); |
- broker != policy_brokers_.end(); ++broker) { |
- broker->second->Disconnect(); |
+ for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); |
+ it != policy_brokers_.end(); ++it) { |
+ it->second.broker->Disconnect(); |
} |
} |
DeviceLocalAccountPolicyBroker* |
- DeviceLocalAccountPolicyService::GetBrokerForAccount( |
- const std::string& account_id) { |
- PolicyBrokerMap::iterator entry = policy_brokers_.find(account_id); |
+ DeviceLocalAccountPolicyService::GetBrokerForUser( |
+ const std::string& user_id) { |
+ PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id); |
if (entry == policy_brokers_.end()) |
return NULL; |
- if (!entry->second) |
- entry->second = CreateBroker(account_id).release(); |
+ if (!entry->second.broker) { |
+ entry->second.broker = |
+ CreateBroker(user_id, entry->second.account_id).release(); |
+ } |
- return entry->second; |
+ return entry->second.broker; |
} |
-bool DeviceLocalAccountPolicyService::IsPolicyAvailableForAccount( |
- const std::string& account_id) { |
- DeviceLocalAccountPolicyBroker* broker = GetBrokerForAccount(account_id); |
+bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser( |
+ const std::string& user_id) { |
+ DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id); |
return broker && broker->core()->store()->is_managed(); |
} |
@@ -130,77 +147,69 @@ void DeviceLocalAccountPolicyService::RemoveObserver(Observer* observer) { |
observers_.RemoveObserver(observer); |
} |
-void DeviceLocalAccountPolicyService::OwnershipStatusChanged() { |
- // TODO(mnissler): The policy key has changed, re-fetch policy. For |
- // consumer devices, re-sign the current settings and send updates to |
- // session_manager. |
-} |
+void DeviceLocalAccountPolicyService::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ if (type != chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED || |
+ *content::Details<const std::string>(details).ptr() != |
+ chromeos::kAccountsPrefDeviceLocalAccounts) { |
+ NOTREACHED(); |
+ return; |
+ } |
-void DeviceLocalAccountPolicyService::DeviceSettingsUpdated() { |
- const em::ChromeDeviceSettingsProto* device_settings = |
- device_settings_service_->device_settings(); |
- if (device_settings) |
- UpdateAccountList(*device_settings); |
+ // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still |
+ // pending (because the |cros_settings_| are not trusted yet), the updated |
+ // account list will be processed by that call when it eventually runs. |
+ if (!cros_settings_callback_factory_.HasWeakPtrs()) |
+ UpdateAccountList(); |
} |
void DeviceLocalAccountPolicyService::OnStoreLoaded(CloudPolicyStore* store) { |
DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); |
broker->UpdateRefreshDelay(); |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnPolicyUpdated(broker->account_id())); |
+ FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id())); |
} |
void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) { |
DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnPolicyUpdated(broker->account_id())); |
+ FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id())); |
} |
-void DeviceLocalAccountPolicyService::UpdateAccountList( |
- const em::ChromeDeviceSettingsProto& device_settings) { |
- using google::protobuf::RepeatedPtrField; |
+void DeviceLocalAccountPolicyService::UpdateAccountList() { |
+ if (chromeos::CrosSettingsProvider::TRUSTED != |
+ cros_settings_->PrepareTrustedValues( |
+ base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList, |
+ cros_settings_callback_factory_.GetWeakPtr()))) { |
+ return; |
+ } |
// Update |policy_brokers_|, keeping existing entries. |
PolicyBrokerMap new_policy_brokers; |
- const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = |
- device_settings.device_local_accounts().account(); |
- RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; |
- for (entry = accounts.begin(); entry != accounts.end(); ++entry) { |
- std::string account_id; |
- if (entry->has_type() && |
- entry->type() == |
- em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION) { |
- account_id = entry->account_id(); |
- } else if (entry->has_deprecated_public_session_id()) { |
- account_id = entry->deprecated_public_session_id(); |
- } |
- |
- if (account_id.empty()) |
- continue; |
- |
- // Sanity check for whether this account ID has already been processed. |
- DeviceLocalAccountPolicyBroker*& new_broker = |
- new_policy_brokers[account_id]; |
- if (new_broker) { |
- LOG(WARNING) << "Duplicate public account " << account_id; |
- continue; |
- } |
+ const base::ListValue* device_local_account_list; |
+ cros_settings_->GetList(chromeos::kAccountsPrefDeviceLocalAccounts, |
+ &device_local_account_list); |
+ const std::vector<DeviceLocalAccount> device_local_accounts = |
+ DecodeDeviceLocalAccountsList(device_local_account_list); |
+ for (std::vector<DeviceLocalAccount>::const_iterator it = |
+ device_local_accounts.begin(); |
+ it != device_local_accounts.end(); ++it) { |
+ PolicyBrokerWrapper& wrapper = new_policy_brokers[it->user_id]; |
+ wrapper.account_id = it->account_id; |
// Reuse the existing broker if present. |
- DeviceLocalAccountPolicyBroker*& existing_broker = |
- policy_brokers_[account_id]; |
- new_broker = existing_broker; |
- existing_broker = NULL; |
+ PolicyBrokerWrapper& existing_wrapper = policy_brokers_[it->user_id]; |
+ wrapper.broker = existing_wrapper.broker; |
+ existing_wrapper.broker = NULL; |
// Fire up the cloud connection for fetching policy for the account from |
// the cloud if this is an enterprise-managed device. |
- if (!new_broker || !new_broker->core()->client()) { |
- scoped_ptr<CloudPolicyClient> client( |
- CreateClientForAccount(account_id)); |
- if (client.get()) { |
- if (!new_broker) |
- new_broker = CreateBroker(account_id).release(); |
- new_broker->Connect(client.Pass()); |
+ if (!wrapper.broker || !wrapper.broker->core()->client()) { |
+ scoped_ptr<CloudPolicyClient> client(CreateClient()); |
+ if (client) { |
+ if (!wrapper.broker) |
+ wrapper.broker = CreateBroker(it->user_id, it->account_id).release(); |
+ wrapper.broker->Connect(client.Pass()); |
} |
} |
} |
@@ -212,23 +221,23 @@ void DeviceLocalAccountPolicyService::UpdateAccountList( |
scoped_ptr<DeviceLocalAccountPolicyBroker> |
DeviceLocalAccountPolicyService::CreateBroker( |
+ const std::string& user_id, |
const std::string& account_id) { |
scoped_ptr<DeviceLocalAccountPolicyStore> store( |
new DeviceLocalAccountPolicyStore(account_id, session_manager_client_, |
device_settings_service_)); |
scoped_ptr<DeviceLocalAccountPolicyBroker> broker( |
- new DeviceLocalAccountPolicyBroker(store.Pass())); |
+ new DeviceLocalAccountPolicyBroker(user_id, store.Pass())); |
broker->core()->store()->AddObserver(this); |
broker->core()->store()->Load(); |
return broker.Pass(); |
} |
void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { |
- for (PolicyBrokerMap::iterator broker = map->begin(); broker != map->end(); |
- ++broker) { |
- if (broker->second) { |
- broker->second->core()->store()->RemoveObserver(this); |
- delete broker->second; |
+ for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it) { |
+ if (it->second.broker) { |
+ it->second.broker->core()->store()->RemoveObserver(this); |
+ delete it->second.broker; |
} |
} |
map->clear(); |
@@ -237,17 +246,15 @@ void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { |
DeviceLocalAccountPolicyBroker* |
DeviceLocalAccountPolicyService::GetBrokerForStore( |
CloudPolicyStore* store) { |
- for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); |
- broker != policy_brokers_.end(); ++broker) { |
- if (broker->second->core()->store() == store) |
- return broker->second; |
+ for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); |
+ it != policy_brokers_.end(); ++it) { |
+ if (it->second.broker->core()->store() == store) |
+ return it->second.broker; |
} |
return NULL; |
} |
-scoped_ptr<CloudPolicyClient> |
- DeviceLocalAccountPolicyService::CreateClientForAccount( |
- const std::string& account_id) { |
+scoped_ptr<CloudPolicyClient> DeviceLocalAccountPolicyService::CreateClient() { |
const em::PolicyData* policy_data = device_settings_service_->policy_data(); |
if (!policy_data || |
!policy_data->has_request_token() || |