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/command_line.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
19 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
20 #include "components/policy/core/common/policy_switches.h"
21 #include "components/signin/core/browser/profile_oauth2_token_service.h"
22 #include "components/signin/core/browser/signin_manager.h"
23 #include "net/base/network_change_notifier.h"
24 #include "net/url_request/url_request_context_getter.h"
25 #include "policy/proto/device_management_backend.pb.h"
31 enterprise_management::DeviceRegisterRequest::Type
GetRegistrationType() {
32 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
33 if (command_line
->HasSwitch(switches::kFakeCloudPolicyType
))
34 return enterprise_management::DeviceRegisterRequest::BROWSER
;
36 return enterprise_management::DeviceRegisterRequest::IOS_BROWSER
;
37 #elif defined(OS_ANDROID)
38 return enterprise_management::DeviceRegisterRequest::ANDROID_BROWSER
;
40 #error "This file can be built only on OS_IOS or OS_ANDROID."
46 UserPolicySigninService::UserPolicySigninService(
48 PrefService
* local_state
,
49 DeviceManagementService
* device_management_service
,
50 UserCloudPolicyManager
* policy_manager
,
51 SigninManager
* signin_manager
,
52 scoped_refptr
<net::URLRequestContextGetter
> system_request_context
,
53 ProfileOAuth2TokenService
* token_service
)
54 : UserPolicySigninServiceBase(profile
,
56 device_management_service
,
59 system_request_context
),
60 oauth2_token_service_(token_service
),
61 profile_prefs_(profile
->GetPrefs()),
64 // iOS doesn't create this service with the Profile; instead it's created
65 // a little bit later. See UserPolicySigninServiceFactory.
66 InitializeOnProfileReady(profile
);
70 UserPolicySigninService::~UserPolicySigninService() {}
72 void UserPolicySigninService::RegisterForPolicy(
73 const std::string
& username
,
74 const PolicyRegistrationCallback
& callback
) {
75 RegisterForPolicyInternal(username
, "", callback
);
78 #if !defined(OS_ANDROID)
79 void UserPolicySigninService::RegisterForPolicyWithAccessToken(
80 const std::string
& username
,
81 const std::string
& access_token
,
82 const PolicyRegistrationCallback
& callback
) {
83 RegisterForPolicyInternal(username
, access_token
, callback
);
87 std::vector
<std::string
> UserPolicySigninService::GetScopes() {
88 return CloudPolicyClientRegistrationHelper::GetScopes();
92 void UserPolicySigninService::RegisterForPolicyInternal(
93 const std::string
& username
,
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 GetRegistrationType()));
112 if (access_token
.empty()) {
113 registration_helper_
->StartRegistration(
114 oauth2_token_service_
,
116 base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback
,
117 base::Unretained(this),
118 base::Passed(&policy_client
),
121 #if defined(OS_ANDROID)
124 registration_helper_
->StartRegistrationWithAccessToken(
126 base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback
,
127 base::Unretained(this),
128 base::Passed(&policy_client
),
134 void UserPolicySigninService::CallPolicyRegistrationCallback(
135 scoped_ptr
<CloudPolicyClient
> client
,
136 PolicyRegistrationCallback callback
) {
137 registration_helper_
.reset();
138 callback
.Run(client
->dm_token(), client
->client_id());
141 void UserPolicySigninService::Shutdown() {
142 CancelPendingRegistration();
143 registration_helper_
.reset();
144 UserPolicySigninServiceBase::Shutdown();
147 void UserPolicySigninService::OnInitializationCompleted(
148 CloudPolicyService
* service
) {
149 UserCloudPolicyManager
* manager
= policy_manager();
150 DCHECK_EQ(service
, manager
->core()->service());
151 DCHECK(service
->IsInitializationComplete());
152 // The service is now initialized - if the client is not yet registered, then
153 // it means that there is no cached policy and so we need to initiate a new
154 // client registration.
155 if (manager
->IsClientRegistered()) {
156 DVLOG(1) << "Client already registered - not fetching DMToken";
160 net::NetworkChangeNotifier::ConnectionType connection_type
=
161 net::NetworkChangeNotifier::GetConnectionType();
162 base::TimeDelta retry_delay
= base::TimeDelta::FromDays(3);
163 if (connection_type
== net::NetworkChangeNotifier::CONNECTION_ETHERNET
||
164 connection_type
== net::NetworkChangeNotifier::CONNECTION_WIFI
) {
165 retry_delay
= base::TimeDelta::FromDays(1);
168 base::Time last_check_time
= base::Time::FromInternalValue(
169 profile_prefs_
->GetInt64(prefs::kLastPolicyCheckTime
));
170 base::Time now
= base::Time::Now();
171 base::Time next_check_time
= last_check_time
+ retry_delay
;
173 // Check immediately if no check was ever done before (last_check_time == 0),
174 // or if the last check was in the future (?), or if we're already past the
175 // next check time. Otherwise, delay checking until the next check time.
176 base::TimeDelta try_registration_delay
= base::TimeDelta::FromSeconds(5);
177 if (now
> last_check_time
&& now
< next_check_time
)
178 try_registration_delay
= next_check_time
- now
;
180 base::MessageLoop::current()->PostDelayedTask(
182 base::Bind(&UserPolicySigninService::RegisterCloudPolicyService
,
183 weak_factory_
.GetWeakPtr()),
184 try_registration_delay
);
187 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
188 CancelPendingRegistration();
189 UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
192 void UserPolicySigninService::RegisterCloudPolicyService() {
193 // If the user signed-out while this task was waiting then Shutdown() would
194 // have been called, which would have invalidated this task. Since we're here
195 // then the user must still be signed-in.
196 DCHECK(signin_manager()->IsAuthenticated());
197 DCHECK(!policy_manager()->IsClientRegistered());
198 DCHECK(policy_manager()->core()->client());
200 // Persist the current time as the last policy registration attempt time.
201 profile_prefs_
->SetInt64(prefs::kLastPolicyCheckTime
,
202 base::Time::Now().ToInternalValue());
204 registration_helper_
.reset(new CloudPolicyClientRegistrationHelper(
205 policy_manager()->core()->client(),
206 GetRegistrationType()));
207 registration_helper_
->StartRegistration(
208 oauth2_token_service_
,
209 signin_manager()->GetAuthenticatedUsername(),
210 base::Bind(&UserPolicySigninService::OnRegistrationDone
,
211 base::Unretained(this)));
214 void UserPolicySigninService::CancelPendingRegistration() {
215 weak_factory_
.InvalidateWeakPtrs();
218 void UserPolicySigninService::OnRegistrationDone() {
219 registration_helper_
.reset();
222 } // namespace policy