• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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