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 42 namespace { 43 44 // A BrowsingDataRemover::Observer that clears all Profile data and then 45 // invokes a callback and deletes itself. 46 class 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 74 SigninManagerAndroid::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 87 SigninManagerAndroid::~SigninManagerAndroid() {} 88 89 void 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 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( 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 134 void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env, 135 jobject obj, 136 jstring username) { 137 SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted( 138 base::android::ConvertJavaStringToUTF8(env, username)); 139 } 140 141 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) { 142 SigninManagerFactory::GetForProfile(profile_)->SignOut( 143 signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS); 144 } 145 146 base::android::ScopedJavaLocalRef<jstring> 147 SigninManagerAndroid::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 165 void 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 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; 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 197 void SigninManagerAndroid::OnPolicyFetchDone(bool success) { 198 Java_SigninManager_onPolicyFetchedBeforeSignIn( 199 base::android::AttachCurrentThread(), 200 java_signin_manager_.obj()); 201 } 202 203 #endif 204 205 void 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 217 void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv* env, jobject obj) { 218 ClearLastSignedInUser(); 219 } 220 221 void SigninManagerAndroid::ClearLastSignedInUser() { 222 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername); 223 } 224 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(); 230 } 231 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( 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 259 jboolean SigninManagerAndroid::IsSigninAllowedByPolicy(JNIEnv* env, 260 jobject obj) { 261 return SigninManagerFactory::GetForProfile(profile_)->IsSigninAllowed(); 262 } 263 264 void SigninManagerAndroid::OnSigninAllowedPrefChanged() { 265 Java_SigninManager_onSigninAllowedByPolicyChanged( 266 base::android::AttachCurrentThread(), java_signin_manager_.obj(), 267 SigninManagerFactory::GetForProfile(profile_)->IsSigninAllowed()); 268 } 269 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); 274 } 275 276 static 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 288 static jboolean IsNewProfileManagementEnabled(JNIEnv* env, jclass clazz) { 289 return switches::IsNewProfileManagement(); 290 } 291 292 // static 293 bool SigninManagerAndroid::Register(JNIEnv* env) { 294 return RegisterNativesImpl(env); 295 } 296