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

Commit 3ca78699 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Initial sleep-lock-screen implementation"

parents 73d3d815 1ae6cf91
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -11,13 +11,12 @@
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 * limitations under the License.
 */

package com.android.systemui.plugins;

import android.hardware.Sensor;
import android.hardware.TriggerEventListener;
import android.hardware.SensorListener;

import com.android.systemui.plugins.annotations.ProvidesInterface;

@@ -31,26 +30,30 @@ public interface SensorManagerPlugin extends Plugin {
    int VERSION = 1;

    /**
     * Registers for trigger events from the sensor. Trigger events are one-shot and need to
     * re-registered in order for them to be fired again.
     * Registers for sensor events. Events will be sent until the listener is unregistered.
     * @param sensor
     * @param listener
     * @see android.hardware.SensorManager#requestTriggerSensor(
     *     android.hardware.TriggerEventListener, android.hardware.Sensor)
     * @see android.hardware.SensorManager#registerListener(SensorListener, int)
     */
    void registerTriggerEvent(Sensor sensor, TriggerEventListener listener);
    void registerListener(Sensor sensor, SensorEventListener listener);

    /**
     * Unregisters trigger events from the sensor.
     * Unregisters events from the sensor.
     * @param sensor
     * @param listener
     */
    void unregisterTriggerEvent(Sensor sensor, TriggerEventListener listener);
    void unregisterListener(Sensor sensor, SensorEventListener listener);

    interface TriggerEventListener {
        void onTrigger(TriggerEvent event);
    /**
     * Listener triggered whenever the Sensor has new data.
     */
    interface SensorEventListener {
        void onSensorChanged(SensorEvent event);
    }

    /**
     * Sensor that can be defined in a plugin.
     */
    class Sensor {
        public static final int TYPE_WAKE_LOCK_SCREEN = 1;
        public static final int TYPE_WAKE_DISPLAY = 2;
@@ -67,29 +70,32 @@ public interface SensorManagerPlugin extends Plugin {
        }
    }

    class TriggerEvent {
    /**
     * Event sent by a {@link Sensor}.
     */
    class SensorEvent {
        Sensor mSensor;
        int mVendorType;
        float[] mValues;

        /**
         * Creates a trigger event
         * Creates a sensor event.
         * @param sensor The type of sensor, e.g. TYPE_WAKE_LOCK_SCREEN
         * @param vendorType The vendor type, which should be unique for each type of sensor,
         *                   e.g. SINGLE_TAP = 1, DOUBLE_TAP = 2, etc.
         */
        public TriggerEvent(Sensor sensor, int vendorType) {
        public SensorEvent(Sensor sensor, int vendorType) {
            this(sensor, vendorType, null);
        }

        /**
         * Creates a trigger event
         * Creates a sensor event.
         * @param sensor The type of sensor, e.g. TYPE_WAKE_LOCK_SCREEN
         * @param vendorType The vendor type, which should be unique for each type of sensor,
         *                   e.g. SINGLE_TAP = 1, DOUBLE_TAP = 2, etc.
         * @param values Values captured by the sensor.
         */
        public TriggerEvent(Sensor sensor, int vendorType, float[] values) {
        public SensorEvent(Sensor sensor, int vendorType, float[] values) {
            mSensor = sensor;
            mVendorType = vendorType;
            mValues = values;
+1 −3
Original line number Diff line number Diff line
@@ -44,8 +44,7 @@ public class DozeLog {
    public static final int PULSE_REASON_SENSOR_PICKUP = 3;
    public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
    public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
    public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 6;
    public static final int REASON_SENSOR_WAKE_UP = 7;
    public static final int REASON_SENSOR_WAKE_UP = 6;

    private static boolean sRegisterKeyguardCallback = true;

@@ -212,7 +211,6 @@ public class DozeLog {
            case PULSE_REASON_SENSOR_PICKUP: return "pickup";
            case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
            case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
            case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakeLockScreen";
            case REASON_SENSOR_WAKE_UP: return "wakeup";
            default: throw new IllegalArgumentException("bad reason: " + pulseReason);
        }
+12 −25
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.doze;

import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_DISPLAY;
import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN;

import android.annotation.AnyThread;
import android.app.ActivityManager;
@@ -26,7 +25,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
@@ -114,14 +112,7 @@ public class DozeSensors {
                        DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
                        true /* reports touch coordinates */,
                        true /* touchscreen */),
                new PluginTriggerSensor(
                        new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
                        Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
                        true /* configured */,
                        DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
                        false /* reports touch coordinates */,
                        false /* touchscreen */),
                new PluginTriggerSensor(
                new PluginSensor(
                        new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
                        Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
                        true /* configured */,
@@ -272,7 +263,7 @@ public class DozeSensors {
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
        public void onSensorChanged(android.hardware.SensorEvent event) {
            if (DEBUG) Log.d(TAG, "onSensorChanged " + event);

            mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange();
@@ -417,7 +408,7 @@ public class DozeSensors {

        protected String triggerEventToString(TriggerEvent event) {
            if (event == null) return null;
            final StringBuilder sb = new StringBuilder("TriggerEvent[")
            final StringBuilder sb = new StringBuilder("SensorEvent[")
                    .append(event.timestamp).append(',')
                    .append(event.sensor.getName());
            if (event.values != null) {
@@ -432,23 +423,19 @@ public class DozeSensors {
    /**
     * A Sensor that is injected via plugin.
     */
    private class PluginTriggerSensor extends TriggerSensor {
    private class PluginSensor extends TriggerSensor {

        private final SensorManagerPlugin.Sensor mPluginSensor;
        private final SensorManagerPlugin.TriggerEventListener mTriggerEventListener = (event) -> {
        private final SensorManagerPlugin.SensorEventListener mTriggerEventListener = (event) -> {
            DozeLog.traceSensor(mContext, mPulseReason);
            mHandler.post(mWakeLock.wrap(() -> {
                if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
                mRegistered = false;
                if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
                mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
                        event.getValues());
                if (!mRegistered) {
                    updateListener();  // reregister, this sensor only fires once
                }
            }));
        };

        PluginTriggerSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
        PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
                int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
            super(null, setting, configured, pulseReason, reportsTouchCoordinates,
                    requiresTouchscreen);
@@ -460,13 +447,13 @@ public class DozeSensors {
            if (!mConfigured) return;
            AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
            if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
                asyncSensorManager.requestPluginTriggerSensor(mPluginSensor, mTriggerEventListener);
                asyncSensorManager.registerPluginListener(mPluginSensor, mTriggerEventListener);
                mRegistered = true;
                if (DEBUG) Log.d(TAG, "requestPluginTriggerSensor");
                if (DEBUG) Log.d(TAG, "registerPluginListener");
            } else if (mRegistered) {
                asyncSensorManager.cancelPluginTriggerSensor(mPluginSensor, mTriggerEventListener);
                asyncSensorManager.unregisterPluginListener(mPluginSensor, mTriggerEventListener);
                mRegistered = false;
                if (DEBUG) Log.d(TAG, "cancelPluginTriggerSensor");
                if (DEBUG) Log.d(TAG, "unregisterPluginListener");
            }
        }

@@ -479,7 +466,7 @@ public class DozeSensors {
                    .append(", mSensor=").append(mPluginSensor).append("}").toString();
        }

        private String triggerEventToString(SensorManagerPlugin.TriggerEvent event) {
        private String triggerEventToString(SensorManagerPlugin.SensorEvent event) {
            if (event == null) return null;
            final StringBuilder sb = new StringBuilder("PluginTriggerEvent[")
                    .append(event.getSensor()).append(',')
+10 −9
Original line number Diff line number Diff line
@@ -53,6 +53,12 @@ public class DozeTriggers implements DozeMachine.Part {
    /** adb shell am broadcast -a com.android.systemui.doze.pulse com.android.systemui */
    private static final String PULSE_ACTION = "com.android.systemui.doze.pulse";

    /**
     * Last value sent by the wake-display sensor.
     * Assuming that the screen should start on.
     */
    private static boolean sWakeDisplaySensorState = true;

    private final Context mContext;
    private final DozeMachine mMachine;
    private final DozeSensors mDozeSensors;
@@ -128,7 +134,6 @@ public class DozeTriggers implements DozeMachine.Part {
        boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
        boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
        boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
        boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
        boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
        boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;

@@ -145,14 +150,6 @@ public class DozeTriggers implements DozeMachine.Part {
                if (isDoubleTap) {
                    mDozeHost.onDoubleTap(screenX, screenY);
                    mMachine.wakeUp();
                } else if (isWakeLockScreen) {
                    if (wakeEvent) {
                        mDozeHost.setPassiveInterrupt(true);
                        mMachine.wakeUp();
                        DozeLog.traceLockScreenWakeUp(wakeEvent);
                    } else {
                        if (DEBUG) Log.d(TAG, "Unpulsing");
                    }
                } else if (isPickup) {
                    mDozeHost.setPassiveInterrupt(true);
                    mMachine.wakeUp();
@@ -199,6 +196,7 @@ public class DozeTriggers implements DozeMachine.Part {
        DozeMachine.State state = mMachine.getState();
        boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
        boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
        sWakeDisplaySensorState = wake;

        if (wake) {
            proximityCheckThenCall((result) -> {
@@ -234,6 +232,9 @@ public class DozeTriggers implements DozeMachine.Part {
                }
                mDozeSensors.setListening(true);
                mDozeHost.setPassiveInterrupt(false);
                if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
                    onWakeScreen(false);
                }
                break;
            case DOZE_AOD_PAUSED:
            case DOZE_AOD_PAUSING:
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.doze;

import android.content.Context;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.SensorManagerPlugin;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.util.AsyncSensorManager;

/**
 * Controller responsible for waking up or making the device sleep based on ambient sensors.
 */
public class LockScreenWakeUpController implements StatusBarStateController.StateListener,
        SensorManagerPlugin.SensorEventListener {

    private static final String TAG = LockScreenWakeUpController.class.getSimpleName();
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final AsyncSensorManager mAsyncSensorManager;
    private final SensorManagerPlugin.Sensor mSensor;
    private final AmbientDisplayConfiguration mAmbientConfiguration;
    private final PowerManager mPowerManager;
    private final DozeHost mDozeHost;
    private final Handler mHandler;
    private boolean mRegistered;
    private boolean mDozing;

    public LockScreenWakeUpController(Context context, DozeHost dozeHost) {
        this(Dependency.get(AsyncSensorManager.class),
                new SensorManagerPlugin.Sensor(SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN),
                new AmbientDisplayConfiguration(context),
                context.getSystemService(PowerManager.class),
                dozeHost, Dependency.get(StatusBarStateController.class), new Handler());
    }

    @VisibleForTesting
    public LockScreenWakeUpController(AsyncSensorManager asyncSensorManager,
            SensorManagerPlugin.Sensor sensor, AmbientDisplayConfiguration ambientConfiguration,
            PowerManager powerManager, DozeHost dozeHost,
            StatusBarStateController statusBarStateController, Handler handler) {
        mAsyncSensorManager = asyncSensorManager;
        mSensor = sensor;
        mAmbientConfiguration = ambientConfiguration;
        mPowerManager = powerManager;
        mDozeHost = dozeHost;
        mHandler = handler;
        statusBarStateController.addCallback(this);
    }

    @Override
    public void onStateChanged(int newState) {
        boolean isLockScreen = newState == StatusBarState.KEYGUARD
                || newState == StatusBarState.SHADE_LOCKED;

        if (!mAmbientConfiguration.wakeLockScreenGestureEnabled(UserHandle.USER_CURRENT)) {
            if (mRegistered) {
                mAsyncSensorManager.unregisterPluginListener(mSensor, this);
                mRegistered = false;
            }
            return;
        }

        if (isLockScreen && !mRegistered) {
            mAsyncSensorManager.registerPluginListener(mSensor, this);
            mRegistered = true;
        } else if (!isLockScreen && mRegistered) {
            mAsyncSensorManager.unregisterPluginListener(mSensor, this);
            mRegistered = false;
        }
    }

    @Override
    public void onDozingChanged(boolean isDozing) {
        mDozing = isDozing;
    }

    @Override
    public void onSensorChanged(SensorManagerPlugin.SensorEvent event) {
        mHandler.post(()-> {
            float[] rawValues = event.getValues();
            boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;

            DozeLog.traceLockScreenWakeUp(wakeEvent);
            if (wakeEvent && mDozing) {
                mDozeHost.setPassiveInterrupt(true);
                if (DEBUG) Log.d(TAG, "Wake up.");
                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
            } else if (!wakeEvent && !mDozing) {
                if (DEBUG) Log.d(TAG, "Nap time.");
                mPowerManager.goToSleep(SystemClock.uptimeMillis(),
                        PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
            } else if (DEBUG) {
                Log.d(TAG, "Skip sensor event. Wake? " + wakeEvent + " dozing: " + mDozing);
            }
        });
    }
}
Loading