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

Commit 81d8e8c8 authored by Ariel Goh's avatar Ariel Goh Committed by Justin Chung
Browse files

Add a new button behavior for STEM short press

Launch a targetted activity on short stem primary button press

Test: atest StemKeyGestureTests
Change-Id: Icc017cd8bb054565aac54980d59c216376514c1b
(cherry picked from commit 05e605c55d7eae414f70ef0749a159a747166c8a)
parent 7d5bab13
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -1211,9 +1211,12 @@
        a watch, setting this config is no-op.
           0 - Nothing
           1 - Go to launch all apps
           2 - Launch target activity defined by config_primaryShortPressTargetActivity if available
    -->
    <integer name="config_shortPressOnStemPrimaryBehavior">0</integer>

   <!-- Activity name for the default target activity to be launched. [DO NOT TRANSLATE] -->
   <string name="config_primaryShortPressTargetActivity" translatable="false"></string>

    <!-- Control the behavior of the search key.
            0 - Launch default search activity
+1 −0
Original line number Diff line number Diff line
@@ -466,6 +466,7 @@
  <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
  <java-symbol type="integer" name="config_longPressOnStemPrimaryBehavior" />
  <java-symbol type="integer" name="config_shortPressOnStemPrimaryBehavior" />
  <java-symbol type="string" name="config_primaryShortPressTargetActivity" />
  <java-symbol type="integer" name="config_doublePressOnStemPrimaryBehavior" />
  <java-symbol type="integer" name="config_triplePressOnStemPrimaryBehavior" />
  <java-symbol type="string" name="config_doublePressOnPowerTargetActivity" />
+56 −12
Original line number Diff line number Diff line
@@ -208,7 +208,6 @@ import com.android.internal.policy.LogDecelerateInterpolator;
import com.android.internal.policy.PhoneWindow;
import com.android.internal.policy.TransitionAnimation;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.AccessibilityManagerInternal;
import com.android.server.ExtconStateObserver;
@@ -339,6 +338,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS
    static final int SHORT_PRESS_PRIMARY_NOTHING = 0;
    static final int SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS = 1;
    static final int SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY = 2;

    // Must match: config_longPressOnStemPrimaryBehavior in config.xml
    // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS
@@ -610,6 +610,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // What we do when the user double-taps on home
    private int mDoubleTapOnHomeBehavior;

    // Must match config_primaryShortPressTargetActivity in config.xml
    ComponentName mPrimaryShortPressTargetActivity;

    // Whether to lock the device after the next dreaming transition has finished.
    private boolean mLockAfterDreamingTransitionFinished;

