1 // Copyright 2013 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/android/signin/signin_manager_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/browsing_data/browsing_data_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_remover.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/signin/android_profile_oauth2_token_service.h"
20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
21 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/common/pref_names.h"
23 #include "components/bookmarks/browser/bookmark_model.h"
24 #include "components/signin/core/browser/profile_oauth2_token_service.h"
25 #include "components/signin/core/browser/signin_manager.h"
26 #include "components/signin/core/browser/signin_metrics.h"
27 #include "components/signin/core/common/profile_management_switches.h"
28 #include "jni/SigninManager_jni.h"
30 #if defined(ENABLE_CONFIGURATION_POLICY)
31 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
32 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
33 #include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
34 #include "components/policy/core/browser/browser_policy_connector.h"
35 #include "components/policy/core/common/cloud/cloud_policy_core.h"
36 #include "components/policy/core/common/cloud/cloud_policy_store.h"
37 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
38 #include "google_apis/gaia/gaia_auth_util.h"
39 #include "net/url_request/url_request_context_getter.h"
44 // A BrowsingDataRemover::Observer that clears all Profile data and then
45 // invokes a callback and deletes itself.
46 class ProfileDataRemover
: public BrowsingDataRemover::Observer
{
48 ProfileDataRemover(Profile
* profile
, const base::Closure
& callback
)
49 : callback_(callback
),
50 origin_loop_(base::MessageLoopProxy::current()),
51 remover_(BrowsingDataRemover::CreateForUnboundedRange(profile
)) {
52 remover_
->AddObserver(this);
53 remover_
->Remove(BrowsingDataRemover::REMOVE_ALL
, BrowsingDataHelper::ALL
);
56 virtual ~ProfileDataRemover() {}
58 virtual void OnBrowsingDataRemoverDone() OVERRIDE
{
59 remover_
->RemoveObserver(this);
60 origin_loop_
->PostTask(FROM_HERE
, callback_
);
61 origin_loop_
->DeleteSoon(FROM_HERE
, this);
65 base::Closure callback_
;
66 scoped_refptr
<base::MessageLoopProxy
> origin_loop_
;
67 BrowsingDataRemover
* remover_
;
69 DISALLOW_COPY_AND_ASSIGN(ProfileDataRemover
);
74 SigninManagerAndroid::SigninManagerAndroid(JNIEnv
* env
, jobject obj
)
77 java_signin_manager_
.Reset(env
, obj
);
78 profile_
= ProfileManager::GetActiveUserProfile();
80 pref_change_registrar_
.Init(profile_
->GetPrefs());
81 pref_change_registrar_
.Add(
82 prefs::kSigninAllowed
,
83 base::Bind(&SigninManagerAndroid::OnSigninAllowedPrefChanged
,
84 base::Unretained(this)));
87 SigninManagerAndroid::~SigninManagerAndroid() {}
89 void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv
* env
,
92 #if defined(ENABLE_CONFIGURATION_POLICY)
93 username_
= base::android::ConvertJavaStringToUTF8(env
, username
);
94 policy::UserPolicySigninService
* service
=
95 policy::UserPolicySigninServiceFactory::GetForProfile(profile_
);
96 service
->RegisterForPolicy(
97 base::android::ConvertJavaStringToUTF8(env
, username
),
98 base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone
,
99 weak_factory_
.GetWeakPtr()));
101 // This shouldn't be called when ShouldLoadPolicyForUser() is false.
103 base::android::ScopedJavaLocalRef
<jstring
> domain
;
104 Java_SigninManager_onPolicyCheckedBeforeSignIn(env
,
105 java_signin_manager_
.obj(),
110 void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv
* env
, jobject obj
) {
111 #if defined(ENABLE_CONFIGURATION_POLICY)
112 if (!dm_token_
.empty()) {
113 policy::UserPolicySigninService
* service
=
114 policy::UserPolicySigninServiceFactory::GetForProfile(profile_
);
115 service
->FetchPolicyForSignedInUser(
119 profile_
->GetRequestContext(),
120 base::Bind(&SigninManagerAndroid::OnPolicyFetchDone
,
121 weak_factory_
.GetWeakPtr()));
127 // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when
128 // CheckPolicyBeforeSignIn() failed.
130 Java_SigninManager_onPolicyFetchedBeforeSignIn(env
,
131 java_signin_manager_
.obj());
134 void SigninManagerAndroid::OnSignInCompleted(JNIEnv
* env
,
137 SigninManagerFactory::GetForProfile(profile_
)->OnExternalSigninCompleted(
138 base::android::ConvertJavaStringToUTF8(env
, username
));
141 void SigninManagerAndroid::SignOut(JNIEnv
* env
, jobject obj
) {
142 SigninManagerFactory::GetForProfile(profile_
)->SignOut(
143 signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS
);
146 base::android::ScopedJavaLocalRef
<jstring
>
147 SigninManagerAndroid::GetManagementDomain(JNIEnv
* env
, jobject obj
) {
148 base::android::ScopedJavaLocalRef
<jstring
> domain
;
150 #if defined(ENABLE_CONFIGURATION_POLICY)
151 policy::UserCloudPolicyManager
* manager
=
152 policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_
);
153 policy::CloudPolicyStore
* store
= manager
->core()->store();
155 if (store
&& store
->is_managed() && store
->policy()->has_username()) {
157 base::android::ConvertUTF8ToJavaString(
158 env
, gaia::ExtractDomainName(store
->policy()->username())));
165 void SigninManagerAndroid::WipeProfileData(JNIEnv
* env
, jobject obj
) {
166 // The ProfileDataRemover deletes itself once done.
167 new ProfileDataRemover(
169 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone
,
170 weak_factory_
.GetWeakPtr()));
173 #if defined(ENABLE_CONFIGURATION_POLICY)
175 void SigninManagerAndroid::OnPolicyRegisterDone(
176 const std::string
& dm_token
,
177 const std::string
& client_id
) {
178 dm_token_
= dm_token
;
179 client_id_
= client_id
;
181 JNIEnv
* env
= base::android::AttachCurrentThread();
182 base::android::ScopedJavaLocalRef
<jstring
> domain
;
183 if (!dm_token_
.empty()) {
184 DCHECK(!username_
.empty());
186 base::android::ConvertUTF8ToJavaString(
187 env
, gaia::ExtractDomainName(username_
)));
192 Java_SigninManager_onPolicyCheckedBeforeSignIn(env
,
193 java_signin_manager_
.obj(),
197 void SigninManagerAndroid::OnPolicyFetchDone(bool success
) {
198 Java_SigninManager_onPolicyFetchedBeforeSignIn(
199 base::android::AttachCurrentThread(),
200 java_signin_manager_
.obj());
205 void SigninManagerAndroid::OnBrowsingDataRemoverDone() {
206 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(profile_
);
207 model
->RemoveAllUserBookmarks();
209 // All the Profile data has been wiped. Clear the last signed in username as
210 // well, so that the next signin doesn't trigger the acount change dialog.
211 ClearLastSignedInUser();
213 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(),
214 java_signin_manager_
.obj());
217 void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv
* env
, jobject obj
) {
218 ClearLastSignedInUser();
221 void SigninManagerAndroid::ClearLastSignedInUser() {
222 profile_
->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername
);
225 void SigninManagerAndroid::MergeSessionCompleted(
226 const std::string
& account_id
,
227 const GoogleServiceAuthError
& error
) {
228 merge_session_helper_
->RemoveObserver(this);
229 merge_session_helper_
.reset();
232 void SigninManagerAndroid::LogInSignedInUser(JNIEnv
* env
, jobject obj
) {
233 SigninManagerBase
* signin_manager
=
234 SigninManagerFactory::GetForProfile(profile_
);
235 if (switches::IsNewProfileManagement()) {
236 // New Mirror code path that just fires the events and let the
237 // Account Reconcilor handles everything.
238 AndroidProfileOAuth2TokenService
* token_service
=
239 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(
241 const std::string
& primary_acct
=
242 signin_manager
->GetAuthenticatedAccountId();
243 token_service
->ValidateAccounts(primary_acct
, true);
246 DVLOG(1) << "SigninManagerAndroid::LogInSignedInUser "
247 " Manually calling MergeSessionHelper";
248 // Old code path that doesn't depend on the new Account Reconcilor.
249 // We manually login.
251 ProfileOAuth2TokenService
* token_service
=
252 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
253 merge_session_helper_
.reset(new MergeSessionHelper(
254 token_service
, profile_
->GetRequestContext(), this));
255 merge_session_helper_
->LogIn(signin_manager
->GetAuthenticatedAccountId());
259 jboolean
SigninManagerAndroid::IsSigninAllowedByPolicy(JNIEnv
* env
,
261 return SigninManagerFactory::GetForProfile(profile_
)->IsSigninAllowed();
264 void SigninManagerAndroid::OnSigninAllowedPrefChanged() {
265 Java_SigninManager_onSigninAllowedByPolicyChanged(
266 base::android::AttachCurrentThread(), java_signin_manager_
.obj(),
267 SigninManagerFactory::GetForProfile(profile_
)->IsSigninAllowed());
270 static jlong
Init(JNIEnv
* env
, jobject obj
) {
271 SigninManagerAndroid
* signin_manager_android
=
272 new SigninManagerAndroid(env
, obj
);
273 return reinterpret_cast<intptr_t>(signin_manager_android
);
276 static jboolean
ShouldLoadPolicyForUser(JNIEnv
* env
,
278 jstring j_username
) {
279 #if defined(ENABLE_CONFIGURATION_POLICY)
280 std::string username
=
281 base::android::ConvertJavaStringToUTF8(env
, j_username
);
282 return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username
);
288 static jboolean
IsNewProfileManagementEnabled(JNIEnv
* env
, jclass clazz
) {
289 return switches::IsNewProfileManagement();
293 bool SigninManagerAndroid::Register(JNIEnv
* env
) {
294 return RegisterNativesImpl(env
);