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

Commit 7ae12c70 authored by beanstown106's avatar beanstown106 Committed by Bruno Martins
Browse files

Long-press power while display is off for torch

Squash of:

Author: beanstown106 <nbenis106@gmail.com>
Date:   Sun Jan 17 09:14:19 2016 -0500
    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
    (cherry picked from commit 604f00ce)

Author: Sam Mortimer <sam@mortimer.me.uk>
Date:   Sat Dec 24 13:22:53 2016 -0800
    [1/3] Torch long press power: add auto-off function
    Change-Id: Icdf50082324f8292859f0df8b271e730b02c84e7

Change-Id: I49222892c8fbc8a63af580c763e8987b225b11d2
parent 47d01b14
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -608,6 +608,9 @@
    <!-- Used to launch a common app (FlipFlap) for devices with flip cover. -->
    <!-- Used to launch a common app (FlipFlap) for devices with flip cover. -->
    <protected-broadcast android:name="lineageos.intent.action.LID_STATE_CHANGED" />
    <protected-broadcast android:name="lineageos.intent.action.LID_STATE_CHANGED" />


    <!-- Used for long press power torch feature - automatic turn off on timeout -->
    <protected-broadcast android:name="com.android.server.policy.PhoneWindowManager.ACTION_TORCH_OFF" />

    <!-- ====================================================================== -->
    <!-- ====================================================================== -->
    <!--                          RUNTIME PERMISSIONS                           -->
    <!--                          RUNTIME PERMISSIONS                           -->
    <!-- ====================================================================== -->
    <!-- ====================================================================== -->
+140 −3
Original line number Original line Diff line number Diff line
@@ -157,8 +157,10 @@ import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.SleepToken;
import android.app.ActivityManagerInternal.SleepToken;
import android.app.ActivityThread;
import android.app.ActivityThread;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.app.IUiModeManager;
import android.app.IUiModeManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.app.SearchManager;
import android.app.StatusBarManager;
import android.app.StatusBarManager;
@@ -181,6 +183,9 @@ import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiPlaybackClient;
@@ -344,6 +349,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static final int LONG_PRESS_POWER_SHUT_OFF = 2;
    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_SHUT_OFF_NO_CONFIRM = 3;
    static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
    static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
    static final int LONG_PRESS_POWER_TORCH = 5;


    static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
    static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
    static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
    static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
@@ -414,6 +420,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER =
    private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER =
            "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";
            "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";


    private static final String ACTION_TORCH_OFF =
            "com.android.server.policy.PhoneWindowManager.ACTION_TORCH_OFF";

    /**
    /**
     * Keyguard stuff
     * Keyguard stuff
     */
     */
@@ -478,6 +487,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    AccessibilityManager mAccessibilityManager;
    AccessibilityManager mAccessibilityManager;
    BurnInProtectionHelper mBurnInProtectionHelper;
    BurnInProtectionHelper mBurnInProtectionHelper;
    AppOpsManager mAppOpsManager;
    AppOpsManager mAppOpsManager;
    AlarmManager mAlarmManager;
    private ScreenshotHelper mScreenshotHelper;
    private ScreenshotHelper mScreenshotHelper;
    private boolean mHasFeatureWatch;
    private boolean mHasFeatureWatch;
    private boolean mHasFeatureLeanback;
    private boolean mHasFeatureLeanback;
@@ -775,6 +785,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // Whether to support long press from power button in non-interactive mode
    // Whether to support long press from power button in non-interactive mode
    private boolean mSupportLongPressPowerWhenNonInteractive;
    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
    // Whether to go to sleep entering theater mode from power button
    private boolean mGoToSleepOnButtonPressTheaterMode;
    private boolean mGoToSleepOnButtonPressTheaterMode;


