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