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