@@ -864,12 +877,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final int MSG_POWER_VERY_LONG_PRESS = 28;
    private static final int MSG_POWER_VERY_LONG_PRESS = 28;
    private static final int MSG_NOTIFY_USER_ACTIVITY = 29;
    private static final int MSG_NOTIFY_USER_ACTIVITY = 29;
    private static final int MSG_RINGER_TOGGLE_CHORD = 30;
    private static final int MSG_RINGER_TOGGLE_CHORD = 30;
    private static final int MSG_TOGGLE_TORCH = 31;


    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;


    private LineageHardwareManager mLineageHardware;
    private LineageHardwareManager mLineageHardware;


    private CameraManager mCameraManager;
    private String mRearFlashCameraId;
    private boolean mTorchLongPressPowerEnabled;
    private boolean mTorchEnabled;
    private int mTorchTimeout;
    private PendingIntent mTorchOffPendingIntent;

    private class PolicyHandler extends Handler {
    private class PolicyHandler extends Handler {
        @Override
        @Override
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
@@ -976,6 +997,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                case MSG_RINGER_TOGGLE_CHORD:
                case MSG_RINGER_TOGGLE_CHORD:
                    handleRingerChordGesture();
                    handleRingerChordGesture();
                    break;
                    break;
                case MSG_TOGGLE_TORCH:
                    toggleTorch();
                    break;
            }
            }
        }
        }
    }
    }
@@ -1044,6 +1068,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            resolver.registerContentObserver(LineageSettings.System.getUriFor(
            resolver.registerContentObserver(LineageSettings.System.getUriFor(
                    LineageSettings.System.ACCELEROMETER_ROTATION_ANGLES), false, this,
                    LineageSettings.System.ACCELEROMETER_ROTATION_ANGLES), false, this,
                    UserHandle.USER_ALL);
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(LineageSettings.System.getUriFor(
                    LineageSettings.System.TORCH_LONG_PRESS_POWER_GESTURE), false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(LineageSettings.System.getUriFor(
                    LineageSettings.System.TORCH_LONG_PRESS_POWER_TIMEOUT), false, this,
                    UserHandle.USER_ALL);


            updateSettings();
            updateSettings();
        }
        }
@@ -1417,6 +1447,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                    if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                        powerLongPress();
                        powerLongPress();
                    } else {
                    } else {
                        mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                        msg.setAsynchronous(true);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageDelayed(msg,
                        mHandler.sendMessageDelayed(msg,
@@ -1430,12 +1461,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    }
                    }
                }
                }
            } else {
            } else {
                wakeUpFromPowerKey(event.getDownTime());

                if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
                if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
                    if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                    if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                        powerLongPress();
                        powerLongPress();
                    } else {
                    } else {
                        mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
                        if (mResolvedLongPressOnPowerBehavior != LONG_PRESS_POWER_TORCH) {
                            wakeUpFromPowerKey(event.getDownTime());
                        }
                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                        msg.setAsynchronous(true);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageDelayed(msg,
                        mHandler.sendMessageDelayed(msg,
@@ -1450,6 +1483,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {


                    mBeganFromNonInteractive = true;
                    mBeganFromNonInteractive = true;
                } else {
                } else {
                    wakeUpFromPowerKey(event.getDownTime());

                    final int maxCount = getMaxMultiPressPowerCount();
                    final int maxCount = getMaxMultiPressPowerCount();


                    if (maxCount <= 1) {
                    if (maxCount <= 1) {
@@ -1504,6 +1539,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (!mPowerKeyHandled) {
        if (!mPowerKeyHandled) {
            mPowerKeyHandled = true;
            mPowerKeyHandled = true;
            mHandler.removeMessages(MSG_POWER_LONG_PRESS);
            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());
            }
        }
        }
        if (hasVeryLongPressOnPowerBehavior()) {
        if (hasVeryLongPressOnPowerBehavior()) {
            mHandler.removeMessages(MSG_POWER_VERY_LONG_PRESS);
            mHandler.removeMessages(MSG_POWER_VERY_LONG_PRESS);
@@ -1630,7 +1669,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }
    }


    private void powerLongPress() {
    private void powerLongPress() {
        final int behavior = getResolvedLongPressOnPowerBehavior();
        final int behavior = mResolvedLongPressOnPowerBehavior;
        switch (behavior) {
        switch (behavior) {
        case LONG_PRESS_POWER_NOTHING:
        case LONG_PRESS_POWER_NOTHING:
            break;
            break;
@@ -1661,6 +1700,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                }
                }
            }
            }
            break;
            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;
        }
        }
    }
    }


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


@@ -2031,6 +2082,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
        mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
        mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
        mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
        mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
        mAccessibilityShortcutController =
        mAccessibilityShortcutController =
