This source file includes following definitions.
- policy_service_
- PolicyServiceObserver
- OnPolicyUpdated
- OnExternalDataSet
- OnExternalDataCleared
- OnExternalDataFetched
- weak_factory_
- Init
- OnPolicyUpdated
- OnDeviceLocalAccountsChanged
- RetrieveDeviceLocalAccounts
- HandleExternalDataPolicyUpdate
- OnExternalDataFetched
#include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer.h"
#include <set>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/settings/cros_settings_names.h"
#include "chromeos/settings/cros_settings_provider.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_service.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
namespace policy {
class CloudExternalDataPolicyObserver::PolicyServiceObserver
: public PolicyService::Observer {
public:
PolicyServiceObserver(CloudExternalDataPolicyObserver* parent,
const std::string& user_id,
PolicyService* policy_service);
virtual ~PolicyServiceObserver();
virtual void OnPolicyUpdated(const PolicyNamespace& ns,
const PolicyMap& previous,
const PolicyMap& current) OVERRIDE;
private:
CloudExternalDataPolicyObserver* parent_;
const std::string user_id_;
PolicyService* policy_service_;
DISALLOW_COPY_AND_ASSIGN(PolicyServiceObserver);
};
CloudExternalDataPolicyObserver::PolicyServiceObserver::PolicyServiceObserver(
CloudExternalDataPolicyObserver* parent,
const std::string& user_id,
PolicyService* policy_service)
: parent_(parent),
user_id_(user_id),
policy_service_(policy_service) {
policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
if (!IsDeviceLocalAccountUser(user_id, NULL)) {
const PolicyMap::Entry* entry = policy_service_->GetPolicies(
PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
.Get(parent_->policy_);
if (entry)
parent_->HandleExternalDataPolicyUpdate(user_id_, entry);
}
}
CloudExternalDataPolicyObserver::PolicyServiceObserver::
~PolicyServiceObserver() {
policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
}
void CloudExternalDataPolicyObserver::PolicyServiceObserver::OnPolicyUpdated(
const PolicyNamespace& ns,
const PolicyMap& previous,
const PolicyMap& current) {
DCHECK(ns == PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
const PolicyMap::Entry* previous_entry = previous.Get(parent_->policy_);
const PolicyMap::Entry* current_entry = current.Get(parent_->policy_);
if ((!previous_entry && current_entry) ||
(previous_entry && !current_entry) ||
(previous_entry && current_entry &&
!previous_entry->Equals(*current_entry))) {
parent_->HandleExternalDataPolicyUpdate(user_id_, current_entry);
}
}
void CloudExternalDataPolicyObserver::Delegate::OnExternalDataSet(
const std::string& policy,
const std::string& user_id) {
}
void CloudExternalDataPolicyObserver::Delegate::OnExternalDataCleared(
const std::string& policy,
const std::string& user_id) {
}
void CloudExternalDataPolicyObserver::Delegate::OnExternalDataFetched(
const std::string& policy,
const std::string& user_id,
scoped_ptr<std::string> data) {
}
CloudExternalDataPolicyObserver::Delegate::~Delegate() {
}
CloudExternalDataPolicyObserver::CloudExternalDataPolicyObserver(
chromeos::CrosSettings* cros_settings,
chromeos::UserManager* user_manager,
DeviceLocalAccountPolicyService* device_local_account_policy_service,
const std::string& policy,
Delegate* delegate)
: cros_settings_(cros_settings),
user_manager_(user_manager),
device_local_account_policy_service_(device_local_account_policy_service),
policy_(policy),
delegate_(delegate),
weak_factory_(this) {
notification_registrar_.Add(
this,
chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
content::NotificationService::AllSources());
if (device_local_account_policy_service_)
device_local_account_policy_service_->AddObserver(this);
device_local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
chromeos::kAccountsPrefDeviceLocalAccounts,
base::Bind(&CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts,
base::Unretained(this)));
}
CloudExternalDataPolicyObserver::~CloudExternalDataPolicyObserver() {
if (device_local_account_policy_service_)
device_local_account_policy_service_->RemoveObserver(this);
for (DeviceLocalAccountEntryMap::iterator it =
device_local_account_entries_.begin();
it != device_local_account_entries_.end(); ++it) {
it->second.DeleteOwnedMembers();
}
device_local_account_entries_.clear();
}
void CloudExternalDataPolicyObserver::Init() {
RetrieveDeviceLocalAccounts();
}
void CloudExternalDataPolicyObserver::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type != chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED) {
NOTREACHED();
return;
}
Profile* profile = content::Details<Profile>(details).ptr();
const chromeos::User* user = user_manager_->GetUserByProfile(profile);
if (!user) {
NOTREACHED();
return;
}
const std::string& user_id = user->email();
if (ContainsKey(logged_in_user_observers_, user_id)) {
NOTREACHED();
return;
}
ProfilePolicyConnector* policy_connector =
ProfilePolicyConnectorFactory::GetForProfile(profile);
logged_in_user_observers_[user_id] = make_linked_ptr(
new PolicyServiceObserver(this,
user_id,
policy_connector->policy_service()));
}
void CloudExternalDataPolicyObserver::OnPolicyUpdated(
const std::string& user_id) {
if (ContainsKey(logged_in_user_observers_, user_id)) {
return;
}
if (!device_local_account_policy_service_) {
NOTREACHED();
return;
}
DeviceLocalAccountPolicyBroker* broker =
device_local_account_policy_service_->GetBrokerForUser(user_id);
if (!broker) {
return;
}
const PolicyMap::Entry* entry =
broker->core()->store()->policy_map().Get(policy_);
if (!entry) {
DeviceLocalAccountEntryMap::iterator it =
device_local_account_entries_.find(user_id);
if (it != device_local_account_entries_.end()) {
it->second.DeleteOwnedMembers();
device_local_account_entries_.erase(it);
HandleExternalDataPolicyUpdate(user_id, NULL);
}
return;
}
PolicyMap::Entry& map_entry = device_local_account_entries_[user_id];
if (map_entry.Equals(*entry))
return;
map_entry.DeleteOwnedMembers();
map_entry = *entry->DeepCopy();
HandleExternalDataPolicyUpdate(user_id, entry);
}
void CloudExternalDataPolicyObserver::OnDeviceLocalAccountsChanged() {
}
void CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts() {
if (chromeos::CrosSettingsProvider::TRUSTED !=
cros_settings_->PrepareTrustedValues(base::Bind(
&CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts,
weak_factory_.GetWeakPtr()))) {
return;
}
std::vector<DeviceLocalAccount> device_local_account_list =
policy::GetDeviceLocalAccounts(cros_settings_);
std::set<std::string> device_local_accounts;
for (std::vector<DeviceLocalAccount>::const_iterator it =
device_local_account_list.begin();
it != device_local_account_list.end(); ++it) {
device_local_accounts.insert(it->user_id);
}
for (DeviceLocalAccountEntryMap::iterator it =
device_local_account_entries_.begin();
it != device_local_account_entries_.end(); ) {
if (!ContainsKey(device_local_accounts, it->first)) {
const std::string user_id = it->first;
it->second.DeleteOwnedMembers();
device_local_account_entries_.erase(it++);
HandleExternalDataPolicyUpdate(user_id, NULL);
} else {
++it;
}
}
for (std::set<std::string>::const_iterator it = device_local_accounts.begin();
it != device_local_accounts.end(); ++it) {
OnPolicyUpdated(*it);
}
}
void CloudExternalDataPolicyObserver::HandleExternalDataPolicyUpdate(
const std::string& user_id,
const PolicyMap::Entry* entry) {
if (!entry) {
delegate_->OnExternalDataCleared(policy_, user_id);
fetch_weak_ptrs_.erase(user_id);
return;
}
delegate_->OnExternalDataSet(policy_, user_id);
linked_ptr<WeakPtrFactory>& weak_ptr_factory = fetch_weak_ptrs_[user_id];
weak_ptr_factory.reset(new WeakPtrFactory(this));
if (entry->external_data_fetcher) {
entry->external_data_fetcher->Fetch(base::Bind(
&CloudExternalDataPolicyObserver::OnExternalDataFetched,
weak_ptr_factory->GetWeakPtr(),
user_id));
} else {
NOTREACHED();
}
}
void CloudExternalDataPolicyObserver::OnExternalDataFetched(
const std::string& user_id,
scoped_ptr<std::string> data) {
FetchWeakPtrMap::iterator it = fetch_weak_ptrs_.find(user_id);
DCHECK(it != fetch_weak_ptrs_.end());
fetch_weak_ptrs_.erase(it);
delegate_->OnExternalDataFetched(policy_, user_id, data.Pass());
}
}