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

Commit 5d0e02b6 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Add double-tap power button to open camera 1/2" into mnc-dr-dev

parents 2ebbf4c8 5941c98c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -5718,6 +5718,15 @@ public final class Settings {
         */
        public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";

        /**
         * Whether the camera launch gesture to double tap the power button when the screen is off
         * should be disabled.
         *
         * @hide
         */
        public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
                "camera_double_tap_power_gesture_disabled";

        /**
         * This are the settings to be backed up.
         *
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ public class MetricsLogger implements MetricsConstants {
    public static final int ACTION_FINGERPRINT_AUTH = 252;
    public static final int ACTION_FINGERPRINT_DELETE = 253;
    public static final int ACTION_FINGERPRINT_RENAME = 254;
    public static final int ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
    public static final int ACTION_WIGGLE_CAMERA_GESTURE = 256;

    public static void visible(Context context, int category) throws IllegalArgumentException {
        if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
+4 −0
Original line number Diff line number Diff line
@@ -2290,4 +2290,8 @@
    <!-- The OEM specified sensor string type for the gesture to launch camera app, this value
         must match the value of config_cameraLaunchGestureSensorType in OEM's HAL -->
    <string translatable="false" name="config_cameraLaunchGestureSensorStringType"></string>

    <!-- Allow the gesture to double tap the power button twice to start the camera while the device
         is non-interactive. -->
    <bool name="config_cameraDoubleTapPowerGestureEnabled">true</bool>
</resources>
+1 −0
Original line number Diff line number Diff line
@@ -2323,6 +2323,7 @@
  <!-- Gesture -->
  <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
  <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
  <java-symbol type="bool" name="config_cameraDoubleTapPowerGestureEnabled" />

  <java-symbol type="drawable" name="platlogo_m" />
</resources>
+102 −38
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server;

import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -33,10 +32,11 @@ import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.Slog;
import android.view.KeyEvent;

import com.android.internal.logging.MetricsLogger;
import com.android.server.statusbar.StatusBarManagerInternal;

/**
@@ -46,10 +46,16 @@ import com.android.server.statusbar.StatusBarManagerInternal;
 * added.</p>
 * @hide
 */
class GestureLauncherService extends SystemService {
public class GestureLauncherService extends SystemService {
    private static final boolean DBG = false;
    private static final String TAG = "GestureLauncherService";

    /**
     * Time in milliseconds in which the power button must be pressed twice so it will be considered
     * as a camera launch.
     */
    private static final long CAMERA_POWER_DOUBLE_TAP_TIME_MS = 300;

    /** The listener that receives the gesture event. */
    private final GestureEventListener mGestureListener = new GestureEventListener();

@@ -91,13 +97,20 @@ class GestureLauncherService extends SystemService {
     */
    private int mCameraLaunchLastEventExtra = 0;

    /**
     * Whether camera double tap power button gesture is currently enabled;
     */
    private boolean mCameraDoubleTapPowerEnabled;
    private long mLastPowerDownWhileNonInteractive = 0;


    public GestureLauncherService(Context context) {
        super(context);
        mContext = context;
    }

    public void onStart() {
        // Nothing to publish.
        LocalServices.addService(GestureLauncherService.class, this);
    }

    public void onBootPhase(int phase) {
@@ -113,17 +126,21 @@ class GestureLauncherService extends SystemService {
            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "GestureLauncherService");
            updateCameraRegistered();
            updateCameraDoubleTapPowerEnabled();

            mUserId = ActivityManager.getCurrentUser();
            mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));
            registerContentObserver();
            registerContentObservers();
        }
    }

    private void registerContentObserver() {
    private void registerContentObservers() {
        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.CAMERA_GESTURE_DISABLED),
                false, mSettingObserver, mUserId);
        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED),
                false, mSettingObserver, mUserId);
    }

    private void updateCameraRegistered() {
@@ -135,6 +152,13 @@ class GestureLauncherService extends SystemService {
        }
    }

    private void updateCameraDoubleTapPowerEnabled() {
        boolean enabled = isCameraDoubleTapPowerSettingEnabled(mContext, mUserId);
        synchronized (this) {
            mCameraDoubleTapPowerEnabled = enabled;
        }
    }

    private void unregisterCameraLaunchGesture() {
        if (mRegistered) {
            mRegistered = false;
@@ -197,6 +221,12 @@ class GestureLauncherService extends SystemService {
                        Settings.Secure.CAMERA_GESTURE_DISABLED, 0, userId) == 0);
    }

    public static boolean isCameraDoubleTapPowerSettingEnabled(Context context, int userId) {
        return isCameraDoubleTapPowerEnabled(context.getResources())
                && (Settings.Secure.getIntForUser(context.getContentResolver(),
                        Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
    }

    /**
     * Whether to enable the camera launch gesture.
     */
@@ -207,13 +237,64 @@ class GestureLauncherService extends SystemService {
                !SystemProperties.getBoolean("gesture.disable_camera_launch", false);
    }

    public static boolean isCameraDoubleTapPowerEnabled(Resources resources) {
        return resources.getBoolean(
                com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled);
    }

    /**
     * Whether GestureLauncherService should be enabled according to system properties.
     */
    public static boolean isGestureLauncherEnabled(Resources resources) {
        // For now, the only supported gesture is camera launch gesture, so whether to enable this
        // service equals to isCameraLaunchEnabled();
        return isCameraLaunchEnabled(resources);
        return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources);
    }

    public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) {
        boolean launched = false;
        synchronized (this) {
            if (!mCameraDoubleTapPowerEnabled) {
                mLastPowerDownWhileNonInteractive = 0;
                return false;
            }
            if (event.getEventTime() - mLastPowerDownWhileNonInteractive
                    < CAMERA_POWER_DOUBLE_TAP_TIME_MS) {
                launched = true;
            }
            mLastPowerDownWhileNonInteractive = interactive ? 0 : event.getEventTime();
        }
        if (launched) {
            Slog.i(TAG, "Power button double tap gesture detected, launching camera.");
            launched = handleCameraLaunchGesture(false /* useWakelock */,
                    MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE);
        }
        return launched;
    }

    /**
     * @return true if camera was launched, false otherwise.
     */
    private boolean handleCameraLaunchGesture(boolean useWakelock, int logCategory) {
        boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
        if (!userSetupComplete) {
            if (DBG) Slog.d(TAG, String.format(
                    "userSetupComplete = %s, ignoring camera launch gesture.",
                    userSetupComplete));
            return false;
        }
        if (DBG) Slog.d(TAG, String.format(
                "userSetupComplete = %s, performing camera launch gesture.",
                userSetupComplete));

        if (useWakelock) {
            // Make sure we don't sleep too early
            mWakeLock.acquire(500L);
        }
        StatusBarManagerInternal service = LocalServices.getService(
                StatusBarManagerInternal.class);
        service.onCameraLaunchGestureDetected();
        MetricsLogger.action(mContext, logCategory);
        return true;
    }

    private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
