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:
ProfileDataRemover(Profile * profile,const base::Closure & callback)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
~ProfileDataRemover()56 virtual ~ProfileDataRemover() {}
57
OnBrowsingDataRemoverDone()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
SigninManagerAndroid(JNIEnv * env,jobject obj)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 }
81
~SigninManagerAndroid()82 SigninManagerAndroid::~SigninManagerAndroid() {}
83
CheckPolicyBeforeSignIn(JNIEnv * env,jobject obj,jstring username)84 void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env,
85 jobject obj,
86 jstring username) {
87 #if defined(ENABLE_CONFIGURATION_POLICY)
88 username_ = base::android::ConvertJavaStringToUTF8(env, username);
89 policy::UserPolicySigninService* service =
90 policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
91 service->RegisterForPolicy(
92 base::android::ConvertJavaStringToUTF8(env, username),
93 base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone,
94 weak_factory_.GetWeakPtr()));
95 #else
96 // This shouldn't be called when ShouldLoadPolicyForUser() is false.
97 NOTREACHED();
98 base::android::ScopedJavaLocalRef<jstring> domain;
99 Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
100 java_signin_manager_.obj(),
101 domain.obj());
102 #endif
103 }
104
FetchPolicyBeforeSignIn(JNIEnv * env,jobject obj)105 void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) {
106 #if defined(ENABLE_CONFIGURATION_POLICY)
107 if (!dm_token_.empty()) {
108 policy::UserPolicySigninService* service =
109 policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
110 service->FetchPolicyForSignedInUser(
111 username_,
112 dm_token_,
113 client_id_,
114 profile_->GetRequestContext(),
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
OnSignInCompleted(JNIEnv * env,jobject obj,jstring username)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
SignOut(JNIEnv * env,jobject obj)136 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
137 SigninManagerFactory::GetForProfile(profile_)->SignOut(
138 signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS);
139 }
140
141 base::android::ScopedJavaLocalRef<jstring>
GetManagementDomain(JNIEnv * env,jobject obj)142 SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) {
143 base::android::ScopedJavaLocalRef<jstring> domain;
144
145 #if defined(ENABLE_CONFIGURATION_POLICY)
146 policy::UserCloudPolicyManager* manager =
147 policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_);
148 policy::CloudPolicyStore* store = manager->core()->store();
149
150 if (store && store->is_managed() && store->policy()->has_username()) {
151 domain.Reset(
152 base::android::ConvertUTF8ToJavaString(
153 env, gaia::ExtractDomainName(store->policy()->username())));
154 }
155 #endif
156
157 return domain;
158 }
159
WipeProfileData(JNIEnv * env,jobject obj)160 void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) {
161 // The ProfileDataRemover deletes itself once done.
162 new ProfileDataRemover(
163 profile_,
164 base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone,
165 weak_factory_.GetWeakPtr()));
166 }
167
168 #if defined(ENABLE_CONFIGURATION_POLICY)
169
OnPolicyRegisterDone(const std::string & dm_token,const std::string & client_id)170 void SigninManagerAndroid::OnPolicyRegisterDone(
171 const std::string& dm_token,
172 const std::string& client_id) {
173 dm_token_ = dm_token;
174 client_id_ = client_id;
175
176 JNIEnv* env = base::android::AttachCurrentThread();
177 base::android::ScopedJavaLocalRef<jstring> domain;
178 if (!dm_token_.empty()) {
179 DCHECK(!username_.empty());
180 domain.Reset(
181 base::android::ConvertUTF8ToJavaString(
182 env, gaia::ExtractDomainName(username_)));
183 } else {
184 username_.clear();
185 }
186
187 Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
188 java_signin_manager_.obj(),
189 domain.obj());
190 }
191
OnPolicyFetchDone(bool success)192 void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
193 Java_SigninManager_onPolicyFetchedBeforeSignIn(
194 base::android::AttachCurrentThread(),
195 java_signin_manager_.obj());
196 }
197
198 #endif
199
OnBrowsingDataRemoverDone()200 void SigninManagerAndroid::OnBrowsingDataRemoverDone() {
201 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_);
202 model->RemoveAllUserBookmarks();
203
204 // All the Profile data has been wiped. Clear the last signed in username as
205 // well, so that the next signin doesn't trigger the acount change dialog.
206 ClearLastSignedInUser();
207
208 Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(),
209 java_signin_manager_.obj());
210 }
211
ClearLastSignedInUser(JNIEnv * env,jobject obj)212 void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv* env, jobject obj) {
213 ClearLastSignedInUser();
214 }
215
ClearLastSignedInUser()216 void SigninManagerAndroid::ClearLastSignedInUser() {
217 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername);
218 }
219
MergeSessionCompleted(const std::string & account_id,const GoogleServiceAuthError & error)220 void SigninManagerAndroid::MergeSessionCompleted(
221 const std::string& account_id,
222 const GoogleServiceAuthError& error) {
223 merge_session_helper_->RemoveObserver(this);
224 merge_session_helper_.reset();
225 }
226
LogInSignedInUser(JNIEnv * env,jobject obj)227 void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) {
228 SigninManagerBase* signin_manager =
229 SigninManagerFactory::GetForProfile(profile_);
230 if (switches::IsNewProfileManagement()) {
231 // New Mirror code path that just fires the events and let the
232 // Account Reconcilor handles everything.
233 AndroidProfileOAuth2TokenService* token_service =
234 ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(
235 profile_);
236 const std::string& primary_acct =
237 signin_manager->GetAuthenticatedAccountId();
238 token_service->ValidateAccounts(primary_acct, true);
239
240 } else {
241 DVLOG(1) << "SigninManagerAndroid::LogInSignedInUser "
242 " Manually calling MergeSessionHelper";
243 // Old code path that doesn't depend on the new Account Reconcilor.
244 // We manually login.
245
246 ProfileOAuth2TokenService* token_service =
247 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
248 merge_session_helper_.reset(new MergeSessionHelper(
249 token_service, profile_->GetRequestContext(), this));
250 merge_session_helper_->LogIn(signin_manager->GetAuthenticatedAccountId());
251 }
252 }
253
Init(JNIEnv * env,jobject obj)254 static jlong Init(JNIEnv* env, jobject obj) {
255 SigninManagerAndroid* signin_manager_android =
256 new SigninManagerAndroid(env, obj);
257 return reinterpret_cast<intptr_t>(signin_manager_android);
258 }
259
ShouldLoadPolicyForUser(JNIEnv * env,jobject obj,jstring j_username)260 static jboolean ShouldLoadPolicyForUser(JNIEnv* env,
261 jobject obj,
262 jstring j_username) {
263 #if defined(ENABLE_CONFIGURATION_POLICY)
264 std::string username =
265 base::android::ConvertJavaStringToUTF8(env, j_username);
266 return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
267 #else
268 return false;
269 #endif
270 }
271
IsNewProfileManagementEnabled(JNIEnv * env,jclass clazz)272 static jboolean IsNewProfileManagementEnabled(JNIEnv* env, jclass clazz) {
273 return switches::IsNewProfileManagement();
274 }
275
276 // static
Register(JNIEnv * env)277 bool SigninManagerAndroid::Register(JNIEnv* env) {
278 return RegisterNativesImpl(env);
279 }
280