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

Commit cce429f5 authored by Roman Birg's avatar Roman Birg Committed by Steve Kondik
Browse files

SystemUI: double tap to sleep improvements



* Make it more reliable
* Add it to keyguard
* Add a content observer to not always query Settings.System on every
touch event

Change-Id: I292c4d9d9f810843590b7a9ec6e15b99ac44009d
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>
parent f4ee2672
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -31,9 +31,11 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -223,11 +225,26 @@ public class NotificationPanelView extends PanelView implements

    private Handler mHandler = new Handler();
    private SettingsObserver mSettingsObserver;

    private boolean mOneFingerQuickSettingsIntercept;
    private boolean mDoubleTapToSleepEnabled;
    private int mStatusBarHeaderHeight;
    private GestureDetector mDoubleTapGesture;

    public NotificationPanelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(!DEBUG);

        mSettingsObserver = new SettingsObserver(mHandler);
        mDoubleTapGesture = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
                if(pm != null)
                    pm.goToSleep(e.getEventTime());
                return true;
            }
        });
    }

    public void setStatusBar(PhoneStatusBar bar) {
@@ -281,7 +298,6 @@ public class NotificationPanelView extends PanelView implements
                }
            }
        });
        mSettingsObserver = new SettingsObserver(mHandler);
    }

    @Override
@@ -303,6 +319,7 @@ public class NotificationPanelView extends PanelView implements
                R.dimen.qs_falsing_threshold);
        mPositionMinSideMargin = getResources().getDimensionPixelSize(
                R.dimen.notification_panel_min_side_margin);
        mStatusBarHeaderHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
    }

    public void updateResources() {
@@ -737,6 +754,11 @@ public class NotificationPanelView extends PanelView implements
        if (mBlockTouches) {
            return false;
        }
        if (mDoubleTapToSleepEnabled
                && mStatusBarState == StatusBarState.KEYGUARD
                && event.getY() < mStatusBarHeaderHeight) {
            mDoubleTapGesture.onTouchEvent(event);
        }
        initDownStates(event);
        if (mListenForHeadsUp && !mHeadsUpTouchHelper.isTrackingHeadsUp()
                && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
@@ -2430,6 +2452,8 @@ public class NotificationPanelView extends PanelView implements
            ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN), false, this);
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.DOUBLE_TAP_SLEEP_GESTURE), false, this);
            update();
        }

@@ -2452,6 +2476,8 @@ public class NotificationPanelView extends PanelView implements
            ContentResolver resolver = mContext.getContentResolver();
            mOneFingerQuickSettingsIntercept = Settings.System.getInt(
                    resolver, Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, 1) == 1;
            mDoubleTapToSleepEnabled = Settings.System.getInt(
                    resolver, Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 1) == 1;
        }
    }
}
+0 −22
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@ import android.util.EventLog;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.GestureDetector;
import android.os.PowerManager;
import android.provider.Settings;

import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogTags;
@@ -50,27 +47,12 @@ public class PhoneStatusBarView extends PanelBar {
            mBar.makeExpandedInvisible();
        }
    };
    private GestureDetector mDoubleTapGesture;

    public PhoneStatusBarView(Context context, AttributeSet attrs) {
        super(context, attrs);

        Resources res = getContext().getResources();
        mBarTransitions = new PhoneStatusBarTransitions(this);

        mDoubleTapGesture = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
                Log.d(TAG, "Gesture!!");
                if(pm != null)
                    pm.goToSleep(e.getEventTime());
                else
                    Log.d(TAG, "getSystemService returned null PowerManager");

                return true;
            }
        });
    }

    public BarTransitions getBarTransitions() {
@@ -165,10 +147,6 @@ public class PhoneStatusBarView extends PanelBar {
            }
        }

        if (Settings.System.getInt(mContext.getContentResolver(),
                    Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 0) == 1)
            mDoubleTapGesture.onTouchEvent(event);

        return barConsumedEvent || super.onTouchEvent(event);
    }

+82 −0
Original line number Diff line number Diff line
@@ -17,19 +17,31 @@
package com.android.systemui.statusbar.phone;

import android.app.StatusBarManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.media.session.MediaSessionLegacyHelper;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -56,11 +68,21 @@ public class StatusBarWindowView extends FrameLayout {
    private PhoneStatusBar mService;
    private final Paint mTransparentSrcPaint = new Paint();

    private int mStatusBarHeaderHeight;

    private boolean mDoubleTapToSleepEnabled;
    private GestureDetector mDoubleTapGesture;
    private Handler mHandler = new Handler();
    private SettingsObserver mSettingsObserver;

    public StatusBarWindowView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMotionEventSplittingEnabled(false);
        mTransparentSrcPaint.setColor(0);
        mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
        mStatusBarHeaderHeight = context
                .getResources().getDimensionPixelSize(R.dimen.status_bar_header_height);
        mSettingsObserver = new SettingsObserver(mHandler);
    }

    @Override
@@ -141,6 +163,21 @@ public class StatusBarWindowView extends FrameLayout {
    protected void onAttachedToWindow () {
        super.onAttachedToWindow();

        mSettingsObserver.observe();
        mDoubleTapGesture = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
                Log.d(TAG, "Gesture!!");
                if(pm != null)
                    pm.goToSleep(e.getEventTime());
                else
                    Log.d(TAG, "getSystemService returned null PowerManager");

                return true;
            }
        });

        // We really need to be able to animate while window animations are going on
        // so that activities may be started asynchronously from panel animations
        final ViewRootImpl root = getViewRootImpl();
@@ -163,6 +200,12 @@ public class StatusBarWindowView extends FrameLayout {
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mSettingsObserver.unobserve();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
@@ -211,6 +254,11 @@ public class StatusBarWindowView extends FrameLayout {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean intercept = false;
        if (mDoubleTapToSleepEnabled
                && ev.getY() < mStatusBarHeaderHeight) {
            if (DEBUG) Log.w(TAG, "logging double tap gesture");
            mDoubleTapGesture.onTouchEvent(ev);
        }
        if (mNotificationPanel.isFullyExpanded()
                && mStackScrollLayout.getVisibility() == View.VISIBLE
                && mService.getBarState() == StatusBarState.KEYGUARD
@@ -305,5 +353,39 @@ public class StatusBarWindowView extends FrameLayout {
            a.recycle();
        }
    }

    class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
            super(handler);
        }

        void observe() {
            ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.DOUBLE_TAP_SLEEP_GESTURE), false, this);
            update();
        }

        void unobserve() {
            ContentResolver resolver = mContext.getContentResolver();
            resolver.unregisterContentObserver(this);
        }

        @Override
        public void onChange(boolean selfChange) {
            update();
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            update();
        }

        public void update() {
            ContentResolver resolver = mContext.getContentResolver();
            mDoubleTapToSleepEnabled = Settings.System.getInt(
                    resolver, Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 1) == 1;
        }
    }
}