blob: 406bcac08dafd5a227c3d3c998b214b3f56bc5da [file] [log] [blame]
Winson Chung7048fea2014-03-18 12:21:24 -07001/*
2 * Copyright (C) 2014 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
17package com.android.systemui.recents;
18
Jason Monk764da992017-02-02 14:11:20 -050019import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
20
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080021import android.app.ActivityManager;
Winson190fe3bf2015-10-20 14:57:24 -070022import android.content.ComponentName;
Winsone6309aa2016-01-08 11:19:21 -080023import android.content.ContentResolver;
Winson Chung7048fea2014-03-18 12:21:24 -070024import android.content.Context;
25import android.content.Intent;
Winson190fe3bf2015-10-20 14:57:24 -070026import android.content.ServiceConnection;
Jorim Jaggi29379ec2016-04-11 23:43:42 -070027import android.content.pm.ActivityInfo;
Winson Chung7048fea2014-03-18 12:21:24 -070028import android.content.res.Configuration;
Muyuan Lia2129992016-03-03 18:30:39 -080029import android.graphics.Point;
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -080030import android.graphics.Rect;
Muyuan Lia2129992016-03-03 18:30:39 -080031import android.hardware.display.DisplayManager;
Winson4727ab92015-11-02 14:35:34 -080032import android.os.Build;
Jim Millera237a312014-11-06 18:05:59 -080033import android.os.Handler;
Winson190fe3bf2015-10-20 14:57:24 -070034import android.os.IBinder;
35import android.os.RemoteException;
Winson4727ab92015-11-02 14:35:34 -080036import android.os.SystemProperties;
Winson Chung7048fea2014-03-18 12:21:24 -070037import android.os.UserHandle;
Winsone9243562015-11-10 16:07:13 -080038import android.provider.Settings;
Winsona00a7852016-02-16 11:05:28 -080039import android.util.EventLog;
Winson190fe3bf2015-10-20 14:57:24 -070040import android.util.Log;
Jorim Jaggid61f2272014-12-19 20:35:35 +010041import android.view.Display;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010042import android.widget.Toast;
Winsonc0d70582016-01-29 10:24:39 -080043
Jorim Jaggi29379ec2016-04-11 23:43:42 -070044import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010045import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Winsona00a7852016-02-16 11:05:28 -080046import com.android.systemui.EventLogConstants;
47import com.android.systemui.EventLogTags;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010048import com.android.systemui.R;
Winson Chung9214eff2014-06-12 13:59:25 -070049import com.android.systemui.RecentsComponent;
Jorim Jaggid61f2272014-12-19 20:35:35 +010050import com.android.systemui.SystemUI;
Winson190fe3bf2015-10-20 14:57:24 -070051import com.android.systemui.recents.events.EventBus;
Winson003eda62016-03-11 14:56:00 -080052import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
Jorim Jaggi899327f2016-02-25 20:44:18 -050053import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
Matthew Ngc422f802017-08-02 14:00:59 -070054import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080055import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
Winson190fe3bf2015-10-20 14:57:24 -070056import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
57import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
Matthew Ng912c7f72017-08-02 22:12:04 +000058import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
Winson675c5d82016-08-23 17:12:22 -070059import com.android.systemui.recents.events.component.ShowUserToastEvent;
Jorim Jaggi11cc01d2016-01-22 19:39:23 -080060import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
Winson Chungffa2ec62014-07-03 15:54:42 -070061import com.android.systemui.recents.misc.SystemServicesProxy;
Winsone7f138c2015-10-22 16:15:21 -070062import com.android.systemui.recents.model.RecentsTaskLoader;
Jorim Jaggidb21bbd2016-04-18 15:32:07 -070063import com.android.systemui.stackdivider.Divider;
Jason Monk764da992017-02-02 14:11:20 -050064import com.android.systemui.statusbar.CommandQueue;
Winson Chung7048fea2014-03-18 12:21:24 -070065
Winson Chungee697562017-05-18 14:29:43 -070066import java.io.FileDescriptor;
67import java.io.PrintWriter;
Winson Chungffa2ec62014-07-03 15:54:42 -070068import java.util.ArrayList;
Manu Cornet906a3a82016-11-04 06:58:15 -070069import java.util.HashSet;
70import java.util.Set;
Winson Chung7048fea2014-03-18 12:21:24 -070071
Winson Chung740c3ac2014-11-12 16:14:38 -080072
Winson190fe3bf2015-10-20 14:57:24 -070073/**
74 * An implementation of the SystemUI recents component, which supports both system and secondary
75 * users.
76 */
Jorim Jaggid61f2272014-12-19 20:35:35 +010077public class Recents extends SystemUI
Jason Monk764da992017-02-02 14:11:20 -050078 implements RecentsComponent, CommandQueue.Callbacks {
Winson190fe3bf2015-10-20 14:57:24 -070079
80 private final static String TAG = "Recents";
81 private final static boolean DEBUG = false;
Winson Chung7048fea2014-03-18 12:21:24 -070082
Winsone6c90732015-09-24 16:06:29 -070083 public final static int EVENT_BUS_PRIORITY = 1;
Winson190fe3bf2015-10-20 14:57:24 -070084 public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
Jorim Jaggidb21bbd2016-04-18 15:32:07 -070085 public final static int RECENTS_GROW_TARGET_INVALID = -1;
Winsone6c90732015-09-24 16:06:29 -070086
Manu Cornet906a3a82016-11-04 06:58:15 -070087 public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
88 static {
89 RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
Manu Cornet906a3a82016-11-04 06:58:15 -070090 }
91
Winson4727ab92015-11-02 14:35:34 -080092 // Purely for experimentation
93 private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
94 private final static String ACTION_SHOW_RECENTS = "com.android.systemui.recents.ACTION_SHOW";
95 private final static String ACTION_HIDE_RECENTS = "com.android.systemui.recents.ACTION_HIDE";
96 private final static String ACTION_TOGGLE_RECENTS = "com.android.systemui.recents.ACTION_TOGGLE";
97
Jorim Jaggi29379ec2016-04-11 23:43:42 -070098 private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
99 private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
100 private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
101
Winsone7f138c2015-10-22 16:15:21 -0700102 private static SystemServicesProxy sSystemServicesProxy;
Winsonc742f972015-11-12 11:32:21 -0800103 private static RecentsDebugFlags sDebugFlags;
Winsone7f138c2015-10-22 16:15:21 -0700104 private static RecentsTaskLoader sTaskLoader;
Winson53ec42c2015-10-28 15:55:35 -0700105 private static RecentsConfiguration sConfiguration;
Winsone7f138c2015-10-22 16:15:21 -0700106
Winson4727ab92015-11-02 14:35:34 -0800107 // For experiments only, allows another package to handle recents if it is defined in the system
108 // properties. This is limited to show/toggle/hide, and does not tie into the ActivityManager,
109 // and does not reside in the home stack.
110 private String mOverrideRecentsPackageName;
111
Winson Chung501d59d2016-10-05 17:49:09 +0000112 private Handler mHandler;
Winson190fe3bf2015-10-20 14:57:24 -0700113 private RecentsImpl mImpl;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800114 private int mDraggingInRecentsCurrentUser;
Winson Chung2002cf52014-12-08 17:26:44 -0800115
Winson190fe3bf2015-10-20 14:57:24 -0700116 // Only For system user, this is the callbacks instance we return to each secondary user
Winsona00a7852016-02-16 11:05:28 -0800117 private RecentsSystemUser mSystemToUserCallbacks;
Winson Chungcdcd4872014-08-05 18:00:13 -0700118
Winson190fe3bf2015-10-20 14:57:24 -0700119 // Only for secondary users, this is the callbacks instance provided by the system user to make
120 // calls back
Winsona00a7852016-02-16 11:05:28 -0800121 private IRecentsSystemUserCallbacks mUserToSystemCallbacks;
Winson Chungb44c24f2014-04-09 15:17:43 -0700122
Winson190fe3bf2015-10-20 14:57:24 -0700123 // The set of runnables to run after binding to the system user's service.
124 private final ArrayList<Runnable> mOnConnectRunnables = new ArrayList<>();
Winson Chung7048fea2014-03-18 12:21:24 -0700125
Winson190fe3bf2015-10-20 14:57:24 -0700126 // Only for secondary users, this is the death handler for the binder from the system user
Winsona00a7852016-02-16 11:05:28 -0800127 private final IBinder.DeathRecipient mUserToSystemCallbacksDeathRcpt = new IBinder.DeathRecipient() {
Winson Chung740c3ac2014-11-12 16:14:38 -0800128 @Override
Winson190fe3bf2015-10-20 14:57:24 -0700129 public void binderDied() {
Winsona00a7852016-02-16 11:05:28 -0800130 mUserToSystemCallbacks = null;
131 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
132 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_UNBOUND,
133 sSystemServicesProxy.getProcessUser());
Winson Chung2002cf52014-12-08 17:26:44 -0800134
Winson190fe3bf2015-10-20 14:57:24 -0700135 // Retry after a fixed duration
136 mHandler.postDelayed(new Runnable() {
137 @Override
138 public void run() {
139 registerWithSystemUser();
Winson Chung0eae5572014-12-11 11:04:19 -0800140 }
Winson190fe3bf2015-10-20 14:57:24 -0700141 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
Winson Chung740c3ac2014-11-12 16:14:38 -0800142 }
Winson190fe3bf2015-10-20 14:57:24 -0700143 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800144
Winson190fe3bf2015-10-20 14:57:24 -0700145 // Only for secondary users, this is the service connection we use to connect to the system user
Winsona00a7852016-02-16 11:05:28 -0800146 private final ServiceConnection mUserToSystemServiceConnection = new ServiceConnection() {
Winson Chung2002cf52014-12-08 17:26:44 -0800147 @Override
Winson190fe3bf2015-10-20 14:57:24 -0700148 public void onServiceConnected(ComponentName name, IBinder service) {
149 if (service != null) {
Winsona00a7852016-02-16 11:05:28 -0800150 mUserToSystemCallbacks = IRecentsSystemUserCallbacks.Stub.asInterface(
Winson190fe3bf2015-10-20 14:57:24 -0700151 service);
Winsona00a7852016-02-16 11:05:28 -0800152 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
153 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_BOUND,
154 sSystemServicesProxy.getProcessUser());
Winson190fe3bf2015-10-20 14:57:24 -0700155
156 // Listen for system user's death, so that we can reconnect later
157 try {
Winsona00a7852016-02-16 11:05:28 -0800158 service.linkToDeath(mUserToSystemCallbacksDeathRcpt, 0);
Winson190fe3bf2015-10-20 14:57:24 -0700159 } catch (RemoteException e) {
160 Log.e(TAG, "Lost connection to (System) SystemUI", e);
161 }
162
163 // Run each of the queued runnables
164 runAndFlushOnConnectRunnables();
Winson Chung2002cf52014-12-08 17:26:44 -0800165 }
Winson190fe3bf2015-10-20 14:57:24 -0700166
167 // Unbind ourselves now that we've registered our callbacks. The
168 // binder to the system user are still valid at this point.
169 mContext.unbindService(this);
Winson Chung2002cf52014-12-08 17:26:44 -0800170 }
Winson Chung2002cf52014-12-08 17:26:44 -0800171
Winson190fe3bf2015-10-20 14:57:24 -0700172 @Override
173 public void onServiceDisconnected(ComponentName name) {
174 // Do nothing
175 }
176 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800177
Jorim Jaggid61f2272014-12-19 20:35:35 +0100178 /**
Winson190fe3bf2015-10-20 14:57:24 -0700179 * Returns the callbacks interface that non-system users can call.
Jorim Jaggid61f2272014-12-19 20:35:35 +0100180 */
Winson190fe3bf2015-10-20 14:57:24 -0700181 public IBinder getSystemUserCallbacks() {
Winsona00a7852016-02-16 11:05:28 -0800182 return mSystemToUserCallbacks;
Winson Chung7048fea2014-03-18 12:21:24 -0700183 }
184
Winsone7f138c2015-10-22 16:15:21 -0700185 public static RecentsTaskLoader getTaskLoader() {
186 return sTaskLoader;
187 }
188
Jorim Jaggi6f9dbcb2017-03-17 17:22:47 +0100189
Winsone7f138c2015-10-22 16:15:21 -0700190 public static SystemServicesProxy getSystemServices() {
191 return sSystemServicesProxy;
192 }
193
Winson53ec42c2015-10-28 15:55:35 -0700194 public static RecentsConfiguration getConfiguration() {
195 return sConfiguration;
196 }
197
Winsonc742f972015-11-12 11:32:21 -0800198 public static RecentsDebugFlags getDebugFlags() {
199 return sDebugFlags;
200 }
201
Jorim Jaggid61f2272014-12-19 20:35:35 +0100202 @Override
203 public void start() {
Winsonc742f972015-11-12 11:32:21 -0800204 sDebugFlags = new RecentsDebugFlags(mContext);
Jaewan Kim938a50b2016-03-14 17:35:43 +0900205 sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
Winson53ec42c2015-10-28 15:55:35 -0700206 sConfiguration = new RecentsConfiguration(mContext);
Matthew Ng43db6d22017-06-27 15:29:39 -0700207 sTaskLoader = new RecentsTaskLoader(mContext);
Winson Chung501d59d2016-10-05 17:49:09 +0000208 mHandler = new Handler();
Sid Soundararajan0e88d322017-03-07 15:37:30 -0800209 mImpl = new RecentsImpl(mContext);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100210
Winson4727ab92015-11-02 14:35:34 -0800211 // Check if there is a recents override package
Jeff Sharkey5ab02432017-06-27 11:01:36 -0600212 if (Build.IS_USERDEBUG || Build.IS_ENG) {
Winson4727ab92015-11-02 14:35:34 -0800213 String cnStr = SystemProperties.get(RECENTS_OVERRIDE_SYSPROP_KEY);
214 if (!cnStr.isEmpty()) {
215 mOverrideRecentsPackageName = cnStr;
216 }
217 }
218
Winson190fe3bf2015-10-20 14:57:24 -0700219 // Register with the event bus
220 EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
Winsonc742f972015-11-12 11:32:21 -0800221 EventBus.getDefault().register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
Winsone7f138c2015-10-22 16:15:21 -0700222 EventBus.getDefault().register(sTaskLoader, EVENT_BUS_PRIORITY);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100223
Winson190fe3bf2015-10-20 14:57:24 -0700224 // Due to the fact that RecentsActivity is per-user, we need to establish and interface for
225 // the system user's Recents component to pass events (like show/hide/toggleRecents) to the
226 // secondary user, and vice versa (like visibility change, screen pinning).
Winsone7f138c2015-10-22 16:15:21 -0700227 final int processUser = sSystemServicesProxy.getProcessUser();
228 if (sSystemServicesProxy.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700229 // For the system user, initialize an instance of the interface that we can pass to the
230 // secondary user
Winson Chung0c7592f2017-02-06 09:04:07 -0800231 getComponent(CommandQueue.class).addCallbacks(this);
Winsona00a7852016-02-16 11:05:28 -0800232 mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
Winson190fe3bf2015-10-20 14:57:24 -0700233 } else {
234 // For the secondary user, bind to the primary user's service to get a persistent
235 // interface to register its implementation and to later update its state
236 registerWithSystemUser();
Jorim Jaggid61f2272014-12-19 20:35:35 +0100237 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100238 putComponent(Recents.class, this);
Winson Chung5abdceb2014-06-05 10:58:05 -0700239 }
240
Jorim Jaggid61f2272014-12-19 20:35:35 +0100241 @Override
Winson Chung8bf05af2014-09-29 13:42:49 -0700242 public void onBootCompleted() {
Winson190fe3bf2015-10-20 14:57:24 -0700243 mImpl.onBootCompleted();
Winson Chung8bf05af2014-09-29 13:42:49 -0700244 }
245
Winson190fe3bf2015-10-20 14:57:24 -0700246 /**
247 * Shows the Recents.
248 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100249 @Override
Jason Monk764da992017-02-02 14:11:20 -0500250 public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
Winsone9243562015-11-10 16:07:13 -0800251 // Ensure the device has been provisioned before allowing the user to interact with
252 // recents
Winsone6309aa2016-01-08 11:19:21 -0800253 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800254 return;
255 }
256
Winson4727ab92015-11-02 14:35:34 -0800257 if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
258 return;
259 }
Jason Monk764da992017-02-02 14:11:20 -0500260 try {
261 ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_RECENT_APPS);
262 } catch (RemoteException e) {
263 }
Winson4727ab92015-11-02 14:35:34 -0800264
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700265 int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
266
Winsone7f138c2015-10-22 16:15:21 -0700267 int currentUser = sSystemServicesProxy.getCurrentUser();
268 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Jorim Jaggi435b2e42015-11-24 15:09:30 -0800269 mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700270 true /* animate */, false /* reloadTasks */, fromHome, recentsGrowTarget);
Winson Chung2002cf52014-12-08 17:26:44 -0800271 } else {
Winsona00a7852016-02-16 11:05:28 -0800272 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700273 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800274 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700275 if (callbacks != null) {
276 try {
Jorim Jaggibb42a462015-11-20 16:27:16 -0800277 callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700278 true /* animate */, false /* reloadTasks */, fromHome,
279 recentsGrowTarget);
Winson190fe3bf2015-10-20 14:57:24 -0700280 } catch (RemoteException e) {
281 Log.e(TAG, "Callback failed", e);
282 }
283 } else {
284 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
285 }
286 }
Winson Chung2002cf52014-12-08 17:26:44 -0800287 }
288 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100289
Winson190fe3bf2015-10-20 14:57:24 -0700290 /**
291 * Hides the Recents.
292 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100293 @Override
Jason Monk764da992017-02-02 14:11:20 -0500294 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winsone9243562015-11-10 16:07:13 -0800295 // Ensure the device has been provisioned before allowing the user to interact with
296 // recents
Winsone6309aa2016-01-08 11:19:21 -0800297 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800298 return;
299 }
300
Winson4727ab92015-11-02 14:35:34 -0800301 if (proxyToOverridePackage(ACTION_HIDE_RECENTS)) {
302 return;
303 }
304
Winsone7f138c2015-10-22 16:15:21 -0700305 int currentUser = sSystemServicesProxy.getCurrentUser();
306 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700307 mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chung2002cf52014-12-08 17:26:44 -0800308 } else {
Winsona00a7852016-02-16 11:05:28 -0800309 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700310 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800311 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700312 if (callbacks != null) {
313 try {
314 callbacks.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
315 } catch (RemoteException e) {
316 Log.e(TAG, "Callback failed", e);
317 }
318 } else {
319 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
320 }
321 }
Winson Chung2002cf52014-12-08 17:26:44 -0800322 }
323 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100324
Winson190fe3bf2015-10-20 14:57:24 -0700325 /**
326 * Toggles the Recents activity.
327 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100328 @Override
Winson Chungebe1ba12017-05-18 15:47:14 -0700329 public void toggleRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800330 // Ensure the device has been provisioned before allowing the user to interact with
331 // recents
Winsone6309aa2016-01-08 11:19:21 -0800332 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800333 return;
334 }
335
Winson4727ab92015-11-02 14:35:34 -0800336 if (proxyToOverridePackage(ACTION_TOGGLE_RECENTS)) {
337 return;
338 }
339
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700340 int growTarget = getComponent(Divider.class).getView().growsRecents();
341
Winsone7f138c2015-10-22 16:15:21 -0700342 int currentUser = sSystemServicesProxy.getCurrentUser();
343 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700344 mImpl.toggleRecents(growTarget);
Winson Chung2002cf52014-12-08 17:26:44 -0800345 } else {
Winsona00a7852016-02-16 11:05:28 -0800346 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700347 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800348 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700349 if (callbacks != null) {
350 try {
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700351 callbacks.toggleRecents(growTarget);
Winson190fe3bf2015-10-20 14:57:24 -0700352 } catch (RemoteException e) {
353 Log.e(TAG, "Callback failed", e);
354 }
355 } else {
356 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
357 }
358 }
Winson Chung2002cf52014-12-08 17:26:44 -0800359 }
360 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100361
Winson190fe3bf2015-10-20 14:57:24 -0700362 /**
363 * Preloads info for the Recents activity.
364 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100365 @Override
Winson Chungebe1ba12017-05-18 15:47:14 -0700366 public void preloadRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800367 // Ensure the device has been provisioned before allowing the user to interact with
368 // recents
Winsone6309aa2016-01-08 11:19:21 -0800369 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800370 return;
371 }
372
Winsone7f138c2015-10-22 16:15:21 -0700373 int currentUser = sSystemServicesProxy.getCurrentUser();
374 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700375 mImpl.preloadRecents();
Winson Chung2002cf52014-12-08 17:26:44 -0800376 } else {
Winsona00a7852016-02-16 11:05:28 -0800377 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700378 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800379 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700380 if (callbacks != null) {
381 try {
382 callbacks.preloadRecents();
383 } catch (RemoteException e) {
384 Log.e(TAG, "Callback failed", e);
385 }
386 } else {
387 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
388 }
Winson Chunga278cae2015-06-09 13:51:13 -0700389 }
Winson Chunge1e20e12015-06-02 14:11:49 -0700390 }
Winson Chung7048fea2014-03-18 12:21:24 -0700391 }
392
Jorim Jaggid61f2272014-12-19 20:35:35 +0100393 @Override
Jason Monk764da992017-02-02 14:11:20 -0500394 public void cancelPreloadRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800395 // Ensure the device has been provisioned before allowing the user to interact with
396 // recents
Winsone6309aa2016-01-08 11:19:21 -0800397 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800398 return;
399 }
400
Winsone7f138c2015-10-22 16:15:21 -0700401 int currentUser = sSystemServicesProxy.getCurrentUser();
402 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700403 mImpl.cancelPreloadingRecents();
Winson Chungb1f74992014-08-08 12:53:09 -0700404 } else {
Winsona00a7852016-02-16 11:05:28 -0800405 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700406 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800407 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700408 if (callbacks != null) {
409 try {
410 callbacks.cancelPreloadingRecents();
411 } catch (RemoteException e) {
412 Log.e(TAG, "Callback failed", e);
413 }
414 } else {
415 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
416 }
417 }
Winson Chungb1f74992014-08-08 12:53:09 -0700418 }
419 }
420
Jorim Jaggid61f2272014-12-19 20:35:35 +0100421 @Override
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700422 public boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds,
423 int metricsDockAction) {
Winsone6309aa2016-01-08 11:19:21 -0800424 // Ensure the device has been provisioned before allowing the user to interact with
425 // recents
426 if (!isUserSetup()) {
427 return false;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800428 }
Winsone6309aa2016-01-08 11:19:21 -0800429
Muyuan Lia2129992016-03-03 18:30:39 -0800430 Point realSize = new Point();
431 if (initialBounds == null) {
432 mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
433 .getRealSize(realSize);
434 initialBounds = new Rect(0, 0, realSize.x, realSize.y);
435 }
436
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800437 int currentUser = sSystemServicesProxy.getCurrentUser();
438 SystemServicesProxy ssp = Recents.getSystemServices();
Winsond46b7272016-04-20 11:54:27 -0700439 ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800440 boolean screenPinningActive = ssp.isScreenPinningActive();
Matthew Ngae1ff4f2016-11-10 15:49:14 -0800441 boolean isRunningTaskInHomeOrRecentsStack = runningTask != null &&
442 ActivityManager.StackId.isHomeOrRecentsStack(runningTask.stackId);
443 if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
Winsond46b7272016-04-20 11:54:27 -0700444 logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
Winson Chungd3395382016-12-13 11:49:09 -0800445 if (runningTask.supportsSplitScreenMultiWindow) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700446 if (metricsDockAction != -1) {
447 MetricsLogger.action(mContext, metricsDockAction,
Winsond46b7272016-04-20 11:54:27 -0700448 runningTask.topActivity.flattenToShortString());
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700449 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100450 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winsond46b7272016-04-20 11:54:27 -0700451 mImpl.dockTopTask(runningTask.id, dragMode, stackCreateMode, initialBounds);
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100452 } else {
453 if (mSystemToUserCallbacks != null) {
454 IRecentsNonSystemUserCallbacks callbacks =
455 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
456 if (callbacks != null) {
457 try {
Winsond46b7272016-04-20 11:54:27 -0700458 callbacks.dockTopTask(runningTask.id, dragMode, stackCreateMode,
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100459 initialBounds);
460 } catch (RemoteException e) {
461 Log.e(TAG, "Callback failed", e);
462 }
463 } else {
464 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800465 }
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800466 }
467 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100468 mDraggingInRecentsCurrentUser = currentUser;
469 return true;
470 } else {
Winson675c5d82016-08-23 17:12:22 -0700471 EventBus.getDefault().send(new ShowUserToastEvent(
Winson Chung80f7b012017-03-28 21:33:28 -0700472 R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100473 return false;
Winsone6309aa2016-01-08 11:19:21 -0800474 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100475 } else {
476 return false;
Winsone6309aa2016-01-08 11:19:21 -0800477 }
Jorim Jaggidd98d412015-11-18 15:57:38 -0800478 }
479
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700480 public static void logDockAttempt(Context ctx, ComponentName activity, int resizeMode) {
481 if (resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE) {
482 MetricsLogger.action(ctx, MetricsEvent.ACTION_WINDOW_DOCK_UNRESIZABLE,
483 activity.flattenToShortString());
484 }
485 MetricsLogger.count(ctx, getMetricsCounterForResizeMode(resizeMode), 1);
486 }
487
488 private static String getMetricsCounterForResizeMode(int resizeMode) {
489 switch (resizeMode) {
490 case ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE:
491 return COUNTER_WINDOW_UNSUPPORTED;
492 case ActivityInfo.RESIZE_MODE_RESIZEABLE:
Wale Ogunwale72a73e32016-10-13 12:16:39 -0700493 case ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION:
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700494 return COUNTER_WINDOW_SUPPORTED;
495 default:
496 return COUNTER_WINDOW_INCOMPATIBLE;
497 }
498 }
499
Jorim Jaggidd98d412015-11-18 15:57:38 -0800500 @Override
501 public void onDraggingInRecents(float distanceFromTop) {
502 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
503 mImpl.onDraggingInRecents(distanceFromTop);
504 } else {
Winsona00a7852016-02-16 11:05:28 -0800505 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800506 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800507 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800508 mDraggingInRecentsCurrentUser);
509 if (callbacks != null) {
510 try {
511 callbacks.onDraggingInRecents(distanceFromTop);
512 } catch (RemoteException e) {
513 Log.e(TAG, "Callback failed", e);
514 }
515 } else {
516 Log.e(TAG, "No SystemUI callbacks found for user: "
517 + mDraggingInRecentsCurrentUser);
518 }
519 }
520 }
521 }
522
523 @Override
524 public void onDraggingInRecentsEnded(float velocity) {
525 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
526 mImpl.onDraggingInRecentsEnded(velocity);
527 } else {
Winsona00a7852016-02-16 11:05:28 -0800528 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800529 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800530 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800531 mDraggingInRecentsCurrentUser);
532 if (callbacks != null) {
533 try {
534 callbacks.onDraggingInRecentsEnded(velocity);
535 } catch (RemoteException e) {
536 Log.e(TAG, "Callback failed", e);
537 }
538 } else {
539 Log.e(TAG, "No SystemUI callbacks found for user: "
540 + mDraggingInRecentsCurrentUser);
541 }
542 }
543 }
Jorim Jaggi75b25972015-10-21 14:51:10 +0200544 }
545
546 @Override
Jorim Jaggid61f2272014-12-19 20:35:35 +0100547 public void showNextAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800548 // Ensure the device has been provisioned before allowing the user to interact with
549 // recents
Winsone6309aa2016-01-08 11:19:21 -0800550 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800551 return;
552 }
553
Winson190fe3bf2015-10-20 14:57:24 -0700554 mImpl.showNextAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700555 }
556
Jorim Jaggid61f2272014-12-19 20:35:35 +0100557 @Override
558 public void showPrevAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800559 // Ensure the device has been provisioned before allowing the user to interact with
560 // recents
Winsone6309aa2016-01-08 11:19:21 -0800561 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800562 return;
563 }
564
Winson190fe3bf2015-10-20 14:57:24 -0700565 mImpl.showPrevAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700566 }
567
Winson Chungee70fbd2017-08-29 14:56:01 -0700568 @Override
569 public void appTransitionFinished() {
Matthew Ng46bc92f2017-09-13 12:53:50 -0700570 if (!Recents.getConfiguration().isLowRamDevice) {
571 // Fallback, reset the flag once an app transition ends
572 EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(
573 false /* waitingForTransitionStart */));
574 }
Winson Chungee70fbd2017-08-29 14:56:01 -0700575 }
576
Winson190fe3bf2015-10-20 14:57:24 -0700577 /**
578 * Updates on configuration change.
579 */
Winson Chung7048fea2014-03-18 12:21:24 -0700580 public void onConfigurationChanged(Configuration newConfig) {
Winsone7f138c2015-10-22 16:15:21 -0700581 int currentUser = sSystemServicesProxy.getCurrentUser();
582 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700583 mImpl.onConfigurationChanged();
Winson Chung2002cf52014-12-08 17:26:44 -0800584 } else {
Winsona00a7852016-02-16 11:05:28 -0800585 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700586 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800587 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700588 if (callbacks != null) {
589 try {
590 callbacks.onConfigurationChanged();
591 } catch (RemoteException e) {
592 Log.e(TAG, "Callback failed", e);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700593 }
Winson190fe3bf2015-10-20 14:57:24 -0700594 } else {
595 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700596 }
Winson190fe3bf2015-10-20 14:57:24 -0700597 }
Winson Chungb0a28ea2014-10-28 15:21:35 -0700598 }
599 }
Winson190fe3bf2015-10-20 14:57:24 -0700600
601 /**
602 * Handle Recents activity visibility changed.
603 */
604 public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
Winson88737542016-02-17 13:27:33 -0800605 SystemServicesProxy ssp = Recents.getSystemServices();
606 int processUser = ssp.getProcessUser();
607 if (ssp.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700608 mImpl.onVisibilityChanged(event.applicationContext, event.visible);
609 } else {
610 postToSystemUser(new Runnable() {
611 @Override
612 public void run() {
613 try {
Winsona00a7852016-02-16 11:05:28 -0800614 mUserToSystemCallbacks.updateRecentsVisibility(event.visible);
Winson190fe3bf2015-10-20 14:57:24 -0700615 } catch (RemoteException e) {
616 Log.e(TAG, "Callback failed", e);
617 }
618 }
619 });
620 }
Matthew Ngc422f802017-08-02 14:00:59 -0700621
622 // This will catch the cases when a user launches from recents to another app
623 // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
624 // would not reset the wait for transition flag. This will catch it and make sure that the
625 // flag is reset.
626 if (!event.visible) {
627 mImpl.setWaitingForTransitionStart(false);
628 }
Winson190fe3bf2015-10-20 14:57:24 -0700629 }
630
631 /**
632 * Handle screen pinning request.
633 */
634 public final void onBusEvent(final ScreenPinningRequestEvent event) {
Winson83c1b072015-11-09 10:48:04 -0800635 int processUser = sSystemServicesProxy.getProcessUser();
636 if (sSystemServicesProxy.isSystemUser(processUser)) {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700637 mImpl.onStartScreenPinning(event.applicationContext, event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700638 } else {
639 postToSystemUser(new Runnable() {
640 @Override
641 public void run() {
642 try {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700643 mUserToSystemCallbacks.startScreenPinning(event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700644 } catch (RemoteException e) {
645 Log.e(TAG, "Callback failed", e);
646 }
647 }
648 });
649 }
650 }
651
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800652 public final void onBusEvent(final RecentsDrawnEvent event) {
653 int processUser = sSystemServicesProxy.getProcessUser();
654 if (!sSystemServicesProxy.isSystemUser(processUser)) {
655 postToSystemUser(new Runnable() {
656 @Override
657 public void run() {
658 try {
Winsona00a7852016-02-16 11:05:28 -0800659 mUserToSystemCallbacks.sendRecentsDrawnEvent();
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800660 } catch (RemoteException e) {
661 Log.e(TAG, "Callback failed", e);
662 }
663 }
664 });
665 }
666 }
667
Jorim Jaggi899327f2016-02-25 20:44:18 -0500668 public final void onBusEvent(final DockedTopTaskEvent event) {
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800669 int processUser = sSystemServicesProxy.getProcessUser();
670 if (!sSystemServicesProxy.isSystemUser(processUser)) {
671 postToSystemUser(new Runnable() {
672 @Override
673 public void run() {
674 try {
Jorim Jaggi899327f2016-02-25 20:44:18 -0500675 mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode,
676 event.initialRect);
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800677 } catch (RemoteException e) {
678 Log.e(TAG, "Callback failed", e);
679 }
680 }
681 });
682 }
683 }
684
685 public final void onBusEvent(final RecentsActivityStartingEvent event) {
686 int processUser = sSystemServicesProxy.getProcessUser();
687 if (!sSystemServicesProxy.isSystemUser(processUser)) {
688 postToSystemUser(new Runnable() {
689 @Override
690 public void run() {
691 try {
Winsona00a7852016-02-16 11:05:28 -0800692 mUserToSystemCallbacks.sendLaunchRecentsEvent();
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800693 } catch (RemoteException e) {
694 Log.e(TAG, "Callback failed", e);
695 }
696 }
697 });
698 }
699 }
700
Matthew Ngc422f802017-08-02 14:00:59 -0700701 public final void onBusEvent(LaunchTaskFailedEvent event) {
702 // Reset the transition when tasks fail to launch
703 mImpl.setWaitingForTransitionStart(false);
704 }
705
Winson003eda62016-03-11 14:56:00 -0800706 public final void onBusEvent(ConfigurationChangedEvent event) {
707 // Update the configuration for the Recents component when the activity configuration
708 // changes as well
709 mImpl.onConfigurationChanged();
710 }
711
Winson675c5d82016-08-23 17:12:22 -0700712 public final void onBusEvent(ShowUserToastEvent event) {
713 int currentUser = sSystemServicesProxy.getCurrentUser();
714 if (sSystemServicesProxy.isSystemUser(currentUser)) {
715 mImpl.onShowCurrentUserToast(event.msgResId, event.msgLength);
716 } else {
717 if (mSystemToUserCallbacks != null) {
718 IRecentsNonSystemUserCallbacks callbacks =
719 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
720 if (callbacks != null) {
721 try {
722 callbacks.showCurrentUserToast(event.msgResId, event.msgLength);
723 } catch (RemoteException e) {
724 Log.e(TAG, "Callback failed", e);
725 }
726 } else {
727 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
728 }
729 }
730 }
731 }
732
Matthew Ng912c7f72017-08-02 22:12:04 +0000733 public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
734 int processUser = sSystemServicesProxy.getProcessUser();
735 if (sSystemServicesProxy.isSystemUser(processUser)) {
736 mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
737 } else {
738 postToSystemUser(new Runnable() {
739 @Override
740 public void run() {
741 try {
742 mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
743 event.waitingForTransitionStart);
744 } catch (RemoteException e) {
745 Log.e(TAG, "Callback failed", e);
746 }
747 }
748 });
749 }
750 }
751
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800752 /**
Winson190fe3bf2015-10-20 14:57:24 -0700753 * Attempts to register with the system user.
754 */
755 private void registerWithSystemUser() {
Winsone7f138c2015-10-22 16:15:21 -0700756 final int processUser = sSystemServicesProxy.getProcessUser();
Winson190fe3bf2015-10-20 14:57:24 -0700757 postToSystemUser(new Runnable() {
758 @Override
759 public void run() {
760 try {
Winsona00a7852016-02-16 11:05:28 -0800761 mUserToSystemCallbacks.registerNonSystemUserCallbacks(
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800762 new RecentsImplProxy(mImpl), processUser);
Winson190fe3bf2015-10-20 14:57:24 -0700763 } catch (RemoteException e) {
764 Log.e(TAG, "Failed to register", e);
765 }
766 }
767 });
768 }
769
770 /**
771 * Runs the runnable in the system user's Recents context, connecting to the service if
772 * necessary.
773 */
774 private void postToSystemUser(final Runnable onConnectRunnable) {
775 mOnConnectRunnables.add(onConnectRunnable);
Winsona00a7852016-02-16 11:05:28 -0800776 if (mUserToSystemCallbacks == null) {
Winson190fe3bf2015-10-20 14:57:24 -0700777 Intent systemUserServiceIntent = new Intent();
778 systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
779 boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
Winsona00a7852016-02-16 11:05:28 -0800780 mUserToSystemServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
781 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
782 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE,
783 sSystemServicesProxy.getProcessUser());
Winson190fe3bf2015-10-20 14:57:24 -0700784 if (!bound) {
785 // Retry after a fixed duration
786 mHandler.postDelayed(new Runnable() {
787 @Override
788 public void run() {
789 registerWithSystemUser();
790 }
791 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
792 }
793 } else {
794 runAndFlushOnConnectRunnables();
795 }
796 }
797
798 /**
799 * Runs all the queued runnables after a service connection is made.
800 */
801 private void runAndFlushOnConnectRunnables() {
802 for (Runnable r : mOnConnectRunnables) {
803 r.run();
804 }
805 mOnConnectRunnables.clear();
806 }
Winson4727ab92015-11-02 14:35:34 -0800807
808 /**
Winsone6309aa2016-01-08 11:19:21 -0800809 * @return whether this device is provisioned and the current user is set up.
Winsone9243562015-11-10 16:07:13 -0800810 */
Winsone6309aa2016-01-08 11:19:21 -0800811 private boolean isUserSetup() {
812 ContentResolver cr = mContext.getContentResolver();
813 return (Settings.Global.getInt(cr, Settings.Global.DEVICE_PROVISIONED, 0) != 0) &&
814 (Settings.Secure.getInt(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0);
Winsone9243562015-11-10 16:07:13 -0800815 }
816
817 /**
Winson4727ab92015-11-02 14:35:34 -0800818 * Attempts to proxy the following action to the override recents package.
819 * @return whether the proxying was successful
820 */
821 private boolean proxyToOverridePackage(String action) {
822 if (mOverrideRecentsPackageName != null) {
823 Intent intent = new Intent(action);
824 intent.setPackage(mOverrideRecentsPackageName);
825 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
826 mContext.sendBroadcast(intent);
827 return true;
828 }
829 return false;
830 }
Winson Chungee697562017-05-18 14:29:43 -0700831
832 @Override
833 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
834 pw.println("Recents");
835 pw.println(" currentUserId=" + SystemServicesProxy.getInstance(mContext).getCurrentUser());
836 }
Winson Chung7048fea2014-03-18 12:21:24 -0700837}