signin_manager_android.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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
37namespace {
38
39// A BrowsingDataRemover::Observer that clears all Profile data and then
40// invokes a callback and deletes itself.
41class 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
69SigninManagerAndroid::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
79SigninManagerAndroid::~SigninManagerAndroid() {}
80
81void 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
102void 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
121void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env,
122                                             jobject obj,
123                                             jstring username) {
124  SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
125      base::android::ConvertJavaStringToUTF8(env, username));
126}
127
128void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
129  SigninManagerFactory::GetForProfile(profile_)->SignOut();
130}
131
132base::android::ScopedJavaLocalRef<jstring>
133SigninManagerAndroid::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
151void 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
161void 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
181void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
182  Java_SigninManager_onPolicyFetchedBeforeSignIn(
183      base::android::AttachCurrentThread(),
184      java_signin_manager_.obj());
185}
186
187#endif
188
189void 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
201static 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
207static 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
220bool SigninManagerAndroid::Register(JNIEnv* env) {
221  return RegisterNativesImpl(env);
222}
223