blob: 46dfc7c60fd9d3d46138bbdb630b4de0fd6ebf47 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
Dianne Hackborn95031ef2018-07-09 09:09:05 -070019import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070021import android.app.ContentProviderHolder;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070022import android.content.ComponentName;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070023import android.content.IContentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.pm.ApplicationInfo;
25import android.content.pm.ProviderInfo;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080026import android.os.IBinder;
27import android.os.IBinder.DeathRecipient;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Process;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080029import android.os.RemoteException;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070030import android.os.UserHandle;
Dianne Hackborn95031ef2018-07-09 09:09:05 -070031import android.util.ArrayMap;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080032import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Dianne Hackborn95031ef2018-07-09 09:09:05 -070034import com.android.internal.app.procstats.AssociationState;
35import com.android.internal.app.procstats.ProcessStats;
36
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import java.io.PrintWriter;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070038import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
Makoto Onuki0b575a32018-04-16 14:33:59 -070040final class ContentProviderRecord implements ComponentName.WithComponentName {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070041 final ActivityManagerService service;
42 public final ProviderInfo info;
43 final int uid;
44 final ApplicationInfo appInfo;
45 final ComponentName name;
Dianne Hackborn7d19e022012-08-07 19:12:33 -070046 final boolean singleton;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070047 public IContentProvider provider;
48 public boolean noReleaseNeeded;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 // All attached clients
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070050 final ArrayList<ContentProviderConnection> connections
51 = new ArrayList<ContentProviderConnection>();
52 //final HashSet<ProcessRecord> clients = new HashSet<ProcessRecord>();
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080053 // Handles for non-framework processes supported by this provider
Dianne Hackborn95031ef2018-07-09 09:09:05 -070054 ArrayMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080055 // Count for external process for which we have no handles.
56 int externalProcessNoHandleCount;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070057 ProcessRecord proc; // if non-null, hosting process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070059 String stringName;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070060 String shortStringName;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080061
62 public ContentProviderRecord(ActivityManagerService _service, ProviderInfo _info,
Dianne Hackborn7d19e022012-08-07 19:12:33 -070063 ApplicationInfo ai, ComponentName _name, boolean _singleton) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080064 service = _service;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070065 info = _info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 uid = ai.uid;
67 appInfo = ai;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070068 name = _name;
Dianne Hackborn7d19e022012-08-07 19:12:33 -070069 singleton = _singleton;
Jason Monk57d53712018-07-18 10:44:10 -040070 noReleaseNeeded = (uid == 0 || uid == Process.SYSTEM_UID)
71 && (_name == null || !"com.android.settings".equals(_name.getPackageName()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 }
73
74 public ContentProviderRecord(ContentProviderRecord cpr) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070075 service = cpr.service;
76 info = cpr.info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 uid = cpr.uid;
78 appInfo = cpr.appInfo;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070079 name = cpr.name;
Dianne Hackborn7d19e022012-08-07 19:12:33 -070080 singleton = cpr.singleton;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 noReleaseNeeded = cpr.noReleaseNeeded;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070082 }
83
84 public ContentProviderHolder newHolder(ContentProviderConnection conn) {
85 ContentProviderHolder holder = new ContentProviderHolder(info);
86 holder.provider = provider;
87 holder.noReleaseNeeded = noReleaseNeeded;
88 holder.connection = conn;
89 return holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 }
91
Dianne Hackborn2aec55a2018-06-26 10:35:35 -070092 public void setProcess(ProcessRecord proc) {
93 this.proc = proc;
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -070094 if (ActivityManagerService.TRACK_PROCSTATS_ASSOCIATIONS) {
95 for (int iconn = connections.size() - 1; iconn >= 0; iconn--) {
96 final ContentProviderConnection conn = connections.get(iconn);
Dianne Hackborn95031ef2018-07-09 09:09:05 -070097 if (proc != null) {
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -070098 conn.startAssociationIfNeeded();
Dianne Hackborn95031ef2018-07-09 09:09:05 -070099 } else {
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -0700100 conn.stopAssociation();
101 }
102 }
103 if (externalProcessTokenToHandle != null) {
104 for (int iext = externalProcessTokenToHandle.size() - 1; iext >= 0; iext--) {
105 final ExternalProcessHandle handle = externalProcessTokenToHandle.valueAt(iext);
106 if (proc != null) {
107 handle.startAssociationIfNeeded(this);
108 } else {
109 handle.stopAssociation();
110 }
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700111 }
112 }
113 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700114 }
115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 public boolean canRunHere(ProcessRecord app) {
117 return (info.multiprocess || info.processName.equals(app.processName))
Dianne Hackborn11941fd2012-09-07 15:35:17 -0700118 && uid == app.info.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 }
120
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700121 public void addExternalProcessHandleLocked(IBinder token, int callingUid, String callingTag) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800122 if (token == null) {
123 externalProcessNoHandleCount++;
124 } else {
125 if (externalProcessTokenToHandle == null) {
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700126 externalProcessTokenToHandle = new ArrayMap<>();
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800127 }
128 ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
129 if (handle == null) {
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700130 handle = new ExternalProcessHandle(token, callingUid, callingTag);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800131 externalProcessTokenToHandle.put(token, handle);
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700132 handle.startAssociationIfNeeded(this);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800133 }
134 handle.mAcquisitionCount++;
135 }
136 }
137
138 public boolean removeExternalProcessHandleLocked(IBinder token) {
139 if (hasExternalProcessHandles()) {
140 boolean hasHandle = false;
141 if (externalProcessTokenToHandle != null) {
142 ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
143 if (handle != null) {
144 hasHandle = true;
145 handle.mAcquisitionCount--;
146 if (handle.mAcquisitionCount == 0) {
147 removeExternalProcessHandleInternalLocked(token);
148 return true;
149 }
150 }
151 }
152 if (!hasHandle) {
153 externalProcessNoHandleCount--;
154 return true;
155 }
156 }
157 return false;
158 }
159
160 private void removeExternalProcessHandleInternalLocked(IBinder token) {
161 ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
162 handle.unlinkFromOwnDeathLocked();
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700163 handle.stopAssociation();
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800164 externalProcessTokenToHandle.remove(token);
165 if (externalProcessTokenToHandle.size() == 0) {
166 externalProcessTokenToHandle = null;
167 }
168 }
169
170 public boolean hasExternalProcessHandles() {
171 return (externalProcessTokenToHandle != null || externalProcessNoHandleCount > 0);
172 }
173
riddle_hsu691a1732015-05-13 18:59:03 +0800174 public boolean hasConnectionOrHandle() {
175 return !connections.isEmpty() || hasExternalProcessHandles();
176 }
177
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700178 void dump(PrintWriter pw, String prefix, boolean full) {
179 if (full) {
180 pw.print(prefix); pw.print("package=");
181 pw.print(info.applicationInfo.packageName);
182 pw.print(" process="); pw.println(info.processName);
183 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -0700184 pw.print(prefix); pw.print("proc="); pw.println(proc);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700185 if (launchingApp != null) {
186 pw.print(prefix); pw.print("launchingApp="); pw.println(launchingApp);
187 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700188 if (full) {
189 pw.print(prefix); pw.print("uid="); pw.print(uid);
190 pw.print(" provider="); pw.println(provider);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700191 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700192 if (singleton) {
193 pw.print(prefix); pw.print("singleton="); pw.println(singleton);
194 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700195 pw.print(prefix); pw.print("authority="); pw.println(info.authority);
196 if (full) {
197 if (info.isSyncable || info.multiprocess || info.initOrder != 0) {
198 pw.print(prefix); pw.print("isSyncable="); pw.print(info.isSyncable);
199 pw.print(" multiprocess="); pw.print(info.multiprocess);
200 pw.print(" initOrder="); pw.println(info.initOrder);
201 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -0800202 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700203 if (full) {
204 if (hasExternalProcessHandles()) {
Dianne Hackborn3133c402014-08-29 12:53:07 -0700205 pw.print(prefix); pw.print("externals:");
206 if (externalProcessTokenToHandle != null) {
207 pw.print(" w/token=");
208 pw.print(externalProcessTokenToHandle.size());
209 }
210 if (externalProcessNoHandleCount > 0) {
211 pw.print(" notoken=");
212 pw.print(externalProcessNoHandleCount);
213 }
214 pw.println();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700215 }
216 } else {
217 if (connections.size() > 0 || externalProcessNoHandleCount > 0) {
218 pw.print(prefix); pw.print(connections.size());
219 pw.print(" connections, "); pw.print(externalProcessNoHandleCount);
220 pw.println(" external handles");
221 }
222 }
223 if (connections.size() > 0) {
224 if (full) {
225 pw.print(prefix); pw.println("Connections:");
226 }
227 for (int i=0; i<connections.size(); i++) {
228 ContentProviderConnection conn = connections.get(i);
229 pw.print(prefix); pw.print(" -> "); pw.println(conn.toClientString());
230 if (conn.provider != this) {
231 pw.print(prefix); pw.print(" *** WRONG PROVIDER: ");
232 pw.println(conn.provider);
233 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -0800234 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 }
237
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800238 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700240 if (stringName != null) {
241 return stringName;
242 }
243 StringBuilder sb = new StringBuilder(128);
244 sb.append("ContentProviderRecord{");
245 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700246 sb.append(" u");
247 sb.append(UserHandle.getUserId(uid));
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700248 sb.append(' ');
Dianne Hackborn9da2d402012-03-15 13:43:08 -0700249 sb.append(name.flattenToShortString());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700250 sb.append('}');
251 return stringName = sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800253
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700254 public String toShortString() {
255 if (shortStringName != null) {
256 return shortStringName;
257 }
258 StringBuilder sb = new StringBuilder(128);
259 sb.append(Integer.toHexString(System.identityHashCode(this)));
260 sb.append('/');
261 sb.append(name.flattenToShortString());
262 return shortStringName = sb.toString();
263 }
264
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800265 // This class represents a handle from an external process to a provider.
266 private class ExternalProcessHandle implements DeathRecipient {
267 private static final String LOG_TAG = "ExternalProcessHanldle";
268
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700269 final IBinder mToken;
270 final int mOwningUid;
271 final String mOwningProcessName;
272 int mAcquisitionCount;
273 AssociationState.SourceState mAssociation;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800274
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700275 public ExternalProcessHandle(IBinder token, int owningUid, String owningProcessName) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800276 mToken = token;
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700277 mOwningUid = owningUid;
278 mOwningProcessName = owningProcessName;
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800279 try {
280 token.linkToDeath(this, 0);
281 } catch (RemoteException re) {
282 Slog.e(LOG_TAG, "Couldn't register for death for token: " + mToken, re);
283 }
284 }
285
286 public void unlinkFromOwnDeathLocked() {
287 mToken.unlinkToDeath(this, 0);
288 }
289
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700290 public void startAssociationIfNeeded(ContentProviderRecord provider) {
291 // If we don't already have an active association, create one... but only if this
292 // is an association between two different processes.
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -0700293 if (ActivityManagerService.TRACK_PROCSTATS_ASSOCIATIONS
294 && mAssociation == null && provider.proc != null
295 && (provider.appInfo.uid != mOwningUid
296 || !provider.info.processName.equals(mOwningProcessName))) {
297 ProcessStats.ProcessStateHolder holder = provider.proc.pkgList.get(
298 provider.name.getPackageName());
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700299 if (holder == null) {
300 Slog.wtf(TAG_AM, "No package in referenced provider "
301 + provider.name.toShortString() + ": proc=" + provider.proc);
302 } else if (holder.pkg == null) {
303 Slog.wtf(TAG_AM, "Inactive holder in referenced provider "
304 + provider.name.toShortString() + ": proc=" + provider.proc);
305 } else {
306 mAssociation = holder.pkg.getAssociationStateLocked(holder.state,
307 provider.name.getClassName()).startSource(mOwningUid,
Dianne Hackborn24bbe582018-12-17 11:58:31 -0800308 mOwningProcessName, null);
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700309
310 }
311 }
312 }
313
314 public void stopAssociation() {
315 if (mAssociation != null) {
316 mAssociation.stop();
317 mAssociation = null;
318 }
319 }
320
Svetoslav Ganov25872aa2012-02-03 19:19:09 -0800321 @Override
322 public void binderDied() {
323 synchronized (service) {
324 if (hasExternalProcessHandles() &&
325 externalProcessTokenToHandle.get(mToken) != null) {
326 removeExternalProcessHandleInternalLocked(mToken);
327 }
328 }
329 }
330 }
Makoto Onuki0b575a32018-04-16 14:33:59 -0700331
332 public ComponentName getComponentName() {
333 return name;
334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335}