Merge "[base] Fix logic around overriding DO when there are accounts on device." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e144f35e39
@@ -538,6 +538,7 @@ package android.app.admin {
|
||||
|
||||
public class DevicePolicyManager {
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public void acknowledgeNewUserDisclaimer();
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void calculateHasIncompatibleAccounts();
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void clearOrganizationId();
|
||||
method @RequiresPermission(android.Manifest.permission.CLEAR_FREEZE_PERIOD) public void clearSystemUpdatePolicyFreezePeriodRecord();
|
||||
method @RequiresPermission(android.Manifest.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS) public long forceNetworkLogs();
|
||||
|
||||
@@ -16824,6 +16824,23 @@ public class DevicePolicyManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate the incompatible accounts cache.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
|
||||
public void calculateHasIncompatibleAccounts() {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.calculateHasIncompatibleAccounts();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if bypassing the device policy management role qualification is allowed
|
||||
* with the current state of the device.
|
||||
|
||||
@@ -608,4 +608,6 @@ interface IDevicePolicyManager {
|
||||
|
||||
boolean isDeviceFinanced(String callerPackageName);
|
||||
String getFinancedDeviceKioskRoleHolder(String callerPackageName);
|
||||
|
||||
void calculateHasIncompatibleAccounts();
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
|
||||
import static android.Manifest.permission.SET_TIME;
|
||||
import static android.Manifest.permission.SET_TIME_ZONE;
|
||||
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
|
||||
import static android.accounts.AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION;
|
||||
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
@@ -532,6 +533,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -1140,6 +1142,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
|
||||
calculateHasIncompatibleAccounts();
|
||||
}
|
||||
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|
||||
&& userHandle == mOwners.getDeviceOwnerUserId()) {
|
||||
mBugreportCollectionManager.checkForPendingBugreportAfterBoot();
|
||||
@@ -1253,6 +1260,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
} else if (ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)) {
|
||||
notifyIfManagedSubscriptionsAreUnavailable(
|
||||
UserHandle.of(userHandle), /* managedProfileAvailable= */ true);
|
||||
} else if (LOGIN_ACCOUNTS_CHANGED_ACTION.equals(action)) {
|
||||
calculateHasIncompatibleAccounts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2105,6 +2114,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
filter.addAction(Intent.ACTION_USER_STOPPED);
|
||||
filter.addAction(Intent.ACTION_USER_SWITCHED);
|
||||
filter.addAction(Intent.ACTION_USER_UNLOCKED);
|
||||
filter.addAction(LOGIN_ACCOUNTS_CHANGED_ACTION);
|
||||
filter.addAction(ACTION_MANAGED_PROFILE_UNAVAILABLE);
|
||||
filter.addAction(ACTION_MANAGED_PROFILE_AVAILABLE);
|
||||
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
||||
@@ -9560,6 +9570,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
synchronized (getLockObject()) {
|
||||
enforceCanSetDeviceOwnerLocked(caller, admin, userId, hasIncompatibleAccountsOrNonAdb);
|
||||
|
||||
Preconditions.checkArgument(isPackageInstalledForUser(admin.getPackageName(), userId),
|
||||
"Invalid component " + admin + " for device owner");
|
||||
final ActiveAdmin activeAdmin = getActiveAdminUncheckedLocked(admin, userId);
|
||||
@@ -18386,6 +18397,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
return isUserAffiliatedWithDeviceLocked(userId);
|
||||
}
|
||||
|
||||
private boolean hasIncompatibleAccountsOnAnyUser() {
|
||||
if (mHasIncompatibleAccounts == null) {
|
||||
// Hasn't loaded for the first time yet - assume the worst
|
||||
return true;
|
||||
}
|
||||
|
||||
for (boolean hasIncompatible : mHasIncompatibleAccounts.values()) {
|
||||
if (hasIncompatible) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasIncompatibleAccounts(int userId) {
|
||||
return mHasIncompatibleAccounts == null ? true
|
||||
: mHasIncompatibleAccounts.getOrDefault(userId, /* default= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a given user has any accounts that'll prevent installing a device or profile
|
||||
* owner {@code owner}.
|
||||
@@ -18423,7 +18454,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
boolean compatible = !hasIncompatibleAccounts(am, accounts);
|
||||
boolean compatible = !hasIncompatibleAccounts(userId);
|
||||
if (compatible) {
|
||||
Slogf.w(LOG_TAG, "All accounts are compatible");
|
||||
} else {
|
||||
@@ -18433,37 +18464,67 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasIncompatibleAccounts(AccountManager am, Account[] accounts) {
|
||||
// TODO(b/244284408): Add test
|
||||
final String[] feature_allow =
|
||||
{ DevicePolicyManager.ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED };
|
||||
final String[] feature_disallow =
|
||||
{ DevicePolicyManager.ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED };
|
||||
|
||||
for (Account account : accounts) {
|
||||
if (hasAccountFeatures(am, account, feature_disallow)) {
|
||||
Slogf.e(LOG_TAG, "%s has %s", account, feature_disallow[0]);
|
||||
return true;
|
||||
}
|
||||
if (!hasAccountFeatures(am, account, feature_allow)) {
|
||||
Slogf.e(LOG_TAG, "%s doesn't have %s", account, feature_allow[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@Override
|
||||
public void calculateHasIncompatibleAccounts() {
|
||||
new CalculateHasIncompatibleAccountsTask().executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, null);
|
||||
}
|
||||
|
||||
private boolean hasAccountFeatures(AccountManager am, Account account, String[] features) {
|
||||
try {
|
||||
// TODO(267156507): Restore without blocking binder thread
|
||||
return false;
|
||||
// return am.hasFeatures(account, features, null, null).getResult();
|
||||
} catch (Exception e) {
|
||||
Slogf.w(LOG_TAG, "Failed to get account feature", e);
|
||||
@Nullable
|
||||
private volatile Map<Integer, Boolean> mHasIncompatibleAccounts;
|
||||
|
||||
class CalculateHasIncompatibleAccountsTask extends AsyncTask<
|
||||
Void, Void, Map<Integer, Boolean>> {
|
||||
private static final String[] FEATURE_ALLOW =
|
||||
{DevicePolicyManager.ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED};
|
||||
private static final String[] FEATURE_DISALLOW =
|
||||
{DevicePolicyManager.ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED};
|
||||
|
||||
@Override
|
||||
protected Map<Integer, Boolean> doInBackground(Void... args) {
|
||||
List<UserInfo> users = mUserManagerInternal.getUsers(/* excludeDying= */ true);
|
||||
Map<Integer, Boolean> results = new HashMap<>();
|
||||
for (UserInfo userInfo : users) {
|
||||
results.put(userInfo.id, userHasIncompatibleAccounts(userInfo.id));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean userHasIncompatibleAccounts(int id) {
|
||||
AccountManager am = mContext.createContextAsUser(UserHandle.of(id), /* flags= */ 0)
|
||||
.getSystemService(AccountManager.class);
|
||||
Account[] accounts = am.getAccounts();
|
||||
|
||||
for (Account account : accounts) {
|
||||
if (hasAccountFeatures(am, account, FEATURE_DISALLOW)) {
|
||||
return true;
|
||||
}
|
||||
if (!hasAccountFeatures(am, account, FEATURE_ALLOW)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Map<Integer, Boolean> results) {
|
||||
mHasIncompatibleAccounts = Collections.unmodifiableMap(results);
|
||||
|
||||
Slogf.i(LOG_TAG, "Finished calculating hasIncompatibleAccountsTask");
|
||||
}
|
||||
|
||||
private static boolean hasAccountFeatures(AccountManager am, Account account,
|
||||
String[] features) {
|
||||
try {
|
||||
return am.hasFeatures(account, features, null, null).getResult();
|
||||
} catch (Exception e) {
|
||||
Slogf.w(LOG_TAG, "Failed to get account feature", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isAdb(CallerIdentity caller) {
|
||||
return isShellUid(caller) || isRootUid(caller);
|
||||
@@ -22295,26 +22356,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasIncompatibleAccountsOnAnyUser() {
|
||||
long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
for (UserInfo user : mUserManagerInternal.getUsers(/* excludeDying= */ true)) {
|
||||
AccountManager am = mContext.createContextAsUser(
|
||||
UserHandle.of(user.id), /* flags= */ 0)
|
||||
.getSystemService(AccountManager.class);
|
||||
Account[] accounts = am.getAccounts();
|
||||
|
||||
if (hasIncompatibleAccounts(am, accounts)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBypassDevicePolicyManagementRoleQualificationStateInternal(
|
||||
String currentRoleHolder, boolean allowBypass) {
|
||||
boolean stateChanged = false;
|
||||
|
||||
Reference in New Issue
Block a user