Notify any profile/device owners of lock task

Add a method for DeviceAdminReceivers of profile/device owners to
be notified that lock task mode has entered or exited for an app
they have whitelisted.

Change-Id: Id124287d41564bbfccdacccf1977b7acb3ddec3f
This commit is contained in:
Jason Monk
2014-06-17 10:24:47 -04:00
parent 5d140e4b1b
commit 35c62a4668
5 changed files with 107 additions and 1 deletions

View File

@@ -5174,6 +5174,7 @@ package android.app.admin {
method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
method public void onDisabled(android.content.Context, android.content.Intent);
method public void onEnabled(android.content.Context, android.content.Intent);
method public void onLockTaskModeChanged(android.content.Context, android.content.Intent);
method public void onPasswordChanged(android.content.Context, android.content.Intent);
method public void onPasswordExpiring(android.content.Context, android.content.Intent);
method public void onPasswordFailed(android.content.Context, android.content.Intent);
@@ -5183,6 +5184,7 @@ package android.app.admin {
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
field public static final java.lang.String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED";
field public static final java.lang.String ACTION_LOCK_TASK_CHANGED = "android.app.action.ACTION_LOCK_TASK_CHANGED";
field public static final java.lang.String ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED";
field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING";
field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
@@ -5190,6 +5192,7 @@ package android.app.admin {
field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE";
field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
field public static final java.lang.String EXTRA_LOCK_TASK_ENTERING = "android.app.extra.LOCK_TASK_ENTERING";
}
public class DevicePolicyManager {

View File

@@ -165,6 +165,40 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
public static final String ACTION_PASSWORD_EXPIRING
= "android.app.action.ACTION_PASSWORD_EXPIRING";
/**
* Action sent to a device administrator to notify that the device is entering
* or exiting lock task mode from an authorized package. The extra
* {@link #EXTRA_LOCK_TASK_ENTERING} will describe whether entering or exiting
* the mode. If entering, the extra {@link #EXTRA_LOCK_TASK_PACKAGE} will describe
* the authorized package using lock task mode.
*
* @see DevicePolicyManager#isLockTaskPermitted
*
* <p>The calling device admin must be the device owner or profile
* owner to receive this broadcast.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_LOCK_TASK_CHANGED
= "android.app.action.ACTION_LOCK_TASK_CHANGED";
/**
* A boolean describing whether the device is currently entering or exiting
* lock task mode.
*
* @see #ACTION_LOCK_TASK_CHANGED
*/
public static final String EXTRA_LOCK_TASK_ENTERING =
"android.app.extra.LOCK_TASK_ENTERING";
/**
* A boolean describing whether the device is currently entering or exiting
* lock task mode.
*
* @see #ACTION_LOCK_TASK_CHANGED
*/
public static final String EXTRA_LOCK_TASK_PACKAGE =
"android.app.extra.LOCK_TASK_PACKAGE";
/**
* Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
* or managed device has completed successfully.
@@ -340,6 +374,19 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
public void onProfileProvisioningComplete(Context context, Intent intent) {
}
/**
* Called when a device is entering or exiting lock task mode by a package
* authorized by {@link DevicePolicyManager#isLockTaskPermitted(ComponentName)}
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
* @param isEnteringLockTask Whether the device is entering or exiting lock task mode.
* @param pkg If entering, the authorized package using lock task mode, otherwise null.
*/
public void onLockTaskModeChanged(Context context, Intent intent, boolean isEnteringLockTask,
String pkg) {
}
/**
* Intercept standard device administrator broadcasts. Implementations
* should not override this method; it is better to implement the
@@ -369,6 +416,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
onPasswordExpiring(context, intent);
} else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
onProfileProvisioningComplete(context, intent);
} else if (ACTION_LOCK_TASK_CHANGED.equals(action)) {
boolean isEntering = intent.getBooleanExtra(EXTRA_LOCK_TASK_ENTERING, false);
String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
onLockTaskModeChanged(context, intent, isEntering, pkg);
}
}
}

View File

@@ -151,4 +151,6 @@ interface IDevicePolicyManager {
void setMasterVolumeMuted(in ComponentName admin, boolean on);
boolean isMasterVolumeMuted(in ComponentName admin);
void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userId);
}

View File

@@ -46,6 +46,8 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.app.IActivityManager.WaitResult;
import android.app.ResultInfo;
import android.app.StatusBarManager;
import android.app.admin.DevicePolicyManager;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
@@ -143,6 +145,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** Status Bar Service **/
private IBinder mToken = new Binder();
private IStatusBarService mStatusBarService;
private IDevicePolicyManager mDevicePolicyManager;
// For debugging to make sure the caller when acquiring/releasing our
// wake lock is the system process.
@@ -281,6 +284,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
private IDevicePolicyManager getDevicePolicyManager() {
synchronized (mService) {
if (mDevicePolicyManager == null) {
mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
if (mDevicePolicyManager == null) {
Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
}
}
return mDevicePolicyManager;
}
}
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
mWindowManager = wm;
@@ -2988,8 +3004,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
final Message lockTaskMsg = Message.obtain();
if (task == null) {
// Take out of lock task mode.
mLockTaskModeTask = null;
lockTaskMsg.arg1 = mLockTaskModeTask.userId;
lockTaskMsg.what = LOCK_TASK_END_MSG;
mLockTaskModeTask = null;
mHandler.sendMessage(lockTaskMsg);
return;
}
@@ -3000,6 +3017,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
mLockTaskModeTask = task;
findTaskToMoveToFrontLocked(task, 0, null);
resumeTopActivitiesLocked();
lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
lockTaskMsg.arg1 = mLockTaskModeTask.userId;
lockTaskMsg.what = LOCK_TASK_START_MSG;
mHandler.sendMessage(lockTaskMsg);
}
@@ -3108,6 +3127,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
(StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
mToken, mService.mContext.getPackageName());
}
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(true,
(String)msg.obj,
msg.arg1);
}
} catch (RemoteException ex) {
throw new RuntimeException(ex);
}
@@ -3120,6 +3144,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
(StatusBarManager.DISABLE_NONE,
mToken, mService.mContext.getPackageName());
}
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
msg.arg1);
}
} catch (RemoteException ex) {
throw new RuntimeException(ex);
}

View File

@@ -3792,6 +3792,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
@Override
public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("notifyLockTaskModeChanged can only be called by system");
}
synchronized (this) {
final DevicePolicyData policy = getUserData(userHandle);
Bundle adminExtras = new Bundle();
adminExtras.putBoolean(DeviceAdminReceiver.EXTRA_LOCK_TASK_ENTERING, isEnabled);
adminExtras.putString(DeviceAdminReceiver.EXTRA_LOCK_TASK_PACKAGE, pkg);
for (ActiveAdmin admin : policy.mAdminList) {
boolean ownsDevice = isDeviceOwner(admin.info.getPackageName());
boolean ownsProfile = (getProfileOwner(userHandle) != null
&& getProfileOwner(userHandle).equals(admin.info.getPackageName()));
if (ownsDevice || ownsProfile) {
sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_LOCK_TASK_CHANGED,
adminExtras, null);
}
}
}
}
@Override
public void setGlobalSetting(ComponentName who, String setting, String value) {
final ContentResolver contentResolver = mContext.getContentResolver();