@@ -2072,6 +2124,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
        }


        mHandler = new PolicyHandler();
        mHandler = new PolicyHandler();
        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        mCameraManager.registerTorchCallback(new TorchModeCallback(), mHandler);
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mOrientationListener = new MyOrientationListener(mContext, mHandler);
        mOrientationListener = new MyOrientationListener(mContext, mHandler);
        try {
        try {
@@ -2348,6 +2402,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            }
            }
        }
        }
        if (DEBUG) Slog.d(TAG, "" + mDeviceKeyHandlers.size() + " device key handlers loaded");
        if (DEBUG) Slog.d(TAG, "" + mDeviceKeyHandlers.size() + " device key handlers loaded");

        // Register for torch off events
        BroadcastReceiver torchReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mTorchOffPendingIntent = null;
                if (mTorchEnabled) {
                    mHandler.removeMessages(MSG_TOGGLE_TORCH);
                    Message msg = mHandler.obtainMessage(MSG_TOGGLE_TORCH);
                    msg.setAsynchronous(true);
                    msg.sendToTarget();
                }
            }
        };
        filter = new IntentFilter();
        filter.addAction(ACTION_TORCH_OFF);
        context.registerReceiver(torchReceiver, filter);
    }
    }


    /**
    /**
@@ -2525,6 +2596,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                updateOrientationListenerLp(); // Enable, disable the orientation listener
                updateOrientationListenerLp(); // Enable, disable the orientation listener
            }
            }


            mTorchLongPressPowerEnabled = LineageSettings.System.getIntForUser(
                    resolver, LineageSettings.System.TORCH_LONG_PRESS_POWER_GESTURE, 0,
                    UserHandle.USER_CURRENT) == 1;
            mTorchTimeout = LineageSettings.System.getIntForUser(
                    resolver, LineageSettings.System.TORCH_LONG_PRESS_POWER_TIMEOUT, 0,
                    UserHandle.USER_CURRENT);

            // Configure wake gesture.
            // Configure wake gesture.
            boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
            boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
                    Settings.Secure.WAKE_GESTURE_ENABLED, 0,
                    Settings.Secure.WAKE_GESTURE_ENABLED, 0,
@@ -8962,6 +9040,65 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + "  ");
        mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + "  ");
    }
    }


    private void cancelTorchOff() {
        if (mTorchOffPendingIntent != null) {
            mAlarmManager.cancel(mTorchOffPendingIntent);
            mTorchOffPendingIntent = null;
        }
    }
     private void toggleTorch() {
        cancelTorchOff();
        final boolean origEnabled = mTorchEnabled;
        try {
            final String rearFlashCameraId = getRearFlashCameraId();
            if (rearFlashCameraId != null) {
                mCameraManager.setTorchMode(rearFlashCameraId, !mTorchEnabled);
                mTorchEnabled = !mTorchEnabled;
            }
        } catch (CameraAccessException e) {
            // Ignore
        }
        // Setup torch off alarm
        if (mTorchEnabled && !origEnabled && mTorchTimeout > 0) {
            Intent torchOff = new Intent(ACTION_TORCH_OFF);
            torchOff.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                    | Intent.FLAG_RECEIVER_FOREGROUND);
            mTorchOffPendingIntent = PendingIntent.getBroadcast(mContext, 0, torchOff, 0);
            mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    SystemClock.elapsedRealtime() + mTorchTimeout * 1000, mTorchOffPendingIntent);
        }
    }
     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);
            Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
            if (flashAvailable != null && flashAvailable
                    && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                mRearFlashCameraId = id;
                break;
            }
        }
        return mRearFlashCameraId;
    }
     private class TorchModeCallback extends CameraManager.TorchCallback {
        @Override
        public void onTorchModeChanged(String cameraId, boolean enabled) {
            if (!cameraId.equals(mRearFlashCameraId)) return;
            mTorchEnabled = enabled;
            if (!mTorchEnabled) {
                cancelTorchOff();
            }
        }
         @Override
        public void onTorchModeUnavailable(String cameraId) {
            if (!cameraId.equals(mRearFlashCameraId)) return;
            mTorchEnabled = false;
            cancelTorchOff();
        }
    }

    private static String allowAllRotationsToString(int allowAll) {
    private static String allowAllRotationsToString(int allowAll) {
        switch (allowAll) {
        switch (allowAll) {
            case -1:
            case -1: