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

Commit 5c0592e2 authored by Matthew Ng's avatar Matthew Ng
Browse files

Add vibrate on down over nav bar and tick on motion up

Added a tick vibration for down and up (after 150ms delay) over back and
home button. Vibration on touch down covers the entire bar.

Fixes: 73942704
Test: tap nav bar or tap home button
Change-Id: Ib53c3667cbdf61a502bab53d98a2874a511acb3f
parent b6956c92
Loading
Loading
Loading
Loading
+62 −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.statusbar;

import android.content.Context;
import android.database.ContentObserver;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.UserHandle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;

public class VibratorHelper {

    private final Vibrator mVibrator;
    private final Context mContext;
    private boolean mHapticFeedbackEnabled;

    final private ContentObserver mVibrationObserver = new ContentObserver(Handler.getMain()) {
        @Override
        public void onChange(boolean selfChange) {
            updateHapticFeedBackEnabled();
        }
    };

    public VibratorHelper(Context context) {
        mContext = context;
        mVibrator = context.getSystemService(Vibrator.class);

        mContext.getContentResolver().registerContentObserver(
                Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED), true,
                mVibrationObserver);
        mVibrationObserver.onChange(false /* selfChange */);
    }

    public void vibrate(final int effectId) {
        if (mHapticFeedbackEnabled) {
            AsyncTask.execute(() ->
                    mVibrator.vibrate(VibrationEffect.get(effectId, false /* fallback */)));
        }
    }

    private void updateHapticFeedBackEnabled() {
        mHapticFeedbackEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) != 0;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.os.VibrationEffect;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.util.Log;
@@ -67,6 +68,7 @@ import com.android.systemui.recents.RecentsOnboarding;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.NavigationBarCompat;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import com.android.systemui.statusbar.policy.TintedKeyButtonDrawable;
@@ -148,6 +150,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
    private Divider mDivider;
    private RecentsOnboarding mRecentsOnboarding;
    private NotificationPanelView mPanelView;
    private final VibratorHelper mVibratorHelper;

    private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;

@@ -243,6 +246,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav

        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
        mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
        mVibratorHelper = new VibratorHelper(context);

        mConfiguration = new Configuration();
        mConfiguration.updateFrom(context.getResources().getConfiguration());
@@ -311,6 +315,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
                } else if (mRecentsButtonBounds.contains(x, y)) {
                    mDownHitTarget = HIT_TARGET_OVERVIEW;
                }

                // Vibrate tick whenever down occurs on navigation bar
                mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
                break;
        }
        return mGestureHelper.onInterceptTouchEvent(event);
+5 −21
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;

import java.io.FileDescriptor;
@@ -66,7 +67,6 @@ public abstract class PanelView extends FrameLayout {
    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
    private boolean mPanelUpdateWhenAnimatorEnds;
    private boolean mVibrateOnOpening;
    private boolean mVibrationEnabled;
    protected boolean mLaunchingNotification;
    private int mFixedDuration = NO_FIXED_DURATION;

@@ -110,13 +110,7 @@ public abstract class PanelView extends FrameLayout {
    private FlingAnimationUtils mFlingAnimationUtilsClosing;
    private FlingAnimationUtils mFlingAnimationUtilsDismissing;
    private FalsingManager mFalsingManager;
    private final Vibrator mVibrator;
    final private ContentObserver mVibrationObserver = new ContentObserver(Handler.getMain()) {
        @Override
        public void onChange(boolean selfChange) {
            updateHapticFeedBackEnabled();
        }
    };
    private final VibratorHelper mVibratorHelper;

    /**
     * Whether an instant expand request is currently pending and we are just waiting for layout.
@@ -218,18 +212,9 @@ public abstract class PanelView extends FrameLayout {
        mFalsingManager = FalsingManager.getInstance(context);
        mNotificationsDragEnabled =
                getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
        mVibrator = mContext.getSystemService(Vibrator.class);
        mVibratorHelper = new VibratorHelper(context);
        mVibrateOnOpening = mContext.getResources().getBoolean(
                R.bool.config_vibrateOnIconAnimation);
        mContext.getContentResolver().registerContentObserver(
                Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED), true,
                mVibrationObserver);
        mVibrationObserver.onChange(false /* selfChange */);
    }

    public void updateHapticFeedBackEnabled() {
        mVibrationEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) != 0;
    }

    protected void loadDimens() {
@@ -421,9 +406,8 @@ public abstract class PanelView extends FrameLayout {
        runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
                false /* collapseWhenFinished */);
        notifyBarPanelExpansionChanged();
        if (mVibrateOnOpening && mVibrationEnabled) {
            AsyncTask.execute(() ->
                    mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_TICK, false)));
        if (mVibrateOnOpening) {
            mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
        }

        //TODO: keyguard opens QS a different way; log that too?
+8 −7
Original line number Diff line number Diff line
@@ -27,12 +27,9 @@ import android.media.AudioManager;
import android.metrics.LogMaker;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
@@ -53,6 +50,7 @@ import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.VibratorHelper;

import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
@@ -75,7 +73,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
    private OnClickListener mOnClickListener;
    private final KeyButtonRipple mRipple;
    private final OverviewProxyService mOverviewProxyService;
    private final Vibrator mVibrator;
    private final VibratorHelper mVibratorHelper;
    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);

    private final Runnable mCheckLongPress = new Runnable() {
@@ -128,7 +126,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        mRipple = new KeyButtonRipple(context, this);
        mVibrator = mContext.getSystemService(Vibrator.class);
        mVibratorHelper = new VibratorHelper(context);
        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
        setBackground(mRipple);
    }
@@ -263,14 +261,17 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
                break;
            case MotionEvent.ACTION_UP:
                final boolean doIt = mIsPressed && !mLongClicked;
                final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
                if (isProxyConnected) {
                    if (doIt) {
                        // Animate the ripple in on touch up with setPressed and then out later
                        setPressed(true);
                        performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
                        if (doHapticFeedback) {
                            mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
                        }
                        playSoundEffect(SoundEffectConstants.CLICK);
                    }
                } else if ((SystemClock.uptimeMillis() - mDownTime) > 150 && !mLongClicked) {
                } else if (doHapticFeedback && !mLongClicked) {
                    // Always send a release ourselves because it doesn't seem to be sent elsewhere
                    // and it feels weird to sometimes get a release haptic and other times not.
                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);