Home | History | Annotate | Download | only in signin
      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_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 "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 #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   DCHECK(g_browser_process);
     78   DCHECK(g_browser_process->profile_manager());
     79   profile_ = g_browser_process->profile_manager()->GetDefaultProfile();
     80   DCHECK(profile_);
     81 }
     82 
     83 SigninManagerAndroid::~SigninManagerAndroid() {}
     84 
     85 void 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 
    106 void 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 
    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 
    136 void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
    137   SigninManagerFactory::GetForProfile(profile_)->SignOut();
    138 }
    139 
    140 base::android::ScopedJavaLocalRef<jstring>
    141 SigninManagerAndroid::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 
    159 void 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 
    169 void 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 
    191 void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
    192   Java_SigninManager_onPolicyFetchedBeforeSignIn(
    193       base::android::AttachCurrentThread(),
    194       java_signin_manager_.obj());
    195 }
    196 
    197 #endif
    198 
    199 void 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 
    211 void 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 
    234 static 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 
    240 static 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
    253 bool SigninManagerAndroid::Register(JNIEnv* env) {
    254   return RegisterNativesImpl(env);
    255 }
    256