Merge "Enable outgoing emergency calls in LockTask mode."
This commit is contained in:
committed by
Android (Google) Code Review
commit
6798bc300e
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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:
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -588,7 +596,7 @@ public class TelecomManager {
|
||||
|
||||
/**
|
||||
* Indicates that the address or number of a call is allowed to be displayed for caller ID.
|
||||
*/
|
||||
*/
|
||||
public static final int PRESENTATION_ALLOWED = 1;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user