blob: 8a905f8c045e141d76240acce57be1112e1b4c08 [file] [log] [blame]
Amith Yamasani742a6712011-05-04 14:49:28 -07001/*
2 * Copyright (C) 2011 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
19import android.content.ComponentName;
Amith Yamasani742a6712011-05-04 14:49:28 -070020import android.os.Binder;
Marco Nelissende7408c2012-02-08 14:57:38 -080021import android.os.RemoteException;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070022import android.os.UserHandle;
Amith Yamasani742a6712011-05-04 14:49:28 -070023import android.util.Slog;
24import android.util.SparseArray;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070025import com.android.internal.os.TransferPipe;
Amith Yamasani742a6712011-05-04 14:49:28 -070026
Marco Nelissende7408c2012-02-08 14:57:38 -080027import java.io.FileDescriptor;
28import java.io.IOException;
Amith Yamasani742a6712011-05-04 14:49:28 -070029import java.io.PrintWriter;
Marco Nelissende7408c2012-02-08 14:57:38 -080030import java.util.ArrayList;
Steven Timotiusfd55a942017-11-15 16:43:57 -080031import java.util.Arrays;
Amith Yamasani742a6712011-05-04 14:49:28 -070032import java.util.HashMap;
33import java.util.Iterator;
34import java.util.Map;
Wale Ogunwale540e1232015-05-01 15:35:39 -070035import java.util.Set;
Amith Yamasani742a6712011-05-04 14:49:28 -070036
37/**
38 * Keeps track of content providers by authority (name) and class. It separates the mapping by
39 * user and ones that are not user-specific (system providers).
40 */
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070041public final class ProviderMap {
Amith Yamasani742a6712011-05-04 14:49:28 -070042
43 private static final String TAG = "ProviderMap";
44
45 private static final boolean DBG = false;
46
Dianne Hackborn2d1b3782012-09-09 17:49:39 -070047 private final ActivityManagerService mAm;
48
Dianne Hackborn7d19e022012-08-07 19:12:33 -070049 private final HashMap<String, ContentProviderRecord> mSingletonByName
Amith Yamasani742a6712011-05-04 14:49:28 -070050 = new HashMap<String, ContentProviderRecord>();
Dianne Hackborn7d19e022012-08-07 19:12:33 -070051 private final HashMap<ComponentName, ContentProviderRecord> mSingletonByClass
Amith Yamasani742a6712011-05-04 14:49:28 -070052 = new HashMap<ComponentName, ContentProviderRecord>();
53
54 private final SparseArray<HashMap<String, ContentProviderRecord>> mProvidersByNamePerUser
55 = new SparseArray<HashMap<String, ContentProviderRecord>>();
56 private final SparseArray<HashMap<ComponentName, ContentProviderRecord>> mProvidersByClassPerUser
57 = new SparseArray<HashMap<ComponentName, ContentProviderRecord>>();
58
Dianne Hackborn2d1b3782012-09-09 17:49:39 -070059 ProviderMap(ActivityManagerService am) {
60 mAm = am;
61 }
62
Amith Yamasani742a6712011-05-04 14:49:28 -070063 ContentProviderRecord getProviderByName(String name) {
64 return getProviderByName(name, -1);
65 }
66
67 ContentProviderRecord getProviderByName(String name, int userId) {
68 if (DBG) {
69 Slog.i(TAG, "getProviderByName: " + name + " , callingUid = " + Binder.getCallingUid());
70 }
71 // Try to find it in the global list
Dianne Hackborn7d19e022012-08-07 19:12:33 -070072 ContentProviderRecord record = mSingletonByName.get(name);
Amith Yamasani742a6712011-05-04 14:49:28 -070073 if (record != null) {
74 return record;
75 }
76
77 // Check the current user's list
78 return getProvidersByName(userId).get(name);
79 }
80
81 ContentProviderRecord getProviderByClass(ComponentName name) {
82 return getProviderByClass(name, -1);
83 }
84
85 ContentProviderRecord getProviderByClass(ComponentName name, int userId) {
86 if (DBG) {
87 Slog.i(TAG, "getProviderByClass: " + name + ", callingUid = " + Binder.getCallingUid());
88 }
89 // Try to find it in the global list
Dianne Hackborn7d19e022012-08-07 19:12:33 -070090 ContentProviderRecord record = mSingletonByClass.get(name);
Amith Yamasani742a6712011-05-04 14:49:28 -070091 if (record != null) {
92 return record;
93 }
94
95 // Check the current user's list
96 return getProvidersByClass(userId).get(name);
97 }
98
99 void putProviderByName(String name, ContentProviderRecord record) {
100 if (DBG) {
101 Slog.i(TAG, "putProviderByName: " + name + " , callingUid = " + Binder.getCallingUid()
102 + ", record uid = " + record.appInfo.uid);
103 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700104 if (record.singleton) {
105 mSingletonByName.put(name, record);
Amith Yamasani742a6712011-05-04 14:49:28 -0700106 } else {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700107 final int userId = UserHandle.getUserId(record.appInfo.uid);
Amith Yamasani742a6712011-05-04 14:49:28 -0700108 getProvidersByName(userId).put(name, record);
109 }
110 }
111
112 void putProviderByClass(ComponentName name, ContentProviderRecord record) {
113 if (DBG) {
114 Slog.i(TAG, "putProviderByClass: " + name + " , callingUid = " + Binder.getCallingUid()
115 + ", record uid = " + record.appInfo.uid);
116 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700117 if (record.singleton) {
118 mSingletonByClass.put(name, record);
Amith Yamasani742a6712011-05-04 14:49:28 -0700119 } else {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700120 final int userId = UserHandle.getUserId(record.appInfo.uid);
Amith Yamasani742a6712011-05-04 14:49:28 -0700121 getProvidersByClass(userId).put(name, record);
122 }
123 }
124
Dianne Hackborn41203752012-08-31 14:05:51 -0700125 void removeProviderByName(String name, int userId) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700126 if (mSingletonByName.containsKey(name)) {
Amith Yamasani742a6712011-05-04 14:49:28 -0700127 if (DBG)
128 Slog.i(TAG, "Removing from globalByName name=" + name);
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700129 mSingletonByName.remove(name);
Amith Yamasani742a6712011-05-04 14:49:28 -0700130 } else {
Dianne Hackborn41203752012-08-31 14:05:51 -0700131 if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
Amith Yamasani742a6712011-05-04 14:49:28 -0700132 if (DBG)
133 Slog.i(TAG,
Dianne Hackborn41203752012-08-31 14:05:51 -0700134 "Removing from providersByName name=" + name + " user=" + userId);
135 HashMap<String, ContentProviderRecord> map = getProvidersByName(userId);
Vairavan Srinivasan88090042012-08-15 23:37:45 -0700136 // map returned by getProvidersByName wouldn't be null
137 map.remove(name);
138 if (map.size() == 0) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700139 mProvidersByNamePerUser.remove(userId);
Vairavan Srinivasan88090042012-08-15 23:37:45 -0700140 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700141 }
142 }
143
Dianne Hackborn41203752012-08-31 14:05:51 -0700144 void removeProviderByClass(ComponentName name, int userId) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700145 if (mSingletonByClass.containsKey(name)) {
Amith Yamasani742a6712011-05-04 14:49:28 -0700146 if (DBG)
147 Slog.i(TAG, "Removing from globalByClass name=" + name);
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700148 mSingletonByClass.remove(name);
Amith Yamasani742a6712011-05-04 14:49:28 -0700149 } else {
Dianne Hackborn41203752012-08-31 14:05:51 -0700150 if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
Amith Yamasani742a6712011-05-04 14:49:28 -0700151 if (DBG)
152 Slog.i(TAG,
Dianne Hackborn41203752012-08-31 14:05:51 -0700153 "Removing from providersByClass name=" + name + " user=" + userId);
154 HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(userId);
Vairavan Srinivasan88090042012-08-15 23:37:45 -0700155 // map returned by getProvidersByClass wouldn't be null
156 map.remove(name);
157 if (map.size() == 0) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700158 mProvidersByClassPerUser.remove(userId);
Vairavan Srinivasan88090042012-08-15 23:37:45 -0700159 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700160 }
161 }
162
Dianne Hackborn41203752012-08-31 14:05:51 -0700163 private HashMap<String, ContentProviderRecord> getProvidersByName(int userId) {
164 if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
Amith Yamasani742a6712011-05-04 14:49:28 -0700165 final HashMap<String, ContentProviderRecord> map = mProvidersByNamePerUser.get(userId);
166 if (map == null) {
167 HashMap<String, ContentProviderRecord> newMap = new HashMap<String, ContentProviderRecord>();
168 mProvidersByNamePerUser.put(userId, newMap);
169 return newMap;
170 } else {
171 return map;
172 }
173 }
174
Dianne Hackborn41203752012-08-31 14:05:51 -0700175 HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int userId) {
176 if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
177 final HashMap<ComponentName, ContentProviderRecord> map
178 = mProvidersByClassPerUser.get(userId);
Amith Yamasani742a6712011-05-04 14:49:28 -0700179 if (map == null) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700180 HashMap<ComponentName, ContentProviderRecord> newMap
181 = new HashMap<ComponentName, ContentProviderRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -0700182 mProvidersByClassPerUser.put(userId, newMap);
183 return newMap;
184 } else {
185 return map;
186 }
187 }
188
Wale Ogunwale540e1232015-05-01 15:35:39 -0700189 private boolean collectPackageProvidersLocked(String packageName,
190 Set<String> filterByClasses, boolean doit, boolean evenPersistent,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700191 HashMap<ComponentName, ContentProviderRecord> providers,
192 ArrayList<ContentProviderRecord> result) {
193 boolean didSomething = false;
194 for (ContentProviderRecord provider : providers.values()) {
Wale Ogunwale540e1232015-05-01 15:35:39 -0700195 final boolean sameComponent = packageName == null
196 || (provider.info.packageName.equals(packageName)
197 && (filterByClasses == null
198 || filterByClasses.contains(provider.name.getClassName())));
199 if (sameComponent
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700200 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
201 if (!doit) {
202 return true;
203 }
204 didSomething = true;
205 result.add(provider);
206 }
207 }
208 return didSomething;
209 }
210
Wale Ogunwale540e1232015-05-01 15:35:39 -0700211 boolean collectPackageProvidersLocked(String packageName, Set<String> filterByClasses,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700212 boolean doit, boolean evenPersistent, int userId,
213 ArrayList<ContentProviderRecord> result) {
riddle_hsu5ff8ba72015-05-15 11:33:03 +0800214 boolean didSomething = false;
Xiaohui Chen7c696362015-09-16 09:56:14 -0700215 if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_SYSTEM) {
riddle_hsu5ff8ba72015-05-15 11:33:03 +0800216 didSomething = collectPackageProvidersLocked(packageName, filterByClasses,
217 doit, evenPersistent, mSingletonByClass, result);
218 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700219 if (!doit && didSomething) {
220 return true;
221 }
222 if (userId == UserHandle.USER_ALL) {
Wale Ogunwale540e1232015-05-01 15:35:39 -0700223 for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
224 if (collectPackageProvidersLocked(packageName, filterByClasses,
225 doit, evenPersistent, mProvidersByClassPerUser.valueAt(i), result)) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700226 if (!doit) {
227 return true;
228 }
229 didSomething = true;
230 }
231 }
232 } else {
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700233 HashMap<ComponentName, ContentProviderRecord> items
234 = getProvidersByClass(userId);
235 if (items != null) {
Wale Ogunwale540e1232015-05-01 15:35:39 -0700236 didSomething |= collectPackageProvidersLocked(packageName, filterByClasses,
237 doit, evenPersistent, items, result);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700238 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700239 }
240 return didSomething;
241 }
242
Dianne Hackborn390517b2013-05-30 15:03:32 -0700243 private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage,
244 String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) {
Amith Yamasani742a6712011-05-04 14:49:28 -0700245 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
Dianne Hackborn390517b2013-05-30 15:03:32 -0700246 boolean written = false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700247 while (it.hasNext()) {
248 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
249 ContentProviderRecord r = e.getValue();
Dianne Hackborn390517b2013-05-30 15:03:32 -0700250 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
251 continue;
252 }
253 if (needSep) {
254 pw.println("");
255 needSep = false;
256 }
257 if (header != null) {
258 pw.println(header);
259 header = null;
260 }
261 written = true;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700262 pw.print(" * ");
263 pw.println(r);
264 r.dump(pw, " ", dumpAll);
Amith Yamasani742a6712011-05-04 14:49:28 -0700265 }
Dianne Hackborn390517b2013-05-30 15:03:32 -0700266 return written;
Amith Yamasani742a6712011-05-04 14:49:28 -0700267 }
268
Dianne Hackborn390517b2013-05-30 15:03:32 -0700269 private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage,
270 String header, boolean needSep, HashMap<String, ContentProviderRecord> map) {
Amith Yamasani742a6712011-05-04 14:49:28 -0700271 Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator();
Dianne Hackborn390517b2013-05-30 15:03:32 -0700272 boolean written = false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700273 while (it.hasNext()) {
274 Map.Entry<String, ContentProviderRecord> e = it.next();
275 ContentProviderRecord r = e.getValue();
Dianne Hackborn390517b2013-05-30 15:03:32 -0700276 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
277 continue;
278 }
279 if (needSep) {
280 pw.println("");
281 needSep = false;
282 }
283 if (header != null) {
284 pw.println(header);
285 header = null;
286 }
287 written = true;
Amith Yamasani742a6712011-05-04 14:49:28 -0700288 pw.print(" ");
289 pw.print(e.getKey());
290 pw.print(": ");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700291 pw.println(r.toShortString());
Amith Yamasani742a6712011-05-04 14:49:28 -0700292 }
Dianne Hackborn390517b2013-05-30 15:03:32 -0700293 return written;
Amith Yamasani742a6712011-05-04 14:49:28 -0700294 }
295
Dianne Hackborn390517b2013-05-30 15:03:32 -0700296 boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) {
297 boolean needSep = false;
298
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700299 if (mSingletonByClass.size() > 0) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -0700300 needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
Dianne Hackborn390517b2013-05-30 15:03:32 -0700301 " Published single-user content providers (by class):", needSep,
302 mSingletonByClass);
Amith Yamasani742a6712011-05-04 14:49:28 -0700303 }
304
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700305 for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
306 HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
Dianne Hackborn390517b2013-05-30 15:03:32 -0700307 needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
308 " Published user " + mProvidersByClassPerUser.keyAt(i)
309 + " content providers (by class):", needSep, map);
Amith Yamasani742a6712011-05-04 14:49:28 -0700310 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700311
312 if (dumpAll) {
Dianne Hackborn390517b2013-05-30 15:03:32 -0700313 needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
314 " Single-user authority to provider mappings:", needSep, mSingletonByName);
Amith Yamasani742a6712011-05-04 14:49:28 -0700315
316 for (int i = 0; i < mProvidersByNamePerUser.size(); i++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -0700317 needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
318 " User " + mProvidersByNamePerUser.keyAt(i)
319 + " authority to provider mappings:", needSep,
320 mProvidersByNamePerUser.valueAt(i));
Amith Yamasani742a6712011-05-04 14:49:28 -0700321 }
322 }
Dianne Hackborn390517b2013-05-30 15:03:32 -0700323 return needSep;
Amith Yamasani742a6712011-05-04 14:49:28 -0700324 }
Marco Nelissende7408c2012-02-08 14:57:38 -0800325
Steven Timotiusfd55a942017-11-15 16:43:57 -0800326 private ArrayList<ContentProviderRecord> getProvidersForName(String name) {
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700327 ArrayList<ContentProviderRecord> allProviders = new ArrayList<ContentProviderRecord>();
Marco Nelissende7408c2012-02-08 14:57:38 -0800328 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
329
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700330 synchronized (mAm) {
331 allProviders.addAll(mSingletonByClass.values());
332 for (int i=0; i<mProvidersByClassPerUser.size(); i++) {
333 allProviders.addAll(mProvidersByClassPerUser.valueAt(i).values());
Marco Nelissende7408c2012-02-08 14:57:38 -0800334 }
335
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700336 if ("all".equals(name)) {
337 providers.addAll(allProviders);
338 } else {
339 ComponentName componentName = name != null
340 ? ComponentName.unflattenFromString(name) : null;
341 int objectId = 0;
342 if (componentName == null) {
343 // Not a '/' separated full component name; maybe an object ID?
344 try {
345 objectId = Integer.parseInt(name, 16);
346 name = null;
347 componentName = null;
348 } catch (RuntimeException e) {
349 }
350 }
351
352 for (int i=0; i<allProviders.size(); i++) {
353 ContentProviderRecord r1 = allProviders.get(i);
Marco Nelissende7408c2012-02-08 14:57:38 -0800354 if (componentName != null) {
355 if (r1.name.equals(componentName)) {
356 providers.add(r1);
357 }
358 } else if (name != null) {
359 if (r1.name.flattenToString().contains(name)) {
360 providers.add(r1);
361 }
362 } else if (System.identityHashCode(r1) == objectId) {
363 providers.add(r1);
364 }
365 }
366 }
367 }
Steven Timotiusfd55a942017-11-15 16:43:57 -0800368 return providers;
369 }
370
371 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
372 int opti, boolean dumpAll) {
373 ArrayList<ContentProviderRecord> providers = getProvidersForName(name);
Marco Nelissende7408c2012-02-08 14:57:38 -0800374
375 if (providers.size() <= 0) {
376 return false;
377 }
378
379 boolean needSep = false;
380 for (int i=0; i<providers.size(); i++) {
381 if (needSep) {
382 pw.println();
383 }
384 needSep = true;
385 dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
386 }
387 return true;
388 }
389
390 /**
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700391 * Before invoking IApplicationThread.dumpProvider(), print meta information to the print
392 * writer and handle passed flags.
Marco Nelissende7408c2012-02-08 14:57:38 -0800393 */
394 private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
395 final ContentProviderRecord r, String[] args, boolean dumpAll) {
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700396 for (String s: args) {
397 if (!dumpAll && s.contains("--proto")) {
398 if (r.proc != null && r.proc.thread != null) {
399 dumpToTransferPipe(null , fd, pw, r, args);
400 }
401 return;
402 }
403 }
Marco Nelissende7408c2012-02-08 14:57:38 -0800404 String innerPrefix = prefix + " ";
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700405 synchronized (mAm) {
Marco Nelissende7408c2012-02-08 14:57:38 -0800406 pw.print(prefix); pw.print("PROVIDER ");
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700407 pw.print(r);
408 pw.print(" pid=");
409 if (r.proc != null) {
410 pw.println(r.proc.pid);
411 } else {
412 pw.println("(not running)");
413 }
Marco Nelissende7408c2012-02-08 14:57:38 -0800414 if (dumpAll) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700415 r.dump(pw, innerPrefix, true);
Marco Nelissende7408c2012-02-08 14:57:38 -0800416 }
417 }
418 if (r.proc != null && r.proc.thread != null) {
419 pw.println(" Client:");
420 pw.flush();
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700421 dumpToTransferPipe(" ", fd, pw, r, args);
422 }
423 }
424
425 /**
Steven Timotiusfd55a942017-11-15 16:43:57 -0800426 * Similar to the dumpProvider, but only dumps the first matching provider.
427 * The provider is responsible for dumping as proto.
428 */
429 protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
430 String[] args) {
431 //add back the --proto arg, which was stripped out by PriorityDump
432 String[] newArgs = Arrays.copyOf(args, args.length + 1);
433 newArgs[args.length] = "--proto";
434
435 ArrayList<ContentProviderRecord> providers = getProvidersForName(name);
436
437 if (providers.size() <= 0) {
438 return false;
439 }
440
441 // Only dump the first provider, since we are dumping in proto format
442 for (int i = 0; i < providers.size(); i++) {
443 final ContentProviderRecord r = providers.get(i);
444 if (r.proc != null && r.proc.thread != null) {
445 dumpToTransferPipe(null, fd, pw, r, newArgs);
446 return true;
447 }
448 }
449 return false;
450 }
451
452 /**
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700453 * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider without
454 * any meta string (e.g., provider info, indentation) written to the file descriptor.
455 */
456 private void dumpToTransferPipe(String prefix, FileDescriptor fd, PrintWriter pw,
457 final ContentProviderRecord r, String[] args) {
458 try {
459 TransferPipe tp = new TransferPipe();
Marco Nelissende7408c2012-02-08 14:57:38 -0800460 try {
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700461 r.proc.thread.dumpProvider(
462 tp.getWriteFd(), r.provider.asBinder(), args);
463 tp.setBufferPrefix(prefix);
464 // Short timeout, since blocking here can
465 // deadlock with the application.
466 tp.go(fd, 2000);
467 } finally {
468 tp.kill();
Marco Nelissende7408c2012-02-08 14:57:38 -0800469 }
Hyunyoung Song9d56bc12017-05-24 16:48:41 -0700470 } catch (IOException ex) {
471 pw.println(" Failure while dumping the provider: " + ex);
472 } catch (RemoteException ex) {
473 pw.println(" Got a RemoteException while dumping the service");
Marco Nelissende7408c2012-02-08 14:57:38 -0800474 }
475 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700476}