1 // Copyright 2014 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/policy/cloud/user_policy_signin_service_mobile.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
18 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
19 #include "components/policy/core/common/policy_switches.h"
20 #include "components/signin/core/browser/profile_oauth2_token_service.h"
21 #include "components/signin/core/browser/signin_manager.h"
22 #include "net/base/network_change_notifier.h"
23 #include "net/url_request/url_request_context_getter.h"
24 #include "policy/proto/device_management_backend.pb.h"
26 namespace em
= enterprise_management
;
33 const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType
=
34 em::DeviceRegisterRequest::IOS_BROWSER
;
35 #elif defined(OS_ANDROID)
36 const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType
=
37 em::DeviceRegisterRequest::ANDROID_BROWSER
;
39 #error "This file can be built only on OS_IOS or OS_ANDROID."
44 UserPolicySigninService::UserPolicySigninService(
46 PrefService
* local_state
,
47 DeviceManagementService
* device_management_service
,
48 UserCloudPolicyManager
* policy_manager
,
49 SigninManager
* signin_manager
,
50 scoped_refptr
<net::URLRequestContextGetter
> system_request_context
,
51 ProfileOAuth2TokenService
* token_service
)
52 : UserPolicySigninServiceBase(profile
,
54 device_management_service
,
57 system_request_context
),
58 oauth2_token_service_(token_service
),
59 profile_prefs_(profile
->GetPrefs()),
62 // iOS doesn't create this service with the Profile; instead it's created
63 // a little bit later. See UserPolicySigninServiceFactory.
64 InitializeOnProfileReady(profile
);
68 UserPolicySigninService::~UserPolicySigninService() {}
70 void UserPolicySigninService::RegisterForPolicy(
71 const std::string
& username
,
72 const std::string
& account_id
,
73 const PolicyRegistrationCallback
& callback
) {
74 RegisterForPolicyInternal(username
, account_id
, "", callback
);
77 #if !defined(OS_ANDROID)
78 void UserPolicySigninService::RegisterForPolicyWithAccessToken(
79 const std::string
& username
,
80 const std::string
& access_token
,
81 const PolicyRegistrationCallback
& callback
) {
82 RegisterForPolicyInternal(username
, "", access_token
, callback
);
86 std::vector
<std::string
> UserPolicySigninService::GetScopes() {
87 return CloudPolicyClientRegistrationHelper::GetScopes();
91 void UserPolicySigninService::RegisterForPolicyInternal(
92 const std::string
& username
,
93 const std::string
& account_id
,
94 const std::string
& access_token
,
95 const PolicyRegistrationCallback
& callback
) {
96 // Create a new CloudPolicyClient for fetching the DMToken.
97 scoped_ptr
<CloudPolicyClient
> policy_client
= CreateClientForRegistrationOnly(
100 callback
.Run(std::string(), std::string());
104 CancelPendingRegistration();
106 // Fire off the registration process. Callback keeps the CloudPolicyClient
107 // alive for the length of the registration process.
108 registration_helper_
.reset(new CloudPolicyClientRegistrationHelper(
110 kCloudPolicyRegistrationType
));
112 if (access_token
.empty()) {
113 registration_helper_
->StartRegistration(
114 oauth2_token_service_
, account_id
,
115 base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback
,
116 base::Unretained(this), base::Passed(&policy_client
),
119 #if defined(OS_ANDROID)
122 registration_helper_
->StartRegistrationWithAccessToken(
124 base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback
,
125 base::Unretained(this),
126 base::Passed(&policy_client
),
132 void UserPolicySigninService::CallPolicyRegistrationCallback(
133 scoped_ptr
<CloudPolicyClient
> client
,
134 PolicyRegistrationCallback callback
) {
135 registration_helper_
.reset();
136 callback
.Run(client
->dm_token(), client
->client_id());
139 void UserPolicySigninService::Shutdown() {
140 CancelPendingRegistration();
141 registration_helper_
.reset();
142 UserPolicySigninServiceBase::Shutdown();
145 void UserPolicySigninService::OnInitializationCompleted(
146 CloudPolicyService
* service
) {
147 UserCloudPolicyManager
* manager
= policy_manager();
148 DCHECK_EQ(service
, manager
->core()->service());
149 DCHECK(service
->IsInitializationComplete());
150 // The service is now initialized - if the client is not yet registered, then
151 // it means that there is no cached policy and so we need to initiate a new
152 // client registration.
153 if (manager
->IsClientRegistered()) {
154 DVLOG(1) << "Client already registered - not fetching DMToken";
158 net::NetworkChangeNotifier::ConnectionType connection_type
=
159 net::NetworkChangeNotifier::GetConnectionType();
160 base::TimeDelta retry_delay
= base::TimeDelta::FromDays(3);
161 if (connection_type
== net::NetworkChangeNotifier::CONNECTION_ETHERNET
||
162 connection_type
== net::NetworkChangeNotifier::CONNECTION_WIFI
) {
163 retry_delay
= base::TimeDelta::FromDays(1);
166 base::Time last_check_time
= base::Time::FromInternalValue(
167 profile_prefs_
->GetInt64(prefs::kLastPolicyCheckTime
));
168 base::Time now
= base::Time::Now();
169 base::Time next_check_time
= last_check_time
+ retry_delay
;
171 // Check immediately if no check was ever done before (last_check_time == 0),
172 // or if the last check was in the future (?), or if we're already past the
173 // next check time. Otherwise, delay checking until the next check time.
174 base::TimeDelta try_registration_delay
= base::TimeDelta::FromSeconds(5);
175 if (now
> last_check_time
&& now
< next_check_time
)
176 try_registration_delay
= next_check_time
- now
;
178 base::MessageLoop::current()->PostDelayedTask(
180 base::Bind(&UserPolicySigninService::RegisterCloudPolicyService
,
181 weak_factory_
.GetWeakPtr()),
182 try_registration_delay
);
185 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
186 CancelPendingRegistration();
187 UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
190 void UserPolicySigninService::RegisterCloudPolicyService() {
191 // If the user signed-out while this task was waiting then Shutdown() would
192 // have been called, which would have invalidated this task. Since we're here
193 // then the user must still be signed-in.
194 DCHECK(signin_manager()->IsAuthenticated());
195 DCHECK(!policy_manager()->IsClientRegistered());
196 DCHECK(policy_manager()->core()->client());
198 // Persist the current time as the last policy registration attempt time.
199 profile_prefs_
->SetInt64(prefs::kLastPolicyCheckTime
,
200 base::Time::Now().ToInternalValue());
202 registration_helper_
.reset(new CloudPolicyClientRegistrationHelper(
203 policy_manager()->core()->client(),
204 kCloudPolicyRegistrationType
));
205 registration_helper_
->StartRegistration(
206 oauth2_token_service_
,
207 signin_manager()->GetAuthenticatedAccountId(),
208 base::Bind(&UserPolicySigninService::OnRegistrationDone
,
209 base::Unretained(this)));
212 void UserPolicySigninService::CancelPendingRegistration() {
213 weak_factory_
.InvalidateWeakPtrs();
216 void UserPolicySigninService::OnRegistrationDone() {
217 registration_helper_
.reset();
220 } // namespace policy