blob: e5caf68c416efae12cbc7a458bab47d109dc691a [file] [log] [blame]
Matthew Ng13dbf872017-10-27 11:02:14 -07001/*
2 * Copyright (C) 2017 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
Winson Chung2dbcf092018-10-24 13:00:41 -070017package com.android.systemui.recents;
Matthew Ng13dbf872017-10-27 11:02:14 -070018
Matthew Nga3fee342019-02-25 15:36:37 -080019import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
Winson Chung7e486912019-04-30 11:11:47 -070020import static android.view.Display.DEFAULT_DISPLAY;
Gus Prevasab336792018-11-14 13:52:20 -050021import static android.view.MotionEvent.ACTION_CANCEL;
Hyunyoung Song547e11e2018-10-04 16:32:23 -070022import static android.view.MotionEvent.ACTION_DOWN;
23import static android.view.MotionEvent.ACTION_UP;
Winson Chung1aa24b92019-04-24 15:17:33 -070024import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
Hyunyoung Song547e11e2018-10-04 16:32:23 -070025
Sunny Goyala6a58122019-04-02 10:20:29 -070026import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
Sunny Goyalaac6c882019-02-11 11:57:58 -080027import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
28import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
29import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
Winson Chung60887932019-06-13 22:37:31 -070030import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
31import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
32import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
Winson Chung67f5c8b2018-09-24 12:09:19 -070033
Matthew Ng42025e32019-02-20 15:02:58 -080034import android.annotation.FloatRange;
Winson Chung4d30e9e2019-04-24 15:13:38 -070035import android.app.ActivityTaskManager;
Matthew Ng30c0a022017-11-10 14:06:29 -080036import android.content.BroadcastReceiver;
Matthew Ng13dbf872017-10-27 11:02:14 -070037import android.content.ComponentName;
38import android.content.Context;
39import android.content.Intent;
Matthew Ng30c0a022017-11-10 14:06:29 -080040import android.content.IntentFilter;
Matthew Ng13dbf872017-10-27 11:02:14 -070041import android.content.ServiceConnection;
Winson Chung38d31c22017-11-08 14:32:32 -080042import android.graphics.Rect;
Sunny Goyalaac6c882019-02-11 11:57:58 -080043import android.graphics.Region;
Sunny Goyala6a58122019-04-02 10:20:29 -070044import android.hardware.input.InputManager;
Winson Chung38d31c22017-11-08 14:32:32 -080045import android.os.Binder;
Sunny Goyalaac6c882019-02-11 11:57:58 -080046import android.os.Bundle;
Matthew Ng13dbf872017-10-27 11:02:14 -070047import android.os.Handler;
48import android.os.IBinder;
Matthew Ngfac87832017-11-10 11:27:29 -080049import android.os.Looper;
Matthew Ng30c0a022017-11-10 14:06:29 -080050import android.os.PatternMatcher;
Matthew Ng13dbf872017-10-27 11:02:14 -070051import android.os.RemoteException;
52import android.os.UserHandle;
53import android.util.Log;
Sunny Goyala6a58122019-04-02 10:20:29 -070054import android.view.InputMonitor;
Hyunyoung Songc1647ea2018-08-20 12:23:46 -070055import android.view.MotionEvent;
Sunny Goyal247eb892019-04-24 11:36:37 -070056import android.view.accessibility.AccessibilityManager;
Gus Prevasab336792018-11-14 13:52:20 -050057
Lucas Dupin086c6fc2018-10-16 18:06:43 -070058import com.android.internal.policy.ScreenDecorationsUtils;
Winson Chung2dbcf092018-10-24 13:00:41 -070059import com.android.systemui.Dumpable;
Winson Chung2dbcf092018-10-24 13:00:41 -070060import com.android.systemui.SysUiServiceProvider;
61import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
Winson Chung38d31c22017-11-08 14:32:32 -080062import com.android.systemui.shared.recents.IOverviewProxy;
63import com.android.systemui.shared.recents.ISystemUiProxy;
Winson Chungd95a2252018-04-04 17:02:29 +000064import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chunge108b672019-03-06 16:11:28 -080065import com.android.systemui.shared.system.QuickStepContract;
Winson Chunga3132982019-04-08 13:27:47 -070066import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
Matthew Ngc603a502018-04-18 17:14:22 -070067import com.android.systemui.stackdivider.Divider;
Winson Chunga3132982019-04-08 13:27:47 -070068import com.android.systemui.statusbar.NavigationBarController;
69import com.android.systemui.statusbar.phone.NavigationBarFragment;
Winson Chunga7067002019-05-07 11:50:42 -070070import com.android.systemui.statusbar.phone.NavigationBarView;
Winson Chung1aa24b92019-04-24 15:17:33 -070071import com.android.systemui.statusbar.phone.NavigationModeController;
Winson Chungcaf2b812018-01-26 10:29:46 -080072import com.android.systemui.statusbar.phone.StatusBar;
Winson Chung60887932019-06-13 22:37:31 -070073import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
Winson Chung7bbeb452019-06-04 10:25:50 -070074import com.android.systemui.statusbar.phone.StatusBarWindowController;
Matthew Ng7d05e772017-11-09 14:41:07 -080075import com.android.systemui.statusbar.policy.CallbackController;
Matthew Ng13dbf872017-10-27 11:02:14 -070076import com.android.systemui.statusbar.policy.DeviceProvisionedController;
77import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
Gus Prevasab336792018-11-14 13:52:20 -050078
Matthew Ng1e43ebd2017-11-14 14:47:05 -080079import java.io.FileDescriptor;
80import java.io.PrintWriter;
Matthew Ng7d05e772017-11-09 14:41:07 -080081import java.util.ArrayList;
82import java.util.List;
Matthew Ng13dbf872017-10-27 11:02:14 -070083
Jason Monk196d6392018-12-20 13:25:34 -050084import javax.inject.Inject;
85import javax.inject.Singleton;
86
Matthew Ng13dbf872017-10-27 11:02:14 -070087/**
88 * Class to send information from overview to launcher with a binder.
89 */
Jason Monk196d6392018-12-20 13:25:34 -050090@Singleton
Winson Chung1aa24b92019-04-24 15:17:33 -070091public class OverviewProxyService implements CallbackController<OverviewProxyListener>,
92 NavigationModeController.ModeChangedListener, Dumpable {
Matthew Ng13dbf872017-10-27 11:02:14 -070093
Sunny Goyal09c12d72018-03-27 10:14:49 -070094 private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
95
Matthew Ngbd824572018-01-17 16:25:56 -080096 public static final String TAG_OPS = "OverviewProxyService";
Matthew Ng96087482018-06-27 15:32:09 -070097 private static final long BACKOFF_MILLIS = 1000;
Matthew Nge3c5af42018-05-02 16:58:44 -070098 private static final long DEFERRED_CALLBACK_MILLIS = 5000;
Matthew Ng13dbf872017-10-27 11:02:14 -070099
Matthew Ngead8e5a2018-08-20 17:20:05 -0700100 // Max backoff caps at 5 mins
101 private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
102
Matthew Ng13dbf872017-10-27 11:02:14 -0700103 private final Context mContext;
104 private final Handler mHandler;
Winson Chung9e572492019-06-07 10:48:45 -0700105 private final NavigationBarController mNavBarController;
106 private final StatusBarWindowController mStatusBarWinController;
Matthew Ngfac87832017-11-10 11:27:29 -0800107 private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
Sunny Goyal09c12d72018-03-27 10:14:49 -0700108 private final ComponentName mRecentsComponentName;
Jason Monk96a37f42018-12-21 14:45:26 -0500109 private final DeviceProvisionedController mDeviceProvisionedController;
Matthew Ng7d05e772017-11-09 14:41:07 -0800110 private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
Winson Chungd95a2252018-04-04 17:02:29 +0000111 private final Intent mQuickStepIntent;
Matthew Ng13dbf872017-10-27 11:02:14 -0700112
Sunny Goyalaac6c882019-02-11 11:57:58 -0800113 private Region mActiveNavBarRegion;
114
Matthew Ng13dbf872017-10-27 11:02:14 -0700115 private IOverviewProxy mOverviewProxy;
116 private int mConnectionBackoffAttempts;
Winson Chunga3132982019-04-08 13:27:47 -0700117 private @SystemUiStateFlags int mSysUiStateFlags;
Winson Chung67f20282019-03-12 23:53:24 -0700118 private boolean mBound;
Winson Chungd95a2252018-04-04 17:02:29 +0000119 private boolean mIsEnabled;
Matthew Ngffb17372018-07-18 12:31:29 -0700120 private int mCurrentBoundedUserId = -1;
Sunny Goyalc73ce702019-06-16 13:50:07 -0700121 private float mNavBarButtonAlpha;
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700122 private MotionEvent mStatusBarGestureDownEvent;
Lucas Dupin086c6fc2018-10-16 18:06:43 -0700123 private float mWindowCornerRadius;
Lucas Dupinf36d0dc2019-01-09 09:07:50 -0800124 private boolean mSupportsRoundedCornersOnWindows;
Winson Chung1aa24b92019-04-24 15:17:33 -0700125 private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
Matthew Ng13dbf872017-10-27 11:02:14 -0700126
Winson Chung38d31c22017-11-08 14:32:32 -0800127 private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
Winson Chungcaf2b812018-01-26 10:29:46 -0800128
Sunny Goyal247eb892019-04-24 11:36:37 -0700129 @Override
Winson Chungcaf2b812018-01-26 10:29:46 -0800130 public void startScreenPinning(int taskId) {
Matthew Ngffb17372018-07-18 12:31:29 -0700131 if (!verifyCaller("startScreenPinning")) {
132 return;
133 }
Winson Chungcaf2b812018-01-26 10:29:46 -0800134 long token = Binder.clearCallingIdentity();
135 try {
136 mHandler.post(() -> {
Winson Chung06ca2742018-06-29 12:26:49 -0700137 StatusBar statusBar = SysUiServiceProvider.getComponent(mContext,
Winson Chungcaf2b812018-01-26 10:29:46 -0800138 StatusBar.class);
139 if (statusBar != null) {
140 statusBar.showScreenPinningRequest(taskId, false /* allowCancel */);
141 }
142 });
143 } finally {
144 Binder.restoreCallingIdentity(token);
145 }
146 }
147
Sunny Goyal247eb892019-04-24 11:36:37 -0700148 @Override
Winson Chung4d30e9e2019-04-24 15:13:38 -0700149 public void stopScreenPinning() {
150 if (!verifyCaller("stopScreenPinning")) {
151 return;
152 }
153 long token = Binder.clearCallingIdentity();
154 try {
155 mHandler.post(() -> {
156 try {
157 ActivityTaskManager.getService().stopSystemLockTaskMode();
158 } catch (RemoteException e) {
159 Log.e(TAG_OPS, "Failed to stop screen pinning");
160 }
161 });
162 } finally {
163 Binder.restoreCallingIdentity(token);
164 }
165 }
166
167 @Override
Hyunyoung Songc1647ea2018-08-20 12:23:46 -0700168 public void onStatusBarMotionEvent(MotionEvent event) {
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700169 if (!verifyCaller("onStatusBarMotionEvent")) {
170 return;
171 }
Hyunyoung Songc1647ea2018-08-20 12:23:46 -0700172 long token = Binder.clearCallingIdentity();
173 try {
174 // TODO move this logic to message queue
175 mHandler.post(()->{
176 StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
177 if (bar != null) {
178 bar.dispatchNotificationsPanelTouchEvent(event);
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700179
180 int action = event.getActionMasked();
181 if (action == ACTION_DOWN) {
182 mStatusBarGestureDownEvent = MotionEvent.obtain(event);
183 }
184 if (action == ACTION_UP || action == ACTION_CANCEL) {
185 mStatusBarGestureDownEvent.recycle();
186 mStatusBarGestureDownEvent = null;
187 }
188 event.recycle();
Hyunyoung Songc1647ea2018-08-20 12:23:46 -0700189 }
190 });
191 } finally {
192 Binder.restoreCallingIdentity(token);
193 }
194 }
195
Sunny Goyal247eb892019-04-24 11:36:37 -0700196 @Override
Winson Chungc1674272018-02-21 10:15:17 -0800197 public void onSplitScreenInvoked() {
Matthew Ngffb17372018-07-18 12:31:29 -0700198 if (!verifyCaller("onSplitScreenInvoked")) {
199 return;
200 }
Winson Chungc1674272018-02-21 10:15:17 -0800201 long token = Binder.clearCallingIdentity();
202 try {
Winson Chung67f5c8b2018-09-24 12:09:19 -0700203 Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
204 if (divider != null) {
205 divider.onDockedFirstAnimationFrame();
206 }
Winson Chungc1674272018-02-21 10:15:17 -0800207 } finally {
208 Binder.restoreCallingIdentity(token);
209 }
210 }
211
Sunny Goyal247eb892019-04-24 11:36:37 -0700212 @Override
Tracy Zhou27599052018-04-16 15:47:29 -0700213 public void onOverviewShown(boolean fromHome) {
Matthew Ngffb17372018-07-18 12:31:29 -0700214 if (!verifyCaller("onOverviewShown")) {
215 return;
216 }
Tracy Zhou27599052018-04-16 15:47:29 -0700217 long token = Binder.clearCallingIdentity();
218 try {
219 mHandler.post(() -> {
220 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
221 mConnectionCallbacks.get(i).onOverviewShown(fromHome);
222 }
223 });
224 } finally {
225 Binder.restoreCallingIdentity(token);
226 }
227 }
228
Sunny Goyal247eb892019-04-24 11:36:37 -0700229 @Override
Matthew Ngc603a502018-04-18 17:14:22 -0700230 public Rect getNonMinimizedSplitScreenSecondaryBounds() {
Matthew Ngffb17372018-07-18 12:31:29 -0700231 if (!verifyCaller("getNonMinimizedSplitScreenSecondaryBounds")) {
232 return null;
233 }
Matthew Ngc603a502018-04-18 17:14:22 -0700234 long token = Binder.clearCallingIdentity();
235 try {
Winson Chung06ca2742018-06-29 12:26:49 -0700236 Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
Matthew Ngc603a502018-04-18 17:14:22 -0700237 if (divider != null) {
238 return divider.getView().getNonMinimizedSplitScreenSecondaryBounds();
239 }
240 return null;
241 } finally {
242 Binder.restoreCallingIdentity(token);
243 }
244 }
Matthew Ng96985e72018-05-08 15:46:13 -0700245
Sunny Goyal247eb892019-04-24 11:36:37 -0700246 @Override
Sunny Goyalc73ce702019-06-16 13:50:07 -0700247 public void setNavBarButtonAlpha(float alpha, boolean animate) {
248 if (!verifyCaller("setNavBarButtonAlpha")) {
Matthew Ngffb17372018-07-18 12:31:29 -0700249 return;
250 }
Matthew Ng96985e72018-05-08 15:46:13 -0700251 long token = Binder.clearCallingIdentity();
252 try {
Sunny Goyalc73ce702019-06-16 13:50:07 -0700253 mNavBarButtonAlpha = alpha;
254 mHandler.post(() -> notifyNavBarButtonAlphaChanged(alpha, animate));
Matthew Ng96985e72018-05-08 15:46:13 -0700255 } finally {
256 Binder.restoreCallingIdentity(token);
257 }
258 }
Matthew Ngffb17372018-07-18 12:31:29 -0700259
Sunny Goyal247eb892019-04-24 11:36:37 -0700260 @Override
Sunny Goyalc73ce702019-06-16 13:50:07 -0700261 public void setBackButtonAlpha(float alpha, boolean animate) {
262 setNavBarButtonAlpha(alpha, animate);
263 }
264
265 @Override
Matthew Ng42025e32019-02-20 15:02:58 -0800266 public void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {
267 if (!verifyCaller("onAssistantProgress")) {
268 return;
269 }
270 long token = Binder.clearCallingIdentity();
271 try {
272 mHandler.post(() -> notifyAssistantProgress(progress));
273 } finally {
274 Binder.restoreCallingIdentity(token);
275 }
276 }
277
Sunny Goyal247eb892019-04-24 11:36:37 -0700278 @Override
Miranda Kephart4be26902019-05-17 13:55:37 -0400279 public void onAssistantGestureCompletion(float velocity) {
280 if (!verifyCaller("onAssistantGestureCompletion")) {
281 return;
282 }
283 long token = Binder.clearCallingIdentity();
284 try {
285 mHandler.post(() -> notifyAssistantGestureCompletion(velocity));
286 } finally {
287 Binder.restoreCallingIdentity(token);
288 }
289 }
290
291 @Override
Matthew Ng42025e32019-02-20 15:02:58 -0800292 public void startAssistant(Bundle bundle) {
293 if (!verifyCaller("startAssistant")) {
294 return;
295 }
296 long token = Binder.clearCallingIdentity();
297 try {
298 mHandler.post(() -> notifyStartAssistant(bundle));
299 } finally {
300 Binder.restoreCallingIdentity(token);
301 }
302 }
303
Sunny Goyal247eb892019-04-24 11:36:37 -0700304 @Override
Sunny Goyala6a58122019-04-02 10:20:29 -0700305 public Bundle monitorGestureInput(String name, int displayId) {
306 if (!verifyCaller("monitorGestureInput")) {
307 return null;
308 }
309 long token = Binder.clearCallingIdentity();
310 try {
311 InputMonitor monitor =
312 InputManager.getInstance().monitorGestureInput(name, displayId);
313 Bundle result = new Bundle();
314 result.putParcelable(KEY_EXTRA_INPUT_MONITOR, monitor);
315 return result;
316 } finally {
317 Binder.restoreCallingIdentity(token);
318 }
319 }
320
Sunny Goyal247eb892019-04-24 11:36:37 -0700321 @Override
322 public void notifyAccessibilityButtonClicked(int displayId) {
323 if (!verifyCaller("notifyAccessibilityButtonClicked")) {
324 return;
325 }
326 long token = Binder.clearCallingIdentity();
327 try {
328 AccessibilityManager.getInstance(mContext)
329 .notifyAccessibilityButtonClicked(displayId);
330 } finally {
331 Binder.restoreCallingIdentity(token);
332 }
333 }
334
335 @Override
336 public void notifyAccessibilityButtonLongClicked() {
337 if (!verifyCaller("notifyAccessibilityButtonLongClicked")) {
338 return;
339 }
340 long token = Binder.clearCallingIdentity();
341 try {
342 Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
343 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
344 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
345 } finally {
346 Binder.restoreCallingIdentity(token);
347 }
348 }
349
Matthew Ngffb17372018-07-18 12:31:29 -0700350 private boolean verifyCaller(String reason) {
351 final int callerId = Binder.getCallingUserHandle().getIdentifier();
352 if (callerId != mCurrentBoundedUserId) {
353 Log.w(TAG_OPS, "Launcher called sysui with invalid user: " + callerId + ", reason: "
354 + reason);
355 return false;
356 }
357 return true;
358 }
Winson Chung38d31c22017-11-08 14:32:32 -0800359 };
360
Matthew Nge3c5af42018-05-02 16:58:44 -0700361 private final Runnable mDeferredConnectionCallback = () -> {
362 Log.w(TAG_OPS, "Binder supposed established connection but actual connection to service "
363 + "timed out, trying again");
Matthew Ngead8e5a2018-08-20 17:20:05 -0700364 retryConnectionWithBackoff();
Matthew Nge3c5af42018-05-02 16:58:44 -0700365 };
366
Winson Chungd95a2252018-04-04 17:02:29 +0000367 private final BroadcastReceiver mLauncherStateChangedReceiver = new BroadcastReceiver() {
Matthew Ng30c0a022017-11-10 14:06:29 -0800368 @Override
369 public void onReceive(Context context, Intent intent) {
Winson Chungd95a2252018-04-04 17:02:29 +0000370 updateEnabledState();
371
Matthew Ng30c0a022017-11-10 14:06:29 -0800372 // Reconnect immediately, instead of waiting for resume to arrive.
373 startConnectionToCurrentUser();
374 }
375 };
376
Matthew Ng13dbf872017-10-27 11:02:14 -0700377 private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
378 @Override
379 public void onServiceConnected(ComponentName name, IBinder service) {
Matthew Nge3c5af42018-05-02 16:58:44 -0700380 mConnectionBackoffAttempts = 0;
Winson Chung7378d282019-04-19 13:56:44 -0700381 mHandler.removeCallbacks(mDeferredConnectionCallback);
Matthew Nge3c5af42018-05-02 16:58:44 -0700382 try {
383 service.linkToDeath(mOverviewServiceDeathRcpt, 0);
384 } catch (RemoteException e) {
Winson Chung7378d282019-04-19 13:56:44 -0700385 // Failed to link to death (process may have died between binding and connecting),
386 // just unbind the service for now and retry again
Matthew Nge3c5af42018-05-02 16:58:44 -0700387 Log.e(TAG_OPS, "Lost connection to launcher service", e);
Winson Chung7378d282019-04-19 13:56:44 -0700388 disconnectFromLauncherService();
389 retryConnectionWithBackoff();
390 return;
Matthew Ng13dbf872017-10-27 11:02:14 -0700391 }
Sunny Goyalaac6c882019-02-11 11:57:58 -0800392
Winson Chung7378d282019-04-19 13:56:44 -0700393 mCurrentBoundedUserId = mDeviceProvisionedController.getCurrentUser();
394 mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
395
Sunny Goyalaac6c882019-02-11 11:57:58 -0800396 Bundle params = new Bundle();
397 params.putBinder(KEY_EXTRA_SYSUI_PROXY, mSysUiProxy.asBinder());
Sunny Goyalaac6c882019-02-11 11:57:58 -0800398 params.putFloat(KEY_EXTRA_WINDOW_CORNER_RADIUS, mWindowCornerRadius);
399 params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows);
400 try {
401 mOverviewProxy.onInitialize(params);
402 } catch (RemoteException e) {
Sunny Goyala6a58122019-04-02 10:20:29 -0700403 mCurrentBoundedUserId = -1;
404 Log.e(TAG_OPS, "Failed to call onInitialize()", e);
Sunny Goyalaac6c882019-02-11 11:57:58 -0800405 }
406 dispatchNavButtonBounds();
407
Winson Chunga3132982019-04-08 13:27:47 -0700408 // Update the systemui state flags
409 updateSystemUiStateFlags();
410
Matthew Nge3c5af42018-05-02 16:58:44 -0700411 notifyConnectionChanged();
412 }
413
414 @Override
415 public void onNullBinding(ComponentName name) {
416 Log.w(TAG_OPS, "Null binding of '" + name + "', try reconnecting");
Matthew Ngffb17372018-07-18 12:31:29 -0700417 mCurrentBoundedUserId = -1;
Matthew Ngead8e5a2018-08-20 17:20:05 -0700418 retryConnectionWithBackoff();
Matthew Nge3c5af42018-05-02 16:58:44 -0700419 }
420
421 @Override
422 public void onBindingDied(ComponentName name) {
423 Log.w(TAG_OPS, "Binding died of '" + name + "', try reconnecting");
Matthew Ngffb17372018-07-18 12:31:29 -0700424 mCurrentBoundedUserId = -1;
Matthew Ngead8e5a2018-08-20 17:20:05 -0700425 retryConnectionWithBackoff();
Matthew Ng13dbf872017-10-27 11:02:14 -0700426 }
427
428 @Override
429 public void onServiceDisconnected(ComponentName name) {
430 // Do nothing
Matthew Ngffb17372018-07-18 12:31:29 -0700431 mCurrentBoundedUserId = -1;
Matthew Ng13dbf872017-10-27 11:02:14 -0700432 }
433 };
434
435 private final DeviceProvisionedListener mDeviceProvisionedCallback =
436 new DeviceProvisionedListener() {
Winson Chunga3132982019-04-08 13:27:47 -0700437 @Override
438 public void onUserSetupChanged() {
439 if (mDeviceProvisionedController.isCurrentUserSetup()) {
Matthew Ngfac87832017-11-10 11:27:29 -0800440 internalConnectToCurrentUser();
Matthew Ng13dbf872017-10-27 11:02:14 -0700441 }
Winson Chunga3132982019-04-08 13:27:47 -0700442 }
443
444 @Override
445 public void onUserSwitched() {
446 mConnectionBackoffAttempts = 0;
447 internalConnectToCurrentUser();
448 }
449 };
Matthew Ng13dbf872017-10-27 11:02:14 -0700450
Winson Chung60887932019-06-13 22:37:31 -0700451 private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged;
452
Matthew Ng13dbf872017-10-27 11:02:14 -0700453 // This is the death handler for the binder from the launcher service
Matthew Ng30c0a022017-11-10 14:06:29 -0800454 private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700455 = this::cleanupAfterDeath;
Matthew Ng13dbf872017-10-27 11:02:14 -0700456
Jason Monk196d6392018-12-20 13:25:34 -0500457 @Inject
Winson Chung9e572492019-06-07 10:48:45 -0700458 public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
459 NavigationBarController navBarController, NavigationModeController navModeController,
460 StatusBarWindowController statusBarWinController) {
Matthew Ng13dbf872017-10-27 11:02:14 -0700461 mContext = context;
462 mHandler = new Handler();
Winson Chung9e572492019-06-07 10:48:45 -0700463 mNavBarController = navBarController;
464 mStatusBarWinController = statusBarWinController;
Jason Monk96a37f42018-12-21 14:45:26 -0500465 mDeviceProvisionedController = provisionController;
Matthew Ng13dbf872017-10-27 11:02:14 -0700466 mConnectionBackoffAttempts = 0;
Sunny Goyal09c12d72018-03-27 10:14:49 -0700467 mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
468 com.android.internal.R.string.config_recentsComponentName));
Winson Chungd95a2252018-04-04 17:02:29 +0000469 mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
470 .setPackage(mRecentsComponentName.getPackageName());
Lucas Dupin086c6fc2018-10-16 18:06:43 -0700471 mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(mContext.getResources());
Lucas Dupinf36d0dc2019-01-09 09:07:50 -0800472 mSupportsRoundedCornersOnWindows = ScreenDecorationsUtils
473 .supportsRoundedCornersOnWindows(mContext.getResources());
Matthew Ng30c0a022017-11-10 14:06:29 -0800474
Matthew Ng33b5e982019-03-27 17:15:10 -0700475 // Assumes device always starts with back button until launcher tells it that it does not
Sunny Goyalc73ce702019-06-16 13:50:07 -0700476 mNavBarButtonAlpha = 1.0f;
Matthew Ng33b5e982019-03-27 17:15:10 -0700477
Winson Chung1bb74552019-05-15 16:09:22 -0700478 // Listen for nav bar mode changes
Winson Chung9e572492019-06-07 10:48:45 -0700479 mNavBarMode = navModeController.addListener(this);
Winson Chung1aa24b92019-04-24 15:17:33 -0700480
Winson Chung1bb74552019-05-15 16:09:22 -0700481 // Listen for device provisioned/user setup
482 updateEnabledState();
483 mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
484
485 // Listen for launcher package changes
486 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
487 filter.addDataScheme("package");
488 filter.addDataSchemeSpecificPart(mRecentsComponentName.getPackageName(),
489 PatternMatcher.PATTERN_LITERAL);
490 filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
491 mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
Winson Chung60887932019-06-13 22:37:31 -0700492
493 // Listen for status bar state changes
494 statusBarWinController.registerCallback(mStatusBarWindowCallback);
Matthew Ng13dbf872017-10-27 11:02:14 -0700495 }
496
Winson Chung04ff8bda2019-04-02 15:08:59 -0700497 public void notifyBackAction(boolean completed, int downX, int downY, boolean isButton,
498 boolean gestureSwipeLeft) {
499 try {
500 if (mOverviewProxy != null) {
501 mOverviewProxy.onBackAction(completed, downX, downY, isButton, gestureSwipeLeft);
502 }
503 } catch (RemoteException e) {
504 Log.e(TAG_OPS, "Failed to notify back action", e);
505 }
506 }
507
Winson Chung7e486912019-04-30 11:11:47 -0700508 public void setSystemUiStateFlag(int flag, boolean enabled, int displayId) {
509 if (displayId != DEFAULT_DISPLAY) {
510 // Ignore non-default displays for now
511 return;
512 }
513
Winson Chunga3132982019-04-08 13:27:47 -0700514 int newState = mSysUiStateFlags;
515 if (enabled) {
516 newState |= flag;
517 } else {
518 newState &= ~flag;
519 }
520 if (mSysUiStateFlags != newState) {
521 mSysUiStateFlags = newState;
Winson Chunga7067002019-05-07 11:50:42 -0700522 notifySystemUiStateChanged(mSysUiStateFlags);
Winson Chunga3132982019-04-08 13:27:47 -0700523 notifySystemUiStateFlags(mSysUiStateFlags);
524 }
525 }
526
Winson Chunge2a686d2019-04-17 16:54:23 -0700527 public int getSystemUiStateFlags() {
528 return mSysUiStateFlags;
529 }
530
Winson Chunga3132982019-04-08 13:27:47 -0700531 private void updateSystemUiStateFlags() {
Winson Chung9e572492019-06-07 10:48:45 -0700532 final NavigationBarFragment navBarFragment =
533 mNavBarController.getDefaultNavigationBarFragment();
534 final NavigationBarView navBarView =
535 mNavBarController.getNavigationBarView(mContext.getDisplayId());
Winson Chunga7067002019-05-07 11:50:42 -0700536
Winson Chunga3132982019-04-08 13:27:47 -0700537 mSysUiStateFlags = 0;
Winson Chunga7067002019-05-07 11:50:42 -0700538 if (navBarFragment != null) {
539 navBarFragment.updateSystemUiStateFlags(-1);
540 }
541 if (navBarView != null) {
542 navBarView.updateSystemUiStateFlags();
543 }
Winson Chung9e572492019-06-07 10:48:45 -0700544 if (mStatusBarWinController != null) {
Winson Chung60887932019-06-13 22:37:31 -0700545 mStatusBarWinController.notifyStateChangedCallbacks();
Winson Chunga7067002019-05-07 11:50:42 -0700546 }
Winson Chunga3132982019-04-08 13:27:47 -0700547 notifySystemUiStateFlags(mSysUiStateFlags);
548 }
549
550 private void notifySystemUiStateFlags(int flags) {
551 try {
552 if (mOverviewProxy != null) {
553 mOverviewProxy.onSystemUiStateChanged(flags);
554 }
555 } catch (RemoteException e) {
556 Log.e(TAG_OPS, "Failed to notify sysui state change", e);
557 }
558 }
559
Winson Chung60887932019-06-13 22:37:31 -0700560 private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
561 boolean bouncerShowing) {
562 int displayId = mContext.getDisplayId();
563 setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
564 keyguardShowing && !keyguardOccluded, displayId);
565 setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
566 keyguardShowing && keyguardOccluded, displayId);
567 setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing, displayId);
568 }
569
Sunny Goyalaac6c882019-02-11 11:57:58 -0800570 /**
571 * Sets the navbar region which can receive touch inputs
572 */
573 public void onActiveNavBarRegionChanges(Region activeRegion) {
574 mActiveNavBarRegion = activeRegion;
575 dispatchNavButtonBounds();
576 }
577
578 private void dispatchNavButtonBounds() {
579 if (mOverviewProxy != null && mActiveNavBarRegion != null) {
580 try {
581 mOverviewProxy.onActiveNavBarRegionChanges(mActiveNavBarRegion);
582 } catch (RemoteException e) {
583 Log.e(TAG_OPS, "Failed to call onActiveNavBarRegionChanges()", e);
584 }
585 }
586 }
587
Matthew Ngc83b9892018-08-21 16:31:13 -0700588 public float getBackButtonAlpha() {
Sunny Goyalc73ce702019-06-16 13:50:07 -0700589 return mNavBarButtonAlpha;
Matthew Ngc83b9892018-08-21 16:31:13 -0700590 }
591
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700592 public void cleanupAfterDeath() {
593 if (mStatusBarGestureDownEvent != null) {
594 mHandler.post(()-> {
595 StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
596 if (bar != null) {
Hyunyoung Song547e11e2018-10-04 16:32:23 -0700597 mStatusBarGestureDownEvent.setAction(MotionEvent.ACTION_CANCEL);
598 bar.dispatchNotificationsPanelTouchEvent(mStatusBarGestureDownEvent);
599 mStatusBarGestureDownEvent.recycle();
600 mStatusBarGestureDownEvent = null;
601 }
602 });
603 }
604 startConnectionToCurrentUser();
605 }
606
Matthew Ng13dbf872017-10-27 11:02:14 -0700607 public void startConnectionToCurrentUser() {
Matthew Ngfac87832017-11-10 11:27:29 -0800608 if (mHandler.getLooper() != Looper.myLooper()) {
609 mHandler.post(mConnectionRunnable);
610 } else {
611 internalConnectToCurrentUser();
612 }
613 }
614
615 private void internalConnectToCurrentUser() {
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800616 disconnectFromLauncherService();
617
Matthew Ng13dbf872017-10-27 11:02:14 -0700618 // If user has not setup yet or already connected, do not try to connect
Winson Chungd95a2252018-04-04 17:02:29 +0000619 if (!mDeviceProvisionedController.isCurrentUserSetup() || !isEnabled()) {
Matthew Nge3c5af42018-05-02 16:58:44 -0700620 Log.v(TAG_OPS, "Cannot attempt connection, is setup "
621 + mDeviceProvisionedController.isCurrentUserSetup() + ", is enabled "
622 + isEnabled());
Matthew Ng13dbf872017-10-27 11:02:14 -0700623 return;
624 }
625 mHandler.removeCallbacks(mConnectionRunnable);
Sunny Goyal09c12d72018-03-27 10:14:49 -0700626 Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP)
627 .setPackage(mRecentsComponentName.getPackageName());
Matthew Ng10b6c41a2018-03-26 18:01:37 -0700628 try {
Winson Chung67f20282019-03-12 23:53:24 -0700629 mBound = mContext.bindServiceAsUser(launcherServiceIntent,
Winson Chunge7cb0c12018-07-30 16:11:38 -0700630 mOverviewServiceConnection,
631 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
Matthew Ng10b6c41a2018-03-26 18:01:37 -0700632 UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
633 } catch (SecurityException e) {
634 Log.e(TAG_OPS, "Unable to bind because of security error", e);
635 }
Winson Chung67f20282019-03-12 23:53:24 -0700636 if (mBound) {
Matthew Nge3c5af42018-05-02 16:58:44 -0700637 // Ensure that connection has been established even if it thinks it is bound
638 mHandler.postDelayed(mDeferredConnectionCallback, DEFERRED_CALLBACK_MILLIS);
639 } else {
Matthew Ng13dbf872017-10-27 11:02:14 -0700640 // Retry after exponential backoff timeout
Matthew Ngead8e5a2018-08-20 17:20:05 -0700641 retryConnectionWithBackoff();
Matthew Ng13dbf872017-10-27 11:02:14 -0700642 }
643 }
644
Matthew Ngead8e5a2018-08-20 17:20:05 -0700645 private void retryConnectionWithBackoff() {
646 if (mHandler.hasCallbacks(mConnectionRunnable)) {
647 return;
648 }
649 final long timeoutMs = (long) Math.min(
650 Math.scalb(BACKOFF_MILLIS, mConnectionBackoffAttempts), MAX_BACKOFF_MILLIS);
651 mHandler.postDelayed(mConnectionRunnable, timeoutMs);
652 mConnectionBackoffAttempts++;
653 Log.w(TAG_OPS, "Failed to connect on attempt " + mConnectionBackoffAttempts
654 + " will try again in " + timeoutMs + "ms");
655 }
656
Matthew Ng7d05e772017-11-09 14:41:07 -0800657 @Override
658 public void addCallback(OverviewProxyListener listener) {
659 mConnectionCallbacks.add(listener);
660 listener.onConnectionChanged(mOverviewProxy != null);
Sunny Goyalc73ce702019-06-16 13:50:07 -0700661 listener.onNavBarButtonAlphaChanged(mNavBarButtonAlpha, false);
Winson Chunga7067002019-05-07 11:50:42 -0700662 listener.onSystemUiStateChanged(mSysUiStateFlags);
Matthew Ng7d05e772017-11-09 14:41:07 -0800663 }
664
665 @Override
666 public void removeCallback(OverviewProxyListener listener) {
667 mConnectionCallbacks.remove(listener);
668 }
669
Matthew Ngc1a97b12018-03-28 14:02:00 -0700670 public boolean shouldShowSwipeUpUI() {
Matthew Ngb2f89d32019-04-24 11:40:12 -0700671 return isEnabled() && !QuickStepContract.isLegacyMode(mNavBarMode);
Winson Chungd95a2252018-04-04 17:02:29 +0000672 }
673
674 public boolean isEnabled() {
675 return mIsEnabled;
Matthew Ngc1a97b12018-03-28 14:02:00 -0700676 }
677
Matthew Ng13dbf872017-10-27 11:02:14 -0700678 public IOverviewProxy getProxy() {
679 return mOverviewProxy;
680 }
681
682 private void disconnectFromLauncherService() {
Winson Chung67f20282019-03-12 23:53:24 -0700683 if (mBound) {
684 // Always unbind the service (ie. if called through onNullBinding or onBindingDied)
685 mContext.unbindService(mOverviewServiceConnection);
686 mBound = false;
687 }
688
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800689 if (mOverviewProxy != null) {
Matthew Ngeb6893b2017-11-09 17:15:33 -0800690 mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800691 mOverviewProxy = null;
Sunny Goyalc73ce702019-06-16 13:50:07 -0700692 notifyNavBarButtonAlphaChanged(1f, false /* animate */);
Matthew Ng7d05e772017-11-09 14:41:07 -0800693 notifyConnectionChanged();
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800694 }
Matthew Ng13dbf872017-10-27 11:02:14 -0700695 }
Matthew Ng7d05e772017-11-09 14:41:07 -0800696
Sunny Goyalc73ce702019-06-16 13:50:07 -0700697 private void notifyNavBarButtonAlphaChanged(float alpha, boolean animate) {
Matthew Ng53896452018-05-30 11:27:39 -0700698 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
Sunny Goyalc73ce702019-06-16 13:50:07 -0700699 mConnectionCallbacks.get(i).onNavBarButtonAlphaChanged(alpha, animate);
Matthew Ng53896452018-05-30 11:27:39 -0700700 }
701 }
702
Matthew Ng7d05e772017-11-09 14:41:07 -0800703 private void notifyConnectionChanged() {
704 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
705 mConnectionCallbacks.get(i).onConnectionChanged(mOverviewProxy != null);
706 }
707 }
708
Matthew Ng2ea93b72018-03-14 19:43:18 +0000709 public void notifyQuickStepStarted() {
Winson Chungcbb15a92018-01-25 17:46:16 +0000710 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000711 mConnectionCallbacks.get(i).onQuickStepStarted();
Winson Chungcbb15a92018-01-25 17:46:16 +0000712 }
713 }
714
Tracy Zhou27599052018-04-16 15:47:29 -0700715 public void notifyQuickScrubStarted() {
716 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
717 mConnectionCallbacks.get(i).onQuickScrubStarted();
718 }
719 }
720
Matthew Ng42025e32019-02-20 15:02:58 -0800721 private void notifyAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {
722 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
723 mConnectionCallbacks.get(i).onAssistantProgress(progress);
724 }
725 }
726
Miranda Kephart4be26902019-05-17 13:55:37 -0400727 private void notifyAssistantGestureCompletion(float velocity) {
728 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
729 mConnectionCallbacks.get(i).onAssistantGestureCompletion(velocity);
730 }
731 }
732
Winson Chunga7067002019-05-07 11:50:42 -0700733 private void notifySystemUiStateChanged(int sysuiStateFlags) {
734 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
735 mConnectionCallbacks.get(i).onSystemUiStateChanged(sysuiStateFlags);
736 }
737 }
738
Matthew Ng42025e32019-02-20 15:02:58 -0800739 private void notifyStartAssistant(Bundle bundle) {
740 for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
741 mConnectionCallbacks.get(i).startAssistant(bundle);
742 }
743 }
744
Govinda Wassermanc4c70f32019-03-28 11:18:14 -0400745 public void notifyAssistantVisibilityChanged(float visibility) {
746 try {
Winson Chung0620c3b2019-04-10 09:47:13 -0700747 if (mOverviewProxy != null) {
748 mOverviewProxy.onAssistantVisibilityChanged(visibility);
749 }
Govinda Wassermanc4c70f32019-03-28 11:18:14 -0400750 } catch (RemoteException e) {
751 Log.e(TAG_OPS, "Failed to call onAssistantVisibilityChanged()", e);
752 }
753 }
754
Winson Chungd95a2252018-04-04 17:02:29 +0000755 private void updateEnabledState() {
Winson Chung6e4b0b562018-04-04 09:13:37 -0700756 mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent,
Matthew Nga3fee342019-02-25 15:36:37 -0800757 MATCH_SYSTEM_ONLY,
Winson Chungd95a2252018-04-04 17:02:29 +0000758 ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
759 }
760
Matthew Ng1e43ebd2017-11-14 14:47:05 -0800761 @Override
Winson Chung1aa24b92019-04-24 15:17:33 -0700762 public void onNavigationModeChanged(int mode) {
763 mNavBarMode = mode;
764 }
765
766 @Override
Matthew Ng1e43ebd2017-11-14 14:47:05 -0800767 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Matthew Ngbd824572018-01-17 16:25:56 -0800768 pw.println(TAG_OPS + " state:");
Winson Chung387e38b2018-07-09 14:30:54 -0700769 pw.print(" recentsComponentName="); pw.println(mRecentsComponentName);
770 pw.print(" isConnected="); pw.println(mOverviewProxy != null);
Matthew Ng1e43ebd2017-11-14 14:47:05 -0800771 pw.print(" isCurrentUserSetup="); pw.println(mDeviceProvisionedController
772 .isCurrentUserSetup());
Winson Chung387e38b2018-07-09 14:30:54 -0700773 pw.print(" connectionBackoffAttempts="); pw.println(mConnectionBackoffAttempts);
Winson Chung387e38b2018-07-09 14:30:54 -0700774
775 pw.print(" quickStepIntent="); pw.println(mQuickStepIntent);
776 pw.print(" quickStepIntentResolved="); pw.println(isEnabled());
Winson Chunga3132982019-04-08 13:27:47 -0700777 pw.print(" mSysUiStateFlags="); pw.println(mSysUiStateFlags);
Winson Chunga7067002019-05-07 11:50:42 -0700778 pw.println(" " + QuickStepContract.getSystemUiStateString(mSysUiStateFlags));
779 pw.print(" backGestureDisabled=");
780 pw.println(QuickStepContract.isBackGestureDisabled(mSysUiStateFlags));
781 pw.print(" assistantGestureDisabled=");
782 pw.println(QuickStepContract.isAssistantGestureDisabled(mSysUiStateFlags));
Matthew Ng1e43ebd2017-11-14 14:47:05 -0800783 }
784
Matthew Ng7d05e772017-11-09 14:41:07 -0800785 public interface OverviewProxyListener {
Winson Chungcbb15a92018-01-25 17:46:16 +0000786 default void onConnectionChanged(boolean isConnected) {}
Matthew Ng2ea93b72018-03-14 19:43:18 +0000787 default void onQuickStepStarted() {}
Tracy Zhou27599052018-04-16 15:47:29 -0700788 default void onOverviewShown(boolean fromHome) {}
789 default void onQuickScrubStarted() {}
Sunny Goyalc73ce702019-06-16 13:50:07 -0700790 /** Notify changes in the nav bar button alpha */
791 default void onNavBarButtonAlphaChanged(float alpha, boolean animate) {}
Winson Chunga7067002019-05-07 11:50:42 -0700792 default void onSystemUiStateChanged(int sysuiStateFlags) {}
Matthew Ng42025e32019-02-20 15:02:58 -0800793 default void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {}
Miranda Kephart4be26902019-05-17 13:55:37 -0400794 default void onAssistantGestureCompletion(float velocity) {}
Matthew Ng42025e32019-02-20 15:02:58 -0800795 default void startAssistant(Bundle bundle) {}
Matthew Ng7d05e772017-11-09 14:41:07 -0800796 }
Matthew Ng13dbf872017-10-27 11:02:14 -0700797}