Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6798bc30 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enable outgoing emergency calls in LockTask mode."

parents 7d09c01d 858f132e
Loading
Loading
Loading
Loading
+56 −5
Original line number Diff line number Diff line
@@ -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() {
+44 −3
Original line number Diff line number Diff line
@@ -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;
    }
+9 −1
Original line number Diff line number Diff line
@@ -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.