Merge "Add vibrate on down over nav bar and tick on motion up" into pi-dev
am: 25092e1d93
Change-Id: Iba49dbe9db30f83908d988a6ae67e18bdca42122
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
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.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.NavigationBarCompat;
|
import com.android.systemui.shared.system.NavigationBarCompat;
|
||||||
import com.android.systemui.stackdivider.Divider;
|
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.DeadZone;
|
||||||
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
|
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
|
||||||
import com.android.systemui.statusbar.policy.TintedKeyButtonDrawable;
|
import com.android.systemui.statusbar.policy.TintedKeyButtonDrawable;
|
||||||
@@ -148,6 +150,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
|||||||
private Divider mDivider;
|
private Divider mDivider;
|
||||||
private RecentsOnboarding mRecentsOnboarding;
|
private RecentsOnboarding mRecentsOnboarding;
|
||||||
private NotificationPanelView mPanelView;
|
private NotificationPanelView mPanelView;
|
||||||
|
private final VibratorHelper mVibratorHelper;
|
||||||
|
|
||||||
private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
|
private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
|
||||||
|
|
||||||
@@ -243,6 +246,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
|||||||
|
|
||||||
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
||||||
mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
|
mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
|
||||||
|
mVibratorHelper = new VibratorHelper(context);
|
||||||
|
|
||||||
mConfiguration = new Configuration();
|
mConfiguration = new Configuration();
|
||||||
mConfiguration.updateFrom(context.getResources().getConfiguration());
|
mConfiguration.updateFrom(context.getResources().getConfiguration());
|
||||||
@@ -311,6 +315,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
|||||||
} else if (mRecentsButtonBounds.contains(x, y)) {
|
} else if (mRecentsButtonBounds.contains(x, y)) {
|
||||||
mDownHitTarget = HIT_TARGET_OVERVIEW;
|
mDownHitTarget = HIT_TARGET_OVERVIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vibrate tick whenever down occurs on navigation bar
|
||||||
|
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return mGestureHelper.onInterceptTouchEvent(event);
|
return mGestureHelper.onInterceptTouchEvent(event);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import com.android.systemui.classifier.FalsingManager;
|
|||||||
import com.android.systemui.doze.DozeLog;
|
import com.android.systemui.doze.DozeLog;
|
||||||
import com.android.systemui.statusbar.FlingAnimationUtils;
|
import com.android.systemui.statusbar.FlingAnimationUtils;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
|
import com.android.systemui.statusbar.VibratorHelper;
|
||||||
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
|
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -66,7 +67,6 @@ public abstract class PanelView extends FrameLayout {
|
|||||||
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
|
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
|
||||||
private boolean mPanelUpdateWhenAnimatorEnds;
|
private boolean mPanelUpdateWhenAnimatorEnds;
|
||||||
private boolean mVibrateOnOpening;
|
private boolean mVibrateOnOpening;
|
||||||
private boolean mVibrationEnabled;
|
|
||||||
protected boolean mLaunchingNotification;
|
protected boolean mLaunchingNotification;
|
||||||
private int mFixedDuration = NO_FIXED_DURATION;
|
private int mFixedDuration = NO_FIXED_DURATION;
|
||||||
|
|
||||||
@@ -110,13 +110,7 @@ public abstract class PanelView extends FrameLayout {
|
|||||||
private FlingAnimationUtils mFlingAnimationUtilsClosing;
|
private FlingAnimationUtils mFlingAnimationUtilsClosing;
|
||||||
private FlingAnimationUtils mFlingAnimationUtilsDismissing;
|
private FlingAnimationUtils mFlingAnimationUtilsDismissing;
|
||||||
private FalsingManager mFalsingManager;
|
private FalsingManager mFalsingManager;
|
||||||
private final Vibrator mVibrator;
|
private final VibratorHelper mVibratorHelper;
|
||||||
final private ContentObserver mVibrationObserver = new ContentObserver(Handler.getMain()) {
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange) {
|
|
||||||
updateHapticFeedBackEnabled();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether an instant expand request is currently pending and we are just waiting for layout.
|
* 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);
|
mFalsingManager = FalsingManager.getInstance(context);
|
||||||
mNotificationsDragEnabled =
|
mNotificationsDragEnabled =
|
||||||
getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
|
getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
|
||||||
mVibrator = mContext.getSystemService(Vibrator.class);
|
mVibratorHelper = new VibratorHelper(context);
|
||||||
mVibrateOnOpening = mContext.getResources().getBoolean(
|
mVibrateOnOpening = mContext.getResources().getBoolean(
|
||||||
R.bool.config_vibrateOnIconAnimation);
|
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() {
|
protected void loadDimens() {
|
||||||
@@ -421,9 +406,8 @@ public abstract class PanelView extends FrameLayout {
|
|||||||
runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
|
runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
|
||||||
false /* collapseWhenFinished */);
|
false /* collapseWhenFinished */);
|
||||||
notifyBarPanelExpansionChanged();
|
notifyBarPanelExpansionChanged();
|
||||||
if (mVibrateOnOpening && mVibrationEnabled) {
|
if (mVibrateOnOpening) {
|
||||||
AsyncTask.execute(() ->
|
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
|
||||||
mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_TICK, false)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: keyguard opens QS a different way; log that too?
|
//TODO: keyguard opens QS a different way; log that too?
|
||||||
|
|||||||
@@ -27,12 +27,9 @@ import android.media.AudioManager;
|
|||||||
import android.metrics.LogMaker;
|
import android.metrics.LogMaker;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.VibrationEffect;
|
import android.os.VibrationEffect;
|
||||||
import android.os.Vibrator;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
@@ -53,6 +50,7 @@ import com.android.systemui.OverviewProxyService;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
|
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
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_CLICK;
|
||||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_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 OnClickListener mOnClickListener;
|
||||||
private final KeyButtonRipple mRipple;
|
private final KeyButtonRipple mRipple;
|
||||||
private final OverviewProxyService mOverviewProxyService;
|
private final OverviewProxyService mOverviewProxyService;
|
||||||
private final Vibrator mVibrator;
|
private final VibratorHelper mVibratorHelper;
|
||||||
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
|
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
|
||||||
|
|
||||||
private final Runnable mCheckLongPress = new Runnable() {
|
private final Runnable mCheckLongPress = new Runnable() {
|
||||||
@@ -128,7 +126,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
|
|||||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
|
||||||
mRipple = new KeyButtonRipple(context, this);
|
mRipple = new KeyButtonRipple(context, this);
|
||||||
mVibrator = mContext.getSystemService(Vibrator.class);
|
mVibratorHelper = new VibratorHelper(context);
|
||||||
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
||||||
setBackground(mRipple);
|
setBackground(mRipple);
|
||||||
}
|
}
|
||||||
@@ -263,14 +261,17 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
|
|||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
final boolean doIt = mIsPressed && !mLongClicked;
|
final boolean doIt = mIsPressed && !mLongClicked;
|
||||||
|
final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
|
||||||
if (isProxyConnected) {
|
if (isProxyConnected) {
|
||||||
if (doIt) {
|
if (doIt) {
|
||||||
// Animate the ripple in on touch up with setPressed and then out later
|
// Animate the ripple in on touch up with setPressed and then out later
|
||||||
setPressed(true);
|
setPressed(true);
|
||||||
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
if (doHapticFeedback) {
|
||||||
|
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
|
||||||
|
}
|
||||||
playSoundEffect(SoundEffectConstants.CLICK);
|
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
|
// 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.
|
// and it feels weird to sometimes get a release haptic and other times not.
|
||||||
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
|
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
|
||||||
|
|||||||
Reference in New Issue
Block a user