Merge "Introduce DISALLOW_BLUETOOTH_SHARING." into oc-dev

This commit is contained in:
Pavel Grafov
2017-04-28 14:15:53 +00:00
committed by Android (Google) Code Review
13 changed files with 270 additions and 130 deletions

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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.

View File

@@ -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.
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -0,0 +1,3 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<policies setup-complete="true" provisioning-state="3">
</policies>

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View 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);