Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / user_cloud_policy_manager_chromeos.cc
blobe6be0a560701675c45632f91102b6e88a0237f65
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/metrics/sparse_histogram.h"
12 #include "base/sequenced_task_runner.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
15 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
18 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
19 #include "components/policy/core/common/cloud/device_management_service.h"
20 #include "components/policy/core/common/cloud/system_policy_request_context.h"
21 #include "components/policy/core/common/policy_pref_names.h"
22 #include "content/public/common/content_client.h"
23 #include "net/url_request/url_request_context_getter.h"
24 #include "url/gurl.h"
26 namespace em = enterprise_management;
28 namespace policy {
30 namespace {
32 // UMA histogram names.
33 const char kUMADelayInitialization[] =
34 "Enterprise.UserPolicyChromeOS.DelayInitialization";
35 const char kUMAInitialFetchClientError[] =
36 "Enterprise.UserPolicyChromeOS.InitialFetch.ClientError";
37 const char kUMAInitialFetchDelayClientRegister[] =
38 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayClientRegister";
39 const char kUMAInitialFetchDelayOAuth2Token[] =
40 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayOAuth2Token";
41 const char kUMAInitialFetchDelayPolicyFetch[] =
42 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayPolicyFetch";
43 const char kUMAInitialFetchDelayTotal[] =
44 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayTotal";
45 const char kUMAInitialFetchOAuth2Error[] =
46 "Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2Error";
47 const char kUMAInitialFetchOAuth2NetworkError[] =
48 "Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2NetworkError";
50 } // namespace
52 UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
53 scoped_ptr<CloudPolicyStore> store,
54 scoped_ptr<CloudExternalDataManager> external_data_manager,
55 const base::FilePath& component_policy_cache_path,
56 bool wait_for_policy_fetch,
57 base::TimeDelta initial_policy_fetch_timeout,
58 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
59 const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
60 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
61 : CloudPolicyManager(
62 PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
63 store.get(),
64 task_runner,
65 file_task_runner,
66 io_task_runner),
67 store_(store.Pass()),
68 external_data_manager_(external_data_manager.Pass()),
69 component_policy_cache_path_(component_policy_cache_path),
70 wait_for_policy_fetch_(wait_for_policy_fetch),
71 policy_fetch_timeout_(false, false) {
72 time_init_started_ = base::Time::Now();
73 if (wait_for_policy_fetch_) {
74 policy_fetch_timeout_.Start(
75 FROM_HERE,
76 initial_policy_fetch_timeout,
77 base::Bind(&UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout,
78 base::Unretained(this)));
82 UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
84 void UserCloudPolicyManagerChromeOS::Connect(
85 PrefService* local_state,
86 DeviceManagementService* device_management_service,
87 scoped_refptr<net::URLRequestContextGetter> system_request_context,
88 UserAffiliation user_affiliation) {
89 DCHECK(device_management_service);
90 DCHECK(local_state);
91 local_state_ = local_state;
92 scoped_refptr<net::URLRequestContextGetter> request_context;
93 if (system_request_context) {
94 // |system_request_context| can be null for tests.
95 // Use the system request context here instead of a context derived
96 // from the Profile because Connect() is called before the profile is
97 // fully initialized (required so we can perform the initial policy load).
98 // TODO(atwilson): Change this to use a UserPolicyRequestContext once
99 // Connect() is called after profile initialization. http://crbug.com/323591
100 request_context = new SystemPolicyRequestContext(
101 system_request_context,
102 content::GetUserAgent(GURL(
103 device_management_service->GetServerUrl())));
105 scoped_ptr<CloudPolicyClient> cloud_policy_client(
106 new CloudPolicyClient(std::string(), std::string(), user_affiliation,
107 NULL, device_management_service,
108 request_context));
109 core()->Connect(cloud_policy_client.Pass());
110 client()->AddObserver(this);
112 external_data_manager_->Connect(request_context);
114 CreateComponentCloudPolicyService(component_policy_cache_path_,
115 request_context);
117 // Determine the next step after the CloudPolicyService initializes.
118 if (service()->IsInitializationComplete()) {
119 OnInitializationCompleted(service());
120 } else {
121 service()->AddObserver(this);
125 void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
126 const std::string& access_token) {
127 access_token_ = access_token;
128 if (service() && service()->IsInitializationComplete() &&
129 client() && !client()->is_registered()) {
130 OnOAuth2PolicyTokenFetched(
131 access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
135 bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const {
136 return client() && client()->is_registered();
139 void UserCloudPolicyManagerChromeOS::Shutdown() {
140 if (client())
141 client()->RemoveObserver(this);
142 if (service())
143 service()->RemoveObserver(this);
144 token_fetcher_.reset();
145 external_data_manager_->Disconnect();
146 CloudPolicyManager::Shutdown();
149 bool UserCloudPolicyManagerChromeOS::IsInitializationComplete(
150 PolicyDomain domain) const {
151 if (!CloudPolicyManager::IsInitializationComplete(domain))
152 return false;
153 if (domain == POLICY_DOMAIN_CHROME)
154 return !wait_for_policy_fetch_;
155 return true;
158 void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
159 CloudPolicyService* cloud_policy_service) {
160 DCHECK_EQ(service(), cloud_policy_service);
161 cloud_policy_service->RemoveObserver(this);
163 time_init_completed_ = base::Time::Now();
164 UMA_HISTOGRAM_MEDIUM_TIMES(kUMADelayInitialization,
165 time_init_completed_ - time_init_started_);
167 // If the CloudPolicyClient isn't registered at this stage then it needs an
168 // OAuth token for the initial registration.
170 // If |wait_for_policy_fetch_| is true then Profile initialization is blocking
171 // on the initial policy fetch, so the token must be fetched immediately.
172 // In that case, the signin Profile is used to authenticate a Gaia request to
173 // fetch a refresh token, and then the policy token is fetched.
175 // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder
176 // service will eventually call OnAccessTokenAvailable() once an access token
177 // is available. That call may have already happened while waiting for
178 // initialization of the CloudPolicyService, so in that case check if an
179 // access token is already available.
180 if (!client()->is_registered()) {
181 if (wait_for_policy_fetch_) {
182 FetchPolicyOAuthTokenUsingSigninProfile();
183 } else if (!access_token_.empty()) {
184 OnOAuth2PolicyTokenFetched(
185 access_token_, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
189 if (!wait_for_policy_fetch_) {
190 // If this isn't blocking on a policy fetch then
191 // CloudPolicyManager::OnStoreLoaded() already published the cached policy.
192 // Start the refresh scheduler now, which will eventually refresh the
193 // cached policy or make the first fetch once the OAuth2 token is
194 // available.
195 StartRefreshSchedulerIfReady();
199 void UserCloudPolicyManagerChromeOS::OnPolicyFetched(
200 CloudPolicyClient* client) {
201 // No action required. If we're blocked on a policy fetch, we'll learn about
202 // completion of it through OnInitialPolicyFetchComplete().
205 void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged(
206 CloudPolicyClient* cloud_policy_client) {
207 DCHECK_EQ(client(), cloud_policy_client);
209 if (wait_for_policy_fetch_) {
210 time_client_registered_ = base::Time::Now();
211 if (!time_token_available_.is_null()) {
212 UMA_HISTOGRAM_MEDIUM_TIMES(
213 kUMAInitialFetchDelayClientRegister,
214 time_client_registered_ - time_token_available_);
217 // If we're blocked on the policy fetch, now is a good time to issue it.
218 if (client()->is_registered()) {
219 service()->RefreshPolicy(
220 base::Bind(
221 &UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete,
222 base::Unretained(this)));
223 } else {
224 // If the client has switched to not registered, we bail out as this
225 // indicates the cloud policy setup flow has been aborted.
226 CancelWaitForPolicyFetch();
231 void UserCloudPolicyManagerChromeOS::OnClientError(
232 CloudPolicyClient* cloud_policy_client) {
233 DCHECK_EQ(client(), cloud_policy_client);
234 if (wait_for_policy_fetch_) {
235 UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchClientError,
236 cloud_policy_client->status());
238 CancelWaitForPolicyFetch();
241 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
242 CloudPolicyManager::OnComponentCloudPolicyUpdated();
243 StartRefreshSchedulerIfReady();
246 void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() {
247 scoped_refptr<net::URLRequestContextGetter> signin_context;
248 Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile();
249 if (signin_profile)
250 signin_context = signin_profile->GetRequestContext();
251 if (!signin_context.get()) {
252 LOG(ERROR) << "No signin Profile for policy oauth token fetch!";
253 OnOAuth2PolicyTokenFetched(
254 std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE));
255 return;
258 token_fetcher_.reset(new PolicyOAuth2TokenFetcher(
259 signin_context.get(),
260 g_browser_process->system_request_context(),
261 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
262 base::Unretained(this))));
263 token_fetcher_->Start();
266 void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
267 const std::string& policy_token,
268 const GoogleServiceAuthError& error) {
269 DCHECK(!client()->is_registered());
271 time_token_available_ = base::Time::Now();
272 if (wait_for_policy_fetch_) {
273 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayOAuth2Token,
274 time_token_available_ - time_init_completed_);
277 if (error.state() == GoogleServiceAuthError::NONE) {
278 // Start client registration. Either OnRegistrationStateChanged() or
279 // OnClientError() will be called back.
280 client()->Register(em::DeviceRegisterRequest::USER,
281 policy_token, std::string(), false, std::string());
282 } else {
283 // Failed to get a token, stop waiting and use an empty policy.
284 CancelWaitForPolicyFetch();
286 UMA_HISTOGRAM_ENUMERATION(kUMAInitialFetchOAuth2Error,
287 error.state(),
288 GoogleServiceAuthError::NUM_STATES);
289 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
290 UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchOAuth2NetworkError,
291 error.network_error());
295 token_fetcher_.reset();
298 void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
299 bool success) {
300 const base::Time now = base::Time::Now();
301 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayPolicyFetch,
302 now - time_client_registered_);
303 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayTotal,
304 now - time_init_started_);
305 CancelWaitForPolicyFetch();
308 void UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout() {
309 if (!wait_for_policy_fetch_)
310 return;
311 LOG(WARNING) << "Timed out while waiting for the initial policy fetch. "
312 << "The first session will start without policy.";
313 CancelWaitForPolicyFetch();
316 void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
317 if (!wait_for_policy_fetch_)
318 return;
320 wait_for_policy_fetch_ = false;
321 policy_fetch_timeout_.Stop();
322 CheckAndPublishPolicy();
323 // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
324 // can be started.
325 StartRefreshSchedulerIfReady();
328 void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() {
329 if (core()->refresh_scheduler())
330 return; // Already started.
332 if (wait_for_policy_fetch_)
333 return; // Still waiting for the initial, blocking fetch.
335 if (!service() || !local_state_)
336 return; // Not connected.
338 if (component_policy_service() &&
339 !component_policy_service()->is_initialized()) {
340 // If the client doesn't have the list of components to fetch yet then don't
341 // start the scheduler. The |component_policy_service_| will call back into
342 // OnComponentCloudPolicyUpdated() once it's ready.
343 return;
346 core()->StartRefreshScheduler();
347 core()->TrackRefreshDelayPref(local_state_,
348 policy_prefs::kUserPolicyRefreshRate);
351 } // namespace policy