@@ -222,8 +303,9 @@ class GestureLauncherService extends SystemService {
            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
                registerContentObserver();
                registerContentObservers();
                updateCameraRegistered();
                updateCameraDoubleTapPowerEnabled();
            }
        }
    };
@@ -232,6 +314,7 @@ class GestureLauncherService extends SystemService {
        public void onChange(boolean selfChange, android.net.Uri uri, int userId) {
            if (userId == mUserId) {
                updateCameraRegistered();
                updateCameraDoubleTapPowerEnabled();
            }
        }
    };
@@ -244,36 +327,17 @@ class GestureLauncherService extends SystemService {
              return;
            }
            if (event.sensor == mCameraLaunchSensor) {
                handleCameraLaunchGesture(event);
                return;
            }
        }

        private void handleCameraLaunchGesture(SensorEvent event) {
                if (DBG) {
                    float[] values = event.values;
                    Slog.d(TAG, String.format("Received a camera launch event: " +
                            "values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2]));
                }
            boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
            if (!userSetupComplete) {
                if (DBG) Slog.d(TAG, String.format(
                        "userSetupComplete = %s, ignoring camera launch gesture.",
                        userSetupComplete));
                if (handleCameraLaunchGesture(true /* useWakelock */,
                        MetricsLogger.ACTION_WIGGLE_CAMERA_GESTURE)) {
                    trackCameraLaunchEvent(event);
                }
                return;
            }
            if (DBG) Slog.d(TAG, String.format(
                    "userSetupComplete = %s, performing camera launch gesture.",
                    userSetupComplete));

            // Make sure we don't sleep too early
            mWakeLock.acquire(500L);
            StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.onCameraLaunchGestureDetected();
            trackCameraLaunchEvent(event);
            mWakeLock.release();
        }

        @Override
Loading