Merge "Enable outgoing emergency calls in LockTask mode."

This commit is contained in:
TreeHugger Robot
2017-12-06 18:06:44 +00:00
committed by Android (Google) Code Review
3 changed files with 109 additions and 9 deletions

View File

@@ -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() {

View File

@@ -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;
}

View File

@@ -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;
/**