Merge "Introduce DISALLOW_BLUETOOTH_SHARING." into oc-dev
This commit is contained in:
@@ -31680,6 +31680,7 @@ package android.os {
|
||||
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
|
||||
field public static final java.lang.String DISALLOW_AUTOFILL = "no_autofill";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH = "no_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
|
||||
|
||||
@@ -34563,6 +34563,7 @@ package android.os {
|
||||
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
|
||||
field public static final java.lang.String DISALLOW_AUTOFILL = "no_autofill";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH = "no_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
|
||||
|
||||
@@ -31813,6 +31813,7 @@ package android.os {
|
||||
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
|
||||
field public static final java.lang.String DISALLOW_AUTOFILL = "no_autofill";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH = "no_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
|
||||
|
||||
@@ -64,7 +64,7 @@ import java.util.List;
|
||||
*/
|
||||
public class UserManager {
|
||||
|
||||
private static String TAG = "UserManager";
|
||||
private static final String TAG = "UserManager";
|
||||
private final IUserManager mService;
|
||||
private final Context mContext;
|
||||
|
||||
@@ -217,6 +217,23 @@ public class UserManager {
|
||||
*/
|
||||
public static final String DISALLOW_BLUETOOTH = "no_bluetooth";
|
||||
|
||||
/**
|
||||
* Specifies if outgoing bluetooth sharing is disallowed on the device. Device owner and profile
|
||||
* owner can set this restriction. When it is set by device owner, all users on this device will
|
||||
* be affected.
|
||||
*
|
||||
* <p>Default is <code>true</code> for managed profiles and false for otherwise. When a device
|
||||
* upgrades to {@link android.os.Build.VERSION_CODES#O}, the system sets it for all existing
|
||||
* managed profiles.
|
||||
*
|
||||
* <p>Key for user restrictions.
|
||||
* <p>Type: Boolean
|
||||
* @see DevicePolicyManager#addUserRestriction(ComponentName, String)
|
||||
* @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing";
|
||||
|
||||
/**
|
||||
* Specifies if a user is disallowed from transferring files over
|
||||
* USB. This can only be set by device owners and profile owners on the primary user.
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppGlobals;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.IBluetooth;
|
||||
@@ -37,11 +38,11 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -50,7 +51,6 @@ import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -61,15 +61,15 @@ import android.provider.Settings.SettingNotFoundException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.server.pm.PackageManagerService;
|
||||
import com.android.server.pm.UserRestrictionsUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
|
||||
class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
@@ -120,7 +120,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
|
||||
private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
|
||||
|
||||
private static final int MAX_SAVE_RETRIES = 3;
|
||||
private static final int MAX_ERROR_RESTART_RETRIES = 6;
|
||||
|
||||
// Bluetooth persisted setting is off
|
||||
@@ -223,22 +222,25 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
@Override
|
||||
public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
|
||||
Bundle prevRestrictions) {
|
||||
if (!newRestrictions.containsKey(UserManager.DISALLOW_BLUETOOTH)
|
||||
&& !prevRestrictions.containsKey(UserManager.DISALLOW_BLUETOOTH)) {
|
||||
// The relevant restriction has not changed - do nothing.
|
||||
return;
|
||||
if (!UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
|
||||
UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING)) {
|
||||
return; // No relevant changes, nothing to do.
|
||||
}
|
||||
final boolean bluetoothDisallowed =
|
||||
newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
|
||||
if ((mEnable || mEnableExternal) && bluetoothDisallowed) {
|
||||
|
||||
final boolean disallowed = newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
|
||||
|
||||
// DISALLOW_BLUETOOTH is a global restriction that can only be set by DO or PO on the
|
||||
// system user, so we only look at the system user.
|
||||
if (userId == UserHandle.USER_SYSTEM && disallowed && (mEnable || mEnableExternal)) {
|
||||
try {
|
||||
disable(null, true);
|
||||
disable(null /* packageName */, true /* persist */);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Exception when disabling Bluetooth from UserRestrictionsListener",
|
||||
e);
|
||||
Slog.w(TAG, "Exception when disabling Bluetooth", e);
|
||||
}
|
||||
}
|
||||
updateOppLauncherComponentState(bluetoothDisallowed);
|
||||
final boolean sharingDisallowed = disallowed
|
||||
|| newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING);
|
||||
updateOppLauncherComponentState(userId, sharingDisallowed);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -994,11 +996,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
LocalServices.getService(UserManagerInternal.class);
|
||||
userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
|
||||
final boolean isBluetoothDisallowed = isBluetoothDisallowed();
|
||||
PackageManagerService packageManagerService =
|
||||
(PackageManagerService) ServiceManager.getService("package");
|
||||
if (packageManagerService != null && !packageManagerService.isOnlyCoreApps()) {
|
||||
updateOppLauncherComponentState(isBluetoothDisallowed);
|
||||
}
|
||||
if (isBluetoothDisallowed) {
|
||||
return;
|
||||
}
|
||||
@@ -2074,21 +2071,21 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
|
||||
/**
|
||||
* Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
|
||||
* offered to the user if Bluetooth is disallowed. Puts the component to its default state if
|
||||
* Bluetooth is not disallowed.
|
||||
* offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
|
||||
* state if Bluetooth is not disallowed.
|
||||
*
|
||||
* @param bluetoothDisallowed whether the {@link UserManager.DISALLOW_BLUETOOTH} user
|
||||
* restriction was set.
|
||||
* @param userId user to disable bluetooth sharing for.
|
||||
* @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
|
||||
*/
|
||||
private void updateOppLauncherComponentState(boolean bluetoothDisallowed) {
|
||||
private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
|
||||
final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
|
||||
"com.android.bluetooth.opp.BluetoothOppLauncherActivity");
|
||||
final int newState = bluetoothDisallowed
|
||||
final int newState = bluetoothSharingDisallowed
|
||||
? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
: PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
|
||||
try {
|
||||
mContext.getPackageManager()
|
||||
.setComponentEnabledSetting(oppLauncherComponent, newState, 0);
|
||||
final IPackageManager imp = AppGlobals.getPackageManager();
|
||||
imp.setComponentEnabledSetting(oppLauncherComponent, newState, 0 /* flags */, userId);
|
||||
} catch (Exception e) {
|
||||
// The component was not found, do nothing.
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public class UserRestrictionsUtils {
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserManager.DISALLOW_CONFIG_BLUETOOTH,
|
||||
UserManager.DISALLOW_BLUETOOTH,
|
||||
UserManager.DISALLOW_BLUETOOTH_SHARING,
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_CONFIG_CREDENTIALS,
|
||||
UserManager.DISALLOW_REMOVE_USER,
|
||||
@@ -155,6 +156,7 @@ public class UserRestrictionsUtils {
|
||||
*/
|
||||
private static final Set<String> GLOBAL_RESTRICTIONS = Sets.newArraySet(
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_BLUETOOTH_SHARING,
|
||||
UserManager.DISALLOW_RUN_IN_BACKGROUND,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE,
|
||||
UserManager.DISALLOW_UNMUTE_DEVICE
|
||||
@@ -167,6 +169,17 @@ public class UserRestrictionsUtils {
|
||||
UserManager.DISALLOW_ADD_MANAGED_PROFILE
|
||||
);
|
||||
|
||||
/**
|
||||
* User restrictions that default to {@code true} for managed profile owners.
|
||||
*
|
||||
* NB: {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} is also set by default but it is
|
||||
* not set to existing profile owners unless they used to have INSTALL_NON_MARKET_APPS disabled
|
||||
* in settings. So it is handled separately.
|
||||
*/
|
||||
private static final Set<String> DEFAULT_ENABLED_FOR_MANAGED_PROFILES = Sets.newArraySet(
|
||||
UserManager.DISALLOW_BLUETOOTH_SHARING
|
||||
);
|
||||
|
||||
/*
|
||||
* Special user restrictions that are always applied to all users no matter who sets them.
|
||||
*/
|
||||
@@ -307,6 +320,13 @@ public class UserRestrictionsUtils {
|
||||
return DEFAULT_ENABLED_FOR_DEVICE_OWNERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user restrictions that default to {@code true} for managed profile owners.
|
||||
*/
|
||||
public static @NonNull Set<String> getDefaultEnabledForManagedProfiles() {
|
||||
return DEFAULT_ENABLED_FOR_MANAGED_PROFILES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes restrictions that can be set by device owner, and sort them into what should be applied
|
||||
* globally and what should be applied only on the current user.
|
||||
@@ -544,8 +564,8 @@ public class UserRestrictionsUtils {
|
||||
public static void moveRestriction(String restrictionKey, SparseArray<Bundle> srcRestrictions,
|
||||
SparseArray<Bundle> destRestrictions) {
|
||||
for (int i = 0; i < srcRestrictions.size(); i++) {
|
||||
int key = srcRestrictions.keyAt(i);
|
||||
Bundle from = srcRestrictions.valueAt(i);
|
||||
final int key = srcRestrictions.keyAt(i);
|
||||
final Bundle from = srcRestrictions.valueAt(i);
|
||||
if (contains(from, restrictionKey)) {
|
||||
from.remove(restrictionKey);
|
||||
Bundle to = destRestrictions.get(key);
|
||||
@@ -562,4 +582,24 @@ public class UserRestrictionsUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether restrictions differ between two bundles.
|
||||
* @param oldRestrictions old bundle of restrictions.
|
||||
* @param newRestrictions new bundle of restrictions
|
||||
* @param restrictions restrictions of interest, if empty, all restrictions are checked.
|
||||
*/
|
||||
public static boolean restrictionsChanged(Bundle oldRestrictions, Bundle newRestrictions,
|
||||
String... restrictions) {
|
||||
if (restrictions.length == 0) {
|
||||
return areEqual(oldRestrictions, newRestrictions);
|
||||
}
|
||||
for (final String restriction : restrictions) {
|
||||
if (oldRestrictions.getBoolean(restriction, false) !=
|
||||
newRestrictions.getBoolean(restriction, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1903,7 +1903,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
setDeviceOwnerSystemPropertyLocked();
|
||||
findOwnerComponentIfNecessaryLocked();
|
||||
migrateUserRestrictionsIfNecessaryLocked();
|
||||
setDefaultEnabledUserRestrictionsIfNecessaryLocked();
|
||||
maybeSetDefaultDeviceOwnerUserRestrictionsLocked();
|
||||
|
||||
// TODO PO may not have a class name either due to b/17652534. Address that too.
|
||||
|
||||
@@ -1911,36 +1911,80 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void setDefaultEnabledUserRestrictionsIfNecessaryLocked() {
|
||||
/** Apply default restrictions that haven't been applied to device owners yet. */
|
||||
private void maybeSetDefaultDeviceOwnerUserRestrictionsLocked() {
|
||||
final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
|
||||
if (deviceOwner != null
|
||||
&& !UserRestrictionsUtils.getDefaultEnabledForDeviceOwner().equals(
|
||||
deviceOwner.defaultEnabledRestrictionsAlreadySet)) {
|
||||
Slog.i(LOG_TAG,"New user restrictions need to be set by default for the device owner");
|
||||
if (deviceOwner != null) {
|
||||
maybeSetDefaultRestrictionsForAdminLocked(mOwners.getDeviceOwnerUserId(),
|
||||
deviceOwner, UserRestrictionsUtils.getDefaultEnabledForDeviceOwner());
|
||||
}
|
||||
}
|
||||
|
||||
if (VERBOSE_LOG) {
|
||||
Slog.d(LOG_TAG,"Default enabled restrictions for DO: "
|
||||
+ UserRestrictionsUtils.getDefaultEnabledForDeviceOwner()
|
||||
+ ". Restrictions already enabled: "
|
||||
+ deviceOwner.defaultEnabledRestrictionsAlreadySet);
|
||||
}
|
||||
|
||||
Set<String> restrictionsToSet = new ArraySet<>(
|
||||
UserRestrictionsUtils.getDefaultEnabledForDeviceOwner());
|
||||
restrictionsToSet.removeAll(deviceOwner.defaultEnabledRestrictionsAlreadySet);
|
||||
if (!restrictionsToSet.isEmpty()) {
|
||||
for (String restriction : restrictionsToSet) {
|
||||
deviceOwner.ensureUserRestrictions().putBoolean(restriction, true);
|
||||
/** Apply default restrictions that haven't been applied to profile owners yet. */
|
||||
private void maybeSetDefaultProfileOwnerUserRestrictions() {
|
||||
synchronized (this) {
|
||||
for (final int userId : mOwners.getProfileOwnerKeys()) {
|
||||
final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
|
||||
// The following restrictions used to be applied to managed profiles by different
|
||||
// means (via Settings or by disabling components). Now they are proper user
|
||||
// restrictions so we apply them to managed profile owners. Non-managed secondary
|
||||
// users didn't have those restrictions so we skip them to keep existing behavior.
|
||||
if (profileOwner == null || !mUserManager.isManagedProfile(userId)) {
|
||||
continue;
|
||||
}
|
||||
deviceOwner.defaultEnabledRestrictionsAlreadySet.addAll(restrictionsToSet);
|
||||
Slog.i(LOG_TAG,
|
||||
"Enabled the following restrictions by default: " + restrictionsToSet);
|
||||
|
||||
saveUserRestrictionsLocked(mOwners.getDeviceOwnerUserId());
|
||||
maybeSetDefaultRestrictionsForAdminLocked(userId, profileOwner,
|
||||
UserRestrictionsUtils.getDefaultEnabledForManagedProfiles());
|
||||
ensureUnknownSourcesRestrictionForProfileOwnerLocked(
|
||||
userId, profileOwner, false /* newOwner */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} should be added to the
|
||||
* set of restrictions for this profile owner.
|
||||
*/
|
||||
private void ensureUnknownSourcesRestrictionForProfileOwnerLocked(int userId,
|
||||
ActiveAdmin profileOwner, boolean newOwner) {
|
||||
if (newOwner || mInjector.settingsSecureGetIntForUser(
|
||||
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) {
|
||||
profileOwner.ensureUserRestrictions().putBoolean(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
|
||||
saveUserRestrictionsLocked(userId);
|
||||
mInjector.settingsSecurePutIntForUser(
|
||||
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply default restrictions that haven't been applied to a given admin yet.
|
||||
*/
|
||||
private void maybeSetDefaultRestrictionsForAdminLocked(
|
||||
int userId, ActiveAdmin admin, Set<String> defaultRestrictions) {
|
||||
if (defaultRestrictions.equals(admin.defaultEnabledRestrictionsAlreadySet)) {
|
||||
return; // The same set of default restrictions has been already applied.
|
||||
}
|
||||
Slog.i(LOG_TAG, "New user restrictions need to be set by default for user " + userId);
|
||||
|
||||
if (VERBOSE_LOG) {
|
||||
Slog.d(LOG_TAG,"Default enabled restrictions: "
|
||||
+ defaultRestrictions
|
||||
+ ". Restrictions already enabled: "
|
||||
+ admin.defaultEnabledRestrictionsAlreadySet);
|
||||
}
|
||||
|
||||
final Set<String> restrictionsToSet = new ArraySet<>(defaultRestrictions);
|
||||
restrictionsToSet.removeAll(admin.defaultEnabledRestrictionsAlreadySet);
|
||||
if (!restrictionsToSet.isEmpty()) {
|
||||
for (final String restriction : restrictionsToSet) {
|
||||
admin.ensureUserRestrictions().putBoolean(restriction, true);
|
||||
}
|
||||
admin.defaultEnabledRestrictionsAlreadySet.addAll(restrictionsToSet);
|
||||
Slog.i(LOG_TAG, "Enabled the following restrictions by default: " + restrictionsToSet);
|
||||
saveUserRestrictionsLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDeviceOwnerSystemPropertyLocked() {
|
||||
final boolean deviceProvisioned =
|
||||
mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) != 0;
|
||||
@@ -2927,41 +2971,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureUnknownSourcesRestrictionForProfileOwners() {
|
||||
synchronized (this) {
|
||||
for (int userId : mOwners.getProfileOwnerKeys()) {
|
||||
if (!mUserManager.isManagedProfile(userId) ||
|
||||
mInjector.settingsSecureGetIntForUser(
|
||||
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) == 0) {
|
||||
continue;
|
||||
}
|
||||
setUserRestrictionOnBehalfOfProfileOwnerLocked(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId);
|
||||
mInjector.settingsSecurePutIntForUser(
|
||||
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setUserRestrictionOnBehalfOfProfileOwnerLocked(String userRestrictionKey,
|
||||
int userId) {
|
||||
if (UserRestrictionsUtils.isValidRestriction(userRestrictionKey) &&
|
||||
UserRestrictionsUtils.canProfileOwnerChange(userRestrictionKey, userId)) {
|
||||
ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
|
||||
if (profileOwner == null) {
|
||||
return;
|
||||
}
|
||||
Bundle restrictions = profileOwner.ensureUserRestrictions();
|
||||
restrictions.putBoolean(userRestrictionKey, true);
|
||||
saveUserRestrictionsLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void onLockSettingsReady() {
|
||||
getUserData(UserHandle.USER_SYSTEM);
|
||||
loadOwners();
|
||||
cleanUpOldUsers();
|
||||
ensureUnknownSourcesRestrictionForProfileOwners();
|
||||
maybeSetDefaultProfileOwnerUserRestrictions();
|
||||
handleStartUser(UserHandle.USER_SYSTEM);
|
||||
|
||||
// Register an observer for watching for user setup complete and settings changes.
|
||||
@@ -6713,8 +6727,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
synchronized (this) {
|
||||
enforceCanSetProfileOwnerLocked(who, userHandle, hasIncompatibleAccountsOrNonAdb);
|
||||
|
||||
if (getActiveAdminUncheckedLocked(who, userHandle) == null
|
||||
|| getUserData(userHandle).mRemovingAdmins.contains(who)) {
|
||||
final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
|
||||
if (admin == null || getUserData(userHandle).mRemovingAdmins.contains(who)) {
|
||||
throw new IllegalArgumentException("Not active admin: " + who);
|
||||
}
|
||||
|
||||
@@ -6730,10 +6744,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
final long id = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
if (mUserManager.isManagedProfile(userHandle)) {
|
||||
setUserRestrictionOnBehalfOfProfileOwnerLocked(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userHandle);
|
||||
mInjector.settingsSecurePutIntForUser(
|
||||
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userHandle);
|
||||
maybeSetDefaultRestrictionsForAdminLocked(userHandle, admin,
|
||||
UserRestrictionsUtils.getDefaultEnabledForManagedProfiles());
|
||||
ensureUnknownSourcesRestrictionForProfileOwnerLocked(userHandle, admin,
|
||||
true /* newOwner */);
|
||||
}
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(id);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
||||
<policies setup-complete="true" provisioning-state="3">
|
||||
<admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1">
|
||||
<policies flags="991" />
|
||||
<strong-auth-unlock-timeout value="0" />
|
||||
<organization-color value="-16738680" />
|
||||
</admin>
|
||||
</policies>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
||||
<root>
|
||||
<profile-owner
|
||||
package="com.android.frameworks.servicestests"
|
||||
name="com.android.frameworks.servicestests"
|
||||
component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"
|
||||
userRestrictionsMigrated="true" />
|
||||
</root>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
||||
<policies setup-complete="true" provisioning-state="3">
|
||||
</policies>
|
||||
@@ -15,31 +15,28 @@
|
||||
*/
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Pair;
|
||||
import android.provider.Settings;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.Set;
|
||||
|
||||
public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
|
||||
private DpmMockContext mContext;
|
||||
@@ -57,7 +54,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
|
||||
public void testMigration() throws Exception {
|
||||
final File user10dir = mMockContext.addUser(10, 0);
|
||||
final File user11dir = mMockContext.addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
|
||||
final File user12dir = mMockContext.addUser(12, 0);
|
||||
mMockContext.addUser(12, 0);
|
||||
|
||||
setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
|
||||
setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
|
||||
@@ -109,16 +106,13 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
|
||||
|
||||
final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
|
||||
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
Integer userId = (Integer) invocation.getArguments()[0];
|
||||
Bundle bundle = (Bundle) invocation.getArguments()[1];
|
||||
doAnswer(invocation -> {
|
||||
Integer userId = (Integer) invocation.getArguments()[0];
|
||||
Bundle bundle = (Bundle) invocation.getArguments()[1];
|
||||
|
||||
newBaseRestrictions.put(userId, bundle);
|
||||
newBaseRestrictions.put(userId, bundle);
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
|
||||
anyInt(), any(Bundle.class));
|
||||
|
||||
@@ -225,16 +219,13 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
|
||||
|
||||
final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
|
||||
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
Integer userId = (Integer) invocation.getArguments()[0];
|
||||
Bundle bundle = (Bundle) invocation.getArguments()[1];
|
||||
doAnswer(invocation -> {
|
||||
Integer userId = (Integer) invocation.getArguments()[0];
|
||||
Bundle bundle = (Bundle) invocation.getArguments()[1];
|
||||
|
||||
newBaseRestrictions.put(userId, bundle);
|
||||
newBaseRestrictions.put(userId, bundle);
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
|
||||
anyInt(), any(Bundle.class));
|
||||
|
||||
@@ -278,4 +269,63 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
|
||||
),
|
||||
dpms.getProfileOwnerAdminLocked(UserHandle.USER_SYSTEM).ensureUserRestrictions());
|
||||
}
|
||||
|
||||
// Test setting default restrictions for managed profile.
|
||||
public void testMigration3_managedProfileOwner() throws Exception {
|
||||
// Create a managed profile user.
|
||||
final File user10dir = mMockContext.addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
|
||||
// Profile owner package for managed profile user.
|
||||
setUpPackageManagerForAdmin(admin1, UserHandle.getUid(10, 123));
|
||||
// Set up fake UserManager to make it look like a managed profile.
|
||||
when(mMockContext.userManager.isManagedProfile(eq(10))).thenReturn(true);
|
||||
// Set up fake Settings to make it look like INSTALL_NON_MARKET_APPS was reversed.
|
||||
when(mMockContext.settings.settingsSecureGetIntForUser(
|
||||
eq(Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED),
|
||||
eq(0), eq(10))).thenReturn(1);
|
||||
// Write policy and owners files.
|
||||
DpmTestUtils.writeToFile(
|
||||
(new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
|
||||
DpmTestUtils.readAsset(mRealTestContext,
|
||||
"DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml"));
|
||||
DpmTestUtils.writeToFile(
|
||||
(new File(user10dir, "device_policies.xml")).getAbsoluteFile(),
|
||||
DpmTestUtils.readAsset(mRealTestContext,
|
||||
"DevicePolicyManagerServiceMigrationTest3/profile_device_policies.xml"));
|
||||
DpmTestUtils.writeToFile(
|
||||
(new File(user10dir, "profile_owner.xml")).getAbsoluteFile(),
|
||||
DpmTestUtils.readAsset(mRealTestContext,
|
||||
"DevicePolicyManagerServiceMigrationTest3/profile_owner.xml"));
|
||||
|
||||
final DevicePolicyManagerServiceTestable dpms;
|
||||
|
||||
// Initialize DPM/DPMS and let it migrate the persisted information.
|
||||
// (Need clearCallingIdentity() to pass permission checks.)
|
||||
final long ident = mContext.binder.clearCallingIdentity();
|
||||
try {
|
||||
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
|
||||
|
||||
dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
|
||||
|
||||
dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
|
||||
dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
|
||||
} finally {
|
||||
mContext.binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
assertFalse(dpms.mOwners.hasDeviceOwner());
|
||||
assertTrue(dpms.mOwners.hasProfileOwner(10));
|
||||
|
||||
// Check that default restrictions were applied.
|
||||
DpmTestUtils.assertRestrictions(
|
||||
DpmTestUtils.newRestrictions(
|
||||
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserManager.DISALLOW_BLUETOOTH_SHARING
|
||||
),
|
||||
dpms.getProfileOwnerAdminLocked(10).ensureUserRestrictions());
|
||||
|
||||
final Set<String> alreadySet =
|
||||
dpms.getProfileOwnerAdminLocked(10).defaultEnabledRestrictionsAlreadySet;
|
||||
assertEquals(alreadySet.size(), 1);
|
||||
assertTrue(alreadySet.contains(UserManager.DISALLOW_BLUETOOTH_SHARING));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.PendingIntent;
|
||||
import android.app.backup.IBackupManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.database.ContentObserver;
|
||||
@@ -56,17 +55,17 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
|
||||
public static class OwnersTestable extends Owners {
|
||||
public static final String LEGACY_FILE = "legacy.xml";
|
||||
public static final String DEVICE_OWNER_FILE = "device_owner2.xml";
|
||||
public static final String PROFILE_OWNER_FILE_BASE = "profile_owner.xml";
|
||||
public static final String PROFILE_OWNER_FILE = "profile_owner.xml";
|
||||
|
||||
private final File mLegacyFile;
|
||||
private final File mDeviceOwnerFile;
|
||||
private final File mProfileOwnerBase;
|
||||
private final File mUsersDataDir;
|
||||
|
||||
public OwnersTestable(DpmMockContext context) {
|
||||
super(context.userManager, context.userManagerInternal, context.packageManagerInternal);
|
||||
mLegacyFile = new File(context.dataDir, LEGACY_FILE);
|
||||
mDeviceOwnerFile = new File(context.dataDir, DEVICE_OWNER_FILE);
|
||||
mProfileOwnerBase = new File(context.dataDir, PROFILE_OWNER_FILE_BASE);
|
||||
mUsersDataDir = new File(context.dataDir, "users");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +80,8 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
|
||||
|
||||
@Override
|
||||
File getProfileOwnerFileWithTestOverride(int userId) {
|
||||
return new File(mDeviceOwnerFile.getAbsoluteFile() + "-" + userId);
|
||||
final File userDir = new File(mUsersDataDir, String.valueOf(userId));
|
||||
return new File(userDir, PROFILE_OWNER_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ public class DpmMockContext extends MockContext {
|
||||
when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
|
||||
|
||||
// Create a data directory.
|
||||
final File dir = new File(dataDir, "user" + userId);
|
||||
final File dir = new File(dataDir, "users/" + userId);
|
||||
DpmTestUtils.clearDir(dir);
|
||||
|
||||
when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
|
||||
|
||||
Reference in New Issue
Block a user