blob: bf5417dac5d5cecf117f41735dfad13f4d3491fb [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
Winson190fe3bf2015-10-20 14:57:24 -070019import android.content.ComponentName;
Winson Chung7048fea2014-03-18 12:21:24 -070020import android.content.Context;
21import android.content.Intent;
Winson190fe3bf2015-10-20 14:57:24 -070022import android.content.ServiceConnection;
Winson Chung7048fea2014-03-18 12:21:24 -070023import android.content.res.Configuration;
Winson4727ab92015-11-02 14:35:34 -080024import android.os.Build;
Jim Millera237a312014-11-06 18:05:59 -080025import android.os.Handler;
Winson190fe3bf2015-10-20 14:57:24 -070026import android.os.IBinder;
27import android.os.RemoteException;
Winson4727ab92015-11-02 14:35:34 -080028import android.os.SystemProperties;
Winson Chung7048fea2014-03-18 12:21:24 -070029import android.os.UserHandle;
Winson190fe3bf2015-10-20 14:57:24 -070030import android.util.Log;
Jorim Jaggid61f2272014-12-19 20:35:35 +010031import android.view.Display;
Winson Chung7048fea2014-03-18 12:21:24 -070032import android.view.View;
Winson Chung9214eff2014-06-12 13:59:25 -070033import com.android.systemui.RecentsComponent;
Jorim Jaggid61f2272014-12-19 20:35:35 +010034import com.android.systemui.SystemUI;
Winson190fe3bf2015-10-20 14:57:24 -070035import com.android.systemui.recents.events.EventBus;
36import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
37import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
Winson Chungffa2ec62014-07-03 15:54:42 -070038import com.android.systemui.recents.misc.SystemServicesProxy;
Winsone7f138c2015-10-22 16:15:21 -070039import com.android.systemui.recents.model.RecentsTaskLoader;
Winson Chung7048fea2014-03-18 12:21:24 -070040
Winson Chungffa2ec62014-07-03 15:54:42 -070041import java.util.ArrayList;
Winson Chung7048fea2014-03-18 12:21:24 -070042
Winson Chung740c3ac2014-11-12 16:14:38 -080043
Winson190fe3bf2015-10-20 14:57:24 -070044/**
45 * An implementation of the SystemUI recents component, which supports both system and secondary
46 * users.
47 */
Jorim Jaggid61f2272014-12-19 20:35:35 +010048public class Recents extends SystemUI
Winson190fe3bf2015-10-20 14:57:24 -070049 implements RecentsComponent {
50
51 private final static String TAG = "Recents";
52 private final static boolean DEBUG = false;
Winson Chung7048fea2014-03-18 12:21:24 -070053
Winsone6c90732015-09-24 16:06:29 -070054 public final static int EVENT_BUS_PRIORITY = 1;
Winson190fe3bf2015-10-20 14:57:24 -070055 public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
Winsone6c90732015-09-24 16:06:29 -070056
Winson4727ab92015-11-02 14:35:34 -080057 // Purely for experimentation
58 private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
59 private final static String ACTION_SHOW_RECENTS = "com.android.systemui.recents.ACTION_SHOW";
60 private final static String ACTION_HIDE_RECENTS = "com.android.systemui.recents.ACTION_HIDE";
61 private final static String ACTION_TOGGLE_RECENTS = "com.android.systemui.recents.ACTION_TOGGLE";
62
Winsone7f138c2015-10-22 16:15:21 -070063 private static SystemServicesProxy sSystemServicesProxy;
64 private static RecentsTaskLoader sTaskLoader;
Winson53ec42c2015-10-28 15:55:35 -070065 private static RecentsConfiguration sConfiguration;
Winsone7f138c2015-10-22 16:15:21 -070066
Winson4727ab92015-11-02 14:35:34 -080067 // For experiments only, allows another package to handle recents if it is defined in the system
68 // properties. This is limited to show/toggle/hide, and does not tie into the ActivityManager,
69 // and does not reside in the home stack.
70 private String mOverrideRecentsPackageName;
71
Winson190fe3bf2015-10-20 14:57:24 -070072 private Handler mHandler;
73 private RecentsImpl mImpl;
Winson Chung2002cf52014-12-08 17:26:44 -080074
Winson190fe3bf2015-10-20 14:57:24 -070075 // Only For system user, this is the callbacks instance we return to each secondary user
76 private RecentsSystemUser mSystemUserCallbacks;
Winson Chungcdcd4872014-08-05 18:00:13 -070077
Winson190fe3bf2015-10-20 14:57:24 -070078 // Only for secondary users, this is the callbacks instance provided by the system user to make
79 // calls back
80 private IRecentsSystemUserCallbacks mCallbacksToSystemUser;
Winson Chungb44c24f2014-04-09 15:17:43 -070081
Winson190fe3bf2015-10-20 14:57:24 -070082 // The set of runnables to run after binding to the system user's service.
83 private final ArrayList<Runnable> mOnConnectRunnables = new ArrayList<>();
Winson Chung7048fea2014-03-18 12:21:24 -070084
Winson190fe3bf2015-10-20 14:57:24 -070085 // Only for secondary users, this is the death handler for the binder from the system user
86 private final IBinder.DeathRecipient mCallbacksToSystemUserDeathRcpt = new IBinder.DeathRecipient() {
Winson Chung740c3ac2014-11-12 16:14:38 -080087 @Override
Winson190fe3bf2015-10-20 14:57:24 -070088 public void binderDied() {
89 mCallbacksToSystemUser = null;
Winson Chung2002cf52014-12-08 17:26:44 -080090
Winson190fe3bf2015-10-20 14:57:24 -070091 // Retry after a fixed duration
92 mHandler.postDelayed(new Runnable() {
93 @Override
94 public void run() {
95 registerWithSystemUser();
Winson Chung0eae5572014-12-11 11:04:19 -080096 }
Winson190fe3bf2015-10-20 14:57:24 -070097 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
Winson Chung740c3ac2014-11-12 16:14:38 -080098 }
Winson190fe3bf2015-10-20 14:57:24 -070099 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800100
Winson190fe3bf2015-10-20 14:57:24 -0700101 // Only for secondary users, this is the service connection we use to connect to the system user
102 private final ServiceConnection mServiceConnectionToSystemUser = new ServiceConnection() {
Winson Chung2002cf52014-12-08 17:26:44 -0800103 @Override
Winson190fe3bf2015-10-20 14:57:24 -0700104 public void onServiceConnected(ComponentName name, IBinder service) {
105 if (service != null) {
106 mCallbacksToSystemUser = IRecentsSystemUserCallbacks.Stub.asInterface(
107 service);
108
109 // Listen for system user's death, so that we can reconnect later
110 try {
111 service.linkToDeath(mCallbacksToSystemUserDeathRcpt, 0);
112 } catch (RemoteException e) {
113 Log.e(TAG, "Lost connection to (System) SystemUI", e);
114 }
115
116 // Run each of the queued runnables
117 runAndFlushOnConnectRunnables();
Winson Chung2002cf52014-12-08 17:26:44 -0800118 }
Winson190fe3bf2015-10-20 14:57:24 -0700119
120 // Unbind ourselves now that we've registered our callbacks. The
121 // binder to the system user are still valid at this point.
122 mContext.unbindService(this);
Winson Chung2002cf52014-12-08 17:26:44 -0800123 }
Winson Chung2002cf52014-12-08 17:26:44 -0800124
Winson190fe3bf2015-10-20 14:57:24 -0700125 @Override
126 public void onServiceDisconnected(ComponentName name) {
127 // Do nothing
128 }
129 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800130
Jorim Jaggid61f2272014-12-19 20:35:35 +0100131 /**
Winson190fe3bf2015-10-20 14:57:24 -0700132 * Returns the callbacks interface that non-system users can call.
Jorim Jaggid61f2272014-12-19 20:35:35 +0100133 */
Winson190fe3bf2015-10-20 14:57:24 -0700134 public IBinder getSystemUserCallbacks() {
135 return mSystemUserCallbacks;
Winson Chung7048fea2014-03-18 12:21:24 -0700136 }
137
Winsone7f138c2015-10-22 16:15:21 -0700138 public static RecentsTaskLoader getTaskLoader() {
139 return sTaskLoader;
140 }
141
142 public static SystemServicesProxy getSystemServices() {
143 return sSystemServicesProxy;
144 }
145
Winson53ec42c2015-10-28 15:55:35 -0700146 public static RecentsConfiguration getConfiguration() {
147 return sConfiguration;
148 }
149
Jorim Jaggid61f2272014-12-19 20:35:35 +0100150 @Override
151 public void start() {
Winsone7f138c2015-10-22 16:15:21 -0700152 sSystemServicesProxy = new SystemServicesProxy(mContext);
153 sTaskLoader = new RecentsTaskLoader(mContext);
Winson53ec42c2015-10-28 15:55:35 -0700154 sConfiguration = new RecentsConfiguration(mContext);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100155 mHandler = new Handler();
Winson190fe3bf2015-10-20 14:57:24 -0700156 mImpl = new RecentsImpl(mContext);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100157
Winson4727ab92015-11-02 14:35:34 -0800158 // Check if there is a recents override package
159 if ("userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE)) {
160 String cnStr = SystemProperties.get(RECENTS_OVERRIDE_SYSPROP_KEY);
161 if (!cnStr.isEmpty()) {
162 mOverrideRecentsPackageName = cnStr;
163 }
164 }
165
Winson190fe3bf2015-10-20 14:57:24 -0700166 // Register with the event bus
167 EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
Winsone7f138c2015-10-22 16:15:21 -0700168 EventBus.getDefault().register(sTaskLoader, EVENT_BUS_PRIORITY);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100169
Winson190fe3bf2015-10-20 14:57:24 -0700170 // Due to the fact that RecentsActivity is per-user, we need to establish and interface for
171 // the system user's Recents component to pass events (like show/hide/toggleRecents) to the
172 // secondary user, and vice versa (like visibility change, screen pinning).
Winsone7f138c2015-10-22 16:15:21 -0700173 final int processUser = sSystemServicesProxy.getProcessUser();
174 if (sSystemServicesProxy.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700175 // For the system user, initialize an instance of the interface that we can pass to the
176 // secondary user
177 mSystemUserCallbacks = new RecentsSystemUser(mContext, mImpl);
178 } else {
179 // For the secondary user, bind to the primary user's service to get a persistent
180 // interface to register its implementation and to later update its state
181 registerWithSystemUser();
Jorim Jaggid61f2272014-12-19 20:35:35 +0100182 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100183 putComponent(Recents.class, this);
Winson Chung5abdceb2014-06-05 10:58:05 -0700184 }
185
Jorim Jaggid61f2272014-12-19 20:35:35 +0100186 @Override
Winson Chung8bf05af2014-09-29 13:42:49 -0700187 public void onBootCompleted() {
Winson190fe3bf2015-10-20 14:57:24 -0700188 mImpl.onBootCompleted();
Winson Chung8bf05af2014-09-29 13:42:49 -0700189 }
190
Winson190fe3bf2015-10-20 14:57:24 -0700191 /**
192 * Shows the Recents.
193 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100194 @Override
195 public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
Winson4727ab92015-11-02 14:35:34 -0800196 if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
197 return;
198 }
199
Winsone7f138c2015-10-22 16:15:21 -0700200 int currentUser = sSystemServicesProxy.getCurrentUser();
201 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700202 mImpl.showRecents(triggeredFromAltTab);
Winson Chung2002cf52014-12-08 17:26:44 -0800203 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700204 if (mSystemUserCallbacks != null) {
205 IRecentsNonSystemUserCallbacks callbacks =
206 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
207 if (callbacks != null) {
208 try {
209 callbacks.showRecents(triggeredFromAltTab);
210 } catch (RemoteException e) {
211 Log.e(TAG, "Callback failed", e);
212 }
213 } else {
214 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
215 }
216 }
Winson Chung2002cf52014-12-08 17:26:44 -0800217 }
218 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100219
Winson190fe3bf2015-10-20 14:57:24 -0700220 /**
221 * Hides the Recents.
222 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100223 @Override
224 public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winson4727ab92015-11-02 14:35:34 -0800225 if (proxyToOverridePackage(ACTION_HIDE_RECENTS)) {
226 return;
227 }
228
Winsone7f138c2015-10-22 16:15:21 -0700229 int currentUser = sSystemServicesProxy.getCurrentUser();
230 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700231 mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chung2002cf52014-12-08 17:26:44 -0800232 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700233 if (mSystemUserCallbacks != null) {
234 IRecentsNonSystemUserCallbacks callbacks =
235 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
236 if (callbacks != null) {
237 try {
238 callbacks.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
239 } catch (RemoteException e) {
240 Log.e(TAG, "Callback failed", e);
241 }
242 } else {
243 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
244 }
245 }
Winson Chung2002cf52014-12-08 17:26:44 -0800246 }
247 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100248
Winson190fe3bf2015-10-20 14:57:24 -0700249 /**
250 * Toggles the Recents activity.
251 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100252 @Override
253 public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
Winson4727ab92015-11-02 14:35:34 -0800254 if (proxyToOverridePackage(ACTION_TOGGLE_RECENTS)) {
255 return;
256 }
257
Winsone7f138c2015-10-22 16:15:21 -0700258 int currentUser = sSystemServicesProxy.getCurrentUser();
259 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700260 mImpl.toggleRecents();
Winson Chung2002cf52014-12-08 17:26:44 -0800261 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700262 if (mSystemUserCallbacks != null) {
263 IRecentsNonSystemUserCallbacks callbacks =
264 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
265 if (callbacks != null) {
266 try {
267 callbacks.toggleRecents();
268 } catch (RemoteException e) {
269 Log.e(TAG, "Callback failed", e);
270 }
271 } else {
272 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
273 }
274 }
Winson Chung2002cf52014-12-08 17:26:44 -0800275 }
276 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100277
Winson190fe3bf2015-10-20 14:57:24 -0700278 /**
279 * Preloads info for the Recents activity.
280 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100281 @Override
282 public void preloadRecents() {
Winsone7f138c2015-10-22 16:15:21 -0700283 int currentUser = sSystemServicesProxy.getCurrentUser();
284 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700285 mImpl.preloadRecents();
Winson Chung2002cf52014-12-08 17:26:44 -0800286 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700287 if (mSystemUserCallbacks != null) {
288 IRecentsNonSystemUserCallbacks callbacks =
289 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
290 if (callbacks != null) {
291 try {
292 callbacks.preloadRecents();
293 } catch (RemoteException e) {
294 Log.e(TAG, "Callback failed", e);
295 }
296 } else {
297 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
298 }
Winson Chunga278cae2015-06-09 13:51:13 -0700299 }
Winson Chunge1e20e12015-06-02 14:11:49 -0700300 }
Winson Chung7048fea2014-03-18 12:21:24 -0700301 }
302
Jorim Jaggid61f2272014-12-19 20:35:35 +0100303 @Override
304 public void cancelPreloadingRecents() {
Winsone7f138c2015-10-22 16:15:21 -0700305 int currentUser = sSystemServicesProxy.getCurrentUser();
306 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700307 mImpl.cancelPreloadingRecents();
Winson Chungb1f74992014-08-08 12:53:09 -0700308 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700309 if (mSystemUserCallbacks != null) {
310 IRecentsNonSystemUserCallbacks callbacks =
311 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
312 if (callbacks != null) {
313 try {
314 callbacks.cancelPreloadingRecents();
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 Chungb1f74992014-08-08 12:53:09 -0700322 }
323 }
324
Jorim Jaggid61f2272014-12-19 20:35:35 +0100325 @Override
Jorim Jaggi75b25972015-10-21 14:51:10 +0200326 public void dockTopTask() {
327 mImpl.dockTopTask();
328 }
329
330 @Override
Jorim Jaggid61f2272014-12-19 20:35:35 +0100331 public void showNextAffiliatedTask() {
Winson190fe3bf2015-10-20 14:57:24 -0700332 mImpl.showNextAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700333 }
334
Jorim Jaggid61f2272014-12-19 20:35:35 +0100335 @Override
336 public void showPrevAffiliatedTask() {
Winson190fe3bf2015-10-20 14:57:24 -0700337 mImpl.showPrevAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700338 }
339
Winson190fe3bf2015-10-20 14:57:24 -0700340 /**
341 * Updates on configuration change.
342 */
Winson Chung7048fea2014-03-18 12:21:24 -0700343 public void onConfigurationChanged(Configuration newConfig) {
Winsone7f138c2015-10-22 16:15:21 -0700344 int currentUser = sSystemServicesProxy.getCurrentUser();
345 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700346 mImpl.onConfigurationChanged();
Winson Chung2002cf52014-12-08 17:26:44 -0800347 } else {
Winson190fe3bf2015-10-20 14:57:24 -0700348 if (mSystemUserCallbacks != null) {
349 IRecentsNonSystemUserCallbacks callbacks =
350 mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
351 if (callbacks != null) {
352 try {
353 callbacks.onConfigurationChanged();
354 } catch (RemoteException e) {
355 Log.e(TAG, "Callback failed", e);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700356 }
Winson190fe3bf2015-10-20 14:57:24 -0700357 } else {
358 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700359 }
Winson190fe3bf2015-10-20 14:57:24 -0700360 }
Winson Chungb0a28ea2014-10-28 15:21:35 -0700361 }
362 }
Winson190fe3bf2015-10-20 14:57:24 -0700363
364 /**
365 * Handle Recents activity visibility changed.
366 */
367 public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
368 int processUser = event.systemServicesProxy.getProcessUser();
369 if (event.systemServicesProxy.isSystemUser(processUser)) {
370 mImpl.onVisibilityChanged(event.applicationContext, event.visible);
371 } else {
372 postToSystemUser(new Runnable() {
373 @Override
374 public void run() {
375 try {
376 mCallbacksToSystemUser.updateRecentsVisibility(event.visible);
377 } catch (RemoteException e) {
378 Log.e(TAG, "Callback failed", e);
379 }
380 }
381 });
382 }
383 }
384
385 /**
386 * Handle screen pinning request.
387 */
388 public final void onBusEvent(final ScreenPinningRequestEvent event) {
Winson83c1b072015-11-09 10:48:04 -0800389 int processUser = sSystemServicesProxy.getProcessUser();
390 if (sSystemServicesProxy.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700391 mImpl.onStartScreenPinning(event.applicationContext);
392 } else {
393 postToSystemUser(new Runnable() {
394 @Override
395 public void run() {
396 try {
397 mCallbacksToSystemUser.startScreenPinning();
398 } catch (RemoteException e) {
399 Log.e(TAG, "Callback failed", e);
400 }
401 }
402 });
403 }
404 }
405
406 /**
407 * Attempts to register with the system user.
408 */
409 private void registerWithSystemUser() {
Winsone7f138c2015-10-22 16:15:21 -0700410 final int processUser = sSystemServicesProxy.getProcessUser();
Winson190fe3bf2015-10-20 14:57:24 -0700411 postToSystemUser(new Runnable() {
412 @Override
413 public void run() {
414 try {
415 mCallbacksToSystemUser.registerNonSystemUserCallbacks(mImpl, processUser);
416 } catch (RemoteException e) {
417 Log.e(TAG, "Failed to register", e);
418 }
419 }
420 });
421 }
422
423 /**
424 * Runs the runnable in the system user's Recents context, connecting to the service if
425 * necessary.
426 */
427 private void postToSystemUser(final Runnable onConnectRunnable) {
428 mOnConnectRunnables.add(onConnectRunnable);
429 if (mCallbacksToSystemUser == null) {
430 Intent systemUserServiceIntent = new Intent();
431 systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
432 boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
433 mServiceConnectionToSystemUser, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
434 if (!bound) {
435 // Retry after a fixed duration
436 mHandler.postDelayed(new Runnable() {
437 @Override
438 public void run() {
439 registerWithSystemUser();
440 }
441 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
442 }
443 } else {
444 runAndFlushOnConnectRunnables();
445 }
446 }
447
448 /**
449 * Runs all the queued runnables after a service connection is made.
450 */
451 private void runAndFlushOnConnectRunnables() {
452 for (Runnable r : mOnConnectRunnables) {
453 r.run();
454 }
455 mOnConnectRunnables.clear();
456 }
Winson4727ab92015-11-02 14:35:34 -0800457
458 /**
459 * Attempts to proxy the following action to the override recents package.
460 * @return whether the proxying was successful
461 */
462 private boolean proxyToOverridePackage(String action) {
463 if (mOverrideRecentsPackageName != null) {
464 Intent intent = new Intent(action);
465 intent.setPackage(mOverrideRecentsPackageName);
466 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
467 mContext.sendBroadcast(intent);
468 return true;
469 }
470 return false;
471 }
Winson Chung7048fea2014-03-18 12:21:24 -0700472}