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/signin_manager.h" 21 #include "chrome/browser/signin/signin_manager_factory.h" 22 #include "chrome/common/pref_names.h" 23 #include "jni/SigninManager_jni.h" 24 25 #if defined(ENABLE_CONFIGURATION_POLICY) 26 #include "chrome/browser/policy/browser_policy_connector.h" 27 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 28 #include "chrome/browser/policy/cloud/cloud_policy_core.h" 29 #include "chrome/browser/policy/cloud/cloud_policy_store.h" 30 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h" 31 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" 32 #include "chrome/browser/policy/cloud/user_policy_signin_service_android.h" 33 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h" 34 #include "google_apis/gaia/gaia_auth_util.h" 35 #endif 36 37 namespace { 38 39 // A BrowsingDataRemover::Observer that clears all Profile data and then 40 // invokes a callback and deletes itself. 41 class ProfileDataRemover : public BrowsingDataRemover::Observer { 42 public: 43 ProfileDataRemover(Profile* profile, const base::Closure& callback) 44 : callback_(callback), 45 origin_loop_(base::MessageLoopProxy::current()), 46 remover_(BrowsingDataRemover::CreateForUnboundedRange(profile)) { 47 remover_->AddObserver(this); 48 remover_->Remove(BrowsingDataRemover::REMOVE_ALL, BrowsingDataHelper::ALL); 49 } 50 51 virtual ~ProfileDataRemover() {} 52 53 virtual void OnBrowsingDataRemoverDone() OVERRIDE { 54 remover_->RemoveObserver(this); 55 origin_loop_->PostTask(FROM_HERE, callback_); 56 origin_loop_->DeleteSoon(FROM_HERE, this); 57 } 58 59 private: 60 base::Closure callback_; 61 scoped_refptr<base::MessageLoopProxy> origin_loop_; 62 BrowsingDataRemover* remover_; 63 64 DISALLOW_COPY_AND_ASSIGN(ProfileDataRemover); 65 }; 66 67 } // namespace 68 69 SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj) 70 : profile_(NULL), 71 weak_factory_(this) { 72 java_signin_manager_.Reset(env, obj); 73 DCHECK(g_browser_process); 74 DCHECK(g_browser_process->profile_manager()); 75 profile_ = g_browser_process->profile_manager()->GetDefaultProfile(); 76 DCHECK(profile_); 77 } 78 79 SigninManagerAndroid::~SigninManagerAndroid() {} 80 81 void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env, 82 jobject obj, 83 jstring username) { 84 #if defined(ENABLE_CONFIGURATION_POLICY) 85 username_ = base::android::ConvertJavaStringToUTF8(env, username); 86 policy::UserPolicySigninService* service = 87 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 88 service->RegisterPolicyClient( 89 base::android::ConvertJavaStringToUTF8(env, username), 90 base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone, 91 weak_factory_.GetWeakPtr())); 92 #else 93 // This shouldn't be called when ShouldLoadPolicyForUser() is false. 94 NOTREACHED(); 95 base::android::ScopedJavaLocalRef<jstring> domain; 96 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 97 java_signin_manager_.obj(), 98 domain.obj()); 99 #endif 100 } 101 102 void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) { 103 #if defined(ENABLE_CONFIGURATION_POLICY) 104 if (cloud_policy_client_) { 105 policy::UserPolicySigninService* service = 106 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 107 service->FetchPolicyForSignedInUser( 108 cloud_policy_client_.Pass(), 109 base::Bind(&SigninManagerAndroid::OnPolicyFetchDone, 110 weak_factory_.GetWeakPtr())); 111 return; 112 } 113 #endif 114 // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when 115 // CheckPolicyBeforeSignIn() failed. 116 NOTREACHED(); 117 Java_SigninManager_onPolicyFetchedBeforeSignIn(env, 118 java_signin_manager_.obj()); 119 } 120 121 void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env, 122 jobject obj, 123 jstring username) { 124 SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted( 125 base::android::ConvertJavaStringToUTF8(env, username)); 126 } 127 128 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) { 129 SigninManagerFactory::GetForProfile(profile_)->SignOut(); 130 } 131 132 base::android::ScopedJavaLocalRef<jstring> 133 SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) { 134 base::android::ScopedJavaLocalRef<jstring> domain; 135 136 #if defined(ENABLE_CONFIGURATION_POLICY) 137 policy::UserCloudPolicyManager* manager = 138 policy::UserCloudPolicyManagerFactory::GetForProfile(profile_); 139 policy::CloudPolicyStore* store = manager->core()->store(); 140 141 if (store && store->is_managed() && store->policy()->has_username()) { 142 domain.Reset( 143 base::android::ConvertUTF8ToJavaString( 144 env, gaia::ExtractDomainName(store->policy()->username()))); 145 } 146 #endif 147 148 return domain; 149 } 150 151 void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) { 152 // The ProfileDataRemover deletes itself once done. 153 new ProfileDataRemover( 154 profile_, 155 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone, 156 weak_factory_.GetWeakPtr())); 157 } 158 159 #if defined(ENABLE_CONFIGURATION_POLICY) 160 161 void SigninManagerAndroid::OnPolicyRegisterDone( 162 scoped_ptr<policy::CloudPolicyClient> client) { 163 cloud_policy_client_ = client.Pass(); 164 165 JNIEnv* env = base::android::AttachCurrentThread(); 166 base::android::ScopedJavaLocalRef<jstring> domain; 167 if (cloud_policy_client_) { 168 DCHECK(!username_.empty()); 169 domain.Reset( 170 base::android::ConvertUTF8ToJavaString( 171 env, gaia::ExtractDomainName(username_))); 172 } else { 173 username_.clear(); 174 } 175 176 Java_SigninManager_onPolicyCheckedBeforeSignIn(env, 177 java_signin_manager_.obj(), 178 domain.obj()); 179 } 180 181 void SigninManagerAndroid::OnPolicyFetchDone(bool success) { 182 Java_SigninManager_onPolicyFetchedBeforeSignIn( 183 base::android::AttachCurrentThread(), 184 java_signin_manager_.obj()); 185 } 186 187 #endif 188 189 void SigninManagerAndroid::OnBrowsingDataRemoverDone() { 190 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_); 191 model->RemoveAll(); 192 193 // All the Profile data has been wiped. Clear the last signed in username as 194 // well, so that the next signin doesn't trigger the acount change dialog. 195 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername); 196 197 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(), 198 java_signin_manager_.obj()); 199 } 200 201 static int Init(JNIEnv* env, jobject obj) { 202 SigninManagerAndroid* signin_manager_android = 203 new SigninManagerAndroid(env, obj); 204 return reinterpret_cast<jint>(signin_manager_android); 205 } 206 207 static jboolean ShouldLoadPolicyForUser(JNIEnv* env, 208 jobject obj, 209 jstring j_username) { 210 #if defined(ENABLE_CONFIGURATION_POLICY) 211 std::string username = 212 base::android::ConvertJavaStringToUTF8(env, j_username); 213 return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username); 214 #else 215 return false; 216 #endif 217 } 218 219 // static 220 bool SigninManagerAndroid::Register(JNIEnv* env) { 221 return RegisterNativesImpl(env); 222 } 223