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

Commit 3cfdccaf authored by Danesh M's avatar Danesh M Committed by Michael Bestas
Browse files

Camera: allow camera to use power key as shutter



Provides a way for an app to take control of the power key.
Used by the camera to make the power key control the shutter.

Change-Id: I85a1e1761199f4604672be42a3a5005227f5451a
(cherry picked from commit 15661444)

Prevent power key capture when screen is off

The ability for an activity to capture the power key, which was
added to support power key as shutter in the camera, should only
allow the capture when the screen is on. Otherwise, if an activity
that captures the power key is to the front when the device turns
off, the user will be unable to turn it back on.

Change-Id: Ib119d6914ec72554b404c1cc17eef3a932d5d402

PhoneWindowManager: add mTopFullscreenOpaqueWindowState null check to fix exception

Discovered through extensive testing with double press power for camera combined
with long press power for torch (though these features are not required to
trigger the issue), lack of null check here can occasionally result in either of:

1) screen is off, power press will NOT turn the screen on (needs to be woken
   via fingerprint, power cable connect or leave device for a minute or
   so and it will eventually wake on power press again).
OR
2) screen is on, power press will not turn the screen off

It requires pressing power shortly after screen off or screen on at just
the right time to trigger.  Issue is reproducible on angler.

E InputManager-JNI: An exception was thrown by callback 'interceptKeyBeforeQueueing'.
E InputManager-JNI: java.lang.NullPointerException: Attempt to invoke interface method
 'android.view.WindowManager$LayoutParams android.view.WindowManagerPolicy$WindowState.getAttrs()'
on a null object reference
E InputManager-JNI:      at com.android.server.policy.PhoneWindowManager.interceptKeyBeforeQueueing(PhoneWindowManager.java:6647)
E InputManager-JNI:      at com.android.server.wm.InputMonitor.interceptKeyBeforeQueueing(InputMonitor.java:399)
E InputManager-JNI:      at com.android.server.input.InputManagerService.interceptKeyBeforeQueueing(InputManagerService.java:1979)

Change-Id: I77d094130d58b152fdfa515f53661543976b33bf
(cherry picked from commit dc0c974e)

core: Update PREVENT_POWER_KEY permission for M

Change-Id: Iac053a317314fad08545c8dc411ad44f977b8f3e

WindowManager: Add clearPrivateFlags

[mikeioannina]: Refactor for Q

Squashed with the following:

Author: Alexander Martinz <amartinz@shiftphones.com>
Date:   Thu Apr 23 13:06:34 2020 +0200

    Camera: Rename prevent power key permission

    * We must not use the "android" namespace or CTS fails.

    Change-Id: I034216efe5d472b0bc72cd293001b518f92aec41
    Signed-off-by: Alexander Martinz's avatarAlexander Martinz <amartinz@shiftphones.com>

Change-Id: I0b51a52bf26f3566e74063e22f5c1b187c74b525
parent e31f2106
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1166,6 +1166,11 @@ public abstract class Window {
        setFlags(0, flags);
    }

    /** @hide */
    public void clearPrivateFlags(int flags) {
        setPrivateFlags(0, flags);
    }

    /**
     * Set the flags of the window, as per the
     * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
@@ -1193,6 +1198,10 @@ public abstract class Window {
    }

    private void setPrivateFlags(int flags, int mask) {
        if ((flags & mask & WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY) != 0) {
            mContext.enforceCallingOrSelfPermission("lineage.permission.PREVENT_POWER_KEY",
                    "No permission to prevent power key");
        }
        final WindowManager.LayoutParams attrs = getAttributes();
        attrs.privateFlags = (attrs.privateFlags & ~mask) | (flags & mask);
        dispatchWindowAttributesChanged(attrs);
+6 −0
Original line number Diff line number Diff line
@@ -2032,6 +2032,12 @@ public interface WindowManager extends ViewManager {
         */
        public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x10000000;

        /**
         * Window flag: Overrides default power key behavior
         * @hide
         */
        public static final int PRIVATE_FLAG_PREVENT_POWER_KEY = 0x20000000;

        /**
         * An internal annotation for flags that can be specified to {@link #softInputMode}.
         *
+8 −0
Original line number Diff line number Diff line
@@ -5045,6 +5045,14 @@
    <permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
                android:protectionLevel="signature|appPredictor" />

    <!-- LineageOS additions -->

    <!-- Allows an application to override the power key action
         @hide <p>Not for use by third-party applications.
    -->
    <permission android:name="lineage.permission.PREVENT_POWER_KEY"
                android:protectionLevel="signature|privileged" />

    <!-- Attribution for Country Detector. -->
    <attribution android:tag="CountryDetector" android:label="@string/country_detector"/>
    <!-- Attribution for Location service. -->
+5 −0
Original line number Diff line number Diff line
@@ -4412,6 +4412,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                EventLogTags.writeInterceptPower(
                        KeyEvent.actionToString(event.getAction()),
                        mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
                if ((mDefaultDisplayPolicy.getTopFullscreenOpaqueWindowStatePrivateFlags()
                                & WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY) != 0
                        && mDefaultDisplayPolicy.isScreenOnFully()) {
                    return result;
                }
                // Any activity on the power button stops the accessibility shortcut
                cancelPendingAccessibilityShortcutAction();
                result &= ~ACTION_PASS_TO_USER;
+5 −0
Original line number Diff line number Diff line
@@ -797,6 +797,11 @@ public class DisplayPolicy {
        return mScreenOnListener;
    }

    public int getTopFullscreenOpaqueWindowStatePrivateFlags() {
        return mTopFullscreenOpaqueWindowState != null ?
                mTopFullscreenOpaqueWindowState.getAttrs().privateFlags : 0;
    }

    public void screenTurnedOn(ScreenOnListener screenOnListener) {
        synchronized (mLock) {
            mScreenOnEarly = true;