Merge "Introduce more user management APIs"

This commit is contained in:
TreeHugger Robot
2017-12-06 19:10:34 +00:00
committed by Android (Google) Code Review
4 changed files with 152 additions and 1 deletions

View File

@@ -6371,6 +6371,7 @@ package android.app.admin {
method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
method public long getRequiredStrongAuthTimeout(android.content.ComponentName);
method public boolean getScreenCaptureDisabled(android.content.ComponentName);
method public java.util.List<android.os.UserHandle> getSecondaryUsers(android.content.ComponentName);
method public java.lang.CharSequence getShortSupportMessage(android.content.ComponentName);
method public boolean getStorageEncryption(android.content.ComponentName);
method public int getStorageEncryptionStatus();
@@ -6403,6 +6404,7 @@ package android.app.admin {
method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
method public void lockNow();
method public void lockNow(int);
method public boolean logoutUser(android.content.ComponentName);
method public void reboot(android.content.ComponentName);
method public void removeActiveAdmin(android.content.ComponentName);
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -6477,6 +6479,7 @@ package android.app.admin {
method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
method public void setUserIcon(android.content.ComponentName, android.graphics.Bitmap);
method public boolean stopUser(android.content.ComponentName, android.os.UserHandle);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
method public void uninstallCaCert(android.content.ComponentName, byte[]);

View File

@@ -6219,7 +6219,7 @@ public class DevicePolicyManager {
* @return {@code true} if the user was removed, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) {
public boolean removeUser(@NonNull ComponentName admin, @NonNull UserHandle userHandle) {
throwIfParentInstance("removeUser");
try {
return mService.removeUser(admin, userHandle);
@@ -6230,6 +6230,7 @@ public class DevicePolicyManager {
/**
* Called by a device owner to switch the specified user to the foreground.
* <p> This cannot be used to switch to a managed profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param userHandle the user to switch to; null will switch to primary.
@@ -6246,6 +6247,65 @@ public class DevicePolicyManager {
}
}
/**
* Called by a device owner to stop the specified secondary user.
* <p> This cannot be used to stop the primary user or a managed profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param userHandle the user to be stopped.
* @return {@code true} if the user can be stopped, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not a device owner.
*/
public boolean stopUser(@NonNull ComponentName admin, @NonNull UserHandle userHandle) {
throwIfParentInstance("stopUser");
try {
return mService.stopUser(admin, userHandle);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
* Called by a profile owner that is affiliated with the device owner to stop the calling user
* and switch back to primary.
* <p> This has no effect when called on a managed profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return {@code true} if the exit was successful, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not a profile owner affiliated with the device
* owner.
*/
public boolean logoutUser(@NonNull ComponentName admin) {
throwIfParentInstance("logoutUser");
try {
return mService.logoutUser(admin);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
* Called by a device owner to list all secondary users on the device, excluding managed
* profiles.
* <p> Used for various user management APIs, including {@link #switchUser}, {@link #removeUser}
* and {@link #stopUser}.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return list of other {@link UserHandle}s on the device.
* @throws SecurityException if {@code admin} is not a device owner.
* @see #switchUser
* @see #removeUser
* @see #stopUser
*/
public List<UserHandle> getSecondaryUsers(@NonNull ComponentName admin) {
throwIfParentInstance("getSecondaryUsers");
try {
return mService.getSecondaryUsers(admin);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
* Retrieves the application restrictions for a given target application running in the calling
* user.

View File

@@ -215,6 +215,9 @@ interface IDevicePolicyManager {
UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags);
boolean removeUser(in ComponentName who, in UserHandle userHandle);
boolean switchUser(in ComponentName who, in UserHandle userHandle);
boolean stopUser(in ComponentName who, in UserHandle userHandle);
boolean logoutUser(in ComponentName who);
List<UserHandle> getSecondaryUsers(in ComponentName who);
void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);

View File

@@ -19,6 +19,7 @@ package com.android.server.devicepolicy;
import static android.Manifest.permission.BIND_DEVICE_ADMIN;
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
import static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED;
import static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE;
@@ -8402,6 +8403,90 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
@Override
public boolean stopUser(ComponentName who, UserHandle userHandle) {
Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
}
final int userId = userHandle.getIdentifier();
if (isManagedProfile(userId)) {
Log.w(LOG_TAG, "Managed profile cannot be stopped");
return false;
}
final long id = mInjector.binderClearCallingIdentity();
try {
return mInjector.getIActivityManager().stopUser(userId, true /*force*/, null)
== USER_OP_SUCCESS;
} catch (RemoteException e) {
// Same process, should not happen.
return false;
} finally {
mInjector.binderRestoreCallingIdentity(id);
}
}
@Override
public boolean logoutUser(ComponentName who) {
Preconditions.checkNotNull(who, "ComponentName is null");
final int callingUserId = mInjector.userHandleGetCallingUserId();
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
if (!isUserAffiliatedWithDeviceLocked(callingUserId)) {
throw new SecurityException("Admin " + who +
" is neither the device owner or affiliated user's profile owner.");
}
}
if (isManagedProfile(callingUserId)) {
Log.w(LOG_TAG, "Managed profile cannot be logout");
return false;
}
final long id = mInjector.binderClearCallingIdentity();
try {
if (!mInjector.getIActivityManager().switchUser(UserHandle.USER_SYSTEM)) {
Log.w(LOG_TAG, "Failed to switch to primary user");
return false;
}
return mInjector.getIActivityManager().stopUser(callingUserId, true /*force*/, null)
== USER_OP_SUCCESS;
} catch (RemoteException e) {
// Same process, should not happen.
return false;
} finally {
mInjector.binderRestoreCallingIdentity(id);
}
}
@Override
public List<UserHandle> getSecondaryUsers(ComponentName who) {
Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
}
final long id = mInjector.binderClearCallingIdentity();
try {
final List<UserInfo> userInfos = mInjector.getUserManager().getUsers(true
/*excludeDying*/);
final List<UserHandle> userHandles = new ArrayList<>();
for (UserInfo userInfo : userInfos) {
UserHandle userHandle = userInfo.getUserHandle();
if (!userHandle.isSystem() && !isManagedProfile(userHandle.getIdentifier())) {
userHandles.add(userInfo.getUserHandle());
}
}
return userHandles;
} finally {
mInjector.binderRestoreCallingIdentity(id);
}
}
@Override
public Bundle getApplicationRestrictions(ComponentName who, String callerPackage,
String packageName) {