Loading services/core/java/com/android/server/am/LockTaskController.java +56 −5 Original line number Diff line number Diff line Loading @@ -22,8 +22,10 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Context.DEVICE_POLICY_SERVICE; import static android.content.Context.STATUS_BAR_SERVICE; import static android.content.Intent.ACTION_CALL_EMERGENCY; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_CURRENT; import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; Loading @@ -45,6 +47,7 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Debug; import android.os.Handler; Loading @@ -52,9 +55,11 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.telecom.TelecomManager; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -133,6 +138,8 @@ public class LockTaskController { WindowManagerService mWindowManager; @VisibleForTesting LockPatternUtils mLockPatternUtils; @VisibleForTesting TelecomManager mTelecomManager; /** * Helper that is responsible for showing the right toast when a disallowed activity operation Loading Loading @@ -165,7 +172,7 @@ public class LockTaskController { /** * Features that are allowed by DPC to show during LockTask mode. */ private final SparseArray<Integer> mLockTaskFeatures = new SparseArray<>(); private final SparseIntArray mLockTaskFeatures = new SparseIntArray(); /** * Store the current lock task mode. Possible values: Loading Loading @@ -298,6 +305,11 @@ public class LockTaskController { return false; } // Allow emergency calling when the device is protected by a locked keyguard if (isKeyguardAllowed(task.userId) && isEmergencyCallTask(task)) { return false; } return !(isTaskWhitelisted(task) || mLockTaskModeTasks.isEmpty()); } Loading @@ -306,6 +318,37 @@ public class LockTaskController { & DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS) != 0; } private boolean isKeyguardAllowed(int userId) { return (getLockTaskFeaturesForUser(userId) & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0; } private boolean isEmergencyCallTask(TaskRecord task) { final Intent intent = task.intent; if (intent == null) { return false; } // 1. The emergency keypad activity launched on top of the keyguard if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) { return true; } // 2. The intent sent by the keypad, which is handled by Telephony if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) { return true; } // 3. Telephony then starts the default package for making the call final TelecomManager tm = getTelecomManager(); final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null; if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) { return true; } return false; } /** * Stop the current lock task mode. * Loading Loading @@ -686,11 +729,10 @@ public class LockTaskController { mWindowManager.reenableKeyguard(mToken); } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { int lockTaskFeatures = getLockTaskFeaturesForUser(userId); if ((DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD & lockTaskFeatures) == 0) { mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); } else { if (isKeyguardAllowed(userId)) { mWindowManager.reenableKeyguard(mToken); } else { mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); } } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED Loading Loading @@ -784,6 +826,15 @@ public class LockTaskController { return mLockPatternUtils; } @Nullable private TelecomManager getTelecomManager() { if (mTelecomManager == null) { // We don't preserve the TelecomManager object to save memory return mContext.getSystemService(TelecomManager.class); } return mTelecomManager; } // Should only be called on the handler thread @NonNull private LockTaskNotify getLockTaskNotify() { Loading services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java +44 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NONE; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS; import static android.os.Process.SYSTEM_UID; import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_PINNED; Loading @@ -53,6 +54,7 @@ import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.telecom.TelecomManager; import android.util.Pair; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -90,6 +92,7 @@ public class LockTaskControllerTest { @Mock private LockPatternUtils mLockPatternUtils; @Mock private LockTaskNotify mLockTaskNotify; @Mock private StatusBarManagerInternal mStatusBarManagerInternal; @Mock private TelecomManager mTelecomManager; @Mock private RecentTasks mRecentTasks; private LockTaskController mLockTaskController; Loading Loading @@ -118,6 +121,7 @@ public class LockTaskControllerTest { mLockTaskController.setWindowManager(mWindowManager); mLockTaskController.mStatusBarService = mStatusBarService; mLockTaskController.mDevicePolicyManager = mDevicePolicyManager; mLockTaskController.mTelecomManager = mTelecomManager; mLockTaskController.mLockPatternUtils = mLockPatternUtils; mLockTaskController.mLockTaskNotify = mLockTaskNotify; Loading Loading @@ -209,7 +213,7 @@ public class LockTaskControllerTest { @Test public void testLockTaskViolation() throws Exception { // GIVEN one task records with whitelisted auth that is in lock task mode // GIVEN one task record with whitelisted auth that is in lock task mode TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); Loading @@ -233,6 +237,38 @@ public class LockTaskControllerTest { TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV))); } @Test public void testLockTaskViolation_emergencyCall() throws Exception { // GIVEN one task record with whitelisted auth that is in lock task mode TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // GIVEN tasks necessary for emergency calling TaskRecord keypad = getTaskRecord(new Intent().setComponent(EMERGENCY_DIALER_COMPONENT), TaskRecord.LOCK_TASK_AUTH_PINNABLE); TaskRecord callAction = getTaskRecord(new Intent(Intent.ACTION_CALL_EMERGENCY), TaskRecord.LOCK_TASK_AUTH_PINNABLE); TaskRecord dialer = getTaskRecord("com.example.dialer", TaskRecord.LOCK_TASK_AUTH_PINNABLE); when(mTelecomManager.getSystemDialerPackage()) .thenReturn(dialer.intent.getComponent().getPackageName()); // GIVEN keyguard is allowed for lock task mode mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_KEYGUARD); // THEN the above tasks should all be allowed assertFalse(mLockTaskController.isLockTaskModeViolation(keypad)); assertFalse(mLockTaskController.isLockTaskModeViolation(callAction)); assertFalse(mLockTaskController.isLockTaskModeViolation(dialer)); // GIVEN keyguard is disallowed for lock task mode (default) mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NONE); // THEN the above tasks should all be blocked assertTrue(mLockTaskController.isLockTaskModeViolation(keypad)); assertTrue(mLockTaskController.isLockTaskModeViolation(callAction)); assertTrue(mLockTaskController.isLockTaskModeViolation(dialer)); } @Test public void testStopLockTaskMode() throws Exception { // GIVEN one task record with whitelisted auth that is in lock task mode Loading Loading @@ -568,10 +604,15 @@ public class LockTaskControllerTest { } private TaskRecord getTaskRecord(String pkg, int lockTaskAuth) { final Intent intent = new Intent() .setComponent(ComponentName.createRelative(pkg, TEST_CLASS_NAME)); return getTaskRecord(intent, lockTaskAuth); } private TaskRecord getTaskRecord(Intent intent, int lockTaskAuth) { TaskRecord tr = mock(TaskRecord.class); tr.mLockTaskAuth = lockTaskAuth; tr.intent = new Intent() .setComponent(ComponentName.createRelative(pkg, TEST_CLASS_NAME)); tr.intent = intent; tr.userId = TEST_USER_ID; return tr; } Loading telecomm/java/android/telecom/TelecomManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -581,6 +581,14 @@ public class TelecomManager { public static final String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT"; /** * The dialer activity responsible for placing emergency calls from, for example, a locked * keyguard. * @hide */ public static final ComponentName EMERGENCY_DIALER_COMPONENT = ComponentName.createRelative("com.android.phone", ".EmergencyDialer"); /** * The following 4 constants define how properties such as phone numbers and names are * displayed to the user. Loading Loading
services/core/java/com/android/server/am/LockTaskController.java +56 −5 Original line number Diff line number Diff line Loading @@ -22,8 +22,10 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Context.DEVICE_POLICY_SERVICE; import static android.content.Context.STATUS_BAR_SERVICE; import static android.content.Intent.ACTION_CALL_EMERGENCY; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_CURRENT; import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; Loading @@ -45,6 +47,7 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Debug; import android.os.Handler; Loading @@ -52,9 +55,11 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.telecom.TelecomManager; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -133,6 +138,8 @@ public class LockTaskController { WindowManagerService mWindowManager; @VisibleForTesting LockPatternUtils mLockPatternUtils; @VisibleForTesting TelecomManager mTelecomManager; /** * Helper that is responsible for showing the right toast when a disallowed activity operation Loading Loading @@ -165,7 +172,7 @@ public class LockTaskController { /** * Features that are allowed by DPC to show during LockTask mode. */ private final SparseArray<Integer> mLockTaskFeatures = new SparseArray<>(); private final SparseIntArray mLockTaskFeatures = new SparseIntArray(); /** * Store the current lock task mode. Possible values: Loading Loading @@ -298,6 +305,11 @@ public class LockTaskController { return false; } // Allow emergency calling when the device is protected by a locked keyguard if (isKeyguardAllowed(task.userId) && isEmergencyCallTask(task)) { return false; } return !(isTaskWhitelisted(task) || mLockTaskModeTasks.isEmpty()); } Loading @@ -306,6 +318,37 @@ public class LockTaskController { & DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS) != 0; } private boolean isKeyguardAllowed(int userId) { return (getLockTaskFeaturesForUser(userId) & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0; } private boolean isEmergencyCallTask(TaskRecord task) { final Intent intent = task.intent; if (intent == null) { return false; } // 1. The emergency keypad activity launched on top of the keyguard if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) { return true; } // 2. The intent sent by the keypad, which is handled by Telephony if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) { return true; } // 3. Telephony then starts the default package for making the call final TelecomManager tm = getTelecomManager(); final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null; if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) { return true; } return false; } /** * Stop the current lock task mode. * Loading Loading @@ -686,11 +729,10 @@ public class LockTaskController { mWindowManager.reenableKeyguard(mToken); } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { int lockTaskFeatures = getLockTaskFeaturesForUser(userId); if ((DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD & lockTaskFeatures) == 0) { mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); } else { if (isKeyguardAllowed(userId)) { mWindowManager.reenableKeyguard(mToken); } else { mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); } } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED Loading Loading @@ -784,6 +826,15 @@ public class LockTaskController { return mLockPatternUtils; } @Nullable private TelecomManager getTelecomManager() { if (mTelecomManager == null) { // We don't preserve the TelecomManager object to save memory return mContext.getSystemService(TelecomManager.class); } return mTelecomManager; } // Should only be called on the handler thread @NonNull private LockTaskNotify getLockTaskNotify() { Loading
services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java +44 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NONE; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS; import static android.os.Process.SYSTEM_UID; import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_PINNED; Loading @@ -53,6 +54,7 @@ import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.telecom.TelecomManager; import android.util.Pair; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -90,6 +92,7 @@ public class LockTaskControllerTest { @Mock private LockPatternUtils mLockPatternUtils; @Mock private LockTaskNotify mLockTaskNotify; @Mock private StatusBarManagerInternal mStatusBarManagerInternal; @Mock private TelecomManager mTelecomManager; @Mock private RecentTasks mRecentTasks; private LockTaskController mLockTaskController; Loading Loading @@ -118,6 +121,7 @@ public class LockTaskControllerTest { mLockTaskController.setWindowManager(mWindowManager); mLockTaskController.mStatusBarService = mStatusBarService; mLockTaskController.mDevicePolicyManager = mDevicePolicyManager; mLockTaskController.mTelecomManager = mTelecomManager; mLockTaskController.mLockPatternUtils = mLockPatternUtils; mLockTaskController.mLockTaskNotify = mLockTaskNotify; Loading Loading @@ -209,7 +213,7 @@ public class LockTaskControllerTest { @Test public void testLockTaskViolation() throws Exception { // GIVEN one task records with whitelisted auth that is in lock task mode // GIVEN one task record with whitelisted auth that is in lock task mode TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); Loading @@ -233,6 +237,38 @@ public class LockTaskControllerTest { TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV))); } @Test public void testLockTaskViolation_emergencyCall() throws Exception { // GIVEN one task record with whitelisted auth that is in lock task mode TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // GIVEN tasks necessary for emergency calling TaskRecord keypad = getTaskRecord(new Intent().setComponent(EMERGENCY_DIALER_COMPONENT), TaskRecord.LOCK_TASK_AUTH_PINNABLE); TaskRecord callAction = getTaskRecord(new Intent(Intent.ACTION_CALL_EMERGENCY), TaskRecord.LOCK_TASK_AUTH_PINNABLE); TaskRecord dialer = getTaskRecord("com.example.dialer", TaskRecord.LOCK_TASK_AUTH_PINNABLE); when(mTelecomManager.getSystemDialerPackage()) .thenReturn(dialer.intent.getComponent().getPackageName()); // GIVEN keyguard is allowed for lock task mode mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_KEYGUARD); // THEN the above tasks should all be allowed assertFalse(mLockTaskController.isLockTaskModeViolation(keypad)); assertFalse(mLockTaskController.isLockTaskModeViolation(callAction)); assertFalse(mLockTaskController.isLockTaskModeViolation(dialer)); // GIVEN keyguard is disallowed for lock task mode (default) mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NONE); // THEN the above tasks should all be blocked assertTrue(mLockTaskController.isLockTaskModeViolation(keypad)); assertTrue(mLockTaskController.isLockTaskModeViolation(callAction)); assertTrue(mLockTaskController.isLockTaskModeViolation(dialer)); } @Test public void testStopLockTaskMode() throws Exception { // GIVEN one task record with whitelisted auth that is in lock task mode Loading Loading @@ -568,10 +604,15 @@ public class LockTaskControllerTest { } private TaskRecord getTaskRecord(String pkg, int lockTaskAuth) { final Intent intent = new Intent() .setComponent(ComponentName.createRelative(pkg, TEST_CLASS_NAME)); return getTaskRecord(intent, lockTaskAuth); } private TaskRecord getTaskRecord(Intent intent, int lockTaskAuth) { TaskRecord tr = mock(TaskRecord.class); tr.mLockTaskAuth = lockTaskAuth; tr.intent = new Intent() .setComponent(ComponentName.createRelative(pkg, TEST_CLASS_NAME)); tr.intent = intent; tr.userId = TEST_USER_ID; return tr; } Loading
telecomm/java/android/telecom/TelecomManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -581,6 +581,14 @@ public class TelecomManager { public static final String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT"; /** * The dialer activity responsible for placing emergency calls from, for example, a locked * keyguard. * @hide */ public static final ComponentName EMERGENCY_DIALER_COMPONENT = ComponentName.createRelative("com.android.phone", ".EmergencyDialer"); /** * The following 4 constants define how properties such as phone numbers and names are * displayed to the user. Loading