Merge "Add policy for enforcing that all users are ephemeral."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2b04a58dca
@@ -2769,6 +2769,45 @@ public class DevicePolicyManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by a device owner to set whether all users created on the device should be ephemeral.
|
||||
*
|
||||
* <p>The system user is exempt from this policy - it is never ephemeral.
|
||||
*
|
||||
* <p>The calling device admin must be the device owner. If it is not, a security exception will
|
||||
* be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
|
||||
* @param forceEphemeralUsers If true, all the existing users will be deleted and all
|
||||
* subsequently created users will be ephemeral.
|
||||
* @hide
|
||||
*/
|
||||
public void setForceEphemeralUsers(
|
||||
@NonNull ComponentName admin, boolean forceEphemeralUsers) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setForceEphemeralUsers(admin, forceEphemeralUsers);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all users are created ephemeral.
|
||||
* @hide
|
||||
*/
|
||||
public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getForceEphemeralUsers(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to disable keyguard customizations,
|
||||
* such as widgets. After setting this, keyguard features will be disabled according to the
|
||||
|
||||
@@ -230,6 +230,9 @@ interface IDevicePolicyManager {
|
||||
void setAutoTimeRequired(in ComponentName who, boolean required);
|
||||
boolean getAutoTimeRequired();
|
||||
|
||||
void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers);
|
||||
boolean getForceEphemeralUsers(in ComponentName who);
|
||||
|
||||
boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);
|
||||
|
||||
void setUserIcon(in ComponentName admin, in Bitmap icon);
|
||||
|
||||
@@ -91,4 +91,19 @@ public abstract class UserManagerInternal {
|
||||
* the icon is in this method.
|
||||
*/
|
||||
public abstract void setUserIcon(int userId, Bitmap bitmap);
|
||||
|
||||
/**
|
||||
* Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to inform the
|
||||
* user manager whether all users should be created ephemeral.
|
||||
*/
|
||||
public abstract void setForceEphemeralUsers(boolean forceEphemeralUsers);
|
||||
|
||||
/**
|
||||
* Switches to the system user and deletes all other users.
|
||||
*
|
||||
* <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
|
||||
* the force-ephemeral-users policy is toggled on to make sure there are no pre-existing
|
||||
* non-ephemeral users left.
|
||||
*/
|
||||
public abstract void removeAllUsers();
|
||||
}
|
||||
|
||||
@@ -25,9 +25,11 @@ import android.app.ActivityManagerInternal;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.IStopUserCallback;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
@@ -302,6 +304,12 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
|
||||
/**
|
||||
* Whether all users should be created ephemeral.
|
||||
*/
|
||||
@GuardedBy("mUsersLock")
|
||||
private boolean mForceEphemeralUsers;
|
||||
|
||||
private static UserManagerService sInstance;
|
||||
|
||||
public static UserManagerService getInstance() {
|
||||
@@ -1836,23 +1844,25 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
// Add ephemeral flag to guests if required. Also inherit it from parent.
|
||||
userId = getNextAvailableId();
|
||||
Environment.getUserSystemDirectory(userId).mkdirs();
|
||||
boolean ephemeralGuests = Resources.getSystem()
|
||||
.getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
|
||||
if ((isGuest && ephemeralGuests)
|
||||
|| (parent != null && parent.info.isEphemeral())) {
|
||||
flags |= UserInfo.FLAG_EPHEMERAL;
|
||||
}
|
||||
userId = getNextAvailableId();
|
||||
userInfo = new UserInfo(userId, name, null, flags);
|
||||
userInfo.serialNumber = mNextSerialNumber++;
|
||||
long now = System.currentTimeMillis();
|
||||
userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
|
||||
userInfo.partial = true;
|
||||
userData = new UserData();
|
||||
userData.info = userInfo;
|
||||
Environment.getUserSystemDirectory(userInfo.id).mkdirs();
|
||||
|
||||
synchronized (mUsersLock) {
|
||||
// Add ephemeral flag to guests/users if required. Also inherit it from parent.
|
||||
if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
|
||||
|| (parent != null && parent.info.isEphemeral())) {
|
||||
flags |= UserInfo.FLAG_EPHEMERAL;
|
||||
}
|
||||
|
||||
userInfo = new UserInfo(userId, name, null, flags);
|
||||
userInfo.serialNumber = mNextSerialNumber++;
|
||||
long now = System.currentTimeMillis();
|
||||
userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
|
||||
userInfo.partial = true;
|
||||
userData = new UserData();
|
||||
userData.info = userInfo;
|
||||
mUsers.put(userId, userData);
|
||||
}
|
||||
writeUserListLP();
|
||||
@@ -2914,6 +2924,61 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
|
||||
synchronized (mUsersLock) {
|
||||
mForceEphemeralUsers = forceEphemeralUsers;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllUsers() {
|
||||
if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
|
||||
// Remove the non-system users straight away.
|
||||
removeNonSystemUsers();
|
||||
} else {
|
||||
// Switch to the system user first and then remove the other users.
|
||||
BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
int userId =
|
||||
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
||||
if (userId != UserHandle.USER_SYSTEM) {
|
||||
return;
|
||||
}
|
||||
mContext.unregisterReceiver(this);
|
||||
removeNonSystemUsers();
|
||||
}
|
||||
};
|
||||
IntentFilter userSwitchedFilter = new IntentFilter();
|
||||
userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
|
||||
mContext.registerReceiver(
|
||||
userSwitchedReceiver, userSwitchedFilter, null, mHandler);
|
||||
|
||||
// Switch to the system user.
|
||||
ActivityManager am =
|
||||
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
am.switchUser(UserHandle.USER_SYSTEM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all the users except of the system one. */
|
||||
private void removeNonSystemUsers() {
|
||||
ArrayList<UserInfo> usersToRemove = new ArrayList<>();
|
||||
synchronized (mUsersLock) {
|
||||
final int userSize = mUsers.size();
|
||||
for (int i = 0; i < userSize; i++) {
|
||||
UserInfo ui = mUsers.valueAt(i).info;
|
||||
if (ui.id != UserHandle.USER_SYSTEM) {
|
||||
usersToRemove.add(ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (UserInfo ui: usersToRemove) {
|
||||
removeUser(ui.id);
|
||||
}
|
||||
}
|
||||
|
||||
private class Shell extends ShellCommand {
|
||||
|
||||
@@ -471,6 +471,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
|
||||
private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
|
||||
private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
|
||||
private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
|
||||
private static final String TAG_ACCOUNT_TYPE = "account-type";
|
||||
private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
|
||||
= "permitted-accessiblity-services";
|
||||
@@ -559,6 +560,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
boolean disableBluetoothContactSharing = true;
|
||||
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
|
||||
boolean requireAutoTime = false; // Can only be set by a device owner.
|
||||
boolean forceEphemeralUsers = false; // Can only be set by a device owner.
|
||||
|
||||
ActiveAdmin parentAdmin;
|
||||
final boolean isParent;
|
||||
@@ -749,6 +751,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime));
|
||||
out.endTag(null, TAG_REQUIRE_AUTO_TIME);
|
||||
}
|
||||
if (forceEphemeralUsers) {
|
||||
out.startTag(null, TAG_FORCE_EPHEMERAL_USERS);
|
||||
out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
|
||||
out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
|
||||
}
|
||||
if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
|
||||
out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
|
||||
out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
|
||||
@@ -919,7 +926,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
disableScreenCapture = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
} else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
|
||||
requireAutoTime= Boolean.parseBoolean(
|
||||
requireAutoTime = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
} else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
|
||||
forceEphemeralUsers = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
} else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
|
||||
disabledKeyguardFeatures = Integer.parseInt(
|
||||
@@ -1150,6 +1160,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
pw.println(disableScreenCapture);
|
||||
pw.print(prefix); pw.print("requireAutoTime=");
|
||||
pw.println(requireAutoTime);
|
||||
pw.print(prefix); pw.print("forceEphemeralUsers=");
|
||||
pw.println(forceEphemeralUsers);
|
||||
pw.print(prefix); pw.print("disabledKeyguardFeatures=");
|
||||
pw.println(disabledKeyguardFeatures);
|
||||
pw.print(prefix); pw.print("crossProfileWidgetProviders=");
|
||||
@@ -2408,6 +2420,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
if (packageList != null) {
|
||||
mInjector.getPackageManagerInternal().setKeepUninstalledPackages(packageList);
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
// push the force-ephemeral-users policy to the user manager.
|
||||
ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
|
||||
if (deviceOwner != null) {
|
||||
mUserManagerInternal.setForceEphemeralUsers(deviceOwner.forceEphemeralUsers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureDeviceOwnerUserStarted() {
|
||||
@@ -4789,6 +4809,46 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
|
||||
if (!mHasFeature) {
|
||||
return;
|
||||
}
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
boolean removeAllUsers = false;
|
||||
synchronized (this) {
|
||||
final ActiveAdmin deviceOwner =
|
||||
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
|
||||
if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) {
|
||||
deviceOwner.forceEphemeralUsers = forceEphemeralUsers;
|
||||
saveSettingsLocked(mInjector.userHandleGetCallingUserId());
|
||||
mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers);
|
||||
removeAllUsers = forceEphemeralUsers;
|
||||
}
|
||||
}
|
||||
if (removeAllUsers) {
|
||||
long identitity = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
mUserManagerInternal.removeAllUsers();
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(identitity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getForceEphemeralUsers(ComponentName who) {
|
||||
if (!mHasFeature) {
|
||||
return false;
|
||||
}
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
synchronized (this) {
|
||||
final ActiveAdmin deviceOwner =
|
||||
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
|
||||
return deviceOwner.forceEphemeralUsers;
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureDeviceOwnerManagingSingleUser(ComponentName who) throws SecurityException {
|
||||
synchronized (this) {
|
||||
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
|
||||
@@ -5319,6 +5379,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
if (admin != null) {
|
||||
admin.disableCamera = false;
|
||||
admin.userRestrictions = null;
|
||||
admin.forceEphemeralUsers = false;
|
||||
mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
|
||||
}
|
||||
|
||||
clearUserPoliciesLocked(new UserHandle(UserHandle.USER_SYSTEM));
|
||||
|
||||
Reference in New Issue
Block a user