Commit 255b65f2 authored by Pâris MEULEMAN's avatar Pâris MEULEMAN Committed by Commit Bot

Reland "Create ChromeSigninManagerDelegate JNI"

This is a reland of bfe02993

This was reverted in https://crrev.com/c/1674250 following conflict with https://crrev.com/c/1673453
PS2 fixes that.

Original change's description:
> Create ChromeSigninManagerDelegate JNI
>
> This introduces the Jni counterpart of the java
> ChromeSigninManagerDelegate. This interface will provide access to android
> specific dependencies on //chrome/browser to the componentized java
> SigninManager.
>
> This first iteration creates the new objects and implements
> stopApplyingCloudPolicy, fetchAndApplyCloudPolicy, isAccountManaged and
> getManagementDomain.
>
> As discussed in CLs on the java counterpart (bug 963400) this object
> will hold pointers to singletons such as the ActiveUserProfile.
> The native object is created by the java object.
>
> details in document:
> https://docs.google.com/document/d/18887XeZNJ9pmoTdJducssk5_yVU2CQ3EqaRFoMqWCCk/
>
> Bug: 963402
> Change-Id: Iccbb6b30d23f26fc5960b5d9db9c122df3e589f3
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642547
> Commit-Queue: Pâris Meuleman <pmeuleman@chromium.org>
> Reviewed-by: Ted Choc <tedchoc@chromium.org>
> Reviewed-by: Boris Sazonov <bsazonov@chromium.org>
> Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#671684}

