signin_manager_android.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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. 4 5#include "chrome/browser/android/signin/signin_manager_android.h" 6 7#include "base/android/jni_android.h" 8#include "base/android/jni_string.h" 9#include "base/bind.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" 29 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" 40#endif 41 42namespace { 43 44// A BrowsingDataRemover::Observer that clears all Profile data and then 45// invokes a callback and deletes itself. 46class ProfileDataRemover : public BrowsingDataRemover::Observer { 47 public: 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); 54 } 55 56 virtual ~ProfileDataRemover() {} 57 58 virtual void OnBrowsingDataRemoverDone() OVERRIDE { 59 remover_->RemoveObserver(this); 60 origin_loop_->PostTask(FROM_HERE, callback_); 61 origin_loop_->DeleteSoon(FROM_HERE, this); 62 } 63 64 private: 65 base::Closure callback_; 66 scoped_refptr<base::MessageLoopProxy> origin_loop_; 67 BrowsingDataRemover* remover_; 68 69 DISALLOW_COPY_AND_ASSIGN(ProfileDataRemover); 70}; 71 72} // namespace 73 74SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj) 75 : profile_(NULL), 76 weak_factory_(this) { 77 java_signin_manager_.Reset(env, obj); 78 profile_ = ProfileManager::GetActiveUserProfile(); 79 DCHECK(profile_); 80 pref_change_registrar_.Init(profile_->GetPrefs()); 81 pref_change_registrar_.Add( 82 prefs::kSigninAllowed, 83 base::Bind(&SigninManagerAndroid::OnSigninAllowedPrefChanged, 84 base::Unretained(this))); 85} 86 87SigninManagerAndroid::~SigninManagerAndroid() {} 88 89void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env, 90 jobject obj, 91 jstring username) { 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())); 100#else 101 // This shouldn't be called when ShouldLoadPolicyForUser() is false. 102 NOTREACHED(); 103 base::android::ScopedJavaLocalRef<jstring> domain; 104 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 105 java_signin_manager_.obj(), 106 domain.obj()); 107#endif 108} 109 110void 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( 116 username_, 117 dm_token_, 118 client_id_, 119 profile_->GetRequestContext(), 120 base::Bind(&SigninManagerAndroid::OnPolicyFetchDone, 121 weak_factory_.GetWeakPtr())); 122 dm_token_.clear(); 123 client_id_.clear(); 124 return; 125 } 126#endif 127 // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when 128 // CheckPolicyBeforeSignIn() failed. 129 NOTREACHED(); 130 Java_SigninManager_onPolicyFetchedBeforeSignIn(env, 131 java_signin_manager_.obj()); 132} 133 134void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env, 135 jobject obj, 136 jstring username) { 137 SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted( 138 base::android::ConvertJavaStringToUTF8(env, username)); 139} 140 141void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) { 142 SigninManagerFactory::GetForProfile(profile_)->SignOut( 143 signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS); 144} 145 146base::android::ScopedJavaLocalRef<jstring> 147SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) { 148 base::android::ScopedJavaLocalRef<jstring> domain; 149 150#if defined(ENABLE_CONFIGURATION_POLICY) 151 policy::UserCloudPolicyManager* manager = 152 policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_); 153 policy::CloudPolicyStore* store = manager->core()->store(); 154 155 if (store && store->is_managed() && store->policy()->has_username()) { 156 domain.Reset( 157 base::android::ConvertUTF8ToJavaString( 158 env, gaia::ExtractDomainName(store->policy()->username()))); 159 } 160#endif 161 162 return domain; 163} 164 165void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) { 166 // The ProfileDataRemover deletes itself once done. 167 new ProfileDataRemover( 168 profile_, 169 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone, 170 weak_factory_.GetWeakPtr())); 171} 172 173#if defined(ENABLE_CONFIGURATION_POLICY) 174 175void SigninManagerAndroid::OnPolicyRegisterDone( 176 const std::string& dm_token, 177 const std::string& client_id) { 178 dm_token_ = dm_token; 179 client_id_ = client_id; 180 181 JNIEnv* env = base::android::AttachCurrentThread(); 182 base::android::ScopedJavaLocalRef<jstring> domain; 183 if (!dm_token_.empty()) { 184 DCHECK(!username_.empty()); 185 domain.Reset( 186 base::android::ConvertUTF8ToJavaString( 187 env, gaia::ExtractDomainName(username_))); 188 } else { 189 username_.clear(); 190 } 191 192 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 193 java_signin_manager_.obj(), 194 domain.obj()); 195} 196 197void SigninManagerAndroid::OnPolicyFetchDone(bool success) { 198 Java_SigninManager_onPolicyFetchedBeforeSignIn( 199 base::android::AttachCurrentThread(), 200 java_signin_manager_.obj()); 201} 202 203#endif 204 205void SigninManagerAndroid::OnBrowsingDataRemoverDone() { 206 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_); 207 model->RemoveAllUserBookmarks(); 208 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(); 212 213 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(), 214 java_signin_manager_.obj()); 215} 216 217void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv* env, jobject obj) { 218 ClearLastSignedInUser(); 219} 220 221void SigninManagerAndroid::ClearLastSignedInUser() { 222 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername); 223} 224 225void SigninManagerAndroid::MergeSessionCompleted( 226 const std::string& account_id, 227 const GoogleServiceAuthError& error) { 228 merge_session_helper_->RemoveObserver(this); 229 merge_session_helper_.reset(); 230} 231 232void 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( 240 profile_); 241 const std::string& primary_acct = 242 signin_manager->GetAuthenticatedAccountId(); 243 token_service->ValidateAccounts(primary_acct, true); 244 245 } else { 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. 250 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()); 256 } 257} 258 259jboolean SigninManagerAndroid::IsSigninAllowedByPolicy(JNIEnv* env, 260 jobject obj) { 261 return SigninManagerFactory::GetForProfile(profile_)->IsSigninAllowed(); 262} 263 264void SigninManagerAndroid::OnSigninAllowedPrefChanged() { 265 Java_SigninManager_onSigninAllowedByPolicyChanged( 266 base::android::AttachCurrentThread(), java_signin_manager_.obj(), 267 SigninManagerFactory::GetForProfile(profile_)->IsSigninAllowed()); 268} 269 270static 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); 274} 275 276static jboolean ShouldLoadPolicyForUser(JNIEnv* env, 277 jobject obj, 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); 283#else 284 return false; 285#endif 286} 287 288static jboolean IsNewProfileManagementEnabled(JNIEnv* env, jclass clazz) { 289 return switches::IsNewProfileManagement(); 290} 291 292// static 293bool SigninManagerAndroid::Register(JNIEnv* env) { 294 return RegisterNativesImpl(env); 295} 296