Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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 | |
| 17 | package com.android.systemui.shared.system; |
| 18 | |
| 19 | import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 20 | import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; |
| 21 | import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; |
| 22 | import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; |
| 23 | import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; |
| 24 | import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; |
| 25 | import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 26 | |
| 27 | import android.annotation.NonNull; |
| 28 | import android.app.ActivityManager; |
| 29 | import android.app.ActivityManager.RecentTaskInfo; |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 30 | import android.app.ActivityOptions; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 31 | import android.app.AppGlobals; |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 32 | import android.app.IAssistDataReceiver; |
Tony Wickham | fb63fe8 | 2018-01-16 12:14:06 -0800 | [diff] [blame^] | 33 | import android.app.WindowConfiguration.ActivityType; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 34 | import android.content.Context; |
| 35 | import android.content.pm.ActivityInfo; |
| 36 | import android.content.pm.ApplicationInfo; |
| 37 | import android.content.pm.PackageManager; |
| 38 | import android.content.pm.UserInfo; |
| 39 | import android.content.res.Resources; |
| 40 | import android.content.res.Resources.NotFoundException; |
| 41 | import android.graphics.Bitmap; |
| 42 | import android.graphics.drawable.BitmapDrawable; |
| 43 | import android.graphics.drawable.Drawable; |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 44 | import android.os.Bundle; |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 45 | import android.os.Handler; |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 46 | import android.os.Looper; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 47 | import android.os.RemoteException; |
| 48 | import android.os.UserHandle; |
| 49 | import android.util.IconDrawableFactory; |
| 50 | import android.util.Log; |
| 51 | |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 52 | import com.android.systemui.shared.recents.model.Task; |
| 53 | import com.android.systemui.shared.recents.model.Task.TaskKey; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 54 | import com.android.systemui.shared.recents.model.ThumbnailData; |
| 55 | |
| 56 | import java.util.ArrayList; |
| 57 | import java.util.List; |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 58 | import java.util.function.Consumer; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 59 | |
| 60 | public class ActivityManagerWrapper { |
| 61 | |
| 62 | private static final String TAG = "ActivityManagerWrapper"; |
| 63 | |
| 64 | private static final ActivityManagerWrapper sInstance = new ActivityManagerWrapper(); |
| 65 | |
| 66 | private final PackageManager mPackageManager; |
| 67 | private final IconDrawableFactory mDrawableFactory; |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 68 | private final BackgroundExecutor mBackgroundExecutor; |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 69 | private final TaskStackChangeListeners mTaskStackChangeListeners; |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 70 | |
| 71 | private ActivityManagerWrapper() { |
| 72 | final Context context = AppGlobals.getInitialApplication(); |
| 73 | mPackageManager = context.getPackageManager(); |
| 74 | mDrawableFactory = IconDrawableFactory.newInstance(context); |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 75 | mBackgroundExecutor = BackgroundExecutor.get(); |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 76 | mTaskStackChangeListeners = new TaskStackChangeListeners(Looper.getMainLooper()); |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | public static ActivityManagerWrapper getInstance() { |
| 80 | return sInstance; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * @return the current user's id. |
| 85 | */ |
| 86 | public int getCurrentUserId() { |
| 87 | UserInfo ui; |
| 88 | try { |
| 89 | ui = ActivityManager.getService().getCurrentUser(); |
| 90 | return ui != null ? ui.id : 0; |
| 91 | } catch (RemoteException e) { |
| 92 | throw e.rethrowFromSystemServer(); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | /** |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 97 | * @return the top running task (can be {@code null}). |
| 98 | */ |
| 99 | public ActivityManager.RunningTaskInfo getRunningTask() { |
Tony Wickham | fb63fe8 | 2018-01-16 12:14:06 -0800 | [diff] [blame^] | 100 | return getRunningTask(ACTIVITY_TYPE_RECENTS /* ignoreActivityType */); |
| 101 | } |
| 102 | |
| 103 | public ActivityManager.RunningTaskInfo getRunningTask(@ActivityType int ignoreActivityType) { |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 104 | // Note: The set of running tasks from the system is ordered by recency |
| 105 | try { |
| 106 | List<ActivityManager.RunningTaskInfo> tasks = |
Tony Wickham | fb63fe8 | 2018-01-16 12:14:06 -0800 | [diff] [blame^] | 107 | ActivityManager.getService().getFilteredTasks(1, ignoreActivityType, |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 108 | WINDOWING_MODE_PINNED /* ignoreWindowingMode */); |
| 109 | if (tasks.isEmpty()) { |
| 110 | return null; |
| 111 | } |
| 112 | return tasks.get(0); |
| 113 | } catch (RemoteException e) { |
| 114 | return null; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | /** |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 119 | * @return a list of the recents tasks. |
| 120 | */ |
| 121 | public List<RecentTaskInfo> getRecentTasks(int numTasks, int userId) { |
| 122 | try { |
| 123 | return ActivityManager.getService().getRecentTasks(numTasks, |
| 124 | RECENT_IGNORE_UNAVAILABLE, userId).getList(); |
| 125 | } catch (RemoteException e) { |
| 126 | Log.e(TAG, "Failed to get recent tasks", e); |
| 127 | return new ArrayList<>(); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | /** |
| 132 | * @return the task snapshot for the given {@param taskId}. |
| 133 | */ |
| 134 | public @NonNull ThumbnailData getTaskThumbnail(int taskId, boolean reducedResolution) { |
| 135 | ActivityManager.TaskSnapshot snapshot = null; |
| 136 | try { |
| 137 | snapshot = ActivityManager.getService().getTaskSnapshot(taskId, reducedResolution); |
| 138 | } catch (RemoteException e) { |
| 139 | Log.w(TAG, "Failed to retrieve task snapshot", e); |
| 140 | } |
| 141 | if (snapshot != null) { |
| 142 | return new ThumbnailData(snapshot); |
| 143 | } else { |
| 144 | return new ThumbnailData(); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | /** |
| 149 | * @return the task description icon, loading and badging it if it necessary. |
| 150 | */ |
| 151 | public Drawable getBadgedTaskDescriptionIcon(Context context, |
| 152 | ActivityManager.TaskDescription taskDescription, int userId, Resources res) { |
| 153 | Bitmap tdIcon = taskDescription.getInMemoryIcon(); |
| 154 | Drawable dIcon = null; |
| 155 | if (tdIcon != null) { |
| 156 | dIcon = new BitmapDrawable(res, tdIcon); |
| 157 | } else if (taskDescription.getIconResource() != 0) { |
| 158 | try { |
| 159 | dIcon = context.getDrawable(taskDescription.getIconResource()); |
| 160 | } catch (NotFoundException e) { |
| 161 | Log.e(TAG, "Could not find icon drawable from resource", e); |
| 162 | } |
| 163 | } else { |
| 164 | tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon( |
| 165 | taskDescription.getIconFilename(), userId); |
| 166 | if (tdIcon != null) { |
| 167 | dIcon = new BitmapDrawable(res, tdIcon); |
| 168 | } |
| 169 | } |
| 170 | if (dIcon != null) { |
| 171 | return getBadgedIcon(dIcon, userId); |
| 172 | } |
| 173 | return null; |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * @return the given icon for a user, badging if necessary. |
| 178 | */ |
| 179 | private Drawable getBadgedIcon(Drawable icon, int userId) { |
| 180 | if (userId != UserHandle.myUserId()) { |
| 181 | icon = mPackageManager.getUserBadgedIcon(icon, new UserHandle(userId)); |
| 182 | } |
| 183 | return icon; |
| 184 | } |
| 185 | |
| 186 | /** |
| 187 | * @return the activity icon for the ActivityInfo for a user, badging if necessary. |
| 188 | */ |
| 189 | public Drawable getBadgedActivityIcon(ActivityInfo info, int userId) { |
| 190 | return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId); |
| 191 | } |
| 192 | |
| 193 | /** |
| 194 | * @return the application icon for the ApplicationInfo for a user, badging if necessary. |
| 195 | */ |
| 196 | public Drawable getBadgedApplicationIcon(ApplicationInfo appInfo, int userId) { |
| 197 | return mDrawableFactory.getBadgedIcon(appInfo, userId); |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * @return the activity label, badging if necessary. |
| 202 | */ |
| 203 | public String getBadgedActivityLabel(ActivityInfo info, int userId) { |
| 204 | return getBadgedLabel(info.loadLabel(mPackageManager).toString(), userId); |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * @return the application label, badging if necessary. |
| 209 | */ |
| 210 | public String getBadgedApplicationLabel(ApplicationInfo appInfo, int userId) { |
| 211 | return getBadgedLabel(appInfo.loadLabel(mPackageManager).toString(), userId); |
| 212 | } |
| 213 | |
| 214 | /** |
| 215 | * @return the content description for a given task, badging it if necessary. The content |
| 216 | * description joins the app and activity labels. |
| 217 | */ |
| 218 | public String getBadgedContentDescription(ActivityInfo info, int userId, |
| 219 | ActivityManager.TaskDescription td) { |
| 220 | String activityLabel; |
| 221 | if (td != null && td.getLabel() != null) { |
| 222 | activityLabel = td.getLabel(); |
| 223 | } else { |
| 224 | activityLabel = info.loadLabel(mPackageManager).toString(); |
| 225 | } |
| 226 | String applicationLabel = info.applicationInfo.loadLabel(mPackageManager).toString(); |
| 227 | String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId); |
| 228 | return applicationLabel.equals(activityLabel) |
| 229 | ? badgedApplicationLabel |
| 230 | : badgedApplicationLabel + " " + activityLabel; |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * @return the given label for a user, badging if necessary. |
| 235 | */ |
| 236 | private String getBadgedLabel(String label, int userId) { |
| 237 | if (userId != UserHandle.myUserId()) { |
| 238 | label = mPackageManager.getUserBadgedLabel(label, new UserHandle(userId)).toString(); |
| 239 | } |
| 240 | return label; |
| 241 | } |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 242 | |
| 243 | /** |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 244 | * Starts the recents activity. The caller should manage the thread on which this is called. |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 245 | */ |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 246 | public void startRecentsActivity(AssistDataReceiverCompat assistDataReceiver, Bundle options, |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 247 | ActivityOptions opts, int userId, Consumer<Boolean> resultCallback, |
| 248 | Handler resultCallbackHandler) { |
| 249 | Bundle activityOptions = opts != null ? opts.toBundle() : null; |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 250 | try { |
| 251 | IAssistDataReceiver receiver = null; |
| 252 | if (assistDataReceiver != null) { |
| 253 | receiver = new IAssistDataReceiver.Stub() { |
| 254 | public void onHandleAssistData(Bundle resultData) { |
| 255 | assistDataReceiver.onHandleAssistData(resultData); |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 256 | } |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 257 | public void onHandleAssistScreenshot(Bitmap screenshot) { |
| 258 | assistDataReceiver.onHandleAssistScreenshot(screenshot); |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 259 | } |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 260 | }; |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 261 | } |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 262 | ActivityManager.getService().startRecentsActivity(receiver, options, activityOptions, |
| 263 | userId); |
| 264 | if (resultCallback != null) { |
| 265 | resultCallbackHandler.post(new Runnable() { |
| 266 | @Override |
| 267 | public void run() { |
| 268 | resultCallback.accept(true); |
| 269 | } |
| 270 | }); |
| 271 | } |
| 272 | } catch (Exception e) { |
| 273 | if (resultCallback != null) { |
| 274 | resultCallbackHandler.post(new Runnable() { |
| 275 | @Override |
| 276 | public void run() { |
| 277 | resultCallback.accept(false); |
| 278 | } |
| 279 | }); |
| 280 | } |
| 281 | } |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 282 | } |
| 283 | |
| 284 | /** |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 285 | * Starts a task from Recents. |
| 286 | * |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 287 | * @see {@link #startActivityFromRecentsAsync(TaskKey, ActivityOptions, int, int, Consumer, Handler)} |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 288 | */ |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 289 | public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options, |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 290 | Consumer<Boolean> resultCallback, Handler resultCallbackHandler) { |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 291 | startActivityFromRecentsAsync(taskKey, options, WINDOWING_MODE_UNDEFINED, |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 292 | ACTIVITY_TYPE_UNDEFINED, resultCallback, resultCallbackHandler); |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | * Starts a task from Recents. |
| 297 | * |
| 298 | * @param resultCallback The result success callback |
| 299 | * @param resultCallbackHandler The handler to receive the result callback |
| 300 | */ |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 301 | public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options, |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 302 | int windowingMode, int activityType, Consumer<Boolean> resultCallback, |
| 303 | Handler resultCallbackHandler) { |
| 304 | if (taskKey.windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { |
| 305 | // We show non-visible docked tasks in Recents, but we always want to launch |
| 306 | // them in the fullscreen stack. |
| 307 | if (options == null) { |
| 308 | options = ActivityOptions.makeBasic(); |
| 309 | } |
| 310 | options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); |
| 311 | } else if (windowingMode != WINDOWING_MODE_UNDEFINED |
| 312 | || activityType != ACTIVITY_TYPE_UNDEFINED) { |
| 313 | if (options == null) { |
| 314 | options = ActivityOptions.makeBasic(); |
| 315 | } |
| 316 | options.setLaunchWindowingMode(windowingMode); |
| 317 | options.setLaunchActivityType(activityType); |
| 318 | } |
| 319 | final ActivityOptions finalOptions = options; |
| 320 | |
| 321 | // Execute this from another thread such that we can do other things (like caching the |
| 322 | // bitmap for the thumbnail) while AM is busy starting our activity. |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 323 | mBackgroundExecutor.submit(new Runnable() { |
| 324 | @Override |
| 325 | public void run() { |
Winson Chung | 42ce900 | 2017-11-17 13:04:07 -0800 | [diff] [blame] | 326 | boolean result = false; |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 327 | try { |
Winson Chung | 42ce900 | 2017-11-17 13:04:07 -0800 | [diff] [blame] | 328 | result = startActivityFromRecents(taskKey.id, finalOptions); |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 329 | } catch (Exception e) { |
Winson Chung | 42ce900 | 2017-11-17 13:04:07 -0800 | [diff] [blame] | 330 | // Fall through |
| 331 | } |
| 332 | final boolean finalResult = result; |
| 333 | if (resultCallback != null) { |
| 334 | resultCallbackHandler.post(new Runnable() { |
| 335 | @Override |
| 336 | public void run() { |
| 337 | resultCallback.accept(finalResult); |
| 338 | } |
| 339 | }); |
Winson Chung | b05b398 | 2017-11-01 18:02:43 -0700 | [diff] [blame] | 340 | } |
| 341 | } |
| 342 | }); |
| 343 | } |
| 344 | |
| 345 | /** |
Winson Chung | 42ce900 | 2017-11-17 13:04:07 -0800 | [diff] [blame] | 346 | * Starts a task from Recents synchronously. |
| 347 | */ |
| 348 | public boolean startActivityFromRecents(int taskId, ActivityOptions options) { |
| 349 | try { |
| 350 | Bundle optsBundle = options == null ? null : options.toBundle(); |
| 351 | ActivityManager.getService().startActivityFromRecents(taskId, optsBundle); |
| 352 | return true; |
| 353 | } catch (Exception e) { |
| 354 | return false; |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | /** |
Winson Chung | 2cf6ad8 | 2017-11-09 17:36:59 -0800 | [diff] [blame] | 359 | * Registers a task stack listener with the system. |
| 360 | * This should be called on the main thread. |
| 361 | */ |
| 362 | public void registerTaskStackListener(TaskStackChangeListener listener) { |
| 363 | synchronized (mTaskStackChangeListeners) { |
| 364 | mTaskStackChangeListeners.addListener(ActivityManager.getService(), listener); |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | /** |
| 369 | * Unregisters a task stack listener with the system. |
| 370 | * This should be called on the main thread. |
| 371 | */ |
| 372 | public void unregisterTaskStackListener(TaskStackChangeListener listener) { |
| 373 | synchronized (mTaskStackChangeListeners) { |
| 374 | mTaskStackChangeListeners.removeListener(listener); |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | /** |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 379 | * Requests that the system close any open system windows (including other SystemUI). |
| 380 | */ |
| 381 | public void closeSystemWindows(String reason) { |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 382 | mBackgroundExecutor.submit(new Runnable() { |
| 383 | @Override |
| 384 | public void run() { |
| 385 | try { |
| 386 | ActivityManager.getService().closeSystemDialogs(reason); |
| 387 | } catch (RemoteException e) { |
| 388 | Log.w(TAG, "Failed to close system windows", e); |
| 389 | } |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 390 | } |
| 391 | }); |
| 392 | } |
| 393 | |
| 394 | /** |
| 395 | * Removes a task by id. |
| 396 | */ |
| 397 | public void removeTask(int taskId) { |
Winson Chung | 1c5aeff | 2017-11-08 17:32:28 -0800 | [diff] [blame] | 398 | mBackgroundExecutor.submit(new Runnable() { |
| 399 | @Override |
| 400 | public void run() { |
| 401 | try { |
| 402 | ActivityManager.getService().removeTask(taskId); |
| 403 | } catch (RemoteException e) { |
| 404 | Log.w(TAG, "Failed to remove task=" + taskId, e); |
| 405 | } |
Winson Chung | aa35745 | 2017-10-31 11:35:30 -0700 | [diff] [blame] | 406 | } |
| 407 | }); |
| 408 | } |
| 409 | |
| 410 | /** |
| 411 | * Cancels the current window transtion to/from Recents for the given task id. |
| 412 | */ |
| 413 | public void cancelWindowTransition(int taskId) { |
| 414 | try { |
| 415 | ActivityManager.getService().cancelTaskWindowTransition(taskId); |
| 416 | } catch (RemoteException e) { |
| 417 | Log.w(TAG, "Failed to cancel window transition for task=" + taskId, e); |
| 418 | } |
| 419 | } |
Winson Chung | 6519c1b | 2017-10-13 17:12:56 -0700 | [diff] [blame] | 420 | } |