@@ -1415,23 +1418,59 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    private void stemPrimarySinglePressAction(int behavior) {
        if (DEBUG_INPUT) {
            Slog.d(TAG, "stemPrimarySinglePressAction: behavior=" + behavior);
        }
        if (behavior == SHORT_PRESS_PRIMARY_NOTHING) return;

        final boolean keyguardActive = mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
        if (keyguardActive) {
            // If keyguarded then notify the keyguard.
            mKeyguardDelegate.onSystemKeyPressed(KeyEvent.KEYCODE_STEM_PRIMARY);
            return;
        }
        switch (behavior) {
            case SHORT_PRESS_PRIMARY_NOTHING:
                break;
            case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS:
                if (DEBUG_INPUT) {
                    Slog.d(TAG, "Executing stem primary short press action behavior.");
                }
                final boolean keyguardActive =
                        mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
                if (!keyguardActive) {
                    Intent intent = new Intent(Intent.ACTION_ALL_APPS);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
                allAppsIntent.addFlags(
                        Intent.FLAG_ACTIVITY_NEW_TASK
                                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                    startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
                startActivityAsUser(allAppsIntent, UserHandle.CURRENT_OR_SELF);
                break;
            case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY:
                if (DEBUG_INPUT) {
                    Slog.d(
                            TAG,
                            "Executing stem primary short press action behavior for launching "
                                    + "target activity.");
                }
                if (mPrimaryShortPressTargetActivity != null) {
                    Intent targetActivityIntent = new Intent();
                    targetActivityIntent.setComponent(mPrimaryShortPressTargetActivity);
                    ResolveInfo resolveInfo =
                            mContext.getPackageManager()
                                    .resolveActivity(targetActivityIntent, /* flags= */ 0);
                    if (resolveInfo != null) {
                        targetActivityIntent.addFlags(
                                Intent.FLAG_ACTIVITY_NEW_TASK
                                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                                        | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
                        startActivityAsUser(targetActivityIntent, UserHandle.CURRENT_OR_SELF);
                    } else {
                    // If keyguarded then notify the keyguard.
                    mKeyguardDelegate.onSystemKeyPressed(KeyEvent.KEYCODE_STEM_PRIMARY);
                        Slog.wtf(
                                TAG,
                                "Could not resolve activity with : "
                                        + mPrimaryShortPressTargetActivity.flattenToString()
                                        + " name.");
                    }
                } else {
                    Slog.wtf(
                            TAG,
                            "mPrimaryShortPressTargetActivity must not be null and correctly"
                                + " specified");
                }
                break;
        }
@@ -2244,6 +2283,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mPowerDoublePressTargetActivity = ComponentName.unflattenFromString(
            mContext.getResources().getString(
                com.android.internal.R.string.config_doublePressOnPowerTargetActivity));
        mPrimaryShortPressTargetActivity = ComponentName.unflattenFromString(
            mContext.getResources().getString(
                com.android.internal.R.string.config_primaryShortPressTargetActivity));
        mShortPressOnSleepBehavior = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_shortPressOnSleepBehavior);
        mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
@@ -6417,6 +6459,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                return "SHORT_PRESS_PRIMARY_NOTHING";
            case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS:
                return "SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS";
            case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY:
                return "SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY";
            default:
                return Integer.toString(behavior);
        }
+27 −0
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import static android.provider.Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS;
import static android.view.KeyEvent.KEYCODE_STEM_PRIMARY;

import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY;

import android.content.ComponentName;
import android.provider.Settings;

import org.junit.Test;
@@ -32,6 +34,9 @@ import org.junit.Test;
 * atest WmTests:StemKeyGestureTests
 */
public class StemKeyGestureTests extends ShortcutKeyTestBase {

    private static final String TEST_TARGET_ACTIVITY = "com.android.server.policy/.TestActivity";

    /**
     * Stem single key should not launch behavior during set up.
     */
@@ -63,6 +68,28 @@ public class StemKeyGestureTests extends ShortcutKeyTestBase {
        mPhoneWindowManager.assertOpenAllAppView();
    }

    /**
     * Stem single key should not launch behavior during set up.
     */
    @Test
    public void stemSingleKey_launchTargetActivity() {
        overrideBehavior(
                STEM_PRIMARY_BUTTON_SHORT_PRESS,
                SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY);
        setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
        mPhoneWindowManager.overrideStartActivity();
        mPhoneWindowManager.setKeyguardServiceDelegateIsShowing(false);
        mPhoneWindowManager.overrideIsUserSetupComplete(true);
        mPhoneWindowManager.assumeResolveActivityNotNull();

        ComponentName targetComponent = ComponentName.unflattenFromString(TEST_TARGET_ACTIVITY);
        mPhoneWindowManager.overrideStemPressTargetActivity(targetComponent);

        sendKey(KEYCODE_STEM_PRIMARY);

        mPhoneWindowManager.assertActivityTargetLaunched(targetComponent);
    }

    private void overrideBehavior(String key, int expectedBehavior) {
        Settings.Global.putLong(mContext.getContentResolver(), key, expectedBehavior);
    }
+20 −0
Original line number Diff line number Diff line
@@ -59,9 +59,11 @@ import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.hardware.SensorPrivacyManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
@@ -433,6 +435,12 @@ class TestPhoneWindowManager {
        doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing();
    }

    void assumeResolveActivityNotNull() {
        ResolveInfo resolveInfo = new ResolveInfo();
        doReturn(resolveInfo).when(mPackageManager).resolveActivity(any(), anyInt());
        doReturn(mPackageManager).when(mContext).getPackageManager();
    }

    void overrideKeyEventSource(int vendorId, int productId) {
        InputDevice device = new InputDevice.Builder().setId(1).setVendorId(vendorId).setProductId(
                productId).setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType(
@@ -458,6 +466,10 @@ class TestPhoneWindowManager {
        doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
    }

    void overrideStemPressTargetActivity(ComponentName component) {
        mPhoneWindowManager.mPrimaryShortPressTargetActivity = component;
    }

    /**
     * Below functions will check the policy behavior could be invoked.
     */
@@ -613,6 +625,14 @@ class TestPhoneWindowManager {
                .startActivityAsUser(any(Intent.class), any(), any(UserHandle.class));
    }

    void assertActivityTargetLaunched(ComponentName targetActivity) {
        waitForIdle();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
                .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
        Assert.assertEquals(targetActivity, intentCaptor.getValue().getComponent());
    }

    void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
            int expectedKey, int expectedModifierState, String errorMsg) {
        waitForIdle();