blob: ab86dbdbd106b715a2834489931b71b5817d8723 [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
17package com.android.server.am;
18
Winson Chung5d339f02017-10-23 11:10:58 -070019import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
Winson Chung1dbc8112017-09-28 18:05:31 -070020import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
21
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 {
37 private ActivityManagerService mService;
38
39 private int mTaskId;
40 private int mCallingUid;
41
42 public AppTaskImpl(ActivityManagerService service, int taskId, int callingUid) {
43 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
59 synchronized (mService) {
60 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
77 synchronized (mService) {
78 long origId = Binder.clearCallingIdentity();
79 try {
Winson Chung5d339f02017-10-23 11:10:58 -070080 TaskRecord tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId,
81 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.
96 final long origId = Binder.clearCallingIdentity();
97 try {
98 synchronized (this) {
Wale Ogunwaleab5de372017-10-18 06:46:31 -070099 mService.mStackSupervisor.startActivityFromRecents(mTaskId, null);
Winson Chung1dbc8112017-09-28 18:05:31 -0700100 }
101 } finally {
102 Binder.restoreCallingIdentity(origId);
103 }
104 }
105
106 @Override
107 public int startActivity(IBinder whoThread, String callingPackage,
108 Intent intent, String resolvedType, Bundle bOptions) {
109 checkCaller();
110
111 int callingUser = UserHandle.getCallingUserId();
112 TaskRecord tr;
113 IApplicationThread appThread;
114 synchronized (mService) {
Winson Chung5d339f02017-10-23 11:10:58 -0700115 tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId,
116 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
Winson Chung1dbc8112017-09-28 18:05:31 -0700117 if (tr == null) {
118 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
119 }
120 appThread = IApplicationThread.Stub.asInterface(whoThread);
121 if (appThread == null) {
122 throw new IllegalArgumentException("Bad app thread " + appThread);
123 }
124 }
125 return mService.mActivityStarter.startActivityMayWait(appThread, -1, callingPackage,
126 intent, resolvedType, null, null, null, null, 0, 0, null, null,
127 null, bOptions, false, callingUser, tr, "AppTaskImpl");
128 }
129
130 @Override
131 public void setExcludeFromRecents(boolean exclude) {
132 checkCaller();
133
134 synchronized (mService) {
135 long origId = Binder.clearCallingIdentity();
136 try {
Winson Chung5d339f02017-10-23 11:10:58 -0700137 TaskRecord tr = mService.mStackSupervisor.anyTaskForIdLocked(mTaskId,
138 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
Winson Chung1dbc8112017-09-28 18:05:31 -0700139 if (tr == null) {
140 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
141 }
142 Intent intent = tr.getBaseIntent();
143 if (exclude) {
144 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
145 } else {
146 intent.setFlags(intent.getFlags()
147 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
148 }
149 } finally {
150 Binder.restoreCallingIdentity(origId);
151 }
152 }
153 }
Wale Ogunwaleab5de372017-10-18 06:46:31 -0700154}