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/profiles/profiles_state.h" 21 #include "chrome/browser/signin/android_profile_oauth2_token_service.h" 22 #include "chrome/browser/signin/google_auto_login_helper.h" 23 #include "chrome/browser/signin/profile_oauth2_token_service.h" 24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 25 #include "chrome/browser/signin/signin_manager.h" 26 #include "chrome/browser/signin/signin_manager_factory.h" 27 #include "chrome/common/pref_names.h" 28 #include "jni/SigninManager_jni.h" 29 30 #if defined(ENABLE_CONFIGURATION_POLICY) 31 #include "chrome/browser/policy/browser_policy_connector.h" 32 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" 33 #include "chrome/browser/policy/cloud/user_policy_signin_service_android.h" 34 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.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 #endif 40 41 namespace { 42 43 // A BrowsingDataRemover::Observer that clears all Profile data and then 44 // invokes a callback and deletes itself. 45 class 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 73 SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj) 74 : profile_(NULL), 75 weak_factory_(this) { 76 java_signin_manager_.Reset(env, obj); 77 DCHECK(g_browser_process); 78 DCHECK(g_browser_process->profile_manager()); 79 profile_ = g_browser_process->profile_manager()->GetDefaultProfile(); 80 DCHECK(profile_); 81 } 82 83 SigninManagerAndroid::~SigninManagerAndroid() {} 84 85 void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env, 86 jobject obj, 87 jstring username) { 88 #if defined(ENABLE_CONFIGURATION_POLICY) 89 username_ = base::android::ConvertJavaStringToUTF8(env, username); 90 policy::UserPolicySigninService* service = 91 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 92 service->RegisterForPolicy( 93 base::android::ConvertJavaStringToUTF8(env, username), 94 base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone, 95 weak_factory_.GetWeakPtr())); 96 #else 97 // This shouldn't be called when ShouldLoadPolicyForUser() is false. 98 NOTREACHED(); 99 base::android::ScopedJavaLocalRef<jstring> domain; 100 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 101 java_signin_manager_.obj(), 102 domain.obj()); 103 #endif 104 } 105 106 void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) { 107 #if defined(ENABLE_CONFIGURATION_POLICY) 108 if (!dm_token_.empty()) { 109 policy::UserPolicySigninService* service = 110 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 111 service->FetchPolicyForSignedInUser( 112 username_, 113 dm_token_, 114 client_id_, 115 base::Bind(&SigninManagerAndroid::OnPolicyFetchDone, 116 weak_factory_.GetWeakPtr())); 117 dm_token_.clear(); 118 client_id_.clear(); 119 return; 120 } 121 #endif 122 // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when 123 // CheckPolicyBeforeSignIn() failed. 124 NOTREACHED(); 125 Java_SigninManager_onPolicyFetchedBeforeSignIn(env, 126 java_signin_manager_.obj()); 127 } 128 129 void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env, 130 jobject obj, 131 jstring username) { 132 SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted( 133 base::android::ConvertJavaStringToUTF8(env, username)); 134 } 135 136 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) { 137 SigninManagerFactory::GetForProfile(profile_)->SignOut(); 138 } 139 140 base::android::ScopedJavaLocalRef<jstring> 141 SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) { 142 base::android::ScopedJavaLocalRef<jstring> domain; 143 144 #if defined(ENABLE_CONFIGURATION_POLICY) 145 policy::UserCloudPolicyManager* manager = 146 policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_); 147 policy::CloudPolicyStore* store = manager->core()->store(); 148 149 if (store && store->is_managed() && store->policy()->has_username()) { 150 domain.Reset( 151 base::android::ConvertUTF8ToJavaString( 152 env, gaia::ExtractDomainName(store->policy()->username()))); 153 } 154 #endif 155 156 return domain; 157 } 158 159 void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) { 160 // The ProfileDataRemover deletes itself once done. 161 new ProfileDataRemover( 162 profile_, 163 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone, 164 weak_factory_.GetWeakPtr())); 165 } 166 167 #if defined(ENABLE_CONFIGURATION_POLICY) 168 169 void SigninManagerAndroid::OnPolicyRegisterDone( 170 const std::string& dm_token, 171 const std::string& client_id) { 172 dm_token_ = dm_token; 173 client_id_ = client_id; 174 175 JNIEnv* env = base::android::AttachCurrentThread(); 176 base::android::ScopedJavaLocalRef<jstring> domain; 177 if (!dm_token_.empty()) { 178 DCHECK(!username_.empty()); 179 domain.Reset( 180 base::android::ConvertUTF8ToJavaString( 181 env, gaia::ExtractDomainName(username_))); 182 } else { 183 username_.clear(); 184 } 185 186 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 187 java_signin_manager_.obj(), 188 domain.obj()); 189 } 190 191 void SigninManagerAndroid::OnPolicyFetchDone(bool success) { 192 Java_SigninManager_onPolicyFetchedBeforeSignIn( 193 base::android::AttachCurrentThread(), 194 java_signin_manager_.obj()); 195 } 196 197 #endif 198 199 void SigninManagerAndroid::OnBrowsingDataRemoverDone() { 200 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_); 201 model->RemoveAll(); 202 203 // All the Profile data has been wiped. Clear the last signed in username as 204 // well, so that the next signin doesn't trigger the acount change dialog. 205 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername); 206 207 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(), 208 java_signin_manager_.obj()); 209 } 210 211 void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) { 212 if (profiles::IsNewProfileManagementEnabled()) { 213 // New Mirror code path that just fires the events and let the 214 // Account Reconcilor handles everything. 215 AndroidProfileOAuth2TokenService* token_service = 216 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile( 217 profile_); 218 const std::string& primary_acct = token_service->GetPrimaryAccountId(); 219 const std::vector<std::string>& ids = token_service->GetAccounts(); 220 token_service->ValidateAccounts(primary_acct, ids); 221 222 } else { 223 DVLOG(1) << "SigninManagerAndroid::LogInSignedInUser " 224 " Manually calling GoogleAutoLoginHelper"; 225 // Old code path that doesn't depend on the new Account Reconcilor. 226 // We manually login. 227 228 // AutoLogin deletes itself. 229 GoogleAutoLoginHelper* autoLogin = new GoogleAutoLoginHelper(profile_); 230 autoLogin->LogIn(); 231 } 232 } 233 234 static jlong Init(JNIEnv* env, jobject obj) { 235 SigninManagerAndroid* signin_manager_android = 236 new SigninManagerAndroid(env, obj); 237 return reinterpret_cast<intptr_t>(signin_manager_android); 238 } 239 240 static jboolean ShouldLoadPolicyForUser(JNIEnv* env, 241 jobject obj, 242 jstring j_username) { 243 #if defined(ENABLE_CONFIGURATION_POLICY) 244 std::string username = 245 base::android::ConvertJavaStringToUTF8(env, j_username); 246 return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username); 247 #else 248 return false; 249 #endif 250 } 251 252 // static 253 bool SigninManagerAndroid::Register(JNIEnv* env) { 254 return RegisterNativesImpl(env); 255 } 256