Loading core/java/android/app/ActivityManagerNative.java +22 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } case UPDATE_LOCK_TASK_PACKAGES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int userId = data.readInt(); String[] packages = data.readStringArray(); updateLockTaskPackages(userId, packages); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -5687,5 +5696,18 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(userId); data.writeStringArray(packages); mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); reply.recycle(); } private IBinder mRemote; } core/java/android/app/IActivityManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,7 @@ public interface IActivityManager extends IInterface { public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) throws RemoteException; public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException; /* * Private non-Binder interfaces Loading Loading @@ -823,4 +824,5 @@ public interface IActivityManager extends IInterface { int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287; int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288; int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289; int UPDATE_LOCK_TASK_PACKAGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+290; } services/core/java/com/android/server/am/ActivityManagerService.java +57 −62 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ import android.app.IActivityContainerCallback; import android.app.IAppTask; import android.app.ITaskStackListener; import android.app.ProfilerInfo; import android.app.admin.DevicePolicyManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -429,6 +428,11 @@ public final class ActivityManagerService extends ActivityManagerNative */ ActivityInfo mLastAddedTaskActivity; /** * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId. */ SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); public class PendingAssistExtras extends Binder implements Runnable { public final ActivityRecord activity; public final Bundle extras; Loading Loading @@ -8463,52 +8467,54 @@ public final class ActivityManagerService extends ActivityManagerNative } } private boolean isLockTaskAuthorized(String pkg) { final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); try { int uid = mContext.getPackageManager().getPackageUid(pkg, Binder.getCallingUserHandle().getIdentifier()); return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); } catch (NameNotFoundException e) { return false; @Override public void updateLockTaskPackages(int userId, String[] packages) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("updateLockTaskPackage called from non-system process"); } synchronized (this) { mLockTaskPackages.put(userId, packages); } } void startLockTaskMode(TaskRecord task) { final String pkg; synchronized (this) { pkg = task.intent.getComponent().getPackageName(); private boolean isLockTaskAuthorizedLocked(String pkg) { String[] packages = mLockTaskPackages.get(mCurrentUserId); if (packages == null) { return false; } for (int i = packages.length - 1; i >= 0; --i) { if (pkg.equals(packages[i])) { return true; } } return false; } void startLockTaskModeLocked(TaskRecord task) { final String pkg = task.intent.getComponent().getPackageName(); // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode // is initiated by system after the pinning request was shown and locked mode is initiated // by an authorized app directly boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { StatusBarManagerInternal statusBarManager = LocalServices.getService( StatusBarManagerInternal.class); long ident = Binder.clearCallingIdentity(); try { if (!isSystemInitiated && !isLockTaskAuthorizedLocked(pkg)) { StatusBarManagerInternal statusBarManager = LocalServices.getService(StatusBarManagerInternal.class); if (statusBarManager != null) { statusBarManager.showScreenPinningRequest(); } return; } long ident = Binder.clearCallingIdentity(); try { synchronized (this) { // Since we lost lock on task, make sure it is still there. task = mStackSupervisor.anyTaskForIdLocked(task.taskId); if (task != null) { if (!isSystemInitiated && ((mStackSupervisor.getFocusedStack() == null) || (task != mStackSupervisor.getFocusedStack().topTask()))) { final ActivityStack stack = mStackSupervisor.getFocusedStack(); if (!isSystemInitiated && (stack == null || task != stack.topTask())) { throw new IllegalArgumentException("Invalid task, not in foreground"); } mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? ActivityManager.LOCK_TASK_MODE_PINNED : ActivityManager.LOCK_TASK_MODE_LOCKED, "startLockTask"); } } } finally { Binder.restoreCallingIdentity(ident); } Loading @@ -8516,37 +8522,25 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void startLockTaskMode(int taskId) { final TaskRecord task; long ident = Binder.clearCallingIdentity(); try { synchronized (this) { task = mStackSupervisor.anyTaskForIdLocked(taskId); } } finally { Binder.restoreCallingIdentity(ident); } final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); if (task != null) { startLockTaskMode(task); startLockTaskModeLocked(task); } } } @Override public void startLockTaskMode(IBinder token) { final TaskRecord task; long ident = Binder.clearCallingIdentity(); try { synchronized (this) { final ActivityRecord r = ActivityRecord.forTokenLocked(token); if (r == null) { return; } task = r.task; } } finally { Binder.restoreCallingIdentity(ident); } final TaskRecord task = r.task; if (task != null) { startLockTaskMode(task); startLockTaskModeLocked(task); } } } Loading @@ -8556,11 +8550,12 @@ public final class ActivityManagerService extends ActivityManagerNative "startLockTaskModeOnCurrent"); long ident = Binder.clearCallingIdentity(); try { ActivityRecord r = null; synchronized (this) { r = mStackSupervisor.topRunningActivityLocked(); ActivityRecord r = mStackSupervisor.topRunningActivityLocked(); if (r != null) { startLockTaskModeLocked(r.task); } } startLockTaskMode(r.task); } finally { Binder.restoreCallingIdentity(ident); } Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +16 −8 Original line number Diff line number Diff line Loading @@ -280,15 +280,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastMaximumTimeToLock = -1; boolean mUserSetupComplete = false; final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<ComponentName, ActiveAdmin>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<ActiveAdmin>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<ComponentName>(); final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); // This is the list of component allowed to start lock task mode. final List<String> mLockTaskPackages = new ArrayList<String>(); final List<String> mLockTaskPackages = new ArrayList<>(); ComponentName mRestrictionsProvider; Loading @@ -299,7 +296,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>(); final SparseArray<DevicePolicyData> mUserData = new SparseArray<>(); Handler mHandler = new Handler(); Loading Loading @@ -1596,6 +1593,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); updateMaximumTimeToLockLocked(policy); updateLockTaskPackagesLocked(policy, userHandle); } private void updateLockTaskPackagesLocked(DevicePolicyData policy, int userId) { IActivityManager am = ActivityManagerNative.getDefault(); try { am.updateLockTaskPackages(userId, policy.mLockTaskPackages.toArray(new String[0])); } catch (RemoteException e) { // Not gonna happen. } } static void validateQualityConstant(int quality) { Loading Loading @@ -5533,6 +5540,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Store the settings persistently. saveSettingsLocked(userHandle); updateLockTaskPackagesLocked(policy, userHandle); } } Loading Loading
core/java/android/app/ActivityManagerNative.java +22 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } case UPDATE_LOCK_TASK_PACKAGES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int userId = data.readInt(); String[] packages = data.readStringArray(); updateLockTaskPackages(userId, packages); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -5687,5 +5696,18 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(userId); data.writeStringArray(packages); mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); reply.recycle(); } private IBinder mRemote; }
core/java/android/app/IActivityManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,7 @@ public interface IActivityManager extends IInterface { public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) throws RemoteException; public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException; /* * Private non-Binder interfaces Loading Loading @@ -823,4 +824,5 @@ public interface IActivityManager extends IInterface { int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287; int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288; int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289; int UPDATE_LOCK_TASK_PACKAGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+290; }
services/core/java/com/android/server/am/ActivityManagerService.java +57 −62 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ import android.app.IActivityContainerCallback; import android.app.IAppTask; import android.app.ITaskStackListener; import android.app.ProfilerInfo; import android.app.admin.DevicePolicyManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -429,6 +428,11 @@ public final class ActivityManagerService extends ActivityManagerNative */ ActivityInfo mLastAddedTaskActivity; /** * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId. */ SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); public class PendingAssistExtras extends Binder implements Runnable { public final ActivityRecord activity; public final Bundle extras; Loading Loading @@ -8463,52 +8467,54 @@ public final class ActivityManagerService extends ActivityManagerNative } } private boolean isLockTaskAuthorized(String pkg) { final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); try { int uid = mContext.getPackageManager().getPackageUid(pkg, Binder.getCallingUserHandle().getIdentifier()); return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); } catch (NameNotFoundException e) { return false; @Override public void updateLockTaskPackages(int userId, String[] packages) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("updateLockTaskPackage called from non-system process"); } synchronized (this) { mLockTaskPackages.put(userId, packages); } } void startLockTaskMode(TaskRecord task) { final String pkg; synchronized (this) { pkg = task.intent.getComponent().getPackageName(); private boolean isLockTaskAuthorizedLocked(String pkg) { String[] packages = mLockTaskPackages.get(mCurrentUserId); if (packages == null) { return false; } for (int i = packages.length - 1; i >= 0; --i) { if (pkg.equals(packages[i])) { return true; } } return false; } void startLockTaskModeLocked(TaskRecord task) { final String pkg = task.intent.getComponent().getPackageName(); // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode // is initiated by system after the pinning request was shown and locked mode is initiated // by an authorized app directly boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { StatusBarManagerInternal statusBarManager = LocalServices.getService( StatusBarManagerInternal.class); long ident = Binder.clearCallingIdentity(); try { if (!isSystemInitiated && !isLockTaskAuthorizedLocked(pkg)) { StatusBarManagerInternal statusBarManager = LocalServices.getService(StatusBarManagerInternal.class); if (statusBarManager != null) { statusBarManager.showScreenPinningRequest(); } return; } long ident = Binder.clearCallingIdentity(); try { synchronized (this) { // Since we lost lock on task, make sure it is still there. task = mStackSupervisor.anyTaskForIdLocked(task.taskId); if (task != null) { if (!isSystemInitiated && ((mStackSupervisor.getFocusedStack() == null) || (task != mStackSupervisor.getFocusedStack().topTask()))) { final ActivityStack stack = mStackSupervisor.getFocusedStack(); if (!isSystemInitiated && (stack == null || task != stack.topTask())) { throw new IllegalArgumentException("Invalid task, not in foreground"); } mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? ActivityManager.LOCK_TASK_MODE_PINNED : ActivityManager.LOCK_TASK_MODE_LOCKED, "startLockTask"); } } } finally { Binder.restoreCallingIdentity(ident); } Loading @@ -8516,37 +8522,25 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void startLockTaskMode(int taskId) { final TaskRecord task; long ident = Binder.clearCallingIdentity(); try { synchronized (this) { task = mStackSupervisor.anyTaskForIdLocked(taskId); } } finally { Binder.restoreCallingIdentity(ident); } final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); if (task != null) { startLockTaskMode(task); startLockTaskModeLocked(task); } } } @Override public void startLockTaskMode(IBinder token) { final TaskRecord task; long ident = Binder.clearCallingIdentity(); try { synchronized (this) { final ActivityRecord r = ActivityRecord.forTokenLocked(token); if (r == null) { return; } task = r.task; } } finally { Binder.restoreCallingIdentity(ident); } final TaskRecord task = r.task; if (task != null) { startLockTaskMode(task); startLockTaskModeLocked(task); } } } Loading @@ -8556,11 +8550,12 @@ public final class ActivityManagerService extends ActivityManagerNative "startLockTaskModeOnCurrent"); long ident = Binder.clearCallingIdentity(); try { ActivityRecord r = null; synchronized (this) { r = mStackSupervisor.topRunningActivityLocked(); ActivityRecord r = mStackSupervisor.topRunningActivityLocked(); if (r != null) { startLockTaskModeLocked(r.task); } } startLockTaskMode(r.task); } finally { Binder.restoreCallingIdentity(ident); } Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +16 −8 Original line number Diff line number Diff line Loading @@ -280,15 +280,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastMaximumTimeToLock = -1; boolean mUserSetupComplete = false; final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<ComponentName, ActiveAdmin>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<ActiveAdmin>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<ComponentName>(); final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); // This is the list of component allowed to start lock task mode. final List<String> mLockTaskPackages = new ArrayList<String>(); final List<String> mLockTaskPackages = new ArrayList<>(); ComponentName mRestrictionsProvider; Loading @@ -299,7 +296,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>(); final SparseArray<DevicePolicyData> mUserData = new SparseArray<>(); Handler mHandler = new Handler(); Loading Loading @@ -1596,6 +1593,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); updateMaximumTimeToLockLocked(policy); updateLockTaskPackagesLocked(policy, userHandle); } private void updateLockTaskPackagesLocked(DevicePolicyData policy, int userId) { IActivityManager am = ActivityManagerNative.getDefault(); try { am.updateLockTaskPackages(userId, policy.mLockTaskPackages.toArray(new String[0])); } catch (RemoteException e) { // Not gonna happen. } } static void validateQualityConstant(int quality) { Loading Loading @@ -5533,6 +5540,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Store the settings persistently. saveSettingsLocked(userHandle); updateLockTaskPackagesLocked(policy, userHandle); } } Loading