37cd951f34e58577f0e80abcd97b9366eb280ce0
[platform/framework/web/crosswalk.git] / src / chrome / browser / android / signin / signin_manager_android.cc
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/common/profile_management_switches.h"
27 #include "jni/SigninManager_jni.h"
28
29 #if defined(ENABLE_CONFIGURATION_POLICY)
30 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
31 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
32 #include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
33 #include "components/policy/core/browser/browser_policy_connector.h"
34 #include "components/policy/core/common/cloud/cloud_policy_core.h"
35 #include "components/policy/core/common/cloud/cloud_policy_store.h"
36 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
37 #include "google_apis/gaia/gaia_auth_util.h"
38 #include "net/url_request/url_request_context_getter.h"
39 #endif
40
41 namespace {
42
43 // A BrowsingDataRemover::Observer that clears all Profile data and then
44 // invokes a callback and deletes itself.
45 class 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
73 SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj)
74     : profile_(NULL),
75       weak_factory_(this) {
76   java_signin_manager_.Reset(env, obj);
77   profile_ = ProfileManager::GetActiveUserProfile();
78   DCHECK(profile_);
79 }
80
81 SigninManagerAndroid::~SigninManagerAndroid() {}
82
83 void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env,
84                                                    jobject obj,
85                                                    jstring username) {
86 #if defined(ENABLE_CONFIGURATION_POLICY)
87   username_ = base::android::ConvertJavaStringToUTF8(env, username);
88   policy::UserPolicySigninService* service =
89       policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
90   service->RegisterForPolicy(
91       base::android::ConvertJavaStringToUTF8(env, username),
92       base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone,
93                  weak_factory_.GetWeakPtr()));
94 #else
95   // This shouldn't be called when ShouldLoadPolicyForUser() is false.
96   NOTREACHED();
97   base::android::ScopedJavaLocalRef<jstring> domain;
98   Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
99                                                  java_signin_manager_.obj(),
100                                                  domain.obj());
101 #endif
102 }
103
104 void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) {
105 #if defined(ENABLE_CONFIGURATION_POLICY)
106   if (!dm_token_.empty()) {
107     policy::UserPolicySigninService* service =
108         policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
109     service->FetchPolicyForSignedInUser(
110         username_,
111         dm_token_,
112         client_id_,
113         profile_->GetRequestContext(),
114         base::Bind(&SigninManagerAndroid::OnPolicyFetchDone,
115                    weak_factory_.GetWeakPtr()));
116     dm_token_.clear();
117     client_id_.clear();
118     return;
119   }
120 #endif
121   // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when
122   // CheckPolicyBeforeSignIn() failed.
123   NOTREACHED();
124   Java_SigninManager_onPolicyFetchedBeforeSignIn(env,
125                                                  java_signin_manager_.obj());
126 }
127
128 void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env,
129                                              jobject obj,
130                                              jstring username) {
131   SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
132       base::android::ConvertJavaStringToUTF8(env, username));
133 }
134
135 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
136   SigninManagerFactory::GetForProfile(profile_)->SignOut();
137 }
138
139 base::android::ScopedJavaLocalRef<jstring>
140 SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) {
141   base::android::ScopedJavaLocalRef<jstring> domain;
142
143 #if defined(ENABLE_CONFIGURATION_POLICY)
144   policy::UserCloudPolicyManager* manager =
145       policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_);
146   policy::CloudPolicyStore* store = manager->core()->store();
147
148   if (store && store->is_managed() && store->policy()->has_username()) {
149     domain.Reset(
150         base::android::ConvertUTF8ToJavaString(
151             env, gaia::ExtractDomainName(store->policy()->username())));
152   }
153 #endif
154
155   return domain;
156 }
157
158 void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) {
159   // The ProfileDataRemover deletes itself once done.
160   new ProfileDataRemover(
161       profile_,
162       base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone,
163                  weak_factory_.GetWeakPtr()));
164 }
165
166 #if defined(ENABLE_CONFIGURATION_POLICY)
167
168 void SigninManagerAndroid::OnPolicyRegisterDone(
169     const std::string& dm_token,
170     const std::string& client_id) {
171   dm_token_ = dm_token;
172   client_id_ = client_id;
173
174   JNIEnv* env = base::android::AttachCurrentThread();
175   base::android::ScopedJavaLocalRef<jstring> domain;
176   if (!dm_token_.empty()) {
177     DCHECK(!username_.empty());
178     domain.Reset(
179         base::android::ConvertUTF8ToJavaString(
180             env, gaia::ExtractDomainName(username_)));
181   } else {
182     username_.clear();
183   }
184
185   Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
186                                                  java_signin_manager_.obj(),
187                                                  domain.obj());
188 }
189
190 void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
191   Java_SigninManager_onPolicyFetchedBeforeSignIn(
192       base::android::AttachCurrentThread(),
193       java_signin_manager_.obj());
194 }
195
196 #endif
197
198 void SigninManagerAndroid::OnBrowsingDataRemoverDone() {
199   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_);
200   model->RemoveAllUserBookmarks();
201
202   // All the Profile data has been wiped. Clear the last signed in username as
203   // well, so that the next signin doesn't trigger the acount change dialog.
204   ClearLastSignedInUser();
205
206   Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(),
207                                         java_signin_manager_.obj());
208 }
209
210 void SigninManagerAndroid::ClearLastSignedInUser(JNIEnv* env, jobject obj) {
211   ClearLastSignedInUser();
212 }
213
214 void SigninManagerAndroid::ClearLastSignedInUser() {
215   profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername);
216 }
217
218 void SigninManagerAndroid::MergeSessionCompleted(
219     const std::string& account_id,
220     const GoogleServiceAuthError& error) {
221   merge_session_helper_->RemoveObserver(this);
222   merge_session_helper_.reset();
223 }
224
225 void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) {
226   SigninManagerBase* signin_manager =
227       SigninManagerFactory::GetForProfile(profile_);
228   if (switches::IsNewProfileManagement()) {
229     // New Mirror code path that just fires the events and let the
230     // Account Reconcilor handles everything.
231     AndroidProfileOAuth2TokenService* token_service =
232         ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(
233             profile_);
234     const std::string& primary_acct =
235         signin_manager->GetAuthenticatedAccountId();
236     token_service->ValidateAccounts(primary_acct, true);
237
238   } else {
239     DVLOG(1) << "SigninManagerAndroid::LogInSignedInUser "
240         " Manually calling MergeSessionHelper";
241     // Old code path that doesn't depend on the new Account Reconcilor.
242     // We manually login.
243
244     ProfileOAuth2TokenService* token_service =
245         ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
246     merge_session_helper_.reset(new MergeSessionHelper(
247         token_service, profile_->GetRequestContext(), this));
248     merge_session_helper_->LogIn(signin_manager->GetAuthenticatedAccountId());
249   }
250 }
251
252 static jlong Init(JNIEnv* env, jobject obj) {
253   SigninManagerAndroid* signin_manager_android =
254       new SigninManagerAndroid(env, obj);
255   return reinterpret_cast<intptr_t>(signin_manager_android);
256 }
257
258 static jboolean ShouldLoadPolicyForUser(JNIEnv* env,
259                                         jobject obj,
260                                         jstring j_username) {
261 #if defined(ENABLE_CONFIGURATION_POLICY)
262   std::string username =
263       base::android::ConvertJavaStringToUTF8(env, j_username);
264   return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
265 #else
266   return false;
267 #endif
268 }
269
270 static jboolean IsNewProfileManagementEnabled(JNIEnv* env, jclass clazz) {
271   return switches::IsNewProfileManagement();
272 }
273
274 // static
275 bool SigninManagerAndroid::Register(JNIEnv* env) {
276   return RegisterNativesImpl(env);
277 }