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

Commit 604f00ce authored by beanstown106's avatar beanstown106 Committed by Rashed Abdel-Tawab
Browse files

policy: Long-press power while display is off for torch

Long-press the power button while the display is off
to turn the torchlight on and off.

Credits:
 - Lion0738: The main hooks here:
   https://github.com/lion0738/android_frameworks_base/commit/9af2b7844a4d973c8b6c542d7937f56a24a7e5f1
 - Atlantis: The logic on where to hook into this for power button only
 - Alex Cruz: Helping and giving me some pointers along the way

Change-Id: I14365389990eb06daaa127f5db66df45abf6c064
parent 1b730029
Loading
Loading
Loading
Loading
+84 −3
Original line number Diff line number Diff line
@@ -69,6 +69,9 @@ import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
@@ -209,6 +212,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
    static final int LONG_PRESS_POWER_SHUT_OFF = 2;
    static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
    static final int LONG_PRESS_POWER_TORCH = 4;

    static final int LONG_PRESS_BACK_NOTHING = 0;
    static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1;
@@ -786,6 +790,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // Whether to support long press from power button in non-interactive mode
    private boolean mSupportLongPressPowerWhenNonInteractive;

    // Power long press action saved on key down that should happen on key up
    private int mResolvedLongPressOnPowerBehavior;

    // Whether to go to sleep entering theater mode from power button
    private boolean mGoToSleepOnButtonPressTheaterMode;

@@ -847,6 +854,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final int MSG_DISPOSE_INPUT_CONSUMER = 19;
    private static final int MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK = 20;
    private static final int MSG_CAMERA_LONG_PRESS = 21;
    private static final int MSG_TOGGLE_TORCH = 22;

    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -859,6 +867,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    private boolean mVolumeAnswerCall;

    private CameraManager mCameraManager;
    private String mRearFlashCameraId;
    private boolean mTorchLongPressPowerEnabled;
    private boolean mTorchEnabled;

    private class PolicyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
@@ -938,6 +951,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    mIsLongPress = true;
                    break;
                }
                case MSG_TOGGLE_TORCH: {
                    try {
                        final String rearFlashCameraId = getRearFlashCameraId();
                        if (rearFlashCameraId != null) {
                            mCameraManager.setTorchMode(rearFlashCameraId, !mTorchEnabled);
                            mTorchEnabled = !mTorchEnabled;
                        }
                    } catch (CameraAccessException e) {
                        // Ignore
                    }
                    break;
                }
            }
        }
    }
@@ -966,6 +991,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            resolver.registerContentObserver(CMSettings.Secure.getUriFor(
                    CMSettings.Secure.RING_HOME_BUTTON_BEHAVIOR), false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(CMSettings.System.getUriFor(
                    CMSettings.System.TORCH_LONG_PRESS_POWER_GESTURE), false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
                    UserHandle.USER_ALL);
@@ -1292,21 +1320,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                // When interactive, we're already awake.
                // Wait for a long press or for the button to be released to decide what to do.
                if (hasLongPressOnPowerBehavior()) {
                    mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
                    Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageDelayed(msg,
                            ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
                }
            } else {
                wakeUpFromPowerKey(event.getDownTime());

                if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
                    mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
                    if (mResolvedLongPressOnPowerBehavior != LONG_PRESS_POWER_TORCH) {
                        wakeUpFromPowerKey(event.getDownTime());
                    }
                    Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageDelayed(msg,
                            ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
                    mBeganFromNonInteractive = true;
                } else {
                    wakeUpFromPowerKey(event.getDownTime());

                    final int maxCount = getMaxMultiPressPowerCount();

                    if (maxCount <= 1) {
@@ -1361,6 +1394,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (!mPowerKeyHandled) {
            mPowerKeyHandled = true;
            mHandler.removeMessages(MSG_POWER_LONG_PRESS);
            // See if we deferred screen wake because long press power for torch is enabled
            if (mResolvedLongPressOnPowerBehavior == LONG_PRESS_POWER_TORCH && !isScreenOn()) {
                wakeUpFromPowerKey(SystemClock.uptimeMillis());
            }
        }
    }

@@ -1457,7 +1494,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    private void powerLongPress() {
        final int behavior = getResolvedLongPressOnPowerBehavior();
        final int behavior = mResolvedLongPressOnPowerBehavior;
        switch (behavior) {
        case LONG_PRESS_POWER_NOTHING:
            break;
@@ -1475,6 +1512,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
            mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
            break;
        case LONG_PRESS_POWER_TORCH:
            mPowerKeyHandled = true;
            // Toggle torch state asynchronously to help protect against
            // a misbehaving cameraservice from blocking systemui.
            mHandler.removeMessages(MSG_TOGGLE_TORCH);
            Message msg = mHandler.obtainMessage(MSG_TOGGLE_TORCH);
            msg.setAsynchronous(true);
            msg.sendToTarget();
            break;
        }
    }

@@ -1518,6 +1564,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (FactoryTest.isLongPressOnPowerOffEnabled()) {
            return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
        }
        if (mTorchLongPressPowerEnabled && !isScreenOn()) {
            return LONG_PRESS_POWER_TORCH;
        }
        return mLongPressOnPowerBehavior;
    }

@@ -1816,6 +1865,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        mHandler = new PolicyHandler();
        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        mCameraManager.registerTorchCallback(new TorchModeCallback(), mHandler);
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mOrientationListener = new MyOrientationListener(mContext, mHandler);
        try {
@@ -2283,6 +2334,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    CMSettings.Secure.RING_HOME_BUTTON_BEHAVIOR,
                    CMSettings.Secure.RING_HOME_BUTTON_BEHAVIOR_DEFAULT,
                    UserHandle.USER_CURRENT);
            mTorchLongPressPowerEnabled = CMSettings.System.getIntForUser(
                    resolver, CMSettings.System.TORCH_LONG_PRESS_POWER_GESTURE, 0,
                    UserHandle.USER_CURRENT) == 1;
            mHomeWakeScreen = (CMSettings.System.getIntForUser(resolver,
                    CMSettings.System.HOME_WAKE_SCREEN, 1, UserHandle.USER_CURRENT) == 1) &&
                    ((mDeviceHardwareWakeKeys & KEY_MASK_HOME) != 0);
@@ -8928,4 +8982,31 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            mKeyguardDelegate.dump(prefix, pw);
        }
    }

    private String getRearFlashCameraId() throws CameraAccessException {
        if (mRearFlashCameraId != null) return mRearFlashCameraId;
        for (final String id : mCameraManager.getCameraIdList()) {
            CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);
            boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
            int lensDirection = c.get(CameraCharacteristics.LENS_FACING);
            if (flashAvailable && lensDirection == CameraCharacteristics.LENS_FACING_BACK) {
                mRearFlashCameraId = id;
            }
        }
        return mRearFlashCameraId;
    }

    private class TorchModeCallback extends CameraManager.TorchCallback {
        @Override
        public void onTorchModeChanged(String cameraId, boolean enabled) {
            if (!cameraId.equals(mRearFlashCameraId)) return;
            mTorchEnabled = enabled;
        }

        @Override
        public void onTorchModeUnavailable(String cameraId) {
            if (!cameraId.equals(mRearFlashCameraId)) return;
            mTorchEnabled = false;
        }
    }
}