Bug: 963402
Change-Id: Ie0f03bb07e722ef2858a5eaee427c7620e4c157f
TBR: tedchoc@chromium.org, sdefresne@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1675426
Commit-Queue: Pâris Meuleman <pmeuleman@chromium.org>
Auto-Submit: Pâris Meuleman <pmeuleman@chromium.org>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672037}
parent 6029f9e7
......@@ -2671,6 +2671,7 @@ generate_jni("chrome_jni_headers") {
"java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfModelObserverBridge.java",
"java/src/org/chromium/chrome/browser/send_tab_to_self/TargetDeviceInfo.java",
"java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java",
"java/src/org/chromium/chrome/browser/signin/ChromeSigninManagerDelegate.java",
"java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java",
"java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java",
"java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
......
......@@ -11,6 +11,7 @@ import android.content.Context;
import org.chromium.base.Callback;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.JCaller;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
import org.chromium.components.sync.AndroidSyncSettings;
......@@ -21,6 +22,7 @@ import org.chromium.components.sync.AndroidSyncSettings;
*/
public class ChromeSigninManagerDelegate implements SigninManagerDelegate {
private final AndroidSyncSettings mAndroidSyncSettings;
private long mNativeChromeSigninManagerDelegate;
public ChromeSigninManagerDelegate() {
this(AndroidSyncSettings.get());
......@@ -30,12 +32,21 @@ public class ChromeSigninManagerDelegate implements SigninManagerDelegate {
ChromeSigninManagerDelegate(AndroidSyncSettings androidSyncSettings) {
assert androidSyncSettings != null;
mAndroidSyncSettings = androidSyncSettings;
mNativeChromeSigninManagerDelegate = ChromeSigninManagerDelegateJni.get().init(this);
}
@Override
public String getManagementDomain(
@JCaller SigninManager self, long nativeSigninManagerAndroid) {
return SigninManagerJni.get().getManagementDomain(self, nativeSigninManagerAndroid);
public void destroy() {
if (mNativeChromeSigninManagerDelegate != 0) {
ChromeSigninManagerDelegateJni.get().destroy(this, mNativeChromeSigninManagerDelegate);
mNativeChromeSigninManagerDelegate = 0;
}
}
@Override
public String getManagementDomain() {
return ChromeSigninManagerDelegateJni.get().getManagementDomain(
this, mNativeChromeSigninManagerDelegate);
}
@Override
......@@ -52,23 +63,21 @@ public class ChromeSigninManagerDelegate implements SigninManagerDelegate {
}
@Override
public void isAccountManaged(@JCaller SigninManager signinManager,
long nativeSigninManagerAndroid, String email, final Callback<Boolean> callback) {
SigninManagerJni.get().isAccountManaged(
signinManager, nativeSigninManagerAndroid, email, callback);
public void isAccountManaged(String email, final Callback<Boolean> callback) {
ChromeSigninManagerDelegateJni.get().isAccountManaged(
this, mNativeChromeSigninManagerDelegate, email, callback);
}
@Override
public void fetchAndApplyCloudPolicy(@JCaller SigninManager signinManager,
long nativeSigninManagerAndroid, String username, Runnable callback) {
SigninManagerJni.get().fetchAndApplyCloudPolicy(
signinManager, nativeSigninManagerAndroid, username, callback);
public void fetchAndApplyCloudPolicy(String username, final Runnable callback) {
ChromeSigninManagerDelegateJni.get().fetchAndApplyCloudPolicy(
this, mNativeChromeSigninManagerDelegate, username, callback);
}
@Override
public void stopApplyingCloudPolicy(
@JCaller SigninManager signinManager, long nativeSigninManagerAndroid) {
SigninManagerJni.get().abortSignIn(signinManager, nativeSigninManagerAndroid);
public void stopApplyingCloudPolicy() {
ChromeSigninManagerDelegateJni.get().stopApplyingCloudPolicy(
this, mNativeChromeSigninManagerDelegate);
}
@Override
......@@ -91,4 +100,26 @@ public class ChromeSigninManagerDelegate implements SigninManagerDelegate {
signinManager, nativeSigninManagerAndroid, wipeDataCallback);
}
}
// Native methods.
@NativeMethods
interface Natives {
long init(@JCaller ChromeSigninManagerDelegate self);
void destroy(
@JCaller ChromeSigninManagerDelegate self, long nativeChromeSigninManagerDelegate);
void fetchAndApplyCloudPolicy(@JCaller ChromeSigninManagerDelegate self,
long nativeChromeSigninManagerDelegate, String username, Runnable callback);
void stopApplyingCloudPolicy(
@JCaller ChromeSigninManagerDelegate self, long nativeChromeSigninManagerDelegate);
void isAccountManaged(@JCaller ChromeSigninManagerDelegate self,
long nativeChromeSigninManagerDelegate, String username,
Callback<Boolean> callback);
String getManagementDomain(
@JCaller ChromeSigninManagerDelegate self, long nativeChromeSigninManagerDelegate);
}
}
......@@ -178,7 +178,7 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
private static SigninManager sSigninManager;
private static int sSignInAccessPoint = SigninAccessPoint.UNKNOWN;
private final long mNativeSigninManagerAndroid;
private long mNativeSigninManagerAndroid;
private final Context mContext;
private final SigninManagerDelegate mDelegate;
private final AccountTrackerService mAccountTrackerService;
......@@ -247,6 +247,13 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
mAccountTrackerService.addSystemAccountsSeededListener(this);
}
/**
* Perform destruction of the object, cascading destruction to delegate.
*/
public void destroy() {
mDelegate.destroy();
}
/**
* Log the access point when the user see the view of choosing account to sign in.
* @param accessPoint the enum value of AccessPoint defined in signin_metrics.h.
......@@ -441,7 +448,7 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
}
Log.d(TAG, "Checking if account has policy management enabled");
mDelegate.fetchAndApplyCloudPolicy(this, mNativeSigninManagerAndroid,
mDelegate.fetchAndApplyCloudPolicy(
mSignInState.mAccount.name, this::onPolicyFetchedBeforeSignIn);
}
......@@ -582,7 +589,7 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
* Returns the management domain if the signed in account is managed, otherwise returns null.
*/
public String getManagementDomain() {
return mDelegate.getManagementDomain(this, mNativeSigninManagerAndroid);
return mDelegate.getManagementDomain();
}
@VisibleForTesting
......@@ -610,7 +617,7 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
signInState.mCallback.onSignInAborted();
}
mDelegate.stopApplyingCloudPolicy(this, mNativeSigninManagerAndroid);
mDelegate.stopApplyingCloudPolicy();
Log.d(TAG, "Signin flow aborted.");
notifySignInAllowedChanged();
......@@ -684,7 +691,7 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
* otherwise.
*/
public void isAccountManaged(String email, final Callback<Boolean> callback) {
mDelegate.isAccountManaged(this, mNativeSigninManagerAndroid, email, callback);
mDelegate.isAccountManaged(email, callback);
}
public static String extractDomainName(String email) {
......@@ -706,19 +713,12 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
boolean isForceSigninEnabled(@JCaller SigninManager self, long nativeSigninManagerAndroid);
void fetchAndApplyCloudPolicy(@JCaller SigninManager self, long nativeSigninManagerAndroid,
String username, Runnable callback);
void abortSignIn(@JCaller SigninManager self, long nativeSigninManagerAndroid);
void onSignInCompleted(
@JCaller SigninManager self, long nativeSigninManagerAndroid, String username);
void signOut(@JCaller SigninManager self, long nativeSigninManagerAndroid,
@SignoutReason int reason);
String getManagementDomain(@JCaller SigninManager self, long nativeSigninManagerAndroid);
void wipeProfileData(
@JCaller SigninManager self, long nativeSigninManagerAndroid, Runnable callback);
......@@ -731,9 +731,6 @@ public class SigninManager implements AccountTrackerService.OnSystemAccountsSeed
boolean isSignedInOnNative(@JCaller SigninManager self, long nativeSigninManagerAndroid);
void isAccountManaged(@JCaller SigninManager self, long nativeSigninManagerAndroid,
String username, Callback<Boolean> callback);
String extractDomainName(String email);
}
}
......@@ -17,6 +17,11 @@ import org.chromium.base.annotations.JCaller;
* Google Play services.
*/
public interface SigninManagerDelegate {
/**
* Perform destruction of the object, including destructing the associated native object.
*/
public void destroy();
/**
* If there is no Google Play Services available, ask the user to fix by showing either a
* notification or a modal dialog
......@@ -28,7 +33,7 @@ public interface SigninManagerDelegate {
/**
* @return the management domain if the signed in account is managed, otherwise null.
*/
public String getManagementDomain(@JCaller SigninManager self, long nativeSigninManagerAndroid);
public String getManagementDomain();
/**
* @return Whether the device has Google Play Services.
......@@ -38,37 +43,23 @@ public interface SigninManagerDelegate {
/**
* Verifies if the account is managed. Callback may be called either synchronously or
* asynchronously depending on the availability of the result.
* @param signinManager a reference on SigninManager used for the native calls
* @param nativeSigninManagerAndroid a reference on the native SigninManager used for native
* calls
* @param email An email of the account.
* @param callback The callback that will receive true if the account is managed, false
* otherwise.
*/
public void isAccountManaged(@JCaller SigninManager signinManager,
long nativeSigninManagerAndroid, String email, final Callback<Boolean> callback);
public void isAccountManaged(String email, final Callback<Boolean> callback);
/**
* Interact with the UserPolicySigninService to retrieve the user policy if necessary.
* @param signinManager a reference on SigninManager used for the native calls
* @param nativeSigninManagerAndroid a reference on the native SigninManager used for native
* calls
* @param username (email) of the account signing in.
* @param callback The callback called once the policy is retrieved and applied. This is always
* called, even if the user is not managed and no policy was retrieved or
* applied.
* Interact with the UserPolicySigninService to retrieve the user policy.
* @param username (email) of the user signing in.
* @param callback The callback called once the policy is retrieved and applied
*/
public void fetchAndApplyCloudPolicy(@JCaller SigninManager signinManager,
long nativeSigninManagerAndroid, String username, Runnable callback);
public void fetchAndApplyCloudPolicy(String username, Runnable callback);
/**
* Perform the required cloud policy cleanup when a signin is aborted.
* @param signinManager a reference on SigninManager used for the native calls
* @param nativeSigninManagerAndroid a reference on the native SigninManager used for native
* calls
*/
public void stopApplyingCloudPolicy(
@JCaller SigninManager signinManager, long nativeSigninManagerAndroid);
public void stopApplyingCloudPolicy();
/**
* Called AFTER native sign-in is complete, enabling Sync.
......
......@@ -32,7 +32,10 @@ public class ChromeSigninManagerDelegateTest {
public JniMocker mocker = new JniMocker();
@Mock
SigninManager.Natives mNativeMock;
ChromeSigninManagerDelegate.Natives mNativeMock;
@Mock
SigninManager.Natives mSigninManagerNativeMock;
private ChromeSigninManagerDelegate mDelegate;
......@@ -40,7 +43,8 @@ public class ChromeSigninManagerDelegateTest {
public void setUp() {
initMocks(this);
mocker.mock(SigninManagerJni.TEST_HOOKS, mNativeMock);
mocker.mock(ChromeSigninManagerDelegateJni.TEST_HOOKS, mNativeMock);
mocker.mock(SigninManagerJni.TEST_HOOKS, mSigninManagerNativeMock);
// SigninManager interacts with AndroidSyncSettings, but its not the focus
// of this test. Using MockSyncContentResolver reduces burden of test setup.
......@@ -52,28 +56,34 @@ public class ChromeSigninManagerDelegateTest {
public void signOutWithManagedDomain() {
// Stub out various native calls. Some of these are verified as never called
// and those stubs simply allow that verification to catch any issues.
doNothing().when(mNativeMock).wipeProfileData(any(), anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
doNothing().when(mSigninManagerNativeMock).wipeProfileData(any(), anyLong(), any());
doNothing()
.when(mSigninManagerNativeMock)
.wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
// Simulate call from SigninManager
mDelegate.disableSyncAndWipeData(null, 0L, true, null);
// Sign-out should only clear the profile when the user is managed.
verify(mNativeMock, times(1)).wipeProfileData(any(), anyLong(), any());
verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
verify(mSigninManagerNativeMock, times(1)).wipeProfileData(any(), anyLong(), any());
verify(mSigninManagerNativeMock, never())
.wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
}
@Test
public void signOutWithNullDomain() {
// Stub out various native calls. Some of these are verified as never called
// and those stubs simply allow that verification to catch any issues.
doNothing().when(mNativeMock).wipeProfileData(any(), anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
doNothing().when(mSigninManagerNativeMock).wipeProfileData(any(), anyLong(), any());
doNothing()
.when(mSigninManagerNativeMock)
.wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
// Simulate call from SigninManager
mDelegate.disableSyncAndWipeData(null, 0L, false, null);
// Sign-out should only clear the service worker cache when the user is not managed.
verify(mNativeMock, never()).wipeProfileData(any(), anyLong(), any());
verify(mNativeMock, times(1)).wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
verify(mSigninManagerNativeMock, never()).wipeProfileData(any(), anyLong(), any());
verify(mSigninManagerNativeMock, times(1))
.wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
}
}
......@@ -75,7 +75,7 @@ public class SigninManagerTest {
doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt());
doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(true), any());
// See verification of nativeWipeProfileData below.
doReturn("TestDomain").when(mDelegateMock).getManagementDomain(any(), anyLong());
doReturn("TestDomain").when(mDelegateMock).getManagementDomain();
// Trigger the sign out flow!
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
......@@ -98,7 +98,7 @@ public class SigninManagerTest {
doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt());
doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(false), any());
// See verification of nativeWipeGoogleServiceWorkerCaches below.
doReturn(null).when(mDelegateMock).getManagementDomain(any(), anyLong());
doReturn(null).when(mDelegateMock).getManagementDomain();
// Trigger the sign out flow!
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
......@@ -121,11 +121,10 @@ public class SigninManagerTest {
doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt());
doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(true), any());
// See verification of nativeWipeProfileData below.
doReturn("TestDomain").when(mDelegateMock).getManagementDomain(any(), anyLong());
doReturn("TestDomain").when(mDelegateMock).getManagementDomain();
// Trigger the sign out flow!
mSigninManager.onNativeSignOut();
// nativeSignOut should only be called when signOut() is triggered on
// the Java side of the JNI boundary. This test instead initiates sign-out
// from the native side.
......@@ -141,7 +140,7 @@ public class SigninManagerTest {
doNothing().when(mNativeMock).signOut(any(), anyLong(), anyInt());
doNothing().when(mDelegateMock).disableSyncAndWipeData(any(), anyLong(), eq(false), any());
// See verification of nativeWipeGoogleServiceWorkerCaches below.
doReturn(null).when(mDelegateMock).getManagementDomain(any(), anyLong());
doReturn(null).when(mDelegateMock).getManagementDomain();
// Trigger the sign out flow!
mSigninManager.onNativeSignOut();
......@@ -171,7 +170,6 @@ public class SigninManagerTest {
})
.when(mNativeMock)
.signOut(any(), anyLong(), anyInt());
doReturn(null).when(mNativeMock).getManagementDomain(any(), anyLong());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(any(), anyLong(), any());
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
......@@ -191,7 +189,7 @@ public class SigninManagerTest {
doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
// Request that policy is loaded. It will pause sign-in until onPolicyCheckedBeforeSignIn is
// invoked.
doNothing().when(mDelegateMock).fetchAndApplyCloudPolicy(any(), anyLong(), any(), any());
doNothing().when(mDelegateMock).fetchAndApplyCloudPolicy(any(), any());
doReturn(true).when(mSigninManager).isSigninSupported();
doNothing().when(mNativeMock).onSignInCompleted(any(), anyLong(), any());
......
......@@ -2550,6 +2550,8 @@ jumbo_split_static_library("browser") {
"android/shortcut_helper.h",
"android/shortcut_info.cc",
"android/shortcut_info.h",
"android/signin/chrome_signin_manager_delegate.cc",
"android/signin/chrome_signin_manager_delegate.h",
"android/signin/signin_investigator_android.cc",
"android/signin/signin_investigator_android.h",
"android/signin/signin_manager_android.cc",
......
// Copyright 2019 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/chrome_signin_manager_delegate.h"
#include "base/android/callback_android.h"
#include "base/android/jni_string.h"
#include "chrome/android/chrome_jni_headers/ChromeSigninManagerDelegate_jni.h"
#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
#include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "content/public/browser/storage_partition.h"
#include "services/identity/public/cpp/identity_manager.h"
using base::android::JavaParamRef;
namespace {
// Returns whether the user is a managed user or not.
bool ShouldLoadPolicyForUser(const std::string& username) {
return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
}
} // namespace
ChromeSigninManagerDelegate::ChromeSigninManagerDelegate(JNIEnv* env,
jobject obj)
: profile_(ProfileManager::GetActiveUserProfile()),
identity_manager_(IdentityManagerFactory::GetForProfile(profile_)),
user_cloud_policy_manager_(profile_->GetUserCloudPolicyManager()),
user_policy_signin_service_(
policy::UserPolicySigninServiceFactory::GetForProfile(profile_)),
java_ref_(env, obj),
weak_factory_(this) {
DCHECK(profile_);
DCHECK(identity_manager_);
DCHECK(user_cloud_policy_manager_);
DCHECK(user_policy_signin_service_);
}
ChromeSigninManagerDelegate::~ChromeSigninManagerDelegate() {}
void ChromeSigninManagerDelegate::Destroy(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
delete this;
}
void ChromeSigninManagerDelegate::StopApplyingCloudPolicy(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
user_policy_signin_service_->ShutdownUserCloudPolicyManager();
}
void ChromeSigninManagerDelegate::RegisterPolicyWithAccount(
const CoreAccountInfo& account,
RegisterPolicyWithAccountCallback callback) {
if (!ShouldLoadPolicyForUser(account.email)) {
std::move(callback).Run(base::nullopt);
return;
}
user_policy_signin_service_->RegisterForPolicyWithAccountId(
account.email, account.account_id,
base::AdaptCallbackForRepeating(base::BindOnce(
[](RegisterPolicyWithAccountCallback callback,
const std::string& dm_token, const std::string& client_id) {
base::Optional<ManagementCredentials> credentials;
if (!dm_token.empty()) {
credentials.emplace(dm_token, client_id);
}
std::move(callback).Run(credentials);
},
std::move(callback))));
}
void ChromeSigninManagerDelegate::FetchAndApplyCloudPolicy(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_username,
const base::android::JavaParamRef<jobject>& j_callback) {
std::string username =
base::android::ConvertJavaStringToUTF8(env, j_username);
DCHECK(!username.empty());
// TODO(bsazonov): Remove after migrating the sign-in flow to CoreAccountId.
// ExtractDomainName Dchecks that username is a valid email, in practice
// this checks that @ is present and is not the last character.
gaia::ExtractDomainName(username);
CoreAccountInfo account =
identity_manager_
->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username)
.value();
auto callback =
base::BindOnce(base::android::RunRunnableAndroid,
base::android::ScopedJavaGlobalRef<jobject>(j_callback));
RegisterPolicyWithAccount(
account,
base::BindOnce(&ChromeSigninManagerDelegate::OnPolicyRegisterDone,
weak_factory_.GetWeakPtr(), account, std::move(callback)));
}
void ChromeSigninManagerDelegate::OnPolicyRegisterDone(
const CoreAccountInfo& account,
base::OnceCallback<void()> policy_callback,
const base::Optional<ManagementCredentials>& credentials) {
if (credentials) {
FetchPolicyBeforeSignIn(account, std::move(policy_callback),
credentials.value());
} else {
// User's account does not have a policy to fetch.
std::move(policy_callback).Run();
}
}
void ChromeSigninManagerDelegate::FetchPolicyBeforeSignIn(
const CoreAccountInfo& account,
base::OnceCallback<void()> policy_callback,
const ManagementCredentials& credentials) {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
content::BrowserContext::GetDefaultStoragePartition(profile_)
->GetURLLoaderFactoryForBrowserProcess();
user_policy_signin_service_->FetchPolicyForSignedInUser(
AccountIdFromAccountInfo(account), credentials.dm_token,
credentials.client_id, url_loader_factory,
base::AdaptCallbackForRepeating(
base::BindOnce([](base::OnceCallback<void()> callback,
bool success) { std::move(callback).Run(); },
std::move(policy_callback))));
}
void ChromeSigninManagerDelegate::IsAccountManaged(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_username,
const JavaParamRef<jobject>& j_callback) {
base::android::ScopedJavaGlobalRef<jobject> callback(env, j_callback);
std::string username =
base::android::ConvertJavaStringToUTF8(env, j_username);
base::Optional<CoreAccountInfo> account =
identity_manager_
->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username);
RegisterPolicyWithAccount(
account.value_or(CoreAccountInfo{}),
base::BindOnce(
[](base::android::ScopedJavaGlobalRef<jobject> callback,
const base::Optional<ManagementCredentials>& credentials) {
base::android::RunBooleanCallbackAndroid(callback,
credentials.has_value());
},
callback));
}
base::android::ScopedJavaLocalRef<jstring>
ChromeSigninManagerDelegate::GetManagementDomain(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
base::android::ScopedJavaLocalRef<jstring> domain;
policy::CloudPolicyStore* store = user_cloud_policy_manager_->core()->store();
if (store && store->is_managed() && store->policy()->has_username()) {
domain.Reset(base::android::ConvertUTF8ToJavaString(
env, gaia::ExtractDomainName(store->policy()->username())));
}
return domain;
}
// instantiates ChromeSigninManagerDelegate
static jlong JNI_ChromeSigninManagerDelegate_Init(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
ChromeSigninManagerDelegate* chrome_signin_manager_delegate =
new ChromeSigninManagerDelegate(env, obj);
return reinterpret_cast<intptr_t>(chrome_signin_manager_delegate);
}
// Copyright 2019 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.
#ifndef CHROME_BROWSER_ANDROID_SIGNIN_CHROME_SIGNIN_MANAGER_DELEGATE_H_
#define CHROME_BROWSER_ANDROID_SIGNIN_CHROME_SIGNIN_MANAGER_DELEGATE_H_
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/signin/core/browser/account_info.h"
namespace identity {
class IdentityManager;
}
namespace policy {
class UserCloudPolicyManager;
class UserPolicySigninService;
} // namespace policy
class Profile;
// This class provide ChromeSigninManagerDelegate.java access to the native
// dependencies.
class ChromeSigninManagerDelegate {
public:
ChromeSigninManagerDelegate(JNIEnv* env, jobject obj);
void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
// Registers a CloudPolicyClient for fetching policy for a user and fetches
// the policy if necessary.
void FetchAndApplyCloudPolicy(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& username,
const base::android::JavaParamRef<jobject>& j_callback);
void StopApplyingCloudPolicy(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
void IsAccountManaged(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& j_username,
const base::android::JavaParamRef<jobject>& j_callback);
base::android::ScopedJavaLocalRef<jstring> GetManagementDomain(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
private:
struct ManagementCredentials {
ManagementCredentials(const std::string& dm_token,
const std::string& client_id)
: dm_token(dm_token), client_id(client_id) {}
const std::string dm_token;
const std::string client_id;
};
using RegisterPolicyWithAccountCallback = base::OnceCallback<void(
const base::Optional<ManagementCredentials>& credentials)>;
~ChromeSigninManagerDelegate();
ChromeSigninManagerDelegate(const ChromeSigninManagerDelegate&) = delete;
ChromeSigninManagerDelegate& operator=(const ChromeSigninManagerDelegate&) =
delete;
// If required registers for policy with given account. callback will be
// called with credentials if the account is managed.
void RegisterPolicyWithAccount(const CoreAccountInfo& account,
RegisterPolicyWithAccountCallback callback);
void OnPolicyRegisterDone(
const CoreAccountInfo& account_id,
base::OnceCallback<void()> policy_callback,
const base::Optional<ManagementCredentials>& credentials);
void FetchPolicyBeforeSignIn(const CoreAccountInfo& account_id,
base::OnceCallback<void()> policy_callback,
const ManagementCredentials& credentials);
Profile* const profile_ = nullptr;
identity::IdentityManager* const identity_manager_ = nullptr;
policy::UserCloudPolicyManager* const user_cloud_policy_manager_ = nullptr;
policy::UserPolicySigninService* const user_policy_signin_service_ = nullptr;
// A reference to the Java counterpart of this object.
const base::android::ScopedJavaGlobalRef<jobject> java_ref_;
base::WeakPtrFactory<ChromeSigninManagerDelegate> weak_factory_;
};
#endif // CHROME_BROWSER_ANDROID_SIGNIN_CHROME_SIGNIN_MANAGER_DELEGATE_H_
......@@ -26,7 +26,6 @@
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "components/google/core/common/google_util.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
......@@ -50,11 +49,6 @@ void ClearLastSignedInUserForProfile(Profile* profile) {
profile->GetPrefs()->ClearPref(prefs::kGoogleServicesLastUsername);
}
// Returns whether the user is a managed user or not.
bool ShouldLoadPolicyForUser(const std::string& username) {
return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
}
// A BrowsingDataRemover::Observer that clears Profile data and then invokes
// a callback and deletes itself. It can be configured to delete all data
// (for enterprise users) or only Google's service workers (for all users).
......@@ -139,13 +133,8 @@ SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj)
SigninManagerAndroid::~SigninManagerAndroid() {
IdentityManagerFactory::GetForProfile(profile_)->RemoveObserver(this);
}
void SigninManagerAndroid::AbortSignIn(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
policy::UserPolicySigninService* service =
policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
service->ShutdownUserCloudPolicyManager();
// TODO(crbug.com/963408) Call SigninManager.java Destroy once ownership is
// reversed.
}
void SigninManagerAndroid::OnSignInCompleted(
......@@ -178,24 +167,6 @@ void SigninManagerAndroid::SignOut(JNIEnv* env,
signin_metrics::SignoutDelete::IGNORE_METRIC);
}
base::android::ScopedJavaLocalRef<jstring>
SigninManagerAndroid::GetManagementDomain(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
base::android::ScopedJavaLocalRef<jstring> domain;
policy::UserCloudPolicyManager* manager =
profile_->GetUserCloudPolicyManager();
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())));
}
return domain;
}
void SigninManagerAndroid::WipeProfileData(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
......@@ -216,89 +187,6 @@ void SigninManagerAndroid::WipeGoogleServiceWorkerCaches(
base::android::ScopedJavaGlobalRef<jobject>(j_callback)));
}
void SigninManagerAndroid::RegisterPolicyWithAccount(
const CoreAccountInfo& account,
RegisterPolicyWithAccountCallback callback) {
if (!ShouldLoadPolicyForUser(account.email)) {
std::move(callback).Run(base::nullopt);
return;
}
policy::UserPolicySigninService* service =
policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
service->RegisterForPolicyWithAccountId(
account.email, account.account_id,
base::AdaptCallbackForRepeating(base::BindOnce(
[](RegisterPolicyWithAccountCallback callback,
const std::string& dm_token, const std::string& client_id) {
base::Optional<ManagementCredentials> credentials;
if (!dm_token.empty()) {
credentials.emplace(dm_token, client_id);
}
std::move(callback).Run(credentials);
},
std::move(callback))));
}
void SigninManagerAndroid::FetchAndApplyCloudPolicy(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_username,
const base::android::JavaParamRef<jobject>& j_callback) {
std::string username =
base::android::ConvertJavaStringToUTF8(env, j_username);
DCHECK(!username.empty());
// TODO(bsazonov): Remove after migrating the sign-in flow to CoreAccountId.
// ExtractDomainName Dchecks that username is a valid email, in practice
// this checks that @ is present and is not the last character.
gaia::ExtractDomainName(username);
CoreAccountInfo account =
IdentityManagerFactory::GetForProfile(profile_)
->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username)
.value();
auto callback =
base::BindOnce(base::android::RunRunnableAndroid,
base::android::ScopedJavaGlobalRef<jobject>(j_callback));
RegisterPolicyWithAccount(
account,
base::BindOnce(&SigninManagerAndroid::OnPolicyRegisterDone,
weak_factory_.GetWeakPtr(), account, std::move(callback)));
}
void SigninManagerAndroid::OnPolicyRegisterDone(
const CoreAccountInfo& account,
base::OnceClosure policy_callback,
const base::Optional<ManagementCredentials>& credentials) {
if (credentials) {
FetchPolicyBeforeSignIn(account, std::move(policy_callback),
credentials.value());
} else {
// User's account does not have a policy to fetch.
std::move(policy_callback).Run();
}
}
void SigninManagerAndroid::FetchPolicyBeforeSignIn(
const CoreAccountInfo& account,
base::OnceClosure policy_callback,
const ManagementCredentials& credentials) {
policy::UserPolicySigninService* service =
policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
content::BrowserContext::GetDefaultStoragePartition(profile_)
->GetURLLoaderFactoryForBrowserProcess();
service->FetchPolicyForSignedInUser(
AccountIdFromAccountInfo(account), credentials.dm_token,
credentials.client_id, url_loader_factory,
base::AdaptCallbackForRepeating(
base::BindOnce([](base::OnceClosure callback,
bool success) { std::move(callback).Run(); },
std::move(policy_callback))));
}
void SigninManagerAndroid::ClearLastSignedInUser(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
......@@ -363,30 +251,6 @@ static jlong JNI_SigninManager_Init(JNIEnv* env,
return reinterpret_cast<intptr_t>(signin_manager_android);
}
void SigninManagerAndroid::IsAccountManaged(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& j_username,
const JavaParamRef<jobject>& j_callback) {
base::android::ScopedJavaGlobalRef<jobject> callback(env, j_callback);
std::string username =
base::android::ConvertJavaStringToUTF8(env, j_username);
base::Optional<CoreAccountInfo> account =
IdentityManagerFactory::GetForProfile(profile_)
->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(username);
RegisterPolicyWithAccount(
account.value_or(CoreAccountInfo{}),
base::BindOnce(
[](base::android::ScopedJavaGlobalRef<jobject> callback,
const base::Optional<ManagementCredentials>& credentials) {
base::android::RunBooleanCallbackAndroid(callback,
credentials.has_value());
},
callback));
}
base::android::ScopedJavaLocalRef<jstring> JNI_SigninManager_ExtractDomainName(
JNIEnv* env,
const JavaParamRef<jstring>& j_email) {
......
......@@ -29,17 +29,6 @@ class SigninManagerAndroid : public identity::IdentityManager::Observer {
public:
SigninManagerAndroid(JNIEnv* env, jobject obj);
// Registers a CloudPolicyClient for fetching policy for a user and fetches
// the policy if necessary.
void FetchAndApplyCloudPolicy(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& username,
const base::android::JavaParamRef<jobject>& j_callback);
void AbortSignIn(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
// Indicates that the user has made the choice to sign-in. |username|
// contains the email address of the account to use as primary.
void OnSignInCompleted(JNIEnv* env,
......@@ -50,10 +39,6 @@ class SigninManagerAndroid : public identity::IdentityManager::Observer {
const base::android::JavaParamRef<jobject>& obj,
jint signoutReason);
base::android::ScopedJavaLocalRef<jstring> GetManagementDomain(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
// Delete all data for this profile.
void WipeProfileData(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
......@@ -82,47 +67,17 @@ class SigninManagerAndroid : public identity::IdentityManager::Observer {
jboolean IsSignedInOnNative(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
void IsAccountManaged(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& j_username,
const base::android::JavaParamRef<jobject>& j_callback);
// identity::IdentityManager::Observer implementation.
void OnPrimaryAccountCleared(
const CoreAccountInfo& previous_primary_account_info) override;
private:
struct ManagementCredentials {
ManagementCredentials(const std::string& dm_token,
const std::string& client_id)
: dm_token(dm_token), client_id(client_id) {}
const std::string dm_token;
const std::string client_id;
};
using RegisterPolicyWithAccountCallback = base::OnceCallback<void(
const base::Optional<ManagementCredentials>& credentials)>;
friend class SigninManagerAndroidTest;
FRIEND_TEST_ALL_PREFIXES(SigninManagerAndroidTest,
DeleteGoogleServiceWorkerCaches);
~SigninManagerAndroid() override;
// If required registers for policy with given account. callback will be
// called with credentials if the account is managed.
void RegisterPolicyWithAccount(const CoreAccountInfo& account,
RegisterPolicyWithAccountCallback callback);
void OnPolicyRegisterDone(
const CoreAccountInfo& account_id,
base::OnceClosure policy_callback,
const base::Optional<ManagementCredentials>& credentials);
void FetchPolicyBeforeSignIn(const CoreAccountInfo& account_id,
base::OnceClosure policy_callback,
const ManagementCredentials& credentials);
void OnBrowsingDataRemoverDone();
void OnSigninAllowedPrefChanged();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment