blob: 8bb3c0231a768c41379a55d559cc5f1da0083f61 [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
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
20import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
21import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Jason Monk764da992017-02-02 14:11:20 -050022import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
23
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080024import android.app.ActivityManager;
Winson Chunge3dd59c2018-04-02 15:28:40 -070025import android.app.trust.TrustManager;
Winson190fe3bf2015-10-20 14:57:24 -070026import android.content.ComponentName;
Winsone6309aa2016-01-08 11:19:21 -080027import android.content.ContentResolver;
Winson Chung7048fea2014-03-18 12:21:24 -070028import android.content.Context;
29import android.content.Intent;
Winson190fe3bf2015-10-20 14:57:24 -070030import android.content.ServiceConnection;
Jorim Jaggi29379ec2016-04-11 23:43:42 -070031import android.content.pm.ActivityInfo;
Winson Chung7048fea2014-03-18 12:21:24 -070032import android.content.res.Configuration;
Winson Chung6519c1b2017-10-13 17:12:56 -070033import android.content.res.Resources;
Muyuan Lia2129992016-03-03 18:30:39 -080034import android.graphics.Point;
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -080035import android.graphics.Rect;
Muyuan Lia2129992016-03-03 18:30:39 -080036import android.hardware.display.DisplayManager;
Jim Millera237a312014-11-06 18:05:59 -080037import android.os.Handler;
Winson190fe3bf2015-10-20 14:57:24 -070038import android.os.IBinder;
39import android.os.RemoteException;
Winson Chung7048fea2014-03-18 12:21:24 -070040import android.os.UserHandle;
Winsone9243562015-11-10 16:07:13 -080041import android.provider.Settings;
Winsona00a7852016-02-16 11:05:28 -080042import android.util.EventLog;
Winson190fe3bf2015-10-20 14:57:24 -070043import android.util.Log;
Jorim Jaggid61f2272014-12-19 20:35:35 +010044import android.view.Display;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010045import android.widget.Toast;
Winsonc0d70582016-01-29 10:24:39 -080046
Jorim Jaggi29379ec2016-04-11 23:43:42 -070047import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010048import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Winson Chungc1674272018-02-21 10:15:17 -080049import com.android.systemui.Dependency;
Winsona00a7852016-02-16 11:05:28 -080050import com.android.systemui.EventLogConstants;
51import com.android.systemui.EventLogTags;
Winson Chungc1674272018-02-21 10:15:17 -080052import com.android.systemui.OverviewProxyService;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010053import com.android.systemui.R;
Winson Chung9214eff2014-06-12 13:59:25 -070054import com.android.systemui.RecentsComponent;
Winson Chunge3dd59c2018-04-02 15:28:40 -070055import com.android.systemui.SystemUIApplication;
Matthew Ng8a8c89c2018-03-01 13:21:43 -080056import com.android.systemui.shared.recents.IOverviewProxy;
Jorim Jaggid61f2272014-12-19 20:35:35 +010057import com.android.systemui.SystemUI;
Winson190fe3bf2015-10-20 14:57:24 -070058import com.android.systemui.recents.events.EventBus;
Winson003eda62016-03-11 14:56:00 -080059import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
Matthew Ng534e8542017-10-16 14:34:52 -070060import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
Jorim Jaggi899327f2016-02-25 20:44:18 -050061import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
Matthew Ngc422f802017-08-02 14:00:59 -070062import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080063import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
Winson190fe3bf2015-10-20 14:57:24 -070064import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
65import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
Matthew Ng912c7f72017-08-02 22:12:04 +000066import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
Winson675c5d82016-08-23 17:12:22 -070067import com.android.systemui.recents.events.component.ShowUserToastEvent;
Jorim Jaggi11cc01d2016-01-22 19:39:23 -080068import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
Winson Chungffa2ec62014-07-03 15:54:42 -070069import com.android.systemui.recents.misc.SystemServicesProxy;
Winson Chung6519c1b2017-10-13 17:12:56 -070070import com.android.systemui.shared.recents.model.RecentsTaskLoader;
Winson Chungaa357452017-10-31 11:35:30 -070071import com.android.systemui.shared.system.ActivityManagerWrapper;
Jorim Jaggidb21bbd2016-04-18 15:32:07 -070072import com.android.systemui.stackdivider.Divider;
Jason Monk764da992017-02-02 14:11:20 -050073import com.android.systemui.statusbar.CommandQueue;
Winson Chung7048fea2014-03-18 12:21:24 -070074
Winson Chunge3dd59c2018-04-02 15:28:40 -070075import com.android.systemui.statusbar.phone.StatusBar;
Winson Chungee697562017-05-18 14:29:43 -070076import java.io.FileDescriptor;
77import java.io.PrintWriter;
Winson Chungffa2ec62014-07-03 15:54:42 -070078import java.util.ArrayList;
Manu Cornet906a3a82016-11-04 06:58:15 -070079import java.util.HashSet;
80import java.util.Set;
Winson Chung7048fea2014-03-18 12:21:24 -070081
Winson Chung740c3ac2014-11-12 16:14:38 -080082
Winson190fe3bf2015-10-20 14:57:24 -070083/**
84 * An implementation of the SystemUI recents component, which supports both system and secondary
85 * users.
86 */
Jorim Jaggid61f2272014-12-19 20:35:35 +010087public class Recents extends SystemUI
Jason Monk764da992017-02-02 14:11:20 -050088 implements RecentsComponent, CommandQueue.Callbacks {
Winson190fe3bf2015-10-20 14:57:24 -070089
90 private final static String TAG = "Recents";
Winson Chung7048fea2014-03-18 12:21:24 -070091
Winsone6c90732015-09-24 16:06:29 -070092 public final static int EVENT_BUS_PRIORITY = 1;
Winson190fe3bf2015-10-20 14:57:24 -070093 public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
Winsone6c90732015-09-24 16:06:29 -070094
Manu Cornet906a3a82016-11-04 06:58:15 -070095 public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
96 static {
97 RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
Manu Cornet906a3a82016-11-04 06:58:15 -070098 }
99
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700100 private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
101 private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
102 private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
103
Winsone7f138c2015-10-22 16:15:21 -0700104 private static SystemServicesProxy sSystemServicesProxy;
Winsonc742f972015-11-12 11:32:21 -0800105 private static RecentsDebugFlags sDebugFlags;
Winsone7f138c2015-10-22 16:15:21 -0700106 private static RecentsTaskLoader sTaskLoader;
Winson53ec42c2015-10-28 15:55:35 -0700107 private static RecentsConfiguration sConfiguration;
Winsone7f138c2015-10-22 16:15:21 -0700108
Winson Chungc1674272018-02-21 10:15:17 -0800109 private OverviewProxyService mOverviewProxyService;
110
Winson Chung501d59d2016-10-05 17:49:09 +0000111 private Handler mHandler;
Winson190fe3bf2015-10-20 14:57:24 -0700112 private RecentsImpl mImpl;
Winson Chunge3dd59c2018-04-02 15:28:40 -0700113 private TrustManager mTrustManager;
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() {
Winson Chung6519c1b2017-10-13 17:12:56 -0700204 final Resources res = mContext.getResources();
205 final int defaultTaskBarBackgroundColor =
206 mContext.getColor(R.color.recents_task_bar_default_background_color);
207 final int defaultTaskViewBackgroundColor =
208 mContext.getColor(R.color.recents_task_view_default_background_color);
Winson Chung247f1d42017-10-06 15:53:08 -0700209 sDebugFlags = new RecentsDebugFlags();
Jaewan Kim938a50b2016-03-14 17:35:43 +0900210 sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
Winson53ec42c2015-10-28 15:55:35 -0700211 sConfiguration = new RecentsConfiguration(mContext);
Winson Chung6519c1b2017-10-13 17:12:56 -0700212 sTaskLoader = new RecentsTaskLoader(mContext,
213 // TODO: Once we start building the AAR, move these into the loader
214 res.getInteger(R.integer.config_recents_max_thumbnail_count),
215 res.getInteger(R.integer.config_recents_max_icon_count),
216 res.getInteger(R.integer.recents_svelte_level));
217 sTaskLoader.setDefaultColors(defaultTaskBarBackgroundColor, defaultTaskViewBackgroundColor);
Winson Chung501d59d2016-10-05 17:49:09 +0000218 mHandler = new Handler();
Sid Soundararajan0e88d322017-03-07 15:37:30 -0800219 mImpl = new RecentsImpl(mContext);
Winson Chungc1674272018-02-21 10:15:17 -0800220 mOverviewProxyService = Dependency.get(OverviewProxyService.class);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100221
Winson190fe3bf2015-10-20 14:57:24 -0700222 // Register with the event bus
223 EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
Winsonc742f972015-11-12 11:32:21 -0800224 EventBus.getDefault().register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
Winsone7f138c2015-10-22 16:15:21 -0700225 EventBus.getDefault().register(sTaskLoader, EVENT_BUS_PRIORITY);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100226
Winson190fe3bf2015-10-20 14:57:24 -0700227 // Due to the fact that RecentsActivity is per-user, we need to establish and interface for
228 // the system user's Recents component to pass events (like show/hide/toggleRecents) to the
229 // secondary user, and vice versa (like visibility change, screen pinning).
Winsone7f138c2015-10-22 16:15:21 -0700230 final int processUser = sSystemServicesProxy.getProcessUser();
231 if (sSystemServicesProxy.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700232 // For the system user, initialize an instance of the interface that we can pass to the
233 // secondary user
Winson Chung0c7592f2017-02-06 09:04:07 -0800234 getComponent(CommandQueue.class).addCallbacks(this);
Winsona00a7852016-02-16 11:05:28 -0800235 mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
Winson190fe3bf2015-10-20 14:57:24 -0700236 } else {
237 // For the secondary user, bind to the primary user's service to get a persistent
238 // interface to register its implementation and to later update its state
239 registerWithSystemUser();
Jorim Jaggid61f2272014-12-19 20:35:35 +0100240 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100241 putComponent(Recents.class, this);
Winson Chunge3dd59c2018-04-02 15:28:40 -0700242
243 mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
Winson Chung5abdceb2014-06-05 10:58:05 -0700244 }
245
Jorim Jaggid61f2272014-12-19 20:35:35 +0100246 @Override
Winson Chung8bf05af2014-09-29 13:42:49 -0700247 public void onBootCompleted() {
Winson190fe3bf2015-10-20 14:57:24 -0700248 mImpl.onBootCompleted();
Winson Chung8bf05af2014-09-29 13:42:49 -0700249 }
250
Winson190fe3bf2015-10-20 14:57:24 -0700251 /**
252 * Shows the Recents.
253 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100254 @Override
Winson Chungdff7a732017-12-11 12:17:06 -0800255 public void showRecentApps(boolean triggeredFromAltTab) {
Winsone9243562015-11-10 16:07:13 -0800256 // Ensure the device has been provisioned before allowing the user to interact with
257 // recents
Winsone6309aa2016-01-08 11:19:21 -0800258 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800259 return;
260 }
261
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800262 IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
263 if (overviewProxy != null) {
264 try {
265 overviewProxy.onOverviewShown(triggeredFromAltTab);
Winson Chungc1674272018-02-21 10:15:17 -0800266 return;
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800267 } catch (RemoteException e) {
268 Log.e(TAG, "Failed to send overview show event to launcher.", e);
Winson Chungc1674272018-02-21 10:15:17 -0800269 }
270 }
271
Winson Chungaa357452017-10-31 11:35:30 -0700272 ActivityManagerWrapper.getInstance().closeSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700273 int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
Winsone7f138c2015-10-22 16:15:21 -0700274 int currentUser = sSystemServicesProxy.getCurrentUser();
275 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Jorim Jaggi435b2e42015-11-24 15:09:30 -0800276 mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
Winson Chungdff7a732017-12-11 12:17:06 -0800277 true /* animate */, recentsGrowTarget);
Winson Chung2002cf52014-12-08 17:26:44 -0800278 } else {
Winsona00a7852016-02-16 11:05:28 -0800279 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700280 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800281 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700282 if (callbacks != null) {
283 try {
Jorim Jaggibb42a462015-11-20 16:27:16 -0800284 callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
Winson Chungdff7a732017-12-11 12:17:06 -0800285 true /* animate */, recentsGrowTarget);
Winson190fe3bf2015-10-20 14:57:24 -0700286 } catch (RemoteException e) {
287 Log.e(TAG, "Callback failed", e);
288 }
289 } else {
290 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
291 }
292 }
Winson Chung2002cf52014-12-08 17:26:44 -0800293 }
294 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100295
Winson190fe3bf2015-10-20 14:57:24 -0700296 /**
297 * Hides the Recents.
298 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100299 @Override
Jason Monk764da992017-02-02 14:11:20 -0500300 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winsone9243562015-11-10 16:07:13 -0800301 // Ensure the device has been provisioned before allowing the user to interact with
302 // recents
Winsone6309aa2016-01-08 11:19:21 -0800303 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800304 return;
305 }
306
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800307 IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
308 if (overviewProxy != null) {
309 try {
310 overviewProxy.onOverviewHidden(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chungc1674272018-02-21 10:15:17 -0800311 return;
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800312 } catch (RemoteException e) {
313 Log.e(TAG, "Failed to send overview hide event to launcher.", e);
Winson Chungc1674272018-02-21 10:15:17 -0800314 }
315 }
316
Winsone7f138c2015-10-22 16:15:21 -0700317 int currentUser = sSystemServicesProxy.getCurrentUser();
318 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700319 mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chung2002cf52014-12-08 17:26:44 -0800320 } else {
Winsona00a7852016-02-16 11:05:28 -0800321 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700322 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800323 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700324 if (callbacks != null) {
325 try {
326 callbacks.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
327 } catch (RemoteException e) {
328 Log.e(TAG, "Callback failed", e);
329 }
330 } else {
331 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
332 }
333 }
Winson Chung2002cf52014-12-08 17:26:44 -0800334 }
335 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100336
Winson190fe3bf2015-10-20 14:57:24 -0700337 /**
338 * Toggles the Recents activity.
339 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100340 @Override
Winson Chungebe1ba12017-05-18 15:47:14 -0700341 public void toggleRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800342 // Ensure the device has been provisioned before allowing the user to interact with
343 // recents
Winsone6309aa2016-01-08 11:19:21 -0800344 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800345 return;
346 }
347
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800348 // If connected to launcher service, let it handle the toggle logic
349 IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
350 if (overviewProxy != null) {
Winson Chunge3dd59c2018-04-02 15:28:40 -0700351 final Runnable toggleRecents = () -> {
352 try {
353 if (mOverviewProxyService.getProxy() != null) {
354 mOverviewProxyService.getProxy().onOverviewToggle();
355 }
356 } catch (RemoteException e) {
357 Log.e(TAG, "Cannot send toggle recents through proxy service.", e);
358 }
359 };
360 // Preload only if device for current user is unlocked
361 final StatusBar statusBar = getComponent(StatusBar.class);
362 if (statusBar != null && statusBar.isKeyguardShowing()) {
363 statusBar.executeRunnableDismissingKeyguard(() -> {
364 // Flush trustmanager before checking device locked per user
365 mTrustManager.reportKeyguardShowingChanged();
366 mHandler.post(toggleRecents);
367 }, null, true /* dismissShade */, false /* afterKeyguardGone */,
368 true /* deferred */);
369 } else {
370 toggleRecents.run();
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800371 }
Winson Chunge3dd59c2018-04-02 15:28:40 -0700372 return;
Winson Chungc1674272018-02-21 10:15:17 -0800373 }
374
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700375 int growTarget = getComponent(Divider.class).getView().growsRecents();
Winsone7f138c2015-10-22 16:15:21 -0700376 int currentUser = sSystemServicesProxy.getCurrentUser();
377 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700378 mImpl.toggleRecents(growTarget);
Winson Chung2002cf52014-12-08 17:26:44 -0800379 } else {
Winsona00a7852016-02-16 11:05:28 -0800380 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700381 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800382 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700383 if (callbacks != null) {
384 try {
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700385 callbacks.toggleRecents(growTarget);
Winson190fe3bf2015-10-20 14:57:24 -0700386 } catch (RemoteException e) {
387 Log.e(TAG, "Callback failed", e);
388 }
389 } else {
390 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
391 }
392 }
Winson Chung2002cf52014-12-08 17:26:44 -0800393 }
394 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100395
Winson190fe3bf2015-10-20 14:57:24 -0700396 /**
397 * Preloads info for the Recents activity.
398 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100399 @Override
Winson Chungebe1ba12017-05-18 15:47:14 -0700400 public void preloadRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800401 // Ensure the device has been provisioned before allowing the user to interact with
402 // recents
Winsone6309aa2016-01-08 11:19:21 -0800403 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800404 return;
405 }
406
Winson Chungc1674272018-02-21 10:15:17 -0800407 if (mOverviewProxyService.getProxy() != null) {
408 // TODO: Proxy to Launcher
409 return;
410 }
411
Winsone7f138c2015-10-22 16:15:21 -0700412 int currentUser = sSystemServicesProxy.getCurrentUser();
413 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700414 mImpl.preloadRecents();
Winson Chung2002cf52014-12-08 17:26:44 -0800415 } else {
Winsona00a7852016-02-16 11:05:28 -0800416 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700417 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800418 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700419 if (callbacks != null) {
420 try {
421 callbacks.preloadRecents();
422 } catch (RemoteException e) {
423 Log.e(TAG, "Callback failed", e);
424 }
425 } else {
426 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
427 }
Winson Chunga278cae2015-06-09 13:51:13 -0700428 }
Winson Chunge1e20e12015-06-02 14:11:49 -0700429 }
Winson Chung7048fea2014-03-18 12:21:24 -0700430 }
431
Jorim Jaggid61f2272014-12-19 20:35:35 +0100432 @Override
Jason Monk764da992017-02-02 14:11:20 -0500433 public void cancelPreloadRecentApps() {
Winsone9243562015-11-10 16:07:13 -0800434 // Ensure the device has been provisioned before allowing the user to interact with
435 // recents
Winsone6309aa2016-01-08 11:19:21 -0800436 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800437 return;
438 }
439
Winson Chungc1674272018-02-21 10:15:17 -0800440 if (mOverviewProxyService.getProxy() != null) {
441 // TODO: Proxy to Launcher
442 return;
443 }
444
Winsone7f138c2015-10-22 16:15:21 -0700445 int currentUser = sSystemServicesProxy.getCurrentUser();
446 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700447 mImpl.cancelPreloadingRecents();
Winson Chungb1f74992014-08-08 12:53:09 -0700448 } else {
Winsona00a7852016-02-16 11:05:28 -0800449 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700450 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800451 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700452 if (callbacks != null) {
453 try {
454 callbacks.cancelPreloadingRecents();
455 } catch (RemoteException e) {
456 Log.e(TAG, "Callback failed", e);
457 }
458 } else {
459 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
460 }
461 }
Winson Chungb1f74992014-08-08 12:53:09 -0700462 }
463 }
464
Jorim Jaggid61f2272014-12-19 20:35:35 +0100465 @Override
Matthew Ngbf155872017-10-27 15:24:39 -0700466 public boolean splitPrimaryTask(int dragMode, int stackCreateMode, Rect initialBounds,
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700467 int metricsDockAction) {
Winsone6309aa2016-01-08 11:19:21 -0800468 // Ensure the device has been provisioned before allowing the user to interact with
469 // recents
470 if (!isUserSetup()) {
471 return false;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800472 }
Winsone6309aa2016-01-08 11:19:21 -0800473
Muyuan Lia2129992016-03-03 18:30:39 -0800474 Point realSize = new Point();
475 if (initialBounds == null) {
476 mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
477 .getRealSize(realSize);
478 initialBounds = new Rect(0, 0, realSize.x, realSize.y);
479 }
480
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800481 int currentUser = sSystemServicesProxy.getCurrentUser();
Winson Chungb05b3982017-11-01 18:02:43 -0700482 ActivityManager.RunningTaskInfo runningTask =
483 ActivityManagerWrapper.getInstance().getRunningTask();
Wale Ogunwale68278562017-09-23 17:13:55 -0700484 final int activityType = runningTask != null
485 ? runningTask.configuration.windowConfiguration.getActivityType()
486 : ACTIVITY_TYPE_UNDEFINED;
Matthew Ng6ff33b72018-02-27 13:47:38 -0800487 boolean screenPinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
Wale Ogunwale68278562017-09-23 17:13:55 -0700488 boolean isRunningTaskInHomeOrRecentsStack =
489 activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
Matthew Ngae1ff4f2016-11-10 15:49:14 -0800490 if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
Winsond46b7272016-04-20 11:54:27 -0700491 logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
Winson Chungd3395382016-12-13 11:49:09 -0800492 if (runningTask.supportsSplitScreenMultiWindow) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700493 if (metricsDockAction != -1) {
494 MetricsLogger.action(mContext, metricsDockAction,
Winsond46b7272016-04-20 11:54:27 -0700495 runningTask.topActivity.flattenToShortString());
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700496 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100497 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Matthew Ngbf155872017-10-27 15:24:39 -0700498 mImpl.splitPrimaryTask(runningTask.id, dragMode, stackCreateMode,
499 initialBounds);
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100500 } else {
501 if (mSystemToUserCallbacks != null) {
502 IRecentsNonSystemUserCallbacks callbacks =
503 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
504 if (callbacks != null) {
505 try {
Matthew Ngbf155872017-10-27 15:24:39 -0700506 callbacks.splitPrimaryTask(runningTask.id, dragMode,
507 stackCreateMode, initialBounds);
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100508 } catch (RemoteException e) {
509 Log.e(TAG, "Callback failed", e);
510 }
511 } else {
512 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800513 }
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800514 }
515 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100516 mDraggingInRecentsCurrentUser = currentUser;
Winson Chung68f54302018-03-29 18:36:17 -0700517
518 if (mOverviewProxyService.getProxy() != null) {
519 // The overview service is handling split screen, so just skip the wait for the
520 // first draw and notify the divider to start animating now
521 EventBus.getDefault().post(new RecentsDrawnEvent());
522 }
523
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100524 return true;
525 } else {
Winson675c5d82016-08-23 17:12:22 -0700526 EventBus.getDefault().send(new ShowUserToastEvent(
Winson Chung80f7b012017-03-28 21:33:28 -0700527 R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100528 return false;
Winsone6309aa2016-01-08 11:19:21 -0800529 }
Jorim Jaggiaa6c5742016-03-01 14:10:14 +0100530 } else {
531 return false;
Winsone6309aa2016-01-08 11:19:21 -0800532 }
Jorim Jaggidd98d412015-11-18 15:57:38 -0800533 }
534
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700535 public static void logDockAttempt(Context ctx, ComponentName activity, int resizeMode) {
536 if (resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE) {
537 MetricsLogger.action(ctx, MetricsEvent.ACTION_WINDOW_DOCK_UNRESIZABLE,
538 activity.flattenToShortString());
539 }
540 MetricsLogger.count(ctx, getMetricsCounterForResizeMode(resizeMode), 1);
541 }
542
543 private static String getMetricsCounterForResizeMode(int resizeMode) {
544 switch (resizeMode) {
545 case ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE:
546 return COUNTER_WINDOW_UNSUPPORTED;
547 case ActivityInfo.RESIZE_MODE_RESIZEABLE:
Wale Ogunwale72a73e32016-10-13 12:16:39 -0700548 case ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION:
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700549 return COUNTER_WINDOW_SUPPORTED;
550 default:
551 return COUNTER_WINDOW_INCOMPATIBLE;
552 }
553 }
554
Jorim Jaggidd98d412015-11-18 15:57:38 -0800555 @Override
556 public void onDraggingInRecents(float distanceFromTop) {
557 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
558 mImpl.onDraggingInRecents(distanceFromTop);
559 } else {
Winsona00a7852016-02-16 11:05:28 -0800560 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800561 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800562 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800563 mDraggingInRecentsCurrentUser);
564 if (callbacks != null) {
565 try {
566 callbacks.onDraggingInRecents(distanceFromTop);
567 } catch (RemoteException e) {
568 Log.e(TAG, "Callback failed", e);
569 }
570 } else {
571 Log.e(TAG, "No SystemUI callbacks found for user: "
572 + mDraggingInRecentsCurrentUser);
573 }
574 }
575 }
576 }
577
578 @Override
579 public void onDraggingInRecentsEnded(float velocity) {
580 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
581 mImpl.onDraggingInRecentsEnded(velocity);
582 } else {
Winsona00a7852016-02-16 11:05:28 -0800583 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800584 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800585 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800586 mDraggingInRecentsCurrentUser);
587 if (callbacks != null) {
588 try {
589 callbacks.onDraggingInRecentsEnded(velocity);
590 } catch (RemoteException e) {
591 Log.e(TAG, "Callback failed", e);
592 }
593 } else {
594 Log.e(TAG, "No SystemUI callbacks found for user: "
595 + mDraggingInRecentsCurrentUser);
596 }
597 }
598 }
Jorim Jaggi75b25972015-10-21 14:51:10 +0200599 }
600
601 @Override
Jorim Jaggid61f2272014-12-19 20:35:35 +0100602 public void showNextAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800603 // Ensure the device has been provisioned before allowing the user to interact with
604 // recents
Winsone6309aa2016-01-08 11:19:21 -0800605 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800606 return;
607 }
608
Winson190fe3bf2015-10-20 14:57:24 -0700609 mImpl.showNextAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700610 }
611
Jorim Jaggid61f2272014-12-19 20:35:35 +0100612 @Override
613 public void showPrevAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800614 // Ensure the device has been provisioned before allowing the user to interact with
615 // recents
Winsone6309aa2016-01-08 11:19:21 -0800616 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800617 return;
618 }
619
Winson190fe3bf2015-10-20 14:57:24 -0700620 mImpl.showPrevAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700621 }
622
Winson Chungee70fbd2017-08-29 14:56:01 -0700623 @Override
624 public void appTransitionFinished() {
Matthew Ng46bc92f2017-09-13 12:53:50 -0700625 if (!Recents.getConfiguration().isLowRamDevice) {
626 // Fallback, reset the flag once an app transition ends
627 EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(
628 false /* waitingForTransitionStart */));
629 }
Winson Chungee70fbd2017-08-29 14:56:01 -0700630 }
631
Winson190fe3bf2015-10-20 14:57:24 -0700632 /**
633 * Updates on configuration change.
634 */
Winson Chung7048fea2014-03-18 12:21:24 -0700635 public void onConfigurationChanged(Configuration newConfig) {
Winsone7f138c2015-10-22 16:15:21 -0700636 int currentUser = sSystemServicesProxy.getCurrentUser();
637 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700638 mImpl.onConfigurationChanged();
Winson Chung2002cf52014-12-08 17:26:44 -0800639 } else {
Winsona00a7852016-02-16 11:05:28 -0800640 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700641 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800642 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700643 if (callbacks != null) {
644 try {
645 callbacks.onConfigurationChanged();
646 } catch (RemoteException e) {
647 Log.e(TAG, "Callback failed", e);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700648 }
Winson190fe3bf2015-10-20 14:57:24 -0700649 } else {
650 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700651 }
Winson190fe3bf2015-10-20 14:57:24 -0700652 }
Winson Chungb0a28ea2014-10-28 15:21:35 -0700653 }
654 }
Winson190fe3bf2015-10-20 14:57:24 -0700655
656 /**
657 * Handle Recents activity visibility changed.
658 */
659 public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
Winson88737542016-02-17 13:27:33 -0800660 SystemServicesProxy ssp = Recents.getSystemServices();
661 int processUser = ssp.getProcessUser();
662 if (ssp.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700663 mImpl.onVisibilityChanged(event.applicationContext, event.visible);
664 } else {
665 postToSystemUser(new Runnable() {
666 @Override
667 public void run() {
668 try {
Winsona00a7852016-02-16 11:05:28 -0800669 mUserToSystemCallbacks.updateRecentsVisibility(event.visible);
Winson190fe3bf2015-10-20 14:57:24 -0700670 } catch (RemoteException e) {
671 Log.e(TAG, "Callback failed", e);
672 }
673 }
674 });
675 }
Matthew Ngc422f802017-08-02 14:00:59 -0700676
677 // This will catch the cases when a user launches from recents to another app
678 // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
679 // would not reset the wait for transition flag. This will catch it and make sure that the
680 // flag is reset.
681 if (!event.visible) {
682 mImpl.setWaitingForTransitionStart(false);
683 }
Winson190fe3bf2015-10-20 14:57:24 -0700684 }
685
Matthew Ng534e8542017-10-16 14:34:52 -0700686 public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
687 SystemServicesProxy ssp = Recents.getSystemServices();
688 int processUser = ssp.getProcessUser();
689 if (!ssp.isSystemUser(processUser)) {
690 postToSystemUser(new Runnable() {
691 @Override
692 public void run() {
693 try {
694 mUserToSystemCallbacks.sendDockedFirstAnimationFrameEvent();
695 } catch (RemoteException e) {
696 Log.e(TAG, "Callback failed", e);
697 }
698 }
699 });
700 }
701 }
702
Winson190fe3bf2015-10-20 14:57:24 -0700703 /**
704 * Handle screen pinning request.
705 */
706 public final void onBusEvent(final ScreenPinningRequestEvent event) {
Winson83c1b072015-11-09 10:48:04 -0800707 int processUser = sSystemServicesProxy.getProcessUser();
708 if (sSystemServicesProxy.isSystemUser(processUser)) {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700709 mImpl.onStartScreenPinning(event.applicationContext, event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700710 } else {
711 postToSystemUser(new Runnable() {
712 @Override
713 public void run() {
714 try {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700715 mUserToSystemCallbacks.startScreenPinning(event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700716 } catch (RemoteException e) {
717 Log.e(TAG, "Callback failed", e);
718 }
719 }
720 });
721 }
722 }
723
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800724 public final void onBusEvent(final RecentsDrawnEvent event) {
725 int processUser = sSystemServicesProxy.getProcessUser();
726 if (!sSystemServicesProxy.isSystemUser(processUser)) {
727 postToSystemUser(new Runnable() {
728 @Override
729 public void run() {
730 try {
Winsona00a7852016-02-16 11:05:28 -0800731 mUserToSystemCallbacks.sendRecentsDrawnEvent();
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800732 } catch (RemoteException e) {
733 Log.e(TAG, "Callback failed", e);
734 }
735 }
736 });
737 }
738 }
739
Jorim Jaggi899327f2016-02-25 20:44:18 -0500740 public final void onBusEvent(final DockedTopTaskEvent event) {
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800741 int processUser = sSystemServicesProxy.getProcessUser();
742 if (!sSystemServicesProxy.isSystemUser(processUser)) {
743 postToSystemUser(new Runnable() {
744 @Override
745 public void run() {
746 try {
Jorim Jaggi899327f2016-02-25 20:44:18 -0500747 mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode,
748 event.initialRect);
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800749 } catch (RemoteException e) {
750 Log.e(TAG, "Callback failed", e);
751 }
752 }
753 });
754 }
755 }
756
757 public final void onBusEvent(final RecentsActivityStartingEvent event) {
758 int processUser = sSystemServicesProxy.getProcessUser();
759 if (!sSystemServicesProxy.isSystemUser(processUser)) {
760 postToSystemUser(new Runnable() {
761 @Override
762 public void run() {
763 try {
Winsona00a7852016-02-16 11:05:28 -0800764 mUserToSystemCallbacks.sendLaunchRecentsEvent();
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800765 } catch (RemoteException e) {
766 Log.e(TAG, "Callback failed", e);
767 }
768 }
769 });
770 }
771 }
772
Matthew Ngc422f802017-08-02 14:00:59 -0700773 public final void onBusEvent(LaunchTaskFailedEvent event) {
774 // Reset the transition when tasks fail to launch
775 mImpl.setWaitingForTransitionStart(false);
776 }
777
Winson003eda62016-03-11 14:56:00 -0800778 public final void onBusEvent(ConfigurationChangedEvent event) {
779 // Update the configuration for the Recents component when the activity configuration
780 // changes as well
781 mImpl.onConfigurationChanged();
782 }
783
Winson675c5d82016-08-23 17:12:22 -0700784 public final void onBusEvent(ShowUserToastEvent event) {
785 int currentUser = sSystemServicesProxy.getCurrentUser();
786 if (sSystemServicesProxy.isSystemUser(currentUser)) {
787 mImpl.onShowCurrentUserToast(event.msgResId, event.msgLength);
788 } else {
789 if (mSystemToUserCallbacks != null) {
790 IRecentsNonSystemUserCallbacks callbacks =
791 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
792 if (callbacks != null) {
793 try {
794 callbacks.showCurrentUserToast(event.msgResId, event.msgLength);
795 } catch (RemoteException e) {
796 Log.e(TAG, "Callback failed", e);
797 }
798 } else {
799 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
800 }
801 }
802 }
803 }
804
Matthew Ng912c7f72017-08-02 22:12:04 +0000805 public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
806 int processUser = sSystemServicesProxy.getProcessUser();
807 if (sSystemServicesProxy.isSystemUser(processUser)) {
808 mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
809 } else {
810 postToSystemUser(new Runnable() {
811 @Override
812 public void run() {
813 try {
814 mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
815 event.waitingForTransitionStart);
816 } catch (RemoteException e) {
817 Log.e(TAG, "Callback failed", e);
818 }
819 }
820 });
821 }
822 }
823
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800824 /**
Winson190fe3bf2015-10-20 14:57:24 -0700825 * Attempts to register with the system user.
826 */
827 private void registerWithSystemUser() {
Winsone7f138c2015-10-22 16:15:21 -0700828 final int processUser = sSystemServicesProxy.getProcessUser();
Winson190fe3bf2015-10-20 14:57:24 -0700829 postToSystemUser(new Runnable() {
830 @Override
831 public void run() {
832 try {
Winsona00a7852016-02-16 11:05:28 -0800833 mUserToSystemCallbacks.registerNonSystemUserCallbacks(
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800834 new RecentsImplProxy(mImpl), processUser);
Winson190fe3bf2015-10-20 14:57:24 -0700835 } catch (RemoteException e) {
836 Log.e(TAG, "Failed to register", e);
837 }
838 }
839 });
840 }
841
842 /**
843 * Runs the runnable in the system user's Recents context, connecting to the service if
844 * necessary.
845 */
846 private void postToSystemUser(final Runnable onConnectRunnable) {
847 mOnConnectRunnables.add(onConnectRunnable);
Winsona00a7852016-02-16 11:05:28 -0800848 if (mUserToSystemCallbacks == null) {
Winson190fe3bf2015-10-20 14:57:24 -0700849 Intent systemUserServiceIntent = new Intent();
850 systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
851 boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
Winsona00a7852016-02-16 11:05:28 -0800852 mUserToSystemServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
853 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
854 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE,
855 sSystemServicesProxy.getProcessUser());
Winson190fe3bf2015-10-20 14:57:24 -0700856 if (!bound) {
857 // Retry after a fixed duration
858 mHandler.postDelayed(new Runnable() {
859 @Override
860 public void run() {
861 registerWithSystemUser();
862 }
863 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
864 }
865 } else {
866 runAndFlushOnConnectRunnables();
867 }
868 }
869
870 /**
871 * Runs all the queued runnables after a service connection is made.
872 */
873 private void runAndFlushOnConnectRunnables() {
874 for (Runnable r : mOnConnectRunnables) {
875 r.run();
876 }
877 mOnConnectRunnables.clear();
878 }
Winson4727ab92015-11-02 14:35:34 -0800879
880 /**
Winsone6309aa2016-01-08 11:19:21 -0800881 * @return whether this device is provisioned and the current user is set up.
Winsone9243562015-11-10 16:07:13 -0800882 */
Winsone6309aa2016-01-08 11:19:21 -0800883 private boolean isUserSetup() {
884 ContentResolver cr = mContext.getContentResolver();
885 return (Settings.Global.getInt(cr, Settings.Global.DEVICE_PROVISIONED, 0) != 0) &&
886 (Settings.Secure.getInt(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0);
Winsone9243562015-11-10 16:07:13 -0800887 }
888
Winson Chungee697562017-05-18 14:29:43 -0700889 @Override
890 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
891 pw.println("Recents");
892 pw.println(" currentUserId=" + SystemServicesProxy.getInstance(mContext).getCurrentUser());
893 }
Winson Chung7048fea2014-03-18 12:21:24 -0700894}