Add API for device owner to switch users
Once verified that caller is device owner just calls through to
the activity manager and acts like that call.
Change-Id: I34023313cd6742b73d2105655ec6b631879aa37a
diff --git a/api/current.txt b/api/current.txt
index 8642eee..ff33a0c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5330,6 +5330,7 @@
method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public int setStorageEncryption(android.content.ComponentName, boolean);
+ method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallCaCert(android.content.ComponentName, byte[]);
method public void wipeData(int);
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 2feec1b..6ea6b4b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2375,6 +2375,24 @@
}
/**
+ * Called by a device owner to switch the specified user to the foreground.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param userHandle the user to switch to; null will switch to primary.
+ * @return {@code true} if the switch was successful, {@code false} otherwise.
+ *
+ * @see Intent#ACTION_USER_FOREGROUND
+ */
+ public boolean switchUser(ComponentName admin, UserHandle userHandle) {
+ try {
+ return mService.switchUser(admin, userHandle);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not switch user ", re);
+ return false;
+ }
+ }
+
+ /**
* Called by a profile or device owner to get the application restrictions for a given target
* application running in the managed profile.
*
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 40bd7d1..c27d1cc 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -139,6 +139,7 @@
UserHandle createUser(in ComponentName who, in String name);
UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras);
boolean removeUser(in ComponentName who, in UserHandle userHandle);
+ boolean switchUser(in ComponentName who, in UserHandle userHandle);
void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
String[] getAccountTypesWithManagementDisabled();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 61f09f6..5445dc0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3592,6 +3592,30 @@
}
@Override
+ public boolean switchUser(ComponentName who, UserHandle userHandle) {
+ synchronized (this) {
+ if (who == null) {
+ throw new NullPointerException("ComponentName is null");
+ }
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+
+ long id = Binder.clearCallingIdentity();
+ try {
+ int userId = UserHandle.USER_OWNER;
+ if (userHandle != null) {
+ userId = userHandle.getIdentifier();
+ }
+ return ActivityManagerNative.getDefault().switchUser(userId);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Couldn't switch user", e);
+ return false;
+ } finally {
+ restoreCallingIdentity(id);
+ }
+ }
+ }
+
+ @Override
public Bundle getApplicationRestrictions(ComponentName who, String packageName) {
final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());