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

Commit a4d22d71 authored by Michael Wright's avatar Michael Wright Committed by Tim Murray
Browse files

Send power hint on fling gestures.

Use the existing PointerEventListener infrastructure to listen for
gestures that look like flings and hint to the power system when they
happen. Since we don't actually have a bound for the fling like a
regular application would, limit them to five seconds and refresh
every time a new fling is seen until the five second time period is
up.

bug 24059298

Change-Id: I5757a1e88f2ab2ef08cccefa8221d809ae71bb6f
parent 6b04e3a6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -53,6 +53,15 @@ public abstract class PowerManagerInternal {
     */
    public static final int WAKEFULNESS_DOZING = 3;


    /**
     * Power hint: The user is interacting with the device. The corresponding data field must be
     * the expected duration of the fling, or 0 if unknown.
     *
     * This must be kept in sync with the values in hardware/libhardware/include/hardware/power.h
     */
    public static final int POWER_HINT_INTERACTION = 2;

    public static String wakefulnessToString(int wakefulness) {
        switch (wakefulness) {
            case WAKEFULNESS_ASLEEP:
@@ -142,4 +151,6 @@ public abstract class PowerManagerInternal {
    public abstract void updateUidProcState(int uid, int procState);

    public abstract void uidGone(int uid);

    public abstract void powerHint(int hintId, int data);
}
+11 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -267,6 +268,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    PowerManager mPowerManager;
    ActivityManagerInternal mActivityManagerInternal;
    DreamManagerInternal mDreamManagerInternal;
    PowerManagerInternal mPowerManagerInternal;
    IStatusBarService mStatusBarService;
    boolean mPreloadedRecentApps;
    final Object mServiceAquireLock = new Object();
@@ -1330,6 +1332,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);

        // Init display burn-in protection
@@ -1506,6 +1509,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        }
                    }
                    @Override
                    public void onFling(int duration) {
                        if (mPowerManagerInternal != null) {
                            mPowerManagerInternal.powerHint(
                                    PowerManagerInternal.POWER_HINT_INTERACTION, duration);
                        }
                    }
                    @Override
                    public void onDebug() {
                        // no-op
                    }
@@ -6074,6 +6084,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            mKeyguardDelegate.bindService(mContext);
            mKeyguardDelegate.onBootCompleted();
        }
        mSystemGestures.systemReady();
    }

    /** {@inheritDoc} */
+51 −0
Original line number Diff line number Diff line
@@ -17,9 +17,14 @@
package com.android.server.policy;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Slog;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.widget.OverScroller;

/*
 * Listens for system-wide input gestures, firing callbacks when detected.
@@ -31,12 +36,14 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
    private static final long SWIPE_TIMEOUT_MS = 500;
    private static final int MAX_TRACKED_POINTERS = 32;  // max per input system
    private static final int UNTRACKED_POINTER = -1;
    private static final int MAX_FLING_TIME_MILLIS = 5000;

    private static final int SWIPE_NONE = 0;
    private static final int SWIPE_FROM_TOP = 1;
    private static final int SWIPE_FROM_BOTTOM = 2;
    private static final int SWIPE_FROM_RIGHT = 3;

    private final Context mContext;
    private final int mSwipeStartThreshold;
    private final int mSwipeDistanceThreshold;
    private final Callbacks mCallbacks;
@@ -45,13 +52,18 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
    private final float[] mDownY = new float[MAX_TRACKED_POINTERS];
    private final long[] mDownTime = new long[MAX_TRACKED_POINTERS];

    private GestureDetector mGestureDetector;
    private OverScroller mOverscroller;

    int screenHeight;
    int screenWidth;
    private int mDownPointers;
    private boolean mSwipeFireable;
    private boolean mDebugFireable;
    private long mLastFlingTime;

    public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) {
        mContext = context;
        mCallbacks = checkNull("callbacks", callbacks);
        mSwipeStartThreshold = checkNull("context", context).getResources()
                .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
@@ -67,8 +79,17 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
        return arg;
    }

    public void systemReady() {
        Handler h = new Handler(Looper.myLooper());
        mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), h);
        mOverscroller = new OverScroller(mContext);
    }

    @Override
    public void onPointerEvent(MotionEvent event) {
        if (mGestureDetector != null) {
            mGestureDetector.onTouchEvent(event);
        }
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mSwipeFireable = true;
@@ -190,10 +211,40 @@ public class SystemGesturesPointerEventListener implements PointerEventListener
        return SWIPE_NONE;
    }

    private final class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            if (!mOverscroller.isFinished()) {
                mOverscroller.forceFinished(true);
            }
            return true;
        }
        @Override
        public boolean onFling(MotionEvent down, MotionEvent up,
                float velocityX, float velocityY) {
            mOverscroller.computeScrollOffset();
            long now = SystemClock.uptimeMillis();

            if (mLastFlingTime != 0 && now > mLastFlingTime + MAX_FLING_TIME_MILLIS) {
                mOverscroller.forceFinished(true);
            }
            mOverscroller.fling(0, 0, (int)velocityX, (int)velocityY,
                    Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
            int duration = mOverscroller.getDuration();
            if (duration > MAX_FLING_TIME_MILLIS) {
                duration = MAX_FLING_TIME_MILLIS;
            }
            mLastFlingTime = now;
            mCallbacks.onFling(duration);
            return true;
        }
    }

    interface Callbacks {
        void onSwipeFromTop();
        void onSwipeFromBottom();
        void onSwipeFromRight();
        void onFling(int durationMs);
        void onDown();
        void onUpOrCancel();
        void onDebug();
+6 −1
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import java.util.Arrays;

import libcore.util.Objects;

import static android.os.PowerManagerInternal.POWER_HINT_INTERACTION;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
@@ -150,7 +151,6 @@ public final class PowerManagerService extends SystemService
    private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000;

    // Power hints defined in hardware/libhardware/include/hardware/power.h.
    private static final int POWER_HINT_INTERACTION = 2;
    private static final int POWER_HINT_LOW_POWER = 5;

    // Power features defined in hardware/libhardware/include/hardware/power.h.
@@ -3534,5 +3534,10 @@ public final class PowerManagerService extends SystemService
        public void uidGone(int uid) {
            uidGoneInternal(uid);
        }

        @Override
        public void powerHint(int hintId, int data) {
            powerHintInternal(hintId, data);
        }
    }
}