Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (C) 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | package com.android.systemui.statusbar.phone; |
| 17 | |
Mady Mellor | 390bff4 | 2019-04-05 15:09:01 -0700 | [diff] [blame] | 18 | import static android.view.Display.INVALID_DISPLAY; |
| 19 | |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 20 | import android.app.ActivityManager; |
| 21 | import android.content.ComponentName; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 22 | import android.content.Context; |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 23 | import android.content.pm.PackageManager; |
| 24 | import android.content.pm.PackageManager.NameNotFoundException; |
Matthew Ng | 682ad7a | 2019-04-09 15:48:01 -0700 | [diff] [blame] | 25 | import android.content.res.Resources; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 26 | import android.database.ContentObserver; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 27 | import android.graphics.PixelFormat; |
| 28 | import android.graphics.Point; |
| 29 | import android.graphics.PointF; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 30 | import android.graphics.Region; |
| 31 | import android.hardware.display.DisplayManager; |
| 32 | import android.hardware.display.DisplayManager.DisplayListener; |
| 33 | import android.hardware.input.InputManager; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 34 | import android.net.Uri; |
| 35 | import android.os.Handler; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 36 | import android.os.Looper; |
| 37 | import android.os.RemoteException; |
| 38 | import android.os.SystemClock; |
Adam Cohen | a699c28 | 2019-08-07 15:29:34 -0700 | [diff] [blame] | 39 | import android.os.SystemProperties; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 40 | import android.os.UserHandle; |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 41 | import android.provider.DeviceConfig; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 42 | import android.provider.Settings; |
Winson Chung | 4ef8418 | 2020-05-01 15:22:47 -0700 | [diff] [blame] | 43 | import android.util.DisplayMetrics; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 44 | import android.util.Log; |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 45 | import android.util.TypedValue; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 46 | import android.view.ISystemGestureExclusionListener; |
Siarhei Vishniakou | faa8799 | 2019-05-29 09:12:18 -0700 | [diff] [blame] | 47 | import android.view.InputChannel; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 48 | import android.view.InputDevice; |
| 49 | import android.view.InputEvent; |
Siarhei Vishniakou | faa8799 | 2019-05-29 09:12:18 -0700 | [diff] [blame] | 50 | import android.view.InputEventReceiver; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 51 | import android.view.InputMonitor; |
| 52 | import android.view.KeyCharacterMap; |
| 53 | import android.view.KeyEvent; |
| 54 | import android.view.MotionEvent; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 55 | import android.view.Surface; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 56 | import android.view.ViewConfiguration; |
| 57 | import android.view.WindowManager; |
| 58 | import android.view.WindowManagerGlobal; |
| 59 | |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 60 | import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 61 | import com.android.internal.policy.GestureNavigationSettingsObserver; |
Mady Mellor | 390bff4 | 2019-04-05 15:09:01 -0700 | [diff] [blame] | 62 | import com.android.systemui.Dependency; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 63 | import com.android.systemui.R; |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 64 | import com.android.systemui.broadcast.BroadcastDispatcher; |
Mady Mellor | 390bff4 | 2019-04-05 15:09:01 -0700 | [diff] [blame] | 65 | import com.android.systemui.bubbles.BubbleController; |
Vinit Nayak | 59b114e6 | 2019-08-12 11:50:00 -0700 | [diff] [blame] | 66 | import com.android.systemui.model.SysUiState; |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 67 | import com.android.systemui.plugins.NavigationEdgeBackPlugin; |
| 68 | import com.android.systemui.plugins.PluginListener; |
Winson Chung | 04ff8bda | 2019-04-02 15:08:59 -0700 | [diff] [blame] | 69 | import com.android.systemui.recents.OverviewProxyService; |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 70 | import com.android.systemui.settings.CurrentUserTracker; |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 71 | import com.android.systemui.shared.plugins.PluginManager; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 72 | import com.android.systemui.shared.system.ActivityManagerWrapper; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 73 | import com.android.systemui.shared.system.QuickStepContract; |
Muhammad Qureshi | 9bced7d | 2020-01-16 15:22:12 -0800 | [diff] [blame] | 74 | import com.android.systemui.shared.system.SysUiStatsLog; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 75 | import com.android.systemui.shared.system.TaskStackChangeListener; |
Winson Chung | a657ac9 | 2019-12-09 16:43:46 -0800 | [diff] [blame] | 76 | import com.android.systemui.shared.tracing.ProtoTraceable; |
| 77 | import com.android.systemui.tracing.ProtoTracer; |
| 78 | import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto; |
| 79 | import com.android.systemui.tracing.nano.SystemUiTraceProto; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 80 | |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 81 | import java.io.PrintWriter; |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 82 | import java.util.ArrayList; |
| 83 | import java.util.List; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 84 | import java.util.concurrent.Executor; |
| 85 | |
| 86 | /** |
| 87 | * Utility class to handle edge swipes for back gesture |
| 88 | */ |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 89 | public class EdgeBackGestureHandler extends CurrentUserTracker implements DisplayListener, |
Winson Chung | a657ac9 | 2019-12-09 16:43:46 -0800 | [diff] [blame] | 90 | PluginListener<NavigationEdgeBackPlugin>, ProtoTraceable<SystemUiTraceProto> { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 91 | |
| 92 | private static final String TAG = "EdgeBackGestureHandler"; |
Adam Cohen | a699c28 | 2019-08-07 15:29:34 -0700 | [diff] [blame] | 93 | private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt( |
| 94 | "gestures.back_timeout", 250); |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 95 | private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform"; |
| 96 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 97 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 98 | private ISystemGestureExclusionListener mGestureExclusionListener = |
| 99 | new ISystemGestureExclusionListener.Stub() { |
| 100 | @Override |
| 101 | public void onSystemGestureExclusionChanged(int displayId, |
Adrian Roos | 5f2c9a1 | 2019-07-03 18:31:46 +0200 | [diff] [blame] | 102 | Region systemGestureExclusion, Region unrestrictedOrNull) { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 103 | if (displayId == mDisplayId) { |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 104 | mMainExecutor.execute(() -> { |
| 105 | mExcludeRegion.set(systemGestureExclusion); |
| 106 | mUnrestrictedExcludeRegion.set(unrestrictedOrNull != null |
| 107 | ? unrestrictedOrNull : systemGestureExclusion); |
| 108 | }); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 109 | } |
| 110 | } |
| 111 | }; |
| 112 | |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 113 | private OverviewProxyService.OverviewProxyListener mQuickSwitchListener = |
| 114 | new OverviewProxyService.OverviewProxyListener() { |
| 115 | @Override |
| 116 | public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) { |
| 117 | mStartingQuickstepRotation = rotation; |
| 118 | updateDisabledForQuickstep(); |
| 119 | } |
| 120 | }; |
| 121 | |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 122 | private final ContentObserver mFixedRotationObserver = new ContentObserver( |
| 123 | new Handler(Looper.getMainLooper())) { |
| 124 | @Override |
| 125 | public void onChange(boolean selfChange, Uri uri) { |
| 126 | updatedFixedRotation(); |
| 127 | } |
| 128 | }; |
| 129 | |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 130 | private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { |
| 131 | @Override |
| 132 | public void onTaskStackChanged() { |
| 133 | mGestureBlockingActivityRunning = isGestureBlockingActivityRunning(); |
| 134 | } |
| 135 | }; |
| 136 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 137 | private final Context mContext; |
Winson Chung | 04ff8bda | 2019-04-02 15:08:59 -0700 | [diff] [blame] | 138 | private final OverviewProxyService mOverviewProxyService; |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 139 | private final PluginManager mPluginManager; |
| 140 | // Activities which should not trigger Back gesture. |
| 141 | private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 142 | |
| 143 | private final Point mDisplaySize = new Point(); |
| 144 | private final int mDisplayId; |
| 145 | |
| 146 | private final Executor mMainExecutor; |
| 147 | |
| 148 | private final Region mExcludeRegion = new Region(); |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 149 | private final Region mUnrestrictedExcludeRegion = new Region(); |
| 150 | |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 151 | // The left side edge width where touch down is allowed |
| 152 | private int mEdgeWidthLeft; |
| 153 | // The right side edge width where touch down is allowed |
| 154 | private int mEdgeWidthRight; |
Winson Chung | 77b2d1d | 2019-12-20 15:18:42 -0800 | [diff] [blame] | 155 | // The bottom gesture area height |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 156 | private float mBottomGestureHeight; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 157 | // The slop to distinguish between horizontal and vertical motion |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 158 | private float mTouchSlop; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 159 | // Duration after which we consider the event as longpress. |
| 160 | private final int mLongPressTimeout; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 161 | private int mStartingQuickstepRotation = -1; |
| 162 | // We temporarily disable back gesture when user is quickswitching |
| 163 | // between apps of different orientations |
| 164 | private boolean mDisabledForQuickstep; |
| 165 | private boolean mFixedRotationFlagEnabled; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 166 | |
| 167 | private final PointF mDownPoint = new PointF(); |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 168 | private final PointF mEndPoint = new PointF(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 169 | private boolean mThresholdCrossed = false; |
Winson Chung | e2a686d | 2019-04-17 16:54:23 -0700 | [diff] [blame] | 170 | private boolean mAllowGesture = false; |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 171 | private boolean mLogGesture = false; |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 172 | private boolean mInRejectedExclusion = false; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 173 | private boolean mIsOnLeftEdge; |
| 174 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 175 | private boolean mIsAttached; |
| 176 | private boolean mIsGesturalModeEnabled; |
| 177 | private boolean mIsEnabled; |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 178 | private boolean mIsNavBarShownTransiently; |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 179 | private boolean mIsBackGestureAllowed; |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 180 | private boolean mGestureBlockingActivityRunning; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 181 | |
| 182 | private InputMonitor mInputMonitor; |
| 183 | private InputEventReceiver mInputEventReceiver; |
| 184 | |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 185 | private NavigationEdgeBackPlugin mEdgeBackPlugin; |
Selim Cinek | e50b121 | 2019-06-04 18:40:31 -0700 | [diff] [blame] | 186 | private int mLeftInset; |
| 187 | private int mRightInset; |
Vinit Nayak | 59b114e6 | 2019-08-12 11:50:00 -0700 | [diff] [blame] | 188 | private int mSysUiFlags; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 189 | |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 190 | private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver; |
| 191 | |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 192 | private final NavigationEdgeBackPlugin.BackCallback mBackCallback = |
| 193 | new NavigationEdgeBackPlugin.BackCallback() { |
| 194 | @Override |
| 195 | public void triggerBack() { |
| 196 | sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); |
| 197 | sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK); |
| 198 | |
| 199 | mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x, |
| 200 | (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 201 | logGesture(mInRejectedExclusion |
| 202 | ? SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED |
| 203 | : SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | @Override |
| 207 | public void cancelBack() { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 208 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 209 | mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x, |
| 210 | (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 211 | } |
| 212 | }; |
| 213 | |
Vinit Nayak | 59b114e6 | 2019-08-12 11:50:00 -0700 | [diff] [blame] | 214 | public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService, |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 215 | SysUiState sysUiFlagContainer, PluginManager pluginManager) { |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 216 | super(Dependency.get(BroadcastDispatcher.class)); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 217 | mContext = context; |
| 218 | mDisplayId = context.getDisplayId(); |
| 219 | mMainExecutor = context.getMainExecutor(); |
Winson Chung | 04ff8bda | 2019-04-02 15:08:59 -0700 | [diff] [blame] | 220 | mOverviewProxyService = overviewProxyService; |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 221 | mPluginManager = pluginManager; |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 222 | ComponentName recentsComponentName = ComponentName.unflattenFromString( |
| 223 | context.getString(com.android.internal.R.string.config_recentsComponentName)); |
| 224 | if (recentsComponentName != null) { |
| 225 | String recentsPackageName = recentsComponentName.getPackageName(); |
| 226 | PackageManager manager = context.getPackageManager(); |
| 227 | try { |
| 228 | Resources resources = manager.getResourcesForApplication(recentsPackageName); |
| 229 | int resId = resources.getIdentifier( |
| 230 | "gesture_blocking_activities", "array", recentsPackageName); |
| 231 | |
| 232 | if (resId == 0) { |
| 233 | Log.e(TAG, "No resource found for gesture-blocking activities"); |
| 234 | } else { |
| 235 | String[] gestureBlockingActivities = resources.getStringArray(resId); |
| 236 | for (String gestureBlockingActivity : gestureBlockingActivities) { |
| 237 | mGestureBlockingActivities.add( |
| 238 | ComponentName.unflattenFromString(gestureBlockingActivity)); |
| 239 | } |
| 240 | } |
| 241 | } catch (NameNotFoundException e) { |
| 242 | Log.e(TAG, "Failed to add gesture blocking activities", e); |
| 243 | } |
| 244 | } |
Winson Chung | a657ac9 | 2019-12-09 16:43:46 -0800 | [diff] [blame] | 245 | Dependency.get(ProtoTracer.class).add(this); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 246 | |
Winson Chung | 05d4be3 | 2019-06-19 13:12:10 -0700 | [diff] [blame] | 247 | mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT, |
| 248 | ViewConfiguration.getLongPressTimeout()); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 249 | |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 250 | mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver( |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 251 | mContext.getMainThreadHandler(), mContext, this::updateCurrentUserResources); |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 252 | |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 253 | updateCurrentUserResources(); |
Vinit Nayak | 59b114e6 | 2019-08-12 11:50:00 -0700 | [diff] [blame] | 254 | sysUiFlagContainer.addCallback(sysUiFlags -> mSysUiFlags = sysUiFlags); |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 255 | } |
| 256 | |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 257 | public void updateCurrentUserResources() { |
| 258 | Resources res = Dependency.get(NavigationModeController.class).getCurrentUserContext() |
| 259 | .getResources(); |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 260 | mEdgeWidthLeft = mGestureNavigationSettingsObserver.getLeftSensitivity(res); |
| 261 | mEdgeWidthRight = mGestureNavigationSettingsObserver.getRightSensitivity(res); |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 262 | mIsBackGestureAllowed = |
| 263 | !mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible(); |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 264 | |
Winson Chung | 4ef8418 | 2020-05-01 15:22:47 -0700 | [diff] [blame] | 265 | final DisplayMetrics dm = res.getDisplayMetrics(); |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 266 | final float defaultGestureHeight = res.getDimension( |
Winson Chung | 4ef8418 | 2020-05-01 15:22:47 -0700 | [diff] [blame] | 267 | com.android.internal.R.dimen.navigation_bar_gesture_height) / dm.density; |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 268 | final float gestureHeight = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI, |
| 269 | SystemUiDeviceConfigFlags.BACK_GESTURE_BOTTOM_HEIGHT, |
| 270 | defaultGestureHeight); |
Winson Chung | 4ef8418 | 2020-05-01 15:22:47 -0700 | [diff] [blame] | 271 | mBottomGestureHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gestureHeight, |
| 272 | dm); |
Maryam | a142e52 | 2020-04-27 17:41:42 -0700 | [diff] [blame] | 273 | |
| 274 | // Reduce the default touch slop to ensure that we can intercept the gesture |
| 275 | // before the app starts to react to it. |
| 276 | // TODO(b/130352502) Tune this value and extract into a constant |
| 277 | final float backGestureSlop = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI, |
| 278 | SystemUiDeviceConfigFlags.BACK_GESTURE_SLOP_MULTIPLIER, 0.75f); |
| 279 | mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop() * backGestureSlop; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 280 | } |
| 281 | |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 282 | @Override |
| 283 | public void onUserSwitched(int newUserId) { |
| 284 | updateIsEnabled(); |
| 285 | updateCurrentUserResources(); |
| 286 | } |
| 287 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 288 | /** |
| 289 | * @see NavigationBarView#onAttachedToWindow() |
| 290 | */ |
| 291 | public void onNavBarAttached() { |
| 292 | mIsAttached = true; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 293 | updatedFixedRotation(); |
| 294 | if (mFixedRotationFlagEnabled) { |
| 295 | setRotationCallbacks(true); |
| 296 | } |
| 297 | mContext.getContentResolver().registerContentObserver( |
| 298 | Settings.Global.getUriFor(FIXED_ROTATION_TRANSFORM_SETTING_NAME), |
| 299 | false /* notifyForDescendants */, mFixedRotationObserver, UserHandle.USER_ALL); |
Winson Chung | 1aa24b9 | 2019-04-24 15:17:33 -0700 | [diff] [blame] | 300 | updateIsEnabled(); |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 301 | startTracking(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 302 | } |
| 303 | |
| 304 | /** |
| 305 | * @see NavigationBarView#onDetachedFromWindow() |
| 306 | */ |
| 307 | public void onNavBarDetached() { |
| 308 | mIsAttached = false; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 309 | if (mFixedRotationFlagEnabled) { |
| 310 | setRotationCallbacks(false); |
| 311 | } |
| 312 | mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 313 | updateIsEnabled(); |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 314 | stopTracking(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 315 | } |
| 316 | |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 317 | private void setRotationCallbacks(boolean enable) { |
| 318 | if (enable) { |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 319 | mOverviewProxyService.addCallback(mQuickSwitchListener); |
| 320 | } else { |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 321 | mOverviewProxyService.removeCallback(mQuickSwitchListener); |
| 322 | } |
| 323 | } |
| 324 | |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 325 | /** |
| 326 | * @see NavigationModeController.ModeChangedListener#onNavigationModeChanged |
| 327 | */ |
| 328 | public void onNavigationModeChanged(int mode) { |
Winson Chung | 1aa24b9 | 2019-04-24 15:17:33 -0700 | [diff] [blame] | 329 | mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 330 | updateIsEnabled(); |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 331 | updateCurrentUserResources(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 332 | } |
| 333 | |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 334 | public void onNavBarTransientStateChanged(boolean isTransient) { |
| 335 | mIsNavBarShownTransiently = isTransient; |
Winson Chung | 3d6c080 | 2019-10-04 10:37:12 -0700 | [diff] [blame] | 336 | } |
| 337 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 338 | private void disposeInputChannel() { |
| 339 | if (mInputEventReceiver != null) { |
| 340 | mInputEventReceiver.dispose(); |
| 341 | mInputEventReceiver = null; |
| 342 | } |
| 343 | if (mInputMonitor != null) { |
| 344 | mInputMonitor.dispose(); |
| 345 | mInputMonitor = null; |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | private void updateIsEnabled() { |
| 350 | boolean isEnabled = mIsAttached && mIsGesturalModeEnabled; |
| 351 | if (isEnabled == mIsEnabled) { |
| 352 | return; |
| 353 | } |
| 354 | mIsEnabled = isEnabled; |
| 355 | disposeInputChannel(); |
| 356 | |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 357 | if (mEdgeBackPlugin != null) { |
| 358 | mEdgeBackPlugin.onDestroy(); |
| 359 | mEdgeBackPlugin = null; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 360 | } |
| 361 | |
| 362 | if (!mIsEnabled) { |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 363 | mGestureNavigationSettingsObserver.unregister(); |
Sunny Goyal | 1904969 | 2019-04-08 11:56:07 -0700 | [diff] [blame] | 364 | mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 365 | mPluginManager.removePluginListener(this); |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 366 | ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 367 | |
| 368 | try { |
| 369 | WindowManagerGlobal.getWindowManagerService() |
| 370 | .unregisterSystemGestureExclusionListener( |
| 371 | mGestureExclusionListener, mDisplayId); |
Winson Chung | 939f5bd | 2020-04-14 15:05:11 -0700 | [diff] [blame] | 372 | } catch (RemoteException | IllegalArgumentException e) { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 373 | Log.e(TAG, "Failed to unregister window manager callbacks", e); |
| 374 | } |
| 375 | |
| 376 | } else { |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 377 | mGestureNavigationSettingsObserver.register(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 378 | updateDisplaySize(); |
Sunny Goyal | 1904969 | 2019-04-08 11:56:07 -0700 | [diff] [blame] | 379 | mContext.getSystemService(DisplayManager.class).registerDisplayListener(this, |
| 380 | mContext.getMainThreadHandler()); |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 381 | ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 382 | |
| 383 | try { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 384 | WindowManagerGlobal.getWindowManagerService() |
| 385 | .registerSystemGestureExclusionListener( |
| 386 | mGestureExclusionListener, mDisplayId); |
Winson Chung | 939f5bd | 2020-04-14 15:05:11 -0700 | [diff] [blame] | 387 | } catch (RemoteException | IllegalArgumentException e) { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 388 | Log.e(TAG, "Failed to register window manager callbacks", e); |
| 389 | } |
| 390 | |
| 391 | // Register input event receiver |
| 392 | mInputMonitor = InputManager.getInstance().monitorGestureInput( |
| 393 | "edge-swipe", mDisplayId); |
Siarhei Vishniakou | faa8799 | 2019-05-29 09:12:18 -0700 | [diff] [blame] | 394 | mInputEventReceiver = new SysUiInputEventReceiver( |
| 395 | mInputMonitor.getInputChannel(), Looper.getMainLooper()); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 396 | |
| 397 | // Add a nav bar panel window |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 398 | setEdgeBackPlugin(new NavigationBarEdgePanel(mContext)); |
| 399 | mPluginManager.addPluginListener( |
| 400 | this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 401 | } |
| 402 | } |
| 403 | |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 404 | @Override |
| 405 | public void onPluginConnected(NavigationEdgeBackPlugin plugin, Context context) { |
| 406 | setEdgeBackPlugin(plugin); |
| 407 | } |
| 408 | |
| 409 | @Override |
| 410 | public void onPluginDisconnected(NavigationEdgeBackPlugin plugin) { |
| 411 | setEdgeBackPlugin(new NavigationBarEdgePanel(mContext)); |
| 412 | } |
| 413 | |
| 414 | private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) { |
| 415 | if (mEdgeBackPlugin != null) { |
| 416 | mEdgeBackPlugin.onDestroy(); |
| 417 | } |
| 418 | mEdgeBackPlugin = edgeBackPlugin; |
| 419 | mEdgeBackPlugin.setBackCallback(mBackCallback); |
| 420 | mEdgeBackPlugin.setLayoutParams(createLayoutParams()); |
| 421 | updateDisplaySize(); |
| 422 | } |
| 423 | |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 424 | public boolean isHandlingGestures() { |
| 425 | return mIsEnabled && mIsBackGestureAllowed; |
| 426 | } |
| 427 | |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 428 | private WindowManager.LayoutParams createLayoutParams() { |
| 429 | Resources resources = mContext.getResources(); |
| 430 | WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( |
| 431 | resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_width), |
| 432 | resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_height), |
| 433 | WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, |
| 434 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
| 435 | | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
| 436 | | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH |
| 437 | | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, |
| 438 | PixelFormat.TRANSLUCENT); |
| 439 | layoutParams.privateFlags |= |
| 440 | WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; |
| 441 | layoutParams.setTitle(TAG + mContext.getDisplayId()); |
| 442 | layoutParams.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel); |
| 443 | layoutParams.windowAnimations = 0; |
Tiger Huang | 5272444 | 2020-01-20 21:38:42 +0800 | [diff] [blame] | 444 | layoutParams.setFitInsetsTypes(0 /* types */); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 445 | return layoutParams; |
| 446 | } |
| 447 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 448 | private void onInputEvent(InputEvent ev) { |
| 449 | if (ev instanceof MotionEvent) { |
| 450 | onMotionEvent((MotionEvent) ev); |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | private boolean isWithinTouchRegion(int x, int y) { |
Winson Chung | 77b2d1d | 2019-12-20 15:18:42 -0800 | [diff] [blame] | 455 | // Disallow if we are in the bottom gesture area |
| 456 | if (y >= (mDisplaySize.y - mBottomGestureHeight)) { |
| 457 | return false; |
| 458 | } |
| 459 | |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 460 | // If the point is way too far (twice the margin), it is |
| 461 | // not interesting to us for logging purposes, nor we |
| 462 | // should process it. Simply return false and keep |
| 463 | // mLogGesture = false. |
| 464 | if (x > 2 * (mEdgeWidthLeft + mLeftInset) |
| 465 | && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) { |
| 466 | return false; |
Winson Chung | 3d6c080 | 2019-10-04 10:37:12 -0700 | [diff] [blame] | 467 | } |
| 468 | |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 469 | // Denotes whether we should proceed with the gesture. |
| 470 | // Even if it is false, we may want to log it assuming |
| 471 | // it is not invalid due to exclusion. |
| 472 | boolean withinRange = x <= mEdgeWidthLeft + mLeftInset |
| 473 | || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset); |
| 474 | |
| 475 | // Always allow if the user is in a transient sticky immersive state |
| 476 | if (mIsNavBarShownTransiently) { |
| 477 | mLogGesture = true; |
| 478 | return withinRange; |
Winson Chung | 51787a1 | 2019-04-10 15:33:31 -0700 | [diff] [blame] | 479 | } |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 480 | |
| 481 | if (mExcludeRegion.contains(x, y)) { |
| 482 | if (withinRange) { |
| 483 | // Log as exclusion only if it is in acceptable range in the first place. |
| 484 | mOverviewProxyService.notifyBackAction( |
| 485 | false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge); |
| 486 | // We don't have the end point for logging purposes. |
| 487 | mEndPoint.x = -1; |
| 488 | mEndPoint.y = -1; |
| 489 | mLogGesture = true; |
| 490 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED); |
| 491 | } |
| 492 | return false; |
| 493 | } |
| 494 | |
| 495 | mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y); |
| 496 | mLogGesture = true; |
| 497 | return withinRange; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 498 | } |
| 499 | |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 500 | private void cancelGesture(MotionEvent ev) { |
| 501 | // Send action cancel to reset all the touch events |
| 502 | mAllowGesture = false; |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 503 | mLogGesture = false; |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 504 | mInRejectedExclusion = false; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 505 | MotionEvent cancelEv = MotionEvent.obtain(ev); |
| 506 | cancelEv.setAction(MotionEvent.ACTION_CANCEL); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 507 | mEdgeBackPlugin.onMotionEvent(cancelEv); |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 508 | cancelEv.recycle(); |
| 509 | } |
| 510 | |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 511 | private void logGesture(int backType) { |
| 512 | if (!mLogGesture) { |
| 513 | return; |
| 514 | } |
| 515 | mLogGesture = false; |
| 516 | SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backType, |
| 517 | (int) mDownPoint.y, mIsOnLeftEdge |
| 518 | ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT |
| 519 | : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT, |
| 520 | (int) mDownPoint.x, (int) mDownPoint.y, |
| 521 | (int) mEndPoint.x, (int) mEndPoint.y, |
| 522 | mEdgeWidthLeft + mLeftInset, |
| 523 | mDisplaySize.x - (mEdgeWidthRight + mRightInset)); |
| 524 | } |
| 525 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 526 | private void onMotionEvent(MotionEvent ev) { |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 527 | int action = ev.getActionMasked(); |
| 528 | if (action == MotionEvent.ACTION_DOWN) { |
Winson Chung | e2a686d | 2019-04-17 16:54:23 -0700 | [diff] [blame] | 529 | // Verify if this is in within the touch region and we aren't in immersive mode, and |
| 530 | // either the bouncer is showing or the notification panel is hidden |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 531 | mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset; |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 532 | mLogGesture = false; |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 533 | mInRejectedExclusion = false; |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 534 | mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 535 | && !mGestureBlockingActivityRunning |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 536 | && !QuickStepContract.isBackGestureDisabled(mSysUiFlags) |
| 537 | && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()); |
Winson Chung | e2a686d | 2019-04-17 16:54:23 -0700 | [diff] [blame] | 538 | if (mAllowGesture) { |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 539 | mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge); |
| 540 | mEdgeBackPlugin.onMotionEvent(ev); |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 541 | } |
| 542 | if (mLogGesture) { |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 543 | mDownPoint.set(ev.getX(), ev.getY()); |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 544 | mEndPoint.set(-1, -1); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 545 | mThresholdCrossed = false; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 546 | } |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 547 | } else if (mAllowGesture || mLogGesture) { |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 548 | if (!mThresholdCrossed) { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 549 | mEndPoint.x = (int) ev.getX(); |
| 550 | mEndPoint.y = (int) ev.getY(); |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 551 | if (action == MotionEvent.ACTION_POINTER_DOWN) { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 552 | if (mAllowGesture) { |
| 553 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH); |
| 554 | // We do not support multi touch for back gesture |
| 555 | cancelGesture(ev); |
| 556 | } |
| 557 | mLogGesture = false; |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 558 | return; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 559 | } else if (action == MotionEvent.ACTION_MOVE) { |
| 560 | if ((ev.getEventTime() - ev.getDownTime()) > mLongPressTimeout) { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 561 | if (mAllowGesture) { |
| 562 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_LONG_PRESS); |
| 563 | cancelGesture(ev); |
| 564 | } |
| 565 | mLogGesture = false; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 566 | return; |
| 567 | } |
| 568 | float dx = Math.abs(ev.getX() - mDownPoint.x); |
| 569 | float dy = Math.abs(ev.getY() - mDownPoint.y); |
| 570 | if (dy > dx && dy > mTouchSlop) { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 571 | if (mAllowGesture) { |
| 572 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE); |
| 573 | cancelGesture(ev); |
| 574 | } |
| 575 | mLogGesture = false; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 576 | return; |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 577 | } else if (dx > dy && dx > mTouchSlop) { |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 578 | if (mAllowGesture) { |
| 579 | mThresholdCrossed = true; |
| 580 | // Capture inputs |
| 581 | mInputMonitor.pilferPointers(); |
| 582 | } else { |
| 583 | logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE); |
| 584 | } |
Sunny Goyal | 3c317f3 | 2019-05-21 11:49:11 -0700 | [diff] [blame] | 585 | } |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 586 | } |
| 587 | } |
| 588 | |
Maryam Karimzadehgan | 4f9ab82 | 2020-03-09 14:51:07 -0700 | [diff] [blame] | 589 | if (mAllowGesture) { |
| 590 | // forward touch |
| 591 | mEdgeBackPlugin.onMotionEvent(ev); |
| 592 | } |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 593 | } |
Winson Chung | a657ac9 | 2019-12-09 16:43:46 -0800 | [diff] [blame] | 594 | |
| 595 | Dependency.get(ProtoTracer.class).update(); |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 596 | } |
| 597 | |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 598 | private void updateDisabledForQuickstep() { |
| 599 | int rotation = mContext.getResources().getConfiguration().windowConfiguration.getRotation(); |
Vinit Nayak | a2b672c | 2020-04-27 18:35:14 -0700 | [diff] [blame] | 600 | mDisabledForQuickstep = mStartingQuickstepRotation > -1 && |
| 601 | mStartingQuickstepRotation != rotation; |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 602 | } |
| 603 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 604 | @Override |
| 605 | public void onDisplayAdded(int displayId) { } |
| 606 | |
| 607 | @Override |
| 608 | public void onDisplayRemoved(int displayId) { } |
| 609 | |
| 610 | @Override |
| 611 | public void onDisplayChanged(int displayId) { |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 612 | if (mStartingQuickstepRotation > -1) { |
| 613 | updateDisabledForQuickstep(); |
| 614 | } |
| 615 | |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 616 | if (displayId == mDisplayId) { |
| 617 | updateDisplaySize(); |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | private void updateDisplaySize() { |
Riddle Hsu | 410d975 | 2020-02-06 17:29:04 +0800 | [diff] [blame] | 622 | mContext.getDisplay().getRealSize(mDisplaySize); |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 623 | if (mEdgeBackPlugin != null) { |
| 624 | mEdgeBackPlugin.setDisplaySize(mDisplaySize); |
| 625 | } |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 626 | } |
| 627 | |
| 628 | private void sendEvent(int action, int code) { |
| 629 | long when = SystemClock.uptimeMillis(); |
| 630 | final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */, |
| 631 | 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, |
| 632 | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, |
| 633 | InputDevice.SOURCE_KEYBOARD); |
Mady Mellor | 390bff4 | 2019-04-05 15:09:01 -0700 | [diff] [blame] | 634 | |
| 635 | // Bubble controller will give us a valid display id if it should get the back event |
| 636 | BubbleController bubbleController = Dependency.get(BubbleController.class); |
| 637 | int bubbleDisplayId = bubbleController.getExpandedDisplayId(mContext); |
| 638 | if (code == KeyEvent.KEYCODE_BACK && bubbleDisplayId != INVALID_DISPLAY) { |
| 639 | ev.setDisplayId(bubbleDisplayId); |
| 640 | } |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 641 | InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); |
| 642 | } |
Siarhei Vishniakou | faa8799 | 2019-05-29 09:12:18 -0700 | [diff] [blame] | 643 | |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 644 | private void updatedFixedRotation() { |
| 645 | boolean oldFlag = mFixedRotationFlagEnabled; |
| 646 | mFixedRotationFlagEnabled = Settings.Global.getInt(mContext.getContentResolver(), |
| 647 | FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0; |
| 648 | if (oldFlag == mFixedRotationFlagEnabled) { |
| 649 | return; |
| 650 | } |
| 651 | |
| 652 | setRotationCallbacks(mFixedRotationFlagEnabled); |
| 653 | } |
| 654 | |
Selim Cinek | e50b121 | 2019-06-04 18:40:31 -0700 | [diff] [blame] | 655 | public void setInsets(int leftInset, int rightInset) { |
| 656 | mLeftInset = leftInset; |
| 657 | mRightInset = rightInset; |
Andy Wickham | 2029701 | 2019-11-06 14:56:26 -0800 | [diff] [blame] | 658 | if (mEdgeBackPlugin != null) { |
| 659 | mEdgeBackPlugin.setInsets(leftInset, rightInset); |
| 660 | } |
Selim Cinek | e50b121 | 2019-06-04 18:40:31 -0700 | [diff] [blame] | 661 | } |
| 662 | |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 663 | public void dump(PrintWriter pw) { |
| 664 | pw.println("EdgeBackGestureHandler:"); |
| 665 | pw.println(" mIsEnabled=" + mIsEnabled); |
Sunny Goyal | 3841295 | 2020-04-17 11:35:37 -0700 | [diff] [blame] | 666 | pw.println(" mIsBackGestureAllowed=" + mIsBackGestureAllowed); |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 667 | pw.println(" mAllowGesture=" + mAllowGesture); |
Vinit Nayak | f848e9d | 2020-03-24 16:04:09 -0700 | [diff] [blame] | 668 | pw.println(" mDisabledForQuickstep=" + mDisabledForQuickstep); |
Vinit Nayak | 8da8175 | 2020-05-27 22:22:14 -0700 | [diff] [blame] | 669 | pw.println(" mStartingQuickstepRotation=" + mStartingQuickstepRotation); |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 670 | pw.println(" mInRejectedExclusion" + mInRejectedExclusion); |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 671 | pw.println(" mExcludeRegion=" + mExcludeRegion); |
Hyunyoung Song | 36d7a2f | 2019-08-05 17:19:54 -0700 | [diff] [blame] | 672 | pw.println(" mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion); |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 673 | pw.println(" mIsAttached=" + mIsAttached); |
Mehdi Alizadeh | f2b28e9 | 2019-12-05 20:13:49 -0800 | [diff] [blame] | 674 | pw.println(" mEdgeWidthLeft=" + mEdgeWidthLeft); |
| 675 | pw.println(" mEdgeWidthRight=" + mEdgeWidthRight); |
Winson Chung | 316f673 | 2019-06-14 09:31:46 -0700 | [diff] [blame] | 676 | } |
| 677 | |
Andy Wickham | 3b3b9db | 2020-02-18 19:02:11 +0000 | [diff] [blame] | 678 | private boolean isGestureBlockingActivityRunning() { |
| 679 | ActivityManager.RunningTaskInfo runningTask = |
| 680 | ActivityManagerWrapper.getInstance().getRunningTask(); |
| 681 | ComponentName topActivity = runningTask == null ? null : runningTask.topActivity; |
| 682 | return topActivity != null && mGestureBlockingActivities.contains(topActivity); |
| 683 | } |
| 684 | |
Winson Chung | a657ac9 | 2019-12-09 16:43:46 -0800 | [diff] [blame] | 685 | @Override |
| 686 | public void writeToProto(SystemUiTraceProto proto) { |
| 687 | if (proto.edgeBackGestureHandler == null) { |
| 688 | proto.edgeBackGestureHandler = new EdgeBackGestureHandlerProto(); |
| 689 | } |
| 690 | proto.edgeBackGestureHandler.allowGesture = mAllowGesture; |
| 691 | } |
| 692 | |
Siarhei Vishniakou | faa8799 | 2019-05-29 09:12:18 -0700 | [diff] [blame] | 693 | class SysUiInputEventReceiver extends InputEventReceiver { |
| 694 | SysUiInputEventReceiver(InputChannel channel, Looper looper) { |
| 695 | super(channel, looper); |
| 696 | } |
| 697 | |
| 698 | public void onInputEvent(InputEvent event) { |
| 699 | EdgeBackGestureHandler.this.onInputEvent(event); |
| 700 | finishInputEvent(event, true); |
| 701 | } |
| 702 | } |
Sunny Goyal | a6a5812 | 2019-04-02 10:20:29 -0700 | [diff] [blame] | 703 | } |