Merge "Introduce DISALLOW_BLUETOOTH_SHARING." into oc-dev
am: 90357d62e9
Change-Id: I925165817781c3b0f4e37afe8ebcce1ac264d775
diff --git a/api/current.txt b/api/current.txt
index 628194d..5217163 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -31680,6 +31680,7 @@
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";
diff --git a/api/system-current.txt b/api/system-current.txt
index 2757835..0683327 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -34563,6 +34563,7 @@
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";
diff --git a/api/test-current.txt b/api/test-current.txt
index f151116bd..b11cc1e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -31813,6 +31813,7 @@
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";
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f95a34c..52b2f52 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -64,7 +64,7 @@
*/
public class UserManager {
- private static String TAG = "UserManager";
+ private static final String TAG = "UserManager";
private final IUserManager mService;
private final Context mContext;
@@ -218,6 +218,23 @@
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.
* The default value is <code>false</code>.
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 6c18b26..18b4571 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -18,6 +18,7 @@
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.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.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.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 @@
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 @@
@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 @@
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 @@
/**
* 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.
}
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 84381fe..c6667a7 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -74,6 +74,7 @@
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 @@
*/
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 @@
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.
*/
@@ -308,6 +321,13 @@
}
/**
+ * 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 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 @@
}
}
}
+
+ /**
+ * 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;
+ }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2f26f43..2ddce16 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1903,7 +1903,7 @@
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 @@
}
}
- 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 @@
}
}
- 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 @@
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 @@
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);
diff --git a/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_device_policies.xml b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_device_policies.xml
new file mode 100644
index 0000000..b162785
--- /dev/null
+++ b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_device_policies.xml
@@ -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>
diff --git a/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_owner.xml b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_owner.xml
new file mode 100644
index 0000000..7440424
--- /dev/null
+++ b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/profile_owner.xml
@@ -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>
diff --git a/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml
new file mode 100644
index 0000000..5f9a871
--- /dev/null
+++ b/services/tests/servicestests/assets/DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml
@@ -0,0 +1,3 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<policies setup-complete="true" provisioning-state="3">
+</policies>
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index b440095..be1d07b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -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 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 @@
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 @@
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 @@
),
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));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index a6ce1d5..46da3de 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -21,7 +21,6 @@
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 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 @@
@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);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 1ea12d8..23fada4 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -468,7 +468,7 @@
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);