blob: 441c5935a5079297b1c3d04f6766a7092f5ffc68 [file] [log] [blame]
Winson Chung1dbc8112017-09-28 18:05:31 -07001/*
2 * Copyright (C) 2017 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Winson Chung1dbc8112017-09-28 18:05:31 -070018
Wale Ogunwale59507092018-10-29 09:00:30 -070019import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Wale Ogunwaled32da472018-11-16 07:19:28 -080020import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
Winson Chung1dbc8112017-09-28 18:05:31 -070021
22import android.app.ActivityManager;
23import android.app.IAppTask;
24import android.app.IApplicationThread;
25import android.content.Intent;
26import android.os.Binder;
27import android.os.Bundle;
28import android.os.IBinder;
29import android.os.UserHandle;
30
31/**
32 * An implementation of IAppTask, that allows an app to manage its own tasks via
33 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
34 * only the process that calls getAppTasks() can call the AppTask methods.
35 */
36class AppTaskImpl extends IAppTask.Stub {
Wale Ogunwale16e505a2018-05-07 15:00:49 -070037 private ActivityTaskManagerService mService;
Winson Chung1dbc8112017-09-28 18:05:31 -070038
39 private int mTaskId;
40 private int mCallingUid;
41
Wale Ogunwale16e505a2018-05-07 15:00:49 -070042 public AppTaskImpl(ActivityTaskManagerService service, int taskId, int callingUid) {
Winson Chung1dbc8112017-09-28 18:05:31 -070043 mService = service;
44 mTaskId = taskId;
45 mCallingUid = callingUid;
46 }
47
48 private void checkCaller() {
49 if (mCallingUid != Binder.getCallingUid()) {
50 throw new SecurityException("Caller " + mCallingUid
51 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
52 }
53 }
54
55 @Override
56 public void finishAndRemoveTask() {
57 checkCaller();
58
Wale Ogunwale16e505a2018-05-07 15:00:49 -070059 synchronized (mService.mGlobalLock) {
Winson Chung1dbc8112017-09-28 18:05:31 -070060 long origId = Binder.clearCallingIdentity();
61 try {
62 // We remove the task from recents to preserve backwards
63 if (!mService.mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
Winson Chung0ec2a352017-10-26 11:38:30 -070064 REMOVE_FROM_RECENTS, "finish-and-remove-task")) {
Winson Chung1dbc8112017-09-28 18:05:31 -070065 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
66 }
67 } finally {
68 Binder.restoreCallingIdentity(origId);
69 }
70 }
71 }
72
73 @Override
74 public ActivityManager.RecentTaskInfo getTaskInfo() {
75 checkCaller();
76
Wale Ogunwale16e505a2018-05-07 15:00:49 -070077 synchronized (mService.mGlobalLock) {
Winson Chung1dbc8112017-09-28 18:05:31 -070078 long origId = Binder.clearCallingIdentity();
79 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -080080 TaskRecord tr = mService.mRootActivityContainer.anyTaskForId(mTaskId,
Winson Chung5d339f02017-10-23 11:10:58 -070081 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
Winson Chung1dbc8112017-09-28 18:05:31 -070082 if (tr == null) {
83 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
84 }
Winson Chung3f0e59a2017-10-25 10:19:05 -070085 return mService.getRecentTasks().createRecentTaskInfo(tr);
Winson Chung1dbc8112017-09-28 18:05:31 -070086 } finally {
87 Binder.restoreCallingIdentity(origId);
88 }
89 }
90 }
91
92 @Override
93 public void moveToFront() {
94 checkCaller();
95 // Will bring task to front if it already has a root activity.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010096 final int callingPid = Binder.getCallingPid();
97 final int callingUid = Binder.getCallingUid();
Winson Chung1dbc8112017-09-28 18:05:31 -070098 final long origId = Binder.clearCallingIdentity();
99 try {
Wale Ogunwale9c189e12018-07-11 15:22:01 -0700100 synchronized (mService.mGlobalLock) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100101 mService.mStackSupervisor.startActivityFromRecents(callingPid, callingUid, mTaskId,
102 null);
Winson Chung1dbc8112017-09-28 18:05:31 -0700103 }
104 } finally {
105 Binder.restoreCallingIdentity(origId);
106 }
107 }
108
109 @Override
110 public int startActivity(IBinder whoThread, String callingPackage,
111 Intent intent, String resolvedType, Bundle bOptions) {
112 checkCaller();
113
114 int callingUser = UserHandle.getCallingUserId();
115 TaskRecord tr;
116 IApplicationThread appThread;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700117 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800118 tr = mService.mRootActivityContainer.anyTaskForId(mTaskId,
Winson Chung5d339f02017-10-23 11:10:58 -0700119 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
Winson Chung1dbc8112017-09-28 18:05:31 -0700120 if (tr == null) {
121 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
122 }
123 appThread = IApplicationThread.Stub.asInterface(whoThread);
124 if (appThread == null) {
125 throw new IllegalArgumentException("Bad app thread " + appThread);
126 }
127 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800128
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700129 return mService.getActivityStartController().obtainStarter(intent, "AppTaskImpl")
Bryce Lee4c9a5972017-12-01 22:14:24 -0800130 .setCaller(appThread)
131 .setCallingPackage(callingPackage)
132 .setResolvedType(resolvedType)
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100133 .setActivityOptions(bOptions)
134 .setMayWait(callingUser)
Bryce Lee4c9a5972017-12-01 22:14:24 -0800135 .setInTask(tr)
136 .execute();
Winson Chung1dbc8112017-09-28 18:05:31 -0700137 }
138
139 @Override
140 public void setExcludeFromRecents(boolean exclude) {
141 checkCaller();
142
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700143 synchronized (mService.mGlobalLock) {
Winson Chung1dbc8112017-09-28 18:05:31 -0700144 long origId = Binder.clearCallingIdentity();
145 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800146 TaskRecord tr = mService.mRootActivityContainer.anyTaskForId(mTaskId,
Winson Chung5d339f02017-10-23 11:10:58 -0700147 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
Winson Chung1dbc8112017-09-28 18:05:31 -0700148 if (tr == null) {
149 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
150 }
151 Intent intent = tr.getBaseIntent();
152 if (exclude) {
153 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
154 } else {
155 intent.setFlags(intent.getFlags()
156 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
157 }
158 } finally {
159 Binder.restoreCallingIdentity(origId);
160 }
161 }
162 }
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700163}