blob: 790f3f66f6e4d4ff1fd1845dfe539fcfbf8078f7 [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
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080019import android.app.ActivityManager;
Sid Soundararajan4bdb6872016-03-18 13:42:10 -070020import android.app.UiModeManager;
Winson190fe3bf2015-10-20 14:57:24 -070021import android.content.ComponentName;
Winsone6309aa2016-01-08 11:19:21 -080022import android.content.ContentResolver;
Winson Chung7048fea2014-03-18 12:21:24 -070023import android.content.Context;
24import android.content.Intent;
Winson190fe3bf2015-10-20 14:57:24 -070025import android.content.ServiceConnection;
Jorim Jaggi29379ec2016-04-11 23:43:42 -070026import android.content.pm.ActivityInfo;
Winson Chung7048fea2014-03-18 12:21:24 -070027import android.content.res.Configuration;
Muyuan Lia2129992016-03-03 18:30:39 -080028import android.graphics.Point;
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -080029import android.graphics.Rect;
Muyuan Lia2129992016-03-03 18:30:39 -080030import android.hardware.display.DisplayManager;
Winson4727ab92015-11-02 14:35:34 -080031import android.os.Build;
Jim Millera237a312014-11-06 18:05:59 -080032import android.os.Handler;
Winson190fe3bf2015-10-20 14:57:24 -070033import android.os.IBinder;
34import android.os.RemoteException;
Winson4727ab92015-11-02 14:35:34 -080035import android.os.SystemProperties;
Winson Chung7048fea2014-03-18 12:21:24 -070036import android.os.UserHandle;
Winsone9243562015-11-10 16:07:13 -080037import android.provider.Settings;
Winsona00a7852016-02-16 11:05:28 -080038import android.util.EventLog;
Winson190fe3bf2015-10-20 14:57:24 -070039import android.util.Log;
Jorim Jaggid61f2272014-12-19 20:35:35 +010040import android.view.Display;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010041import android.widget.Toast;
Winsonc0d70582016-01-29 10:24:39 -080042
Jorim Jaggi29379ec2016-04-11 23:43:42 -070043import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010044import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Winsona00a7852016-02-16 11:05:28 -080045import com.android.systemui.EventLogConstants;
46import com.android.systemui.EventLogTags;
Jorim Jaggiaa6c5742016-03-01 14:10:14 +010047import com.android.systemui.R;
Winson Chung9214eff2014-06-12 13:59:25 -070048import com.android.systemui.RecentsComponent;
Jorim Jaggid61f2272014-12-19 20:35:35 +010049import com.android.systemui.SystemUI;
Winson190fe3bf2015-10-20 14:57:24 -070050import com.android.systemui.recents.events.EventBus;
Winson003eda62016-03-11 14:56:00 -080051import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
Jorim Jaggi899327f2016-02-25 20:44:18 -050052import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
Jorim Jaggicdb06ca2016-01-25 19:15:12 -080053import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
Winson190fe3bf2015-10-20 14:57:24 -070054import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
55import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
Winson675c5d82016-08-23 17:12:22 -070056import com.android.systemui.recents.events.component.ShowUserToastEvent;
Jorim Jaggi11cc01d2016-01-22 19:39:23 -080057import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
Winson Chungffa2ec62014-07-03 15:54:42 -070058import com.android.systemui.recents.misc.SystemServicesProxy;
Winsone7f138c2015-10-22 16:15:21 -070059import com.android.systemui.recents.model.RecentsTaskLoader;
Manu Cornet1afcea42016-10-18 18:18:21 +080060import com.android.systemui.recents.grid.RecentsGridImpl;
Sid Soundararajan4bdb6872016-03-18 13:42:10 -070061import com.android.systemui.recents.tv.RecentsTvImpl;
Jorim Jaggidb21bbd2016-04-18 15:32:07 -070062import com.android.systemui.stackdivider.Divider;
Winson Chung7048fea2014-03-18 12:21:24 -070063
Winson Chungffa2ec62014-07-03 15:54:42 -070064import java.util.ArrayList;
Manu Cornet906a3a82016-11-04 06:58:15 -070065import java.util.HashSet;
66import java.util.Set;
Winson Chung7048fea2014-03-18 12:21:24 -070067
Winson Chung740c3ac2014-11-12 16:14:38 -080068
Winson190fe3bf2015-10-20 14:57:24 -070069/**
70 * An implementation of the SystemUI recents component, which supports both system and secondary
71 * users.
72 */
Jorim Jaggid61f2272014-12-19 20:35:35 +010073public class Recents extends SystemUI
Winson190fe3bf2015-10-20 14:57:24 -070074 implements RecentsComponent {
75
76 private final static String TAG = "Recents";
77 private final static boolean DEBUG = false;
Winson Chung7048fea2014-03-18 12:21:24 -070078
Winsone6c90732015-09-24 16:06:29 -070079 public final static int EVENT_BUS_PRIORITY = 1;
Winson190fe3bf2015-10-20 14:57:24 -070080 public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
Jorim Jaggidb21bbd2016-04-18 15:32:07 -070081 public final static int RECENTS_GROW_TARGET_INVALID = -1;
Winsone6c90732015-09-24 16:06:29 -070082
Manu Cornet906a3a82016-11-04 06:58:15 -070083 public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
84 static {
85 RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
86 RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY);
Manu Cornet1afcea42016-10-18 18:18:21 +080087 RECENTS_ACTIVITIES.add(RecentsGridImpl.RECENTS_MOSAIC_ACTIVITY);
Manu Cornet906a3a82016-11-04 06:58:15 -070088 }
89
Winson4727ab92015-11-02 14:35:34 -080090 // Purely for experimentation
91 private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
92 private final static String ACTION_SHOW_RECENTS = "com.android.systemui.recents.ACTION_SHOW";
93 private final static String ACTION_HIDE_RECENTS = "com.android.systemui.recents.ACTION_HIDE";
94 private final static String ACTION_TOGGLE_RECENTS = "com.android.systemui.recents.ACTION_TOGGLE";
95
Jorim Jaggi29379ec2016-04-11 23:43:42 -070096 private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
97 private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
98 private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
99
Winsone7f138c2015-10-22 16:15:21 -0700100 private static SystemServicesProxy sSystemServicesProxy;
Winsonc742f972015-11-12 11:32:21 -0800101 private static RecentsDebugFlags sDebugFlags;
Winsone7f138c2015-10-22 16:15:21 -0700102 private static RecentsTaskLoader sTaskLoader;
Winson53ec42c2015-10-28 15:55:35 -0700103 private static RecentsConfiguration sConfiguration;
Winsone7f138c2015-10-22 16:15:21 -0700104
Winson4727ab92015-11-02 14:35:34 -0800105 // For experiments only, allows another package to handle recents if it is defined in the system
106 // properties. This is limited to show/toggle/hide, and does not tie into the ActivityManager,
107 // and does not reside in the home stack.
108 private String mOverrideRecentsPackageName;
109
Winson Chung501d59d2016-10-05 17:49:09 +0000110 private Handler mHandler;
Winson190fe3bf2015-10-20 14:57:24 -0700111 private RecentsImpl mImpl;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800112 private int mDraggingInRecentsCurrentUser;
Winson Chung2002cf52014-12-08 17:26:44 -0800113
Winson190fe3bf2015-10-20 14:57:24 -0700114 // Only For system user, this is the callbacks instance we return to each secondary user
Winsona00a7852016-02-16 11:05:28 -0800115 private RecentsSystemUser mSystemToUserCallbacks;
Winson Chungcdcd4872014-08-05 18:00:13 -0700116
Winson190fe3bf2015-10-20 14:57:24 -0700117 // Only for secondary users, this is the callbacks instance provided by the system user to make
118 // calls back
Winsona00a7852016-02-16 11:05:28 -0800119 private IRecentsSystemUserCallbacks mUserToSystemCallbacks;
Winson Chungb44c24f2014-04-09 15:17:43 -0700120
Winson190fe3bf2015-10-20 14:57:24 -0700121 // The set of runnables to run after binding to the system user's service.
122 private final ArrayList<Runnable> mOnConnectRunnables = new ArrayList<>();
Winson Chung7048fea2014-03-18 12:21:24 -0700123
Winson190fe3bf2015-10-20 14:57:24 -0700124 // Only for secondary users, this is the death handler for the binder from the system user
Winsona00a7852016-02-16 11:05:28 -0800125 private final IBinder.DeathRecipient mUserToSystemCallbacksDeathRcpt = new IBinder.DeathRecipient() {
Winson Chung740c3ac2014-11-12 16:14:38 -0800126 @Override
Winson190fe3bf2015-10-20 14:57:24 -0700127 public void binderDied() {
Winsona00a7852016-02-16 11:05:28 -0800128 mUserToSystemCallbacks = null;
129 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
130 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_UNBOUND,
131 sSystemServicesProxy.getProcessUser());
Winson Chung2002cf52014-12-08 17:26:44 -0800132
Winson190fe3bf2015-10-20 14:57:24 -0700133 // Retry after a fixed duration
134 mHandler.postDelayed(new Runnable() {
135 @Override
136 public void run() {
137 registerWithSystemUser();
Winson Chung0eae5572014-12-11 11:04:19 -0800138 }
Winson190fe3bf2015-10-20 14:57:24 -0700139 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
Winson Chung740c3ac2014-11-12 16:14:38 -0800140 }
Winson190fe3bf2015-10-20 14:57:24 -0700141 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800142
Winson190fe3bf2015-10-20 14:57:24 -0700143 // Only for secondary users, this is the service connection we use to connect to the system user
Winsona00a7852016-02-16 11:05:28 -0800144 private final ServiceConnection mUserToSystemServiceConnection = new ServiceConnection() {
Winson Chung2002cf52014-12-08 17:26:44 -0800145 @Override
Winson190fe3bf2015-10-20 14:57:24 -0700146 public void onServiceConnected(ComponentName name, IBinder service) {
147 if (service != null) {
Winsona00a7852016-02-16 11:05:28 -0800148 mUserToSystemCallbacks = IRecentsSystemUserCallbacks.Stub.asInterface(
Winson190fe3bf2015-10-20 14:57:24 -0700149 service);
Winsona00a7852016-02-16 11:05:28 -0800150 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
151 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_BOUND,
152 sSystemServicesProxy.getProcessUser());
Winson190fe3bf2015-10-20 14:57:24 -0700153
154 // Listen for system user's death, so that we can reconnect later
155 try {
Winsona00a7852016-02-16 11:05:28 -0800156 service.linkToDeath(mUserToSystemCallbacksDeathRcpt, 0);
Winson190fe3bf2015-10-20 14:57:24 -0700157 } catch (RemoteException e) {
158 Log.e(TAG, "Lost connection to (System) SystemUI", e);
159 }
160
161 // Run each of the queued runnables
162 runAndFlushOnConnectRunnables();
Winson Chung2002cf52014-12-08 17:26:44 -0800163 }
Winson190fe3bf2015-10-20 14:57:24 -0700164
165 // Unbind ourselves now that we've registered our callbacks. The
166 // binder to the system user are still valid at this point.
167 mContext.unbindService(this);
Winson Chung2002cf52014-12-08 17:26:44 -0800168 }
Winson Chung2002cf52014-12-08 17:26:44 -0800169
Winson190fe3bf2015-10-20 14:57:24 -0700170 @Override
171 public void onServiceDisconnected(ComponentName name) {
172 // Do nothing
173 }
174 };
Winson Chung740c3ac2014-11-12 16:14:38 -0800175
Jorim Jaggid61f2272014-12-19 20:35:35 +0100176 /**
Winson190fe3bf2015-10-20 14:57:24 -0700177 * Returns the callbacks interface that non-system users can call.
Jorim Jaggid61f2272014-12-19 20:35:35 +0100178 */
Winson190fe3bf2015-10-20 14:57:24 -0700179 public IBinder getSystemUserCallbacks() {
Winsona00a7852016-02-16 11:05:28 -0800180 return mSystemToUserCallbacks;
Winson Chung7048fea2014-03-18 12:21:24 -0700181 }
182
Winsone7f138c2015-10-22 16:15:21 -0700183 public static RecentsTaskLoader getTaskLoader() {
184 return sTaskLoader;
185 }
186
187 public static SystemServicesProxy getSystemServices() {
188 return sSystemServicesProxy;
189 }
190
Winson53ec42c2015-10-28 15:55:35 -0700191 public static RecentsConfiguration getConfiguration() {
192 return sConfiguration;
193 }
194
Winsonc742f972015-11-12 11:32:21 -0800195 public static RecentsDebugFlags getDebugFlags() {
196 return sDebugFlags;
197 }
198
Jorim Jaggid61f2272014-12-19 20:35:35 +0100199 @Override
200 public void start() {
Winsonc742f972015-11-12 11:32:21 -0800201 sDebugFlags = new RecentsDebugFlags(mContext);
Jaewan Kim938a50b2016-03-14 17:35:43 +0900202 sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
Winsone7f138c2015-10-22 16:15:21 -0700203 sTaskLoader = new RecentsTaskLoader(mContext);
Winson53ec42c2015-10-28 15:55:35 -0700204 sConfiguration = new RecentsConfiguration(mContext);
Winson Chung501d59d2016-10-05 17:49:09 +0000205 mHandler = new Handler();
Sid Soundararajan4bdb6872016-03-18 13:42:10 -0700206 UiModeManager uiModeManager = (UiModeManager) mContext.
207 getSystemService(Context.UI_MODE_SERVICE);
208 if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
209 mImpl = new RecentsTvImpl(mContext);
Manu Cornet1afcea42016-10-18 18:18:21 +0800210 } else if (SystemProperties.getBoolean("ro.recents.grid", false) == true) {
211 mImpl = new RecentsGridImpl(mContext);
Sid Soundararajan4bdb6872016-03-18 13:42:10 -0700212 } else {
213 mImpl = new RecentsImpl(mContext);
214 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100215
Winson4727ab92015-11-02 14:35:34 -0800216 // Check if there is a recents override package
217 if ("userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE)) {
218 String cnStr = SystemProperties.get(RECENTS_OVERRIDE_SYSPROP_KEY);
219 if (!cnStr.isEmpty()) {
220 mOverrideRecentsPackageName = cnStr;
221 }
222 }
223
Winson190fe3bf2015-10-20 14:57:24 -0700224 // Register with the event bus
225 EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
Winsonc742f972015-11-12 11:32:21 -0800226 EventBus.getDefault().register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
Winsone7f138c2015-10-22 16:15:21 -0700227 EventBus.getDefault().register(sTaskLoader, EVENT_BUS_PRIORITY);
Jorim Jaggid61f2272014-12-19 20:35:35 +0100228
Winson190fe3bf2015-10-20 14:57:24 -0700229 // Due to the fact that RecentsActivity is per-user, we need to establish and interface for
230 // the system user's Recents component to pass events (like show/hide/toggleRecents) to the
231 // secondary user, and vice versa (like visibility change, screen pinning).
Winsone7f138c2015-10-22 16:15:21 -0700232 final int processUser = sSystemServicesProxy.getProcessUser();
233 if (sSystemServicesProxy.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700234 // For the system user, initialize an instance of the interface that we can pass to the
235 // secondary user
Winsona00a7852016-02-16 11:05:28 -0800236 mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
Winson190fe3bf2015-10-20 14:57:24 -0700237 } else {
238 // For the secondary user, bind to the primary user's service to get a persistent
239 // interface to register its implementation and to later update its state
240 registerWithSystemUser();
Jorim Jaggid61f2272014-12-19 20:35:35 +0100241 }
Jorim Jaggid61f2272014-12-19 20:35:35 +0100242 putComponent(Recents.class, this);
Winson Chung5abdceb2014-06-05 10:58:05 -0700243 }
244
Jorim Jaggid61f2272014-12-19 20:35:35 +0100245 @Override
Winson Chung8bf05af2014-09-29 13:42:49 -0700246 public void onBootCompleted() {
Winson190fe3bf2015-10-20 14:57:24 -0700247 mImpl.onBootCompleted();
Winson Chung8bf05af2014-09-29 13:42:49 -0700248 }
249
Winson190fe3bf2015-10-20 14:57:24 -0700250 /**
251 * Shows the Recents.
252 */
Jorim Jaggid61f2272014-12-19 20:35:35 +0100253 @Override
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700254 public void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
Winsone9243562015-11-10 16:07:13 -0800255 // Ensure the device has been provisioned before allowing the user to interact with
256 // recents
Winsone6309aa2016-01-08 11:19:21 -0800257 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800258 return;
259 }
260
Winson4727ab92015-11-02 14:35:34 -0800261 if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
262 return;
263 }
264
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
294 public void hideRecents(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
Jorim Jaggidb21bbd2016-04-18 15:32:07 -0700329 public void toggleRecents(Display display) {
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
366 public void preloadRecents() {
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
394 public void cancelPreloadingRecents() {
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);
445 if (runningTask.isDockable) {
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(
472 R.string.recents_incompatible_app_message, 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:
493 case ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE:
Wale Ogunwale72a73e32016-10-13 12:16:39 -0700494 case ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION:
Jorim Jaggi29379ec2016-04-11 23:43:42 -0700495 return COUNTER_WINDOW_SUPPORTED;
496 default:
497 return COUNTER_WINDOW_INCOMPATIBLE;
498 }
499 }
500
Jorim Jaggidd98d412015-11-18 15:57:38 -0800501 @Override
502 public void onDraggingInRecents(float distanceFromTop) {
503 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
504 mImpl.onDraggingInRecents(distanceFromTop);
505 } else {
Winsona00a7852016-02-16 11:05:28 -0800506 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800507 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800508 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800509 mDraggingInRecentsCurrentUser);
510 if (callbacks != null) {
511 try {
512 callbacks.onDraggingInRecents(distanceFromTop);
513 } catch (RemoteException e) {
514 Log.e(TAG, "Callback failed", e);
515 }
516 } else {
517 Log.e(TAG, "No SystemUI callbacks found for user: "
518 + mDraggingInRecentsCurrentUser);
519 }
520 }
521 }
522 }
523
524 @Override
525 public void onDraggingInRecentsEnded(float velocity) {
526 if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
527 mImpl.onDraggingInRecentsEnded(velocity);
528 } else {
Winsona00a7852016-02-16 11:05:28 -0800529 if (mSystemToUserCallbacks != null) {
Jorim Jaggidd98d412015-11-18 15:57:38 -0800530 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800531 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
Jorim Jaggidd98d412015-11-18 15:57:38 -0800532 mDraggingInRecentsCurrentUser);
533 if (callbacks != null) {
534 try {
535 callbacks.onDraggingInRecentsEnded(velocity);
536 } catch (RemoteException e) {
537 Log.e(TAG, "Callback failed", e);
538 }
539 } else {
540 Log.e(TAG, "No SystemUI callbacks found for user: "
541 + mDraggingInRecentsCurrentUser);
542 }
543 }
544 }
Jorim Jaggi75b25972015-10-21 14:51:10 +0200545 }
546
547 @Override
Jorim Jaggid61f2272014-12-19 20:35:35 +0100548 public void showNextAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800549 // Ensure the device has been provisioned before allowing the user to interact with
550 // recents
Winsone6309aa2016-01-08 11:19:21 -0800551 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800552 return;
553 }
554
Winson190fe3bf2015-10-20 14:57:24 -0700555 mImpl.showNextAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700556 }
557
Jorim Jaggid61f2272014-12-19 20:35:35 +0100558 @Override
559 public void showPrevAffiliatedTask() {
Winsone9243562015-11-10 16:07:13 -0800560 // Ensure the device has been provisioned before allowing the user to interact with
561 // recents
Winsone6309aa2016-01-08 11:19:21 -0800562 if (!isUserSetup()) {
Winsone9243562015-11-10 16:07:13 -0800563 return;
564 }
565
Winson190fe3bf2015-10-20 14:57:24 -0700566 mImpl.showPrevAffiliatedTask();
Winson Chungb1f74992014-08-08 12:53:09 -0700567 }
568
Winson190fe3bf2015-10-20 14:57:24 -0700569 /**
570 * Updates on configuration change.
571 */
Winson Chung7048fea2014-03-18 12:21:24 -0700572 public void onConfigurationChanged(Configuration newConfig) {
Winsone7f138c2015-10-22 16:15:21 -0700573 int currentUser = sSystemServicesProxy.getCurrentUser();
574 if (sSystemServicesProxy.isSystemUser(currentUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700575 mImpl.onConfigurationChanged();
Winson Chung2002cf52014-12-08 17:26:44 -0800576 } else {
Winsona00a7852016-02-16 11:05:28 -0800577 if (mSystemToUserCallbacks != null) {
Winson190fe3bf2015-10-20 14:57:24 -0700578 IRecentsNonSystemUserCallbacks callbacks =
Winsona00a7852016-02-16 11:05:28 -0800579 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
Winson190fe3bf2015-10-20 14:57:24 -0700580 if (callbacks != null) {
581 try {
582 callbacks.onConfigurationChanged();
583 } catch (RemoteException e) {
584 Log.e(TAG, "Callback failed", e);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700585 }
Winson190fe3bf2015-10-20 14:57:24 -0700586 } else {
587 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
Winson Chungb0a28ea2014-10-28 15:21:35 -0700588 }
Winson190fe3bf2015-10-20 14:57:24 -0700589 }
Winson Chungb0a28ea2014-10-28 15:21:35 -0700590 }
591 }
Winson190fe3bf2015-10-20 14:57:24 -0700592
593 /**
594 * Handle Recents activity visibility changed.
595 */
596 public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
Winson88737542016-02-17 13:27:33 -0800597 SystemServicesProxy ssp = Recents.getSystemServices();
598 int processUser = ssp.getProcessUser();
599 if (ssp.isSystemUser(processUser)) {
Winson190fe3bf2015-10-20 14:57:24 -0700600 mImpl.onVisibilityChanged(event.applicationContext, event.visible);
601 } else {
602 postToSystemUser(new Runnable() {
603 @Override
604 public void run() {
605 try {
Winsona00a7852016-02-16 11:05:28 -0800606 mUserToSystemCallbacks.updateRecentsVisibility(event.visible);
Winson190fe3bf2015-10-20 14:57:24 -0700607 } catch (RemoteException e) {
608 Log.e(TAG, "Callback failed", e);
609 }
610 }
611 });
612 }
613 }
614
615 /**
616 * Handle screen pinning request.
617 */
618 public final void onBusEvent(final ScreenPinningRequestEvent event) {
Winson83c1b072015-11-09 10:48:04 -0800619 int processUser = sSystemServicesProxy.getProcessUser();
620 if (sSystemServicesProxy.isSystemUser(processUser)) {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700621 mImpl.onStartScreenPinning(event.applicationContext, event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700622 } else {
623 postToSystemUser(new Runnable() {
624 @Override
625 public void run() {
626 try {
Andrii Kulian0f051f52016-04-14 00:41:51 -0700627 mUserToSystemCallbacks.startScreenPinning(event.taskId);
Winson190fe3bf2015-10-20 14:57:24 -0700628 } catch (RemoteException e) {
629 Log.e(TAG, "Callback failed", e);
630 }
631 }
632 });
633 }
634 }
635
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800636 public final void onBusEvent(final RecentsDrawnEvent event) {
637 int processUser = sSystemServicesProxy.getProcessUser();
638 if (!sSystemServicesProxy.isSystemUser(processUser)) {
639 postToSystemUser(new Runnable() {
640 @Override
641 public void run() {
642 try {
Winsona00a7852016-02-16 11:05:28 -0800643 mUserToSystemCallbacks.sendRecentsDrawnEvent();
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800644 } catch (RemoteException e) {
645 Log.e(TAG, "Callback failed", e);
646 }
647 }
648 });
649 }
650 }
651
Jorim Jaggi899327f2016-02-25 20:44:18 -0500652 public final void onBusEvent(final DockedTopTaskEvent event) {
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800653 int processUser = sSystemServicesProxy.getProcessUser();
654 if (!sSystemServicesProxy.isSystemUser(processUser)) {
655 postToSystemUser(new Runnable() {
656 @Override
657 public void run() {
658 try {
Jorim Jaggi899327f2016-02-25 20:44:18 -0500659 mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode,
660 event.initialRect);
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800661 } catch (RemoteException e) {
662 Log.e(TAG, "Callback failed", e);
663 }
664 }
665 });
666 }
667 }
668
669 public final void onBusEvent(final RecentsActivityStartingEvent event) {
670 int processUser = sSystemServicesProxy.getProcessUser();
671 if (!sSystemServicesProxy.isSystemUser(processUser)) {
672 postToSystemUser(new Runnable() {
673 @Override
674 public void run() {
675 try {
Winsona00a7852016-02-16 11:05:28 -0800676 mUserToSystemCallbacks.sendLaunchRecentsEvent();
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800677 } catch (RemoteException e) {
678 Log.e(TAG, "Callback failed", e);
679 }
680 }
681 });
682 }
683 }
684
Winson003eda62016-03-11 14:56:00 -0800685 public final void onBusEvent(ConfigurationChangedEvent event) {
686 // Update the configuration for the Recents component when the activity configuration
687 // changes as well
688 mImpl.onConfigurationChanged();
689 }
690
Winson675c5d82016-08-23 17:12:22 -0700691 public final void onBusEvent(ShowUserToastEvent event) {
692 int currentUser = sSystemServicesProxy.getCurrentUser();
693 if (sSystemServicesProxy.isSystemUser(currentUser)) {
694 mImpl.onShowCurrentUserToast(event.msgResId, event.msgLength);
695 } else {
696 if (mSystemToUserCallbacks != null) {
697 IRecentsNonSystemUserCallbacks callbacks =
698 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
699 if (callbacks != null) {
700 try {
701 callbacks.showCurrentUserToast(event.msgResId, event.msgLength);
702 } catch (RemoteException e) {
703 Log.e(TAG, "Callback failed", e);
704 }
705 } else {
706 Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
707 }
708 }
709 }
710 }
711
Jorim Jaggi11cc01d2016-01-22 19:39:23 -0800712 /**
Winson190fe3bf2015-10-20 14:57:24 -0700713 * Attempts to register with the system user.
714 */
715 private void registerWithSystemUser() {
Winsone7f138c2015-10-22 16:15:21 -0700716 final int processUser = sSystemServicesProxy.getProcessUser();
Winson190fe3bf2015-10-20 14:57:24 -0700717 postToSystemUser(new Runnable() {
718 @Override
719 public void run() {
720 try {
Winsona00a7852016-02-16 11:05:28 -0800721 mUserToSystemCallbacks.registerNonSystemUserCallbacks(
Jorim Jaggicdb06ca2016-01-25 19:15:12 -0800722 new RecentsImplProxy(mImpl), processUser);
Winson190fe3bf2015-10-20 14:57:24 -0700723 } catch (RemoteException e) {
724 Log.e(TAG, "Failed to register", e);
725 }
726 }
727 });
728 }
729
730 /**
731 * Runs the runnable in the system user's Recents context, connecting to the service if
732 * necessary.
733 */
734 private void postToSystemUser(final Runnable onConnectRunnable) {
735 mOnConnectRunnables.add(onConnectRunnable);
Winsona00a7852016-02-16 11:05:28 -0800736 if (mUserToSystemCallbacks == null) {
Winson190fe3bf2015-10-20 14:57:24 -0700737 Intent systemUserServiceIntent = new Intent();
738 systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
739 boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
Winsona00a7852016-02-16 11:05:28 -0800740 mUserToSystemServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
741 EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
742 EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE,
743 sSystemServicesProxy.getProcessUser());
Winson190fe3bf2015-10-20 14:57:24 -0700744 if (!bound) {
745 // Retry after a fixed duration
746 mHandler.postDelayed(new Runnable() {
747 @Override
748 public void run() {
749 registerWithSystemUser();
750 }
751 }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
752 }
753 } else {
754 runAndFlushOnConnectRunnables();
755 }
756 }
757
758 /**
759 * Runs all the queued runnables after a service connection is made.
760 */
761 private void runAndFlushOnConnectRunnables() {
762 for (Runnable r : mOnConnectRunnables) {
763 r.run();
764 }
765 mOnConnectRunnables.clear();
766 }
Winson4727ab92015-11-02 14:35:34 -0800767
768 /**
Winsone6309aa2016-01-08 11:19:21 -0800769 * @return whether this device is provisioned and the current user is set up.
Winsone9243562015-11-10 16:07:13 -0800770 */
Winsone6309aa2016-01-08 11:19:21 -0800771 private boolean isUserSetup() {
772 ContentResolver cr = mContext.getContentResolver();
773 return (Settings.Global.getInt(cr, Settings.Global.DEVICE_PROVISIONED, 0) != 0) &&
774 (Settings.Secure.getInt(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0);
Winsone9243562015-11-10 16:07:13 -0800775 }
776
777 /**
Winson4727ab92015-11-02 14:35:34 -0800778 * Attempts to proxy the following action to the override recents package.
779 * @return whether the proxying was successful
780 */
781 private boolean proxyToOverridePackage(String action) {
782 if (mOverrideRecentsPackageName != null) {
783 Intent intent = new Intent(action);
784 intent.setPackage(mOverrideRecentsPackageName);
785 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
786 mContext.sendBroadcast(intent);
787 return true;
788 }
789 return false;
790 }
Winson Chung7048fea2014-03-18 12:21:24 -0700791}