signin_manager_android.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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.h" 15#include "chrome/browser/bookmarks/bookmark_model_factory.h" 16#include "chrome/browser/browser_process.h" 17#include "chrome/browser/browsing_data/browsing_data_helper.h" 18#include "chrome/browser/browsing_data/browsing_data_remover.h" 19#include "chrome/browser/profiles/profile_manager.h" 20#include "chrome/browser/signin/android_profile_oauth2_token_service.h" 21#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 22#include "chrome/browser/signin/signin_manager_factory.h" 23#include "chrome/common/pref_names.h" 24#include "chrome/common/profile_management_switches.h" 25#include "components/signin/core/browser/profile_oauth2_token_service.h" 26#include "components/signin/core/browser/signin_manager.h" 27#include "jni/SigninManager_jni.h" 28 29#if defined(ENABLE_CONFIGURATION_POLICY) 30#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" 31#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h" 32#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h" 33#include "components/policy/core/browser/browser_policy_connector.h" 34#include "components/policy/core/common/cloud/cloud_policy_core.h" 35#include "components/policy/core/common/cloud/cloud_policy_store.h" 36#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" 37#include "google_apis/gaia/gaia_auth_util.h" 38#include "net/url_request/url_request_context_getter.h" 39#endif 40 41namespace { 42 43// A BrowsingDataRemover::Observer that clears all Profile data and then 44// invokes a callback and deletes itself. 45class ProfileDataRemover : public BrowsingDataRemover::Observer { 46 public: 47 ProfileDataRemover(Profile* profile, const base::Closure& callback) 48 : callback_(callback), 49 origin_loop_(base::MessageLoopProxy::current()), 50 remover_(BrowsingDataRemover::CreateForUnboundedRange(profile)) { 51 remover_->AddObserver(this); 52 remover_->Remove(BrowsingDataRemover::REMOVE_ALL, BrowsingDataHelper::ALL); 53 } 54 55 virtual ~ProfileDataRemover() {} 56 57 virtual void OnBrowsingDataRemoverDone() OVERRIDE { 58 remover_->RemoveObserver(this); 59 origin_loop_->PostTask(FROM_HERE, callback_); 60 origin_loop_->DeleteSoon(FROM_HERE, this); 61 } 62 63 private: 64 base::Closure callback_; 65 scoped_refptr<base::MessageLoopProxy> origin_loop_; 66 BrowsingDataRemover* remover_; 67 68 DISALLOW_COPY_AND_ASSIGN(ProfileDataRemover); 69}; 70 71} // namespace 72 73SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj) 74 : profile_(NULL), 75 weak_factory_(this) { 76 java_signin_manager_.Reset(env, obj); 77 profile_ = ProfileManager::GetActiveUserProfile(); 78 DCHECK(profile_); 79} 80 81SigninManagerAndroid::~SigninManagerAndroid() {} 82 83void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env, 84 jobject obj, 85 jstring username) { 86#if defined(ENABLE_CONFIGURATION_POLICY) 87 username_ = base::android::ConvertJavaStringToUTF8(env, username); 88 policy::UserPolicySigninService* service = 89 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 90 service->RegisterForPolicy( 91 base::android::ConvertJavaStringToUTF8(env, username), 92 base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone, 93 weak_factory_.GetWeakPtr())); 94#else 95 // This shouldn't be called when ShouldLoadPolicyForUser() is false. 96 NOTREACHED(); 97 base::android::ScopedJavaLocalRef<jstring> domain; 98 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 99 java_signin_manager_.obj(), 100 domain.obj()); 101#endif 102} 103 104void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) { 105#if defined(ENABLE_CONFIGURATION_POLICY) 106 if (!dm_token_.empty()) { 107 policy::UserPolicySigninService* service = 108 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 109 service->FetchPolicyForSignedInUser( 110 username_, 111 dm_token_, 112 client_id_, 113 profile_->GetRequestContext(), 114 base::Bind(&SigninManagerAndroid::OnPolicyFetchDone, 115 weak_factory_.GetWeakPtr())); 116 dm_token_.clear(); 117 client_id_.clear(); 118 return; 119 } 120#endif 121 // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when 122 // CheckPolicyBeforeSignIn() failed. 123 NOTREACHED(); 124 Java_SigninManager_onPolicyFetchedBeforeSignIn(env, 125 java_signin_manager_.obj()); 126} 127 128void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env, 129 jobject obj, 130 jstring username) { 131 SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted( 132 base::android::ConvertJavaStringToUTF8(env, username)); 133} 134 135void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) { 136 SigninManagerFactory::GetForProfile(profile_)->SignOut(); 137} 138 139base::android::ScopedJavaLocalRef<jstring> 140SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) { 141 base::android::ScopedJavaLocalRef<jstring> domain; 142 143#if defined(ENABLE_CONFIGURATION_POLICY) 144 policy::UserCloudPolicyManager* manager = 145 policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_); 146 policy::CloudPolicyStore* store = manager->core()->store(); 147 148 if (store && store->is_managed() && store->policy()->has_username()) { 149 domain.Reset( 150 base::android::ConvertUTF8ToJavaString( 151 env, gaia::ExtractDomainName(store->policy()->username()))); 152 } 153#endif 154 155 return domain; 156} 157 158void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) { 159 // The ProfileDataRemover deletes itself once done. 160 new ProfileDataRemover( 161 profile_, 162 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone, 163 weak_factory_.GetWeakPtr())); 164} 165 166#if defined(ENABLE_CONFIGURATION_POLICY) 167 168void SigninManagerAndroid::OnPolicyRegisterDone( 169 const std::string& dm_token, 170 const std::string& client_id) { 171 dm_token_ = dm_token; 172 client_id_ = client_id; 173 174 JNIEnv* env = base::android::AttachCurrentThread(); 175 base::android::ScopedJavaLocalRef<jstring> domain; 176 if (!dm_token_.empty()) { 177 DCHECK(!username_.empty()); 178 domain.Reset( 179 base::android::ConvertUTF8ToJavaString( 180 env, gaia::ExtractDomainName(username_))); 181 } else { 182 username_.clear(); 183 } 184 185 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 186 java_signin_manager_.obj(), 187 domain.obj()); 188} 189 190void SigninManagerAndroid::OnPolicyFetchDone(bool success) { 191 Java_SigninManager_onPolicyFetchedBeforeSignIn( 192 base::android::AttachCurrentThread(), 193 java_signin_manager_.obj()); 194} 195 196#endif 197 198void SigninManagerAndroid::OnBrowsingDataRemoverDone() { 199 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_); 200 model->RemoveAll(); 201 202 // All the Profile data has been wiped. Clear the last signed in username as 203 // well, so that the next signin doesn't trigger the acount change dialog. 204 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername); 205 206 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(), 207 java_signin_manager_.obj()); 208} 209 210void SigninManagerAndroid::MergeSessionCompleted( 211 const std::string& account_id, 212 const GoogleServiceAuthError& error) { 213 merge_session_helper_->RemoveObserver(this); 214 merge_session_helper_.reset(); 215} 216 217void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) { 218 SigninManagerBase* signin_manager = 219 SigninManagerFactory::GetForProfile(profile_); 220 if (switches::IsNewProfileManagement()) { 221 // New Mirror code path that just fires the events and let the 222 // Account Reconcilor handles everything. 223 AndroidProfileOAuth2TokenService* token_service = 224 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile( 225 profile_); 226 const std::string& primary_acct = 227 signin_manager->GetAuthenticatedAccountId(); 228 const std::vector<std::string>& ids = token_service->GetAccounts(); 229 token_service->ValidateAccounts(primary_acct, ids); 230 231 } else { 232 DVLOG(1) << "SigninManagerAndroid::LogInSignedInUser " 233 " Manually calling MergeSessionHelper"; 234 // Old code path that doesn't depend on the new Account Reconcilor. 235 // We manually login. 236 237 ProfileOAuth2TokenService* token_service = 238 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 239 merge_session_helper_.reset(new MergeSessionHelper( 240 token_service, profile_->GetRequestContext(), this)); 241 merge_session_helper_->LogIn(signin_manager->GetAuthenticatedAccountId()); 242 } 243} 244 245static jlong Init(JNIEnv* env, jobject obj) { 246 SigninManagerAndroid* signin_manager_android = 247 new SigninManagerAndroid(env, obj); 248 return reinterpret_cast<intptr_t>(signin_manager_android); 249} 250 251static jboolean ShouldLoadPolicyForUser(JNIEnv* env, 252 jobject obj, 253 jstring j_username) { 254#if defined(ENABLE_CONFIGURATION_POLICY) 255 std::string username = 256 base::android::ConvertJavaStringToUTF8(env, j_username); 257 return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username); 258#else 259 return false; 260#endif 261} 262 263static jboolean IsNewProfileManagementEnabled(JNIEnv* env, jclass clazz) { 264 return switches::IsNewProfileManagement(); 265} 266 267// static 268bool SigninManagerAndroid::Register(JNIEnv* env) { 269 return RegisterNativesImpl(env); 270} 271