blob: 8cd2b7e6890d7a48f443e8e013e8626ade2e92c9 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/signin/signin_manager_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "jni/SigninManager_jni.h"
#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud/cloud_policy_core.h"
#include "chrome/browser/policy/cloud/cloud_policy_store.h"
#include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
#include "google_apis/gaia/gaia_auth_util.h"
#endif
namespace {
// A BrowsingDataRemover::Observer that clears all Profile data and then
// invokes a callback and deletes itself.
class ProfileDataRemover : public BrowsingDataRemover::Observer {
public:
ProfileDataRemover(Profile* profile, const base::Closure& callback)
: callback_(callback),
origin_loop_(base::MessageLoopProxy::current()),
remover_(BrowsingDataRemover::CreateForUnboundedRange(profile)) {
remover_->AddObserver(this);
remover_->Remove(BrowsingDataRemover::REMOVE_ALL, BrowsingDataHelper::ALL);
}
virtual ~ProfileDataRemover() {}
virtual void OnBrowsingDataRemoverDone() OVERRIDE {
remover_->RemoveObserver(this);
origin_loop_->PostTask(FROM_HERE, callback_);
origin_loop_->DeleteSoon(FROM_HERE, this);
}
private:
base::Closure callback_;
scoped_refptr<base::MessageLoopProxy> origin_loop_;
BrowsingDataRemover* remover_;
DISALLOW_COPY_AND_ASSIGN(ProfileDataRemover);
};
} // namespace
SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj)
: profile_(NULL),
weak_factory_(this) {
java_signin_manager_.Reset(env, obj);
DCHECK(g_browser_process);
DCHECK(g_browser_process->profile_manager());
profile_ = g_browser_process->profile_manager()->GetDefaultProfile();
DCHECK(profile_);
}
SigninManagerAndroid::~SigninManagerAndroid() {}
void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env,
jobject obj,
jstring username) {
#if defined(ENABLE_CONFIGURATION_POLICY)
username_ = base::android::ConvertJavaStringToUTF8(env, username);
policy::UserPolicySigninService* service =
policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
service->RegisterForPolicy(
base::android::ConvertJavaStringToUTF8(env, username),
base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone,
weak_factory_.GetWeakPtr()));
#else
// This shouldn't be called when ShouldLoadPolicyForUser() is false.
NOTREACHED();
base::android::ScopedJavaLocalRef<jstring> domain;
Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
java_signin_manager_.obj(),
domain.obj());
#endif
}
void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) {
#if defined(ENABLE_CONFIGURATION_POLICY)
if (!dm_token_.empty()) {
policy::UserPolicySigninService* service =
policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
service->FetchPolicyForSignedInUser(
username_,
dm_token_,
client_id_,
base::Bind(&SigninManagerAndroid::OnPolicyFetchDone,
weak_factory_.GetWeakPtr()));
dm_token_.clear();
client_id_.clear();
return;
}
#endif
// This shouldn't be called when ShouldLoadPolicyForUser() is false, or when
// CheckPolicyBeforeSignIn() failed.
NOTREACHED();
Java_SigninManager_onPolicyFetchedBeforeSignIn(env,
java_signin_manager_.obj());
}
void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env,
jobject obj,
jstring username) {
SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
base::android::ConvertJavaStringToUTF8(env, username));
}
void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
SigninManagerFactory::GetForProfile(profile_)->SignOut();
}
base::android::ScopedJavaLocalRef<jstring>
SigninManagerAndroid::GetManagementDomain(JNIEnv* env, jobject obj) {
base::android::ScopedJavaLocalRef<jstring> domain;
#if defined(ENABLE_CONFIGURATION_POLICY)
policy::UserCloudPolicyManager* manager =
policy::UserCloudPolicyManagerFactory::GetForBrowserContext(profile_);
policy::CloudPolicyStore* store = manager->core()->store();
if (store && store->is_managed() && store->policy()->has_username()) {
domain.Reset(
base::android::ConvertUTF8ToJavaString(
env, gaia::ExtractDomainName(store->policy()->username())));
}
#endif
return domain;
}
void SigninManagerAndroid::WipeProfileData(JNIEnv* env, jobject obj) {
// The ProfileDataRemover deletes itself once done.
new ProfileDataRemover(
profile_,
base::Bind(&SigninManagerAndroid::OnBrowsingDataRemoverDone,
weak_factory_.GetWeakPtr()));
}
#if defined(ENABLE_CONFIGURATION_POLICY)
void SigninManagerAndroid::OnPolicyRegisterDone(
const std::string& dm_token,
const std::string& client_id) {
dm_token_ = dm_token;
client_id_ = client_id_;
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jstring> domain;
if (!dm_token_.empty()) {
DCHECK(!username_.empty());
domain.Reset(
base::android::ConvertUTF8ToJavaString(
env, gaia::ExtractDomainName(username_)));
} else {
username_.clear();
}
Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
java_signin_manager_.obj(),
domain.obj());
}
void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
Java_SigninManager_onPolicyFetchedBeforeSignIn(
base::android::AttachCurrentThread(),
java_signin_manager_.obj());
}
#endif
void SigninManagerAndroid::OnBrowsingDataRemoverDone() {
BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_);
model->RemoveAll();
// All the Profile data has been wiped. Clear the last signed in username as
// well, so that the next signin doesn't trigger the acount change dialog.
profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername);
Java_SigninManager_onProfileDataWiped(base::android::AttachCurrentThread(),
java_signin_manager_.obj());
}
void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) {
// AutoLogin deletes itself.
GoogleAutoLoginHelper* autoLogin = new GoogleAutoLoginHelper(profile_);
autoLogin->LogIn();
}
static jlong Init(JNIEnv* env, jobject obj) {
SigninManagerAndroid* signin_manager_android =
new SigninManagerAndroid(env, obj);
return reinterpret_cast<intptr_t>(signin_manager_android);
}
static jboolean ShouldLoadPolicyForUser(JNIEnv* env,
jobject obj,
jstring j_username) {
#if defined(ENABLE_CONFIGURATION_POLICY)
std::string username =
base::android::ConvertJavaStringToUTF8(env, j_username);
return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
#else
return false;
#endif
}
// static
bool SigninManagerAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}