signin_manager_android.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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.h"
33#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
34#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
35#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
36#include "components/policy/core/common/cloud/cloud_policy_core.h"
37#include "components/policy/core/common/cloud/cloud_policy_store.h"
38#include "google_apis/gaia/gaia_auth_util.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  DCHECK(g_browser_process);
78  DCHECK(g_browser_process->profile_manager());
79  profile_ = g_browser_process->profile_manager()->GetDefaultProfile();
80  DCHECK(profile_);
81}
82
83SigninManagerAndroid::~SigninManagerAndroid() {}
84
85void 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
106void 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
129void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env,
130                                             jobject obj,
131                                             jstring username) {
132  SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
133      base::android::ConvertJavaStringToUTF8(env, username));
134}
135
136void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
137  SigninManagerFactory::GetForProfile(profile_)->SignOut();
138}
139
140base::android::ScopedJavaLocalRef<jstring>
141SigninManagerAndroid::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
159void 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
169void 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
191void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
192  Java_SigninManager_onPolicyFetchedBeforeSignIn(
193      base::android::AttachCurrentThread(),
194      java_signin_manager_.obj());
195}
196
197#endif
198
199void 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
211void 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
234static 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
240static 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
253bool SigninManagerAndroid::Register(JNIEnv* env) {
254  return RegisterNativesImpl(env);
255}
256