ProviderMap.java revision 5ff8ba7ace9b748892a2406995fe3eca87f682d4
1742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani/*
2742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Copyright (C) 2011 The Android Open Source Project
3742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
4742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * you may not use this file except in compliance with the License.
6742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * You may obtain a copy of the License at
7742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
8742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani *
10742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Unless required by applicable law or agreed to in writing, software
11742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * See the License for the specific language governing permissions and
14742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * limitations under the License.
15742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */
16742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
17742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasanipackage com.android.server.am;
18742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
19742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.content.ComponentName;
20742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.os.Binder;
21de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissenimport android.os.RemoteException;
22f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
23742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.util.Slog;
24742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.util.SparseArray;
25cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackbornimport com.android.internal.os.TransferPipe;
26742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
27de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissenimport java.io.FileDescriptor;
28de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissenimport java.io.IOException;
29742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.io.PrintWriter;
30de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissenimport java.util.ArrayList;
31742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.HashMap;
32742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.Iterator;
33742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.Map;
34540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwaleimport java.util.Set;
35742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
36742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani/**
37742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Keeps track of content providers by authority (name) and class. It separates the mapping by
38742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * user and ones that are not user-specific (system providers).
39742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */
40be4e6aaa0252dd7da28b7aa85beba982538efa46Dianne Hackbornpublic final class ProviderMap {
41742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
42742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    private static final String TAG = "ProviderMap";
43742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
44742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    private static final boolean DBG = false;
45742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
462d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn    private final ActivityManagerService mAm;
472d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn
487d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    private final HashMap<String, ContentProviderRecord> mSingletonByName
49742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            = new HashMap<String, ContentProviderRecord>();
507d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    private final HashMap<ComponentName, ContentProviderRecord> mSingletonByClass
51742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            = new HashMap<ComponentName, ContentProviderRecord>();
52742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
53742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    private final SparseArray<HashMap<String, ContentProviderRecord>> mProvidersByNamePerUser
54742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            = new SparseArray<HashMap<String, ContentProviderRecord>>();
55742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    private final SparseArray<HashMap<ComponentName, ContentProviderRecord>> mProvidersByClassPerUser
56742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            = new SparseArray<HashMap<ComponentName, ContentProviderRecord>>();
57742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
582d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn    ProviderMap(ActivityManagerService am) {
592d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn        mAm = am;
602d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn    }
612d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn
62742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    ContentProviderRecord getProviderByName(String name) {
63742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getProviderByName(name, -1);
64742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
65742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
66742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    ContentProviderRecord getProviderByName(String name, int userId) {
67742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (DBG) {
68742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Slog.i(TAG, "getProviderByName: " + name + " , callingUid = " + Binder.getCallingUid());
69742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
70742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        // Try to find it in the global list
717d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        ContentProviderRecord record = mSingletonByName.get(name);
72742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (record != null) {
73742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return record;
74742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
75742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
76742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        // Check the current user's list
77742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getProvidersByName(userId).get(name);
78742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
79742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
80742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    ContentProviderRecord getProviderByClass(ComponentName name) {
81742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getProviderByClass(name, -1);
82742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
83742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
84742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    ContentProviderRecord getProviderByClass(ComponentName name, int userId) {
85742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (DBG) {
86742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Slog.i(TAG, "getProviderByClass: " + name + ", callingUid = " + Binder.getCallingUid());
87742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
88742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        // Try to find it in the global list
897d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        ContentProviderRecord record = mSingletonByClass.get(name);
90742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (record != null) {
91742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return record;
92742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
93742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
94742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        // Check the current user's list
95742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        return getProvidersByClass(userId).get(name);
96742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
97742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
98742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    void putProviderByName(String name, ContentProviderRecord record) {
99742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (DBG) {
100742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Slog.i(TAG, "putProviderByName: " + name + " , callingUid = " + Binder.getCallingUid()
101742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                + ", record uid = " + record.appInfo.uid);
102742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
1037d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        if (record.singleton) {
1047d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            mSingletonByName.put(name, record);
105742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
106f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            final int userId = UserHandle.getUserId(record.appInfo.uid);
107742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            getProvidersByName(userId).put(name, record);
108742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
109742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
110742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
111742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    void putProviderByClass(ComponentName name, ContentProviderRecord record) {
112742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (DBG) {
113742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Slog.i(TAG, "putProviderByClass: " + name + " , callingUid = " + Binder.getCallingUid()
114742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                + ", record uid = " + record.appInfo.uid);
115742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
1167d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        if (record.singleton) {
1177d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            mSingletonByClass.put(name, record);
118742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
119f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            final int userId = UserHandle.getUserId(record.appInfo.uid);
120742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            getProvidersByClass(userId).put(name, record);
121742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
122742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
123742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
1244120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn    void removeProviderByName(String name, int userId) {
1257d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        if (mSingletonByName.containsKey(name)) {
126742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (DBG)
127742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                Slog.i(TAG, "Removing from globalByName name=" + name);
1287d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            mSingletonByName.remove(name);
129742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
1304120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn            if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
131742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (DBG)
132742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                Slog.i(TAG,
1334120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                        "Removing from providersByName name=" + name + " user=" + userId);
1344120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn            HashMap<String, ContentProviderRecord> map = getProvidersByName(userId);
1358809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            // map returned by getProvidersByName wouldn't be null
1368809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            map.remove(name);
1378809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            if (map.size() == 0) {
1384120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                mProvidersByNamePerUser.remove(userId);
1398809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            }
140742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
141742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
142742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
1434120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn    void removeProviderByClass(ComponentName name, int userId) {
1447d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        if (mSingletonByClass.containsKey(name)) {
145742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (DBG)
146742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                Slog.i(TAG, "Removing from globalByClass name=" + name);
1477d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            mSingletonByClass.remove(name);
148742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
1494120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn            if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
150742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (DBG)
151742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                Slog.i(TAG,
1524120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                        "Removing from providersByClass name=" + name + " user=" + userId);
1534120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn            HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(userId);
1548809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            // map returned by getProvidersByClass wouldn't be null
1558809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            map.remove(name);
1568809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            if (map.size() == 0) {
1574120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                mProvidersByClassPerUser.remove(userId);
1588809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan            }
159742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
160742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
161742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
1624120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn    private HashMap<String, ContentProviderRecord> getProvidersByName(int userId) {
1634120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn        if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
164742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        final HashMap<String, ContentProviderRecord> map = mProvidersByNamePerUser.get(userId);
165742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (map == null) {
166742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            HashMap<String, ContentProviderRecord> newMap = new HashMap<String, ContentProviderRecord>();
167742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mProvidersByNamePerUser.put(userId, newMap);
168742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return newMap;
169742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
170742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return map;
171742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
172742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
173742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
1744120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn    HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int userId) {
1754120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn        if (userId < 0) throw new IllegalArgumentException("Bad user " + userId);
1764120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn        final HashMap<ComponentName, ContentProviderRecord> map
1774120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                = mProvidersByClassPerUser.get(userId);
178742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (map == null) {
1794120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn            HashMap<ComponentName, ContentProviderRecord> newMap
1804120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn                    = new HashMap<ComponentName, ContentProviderRecord>();
181742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mProvidersByClassPerUser.put(userId, newMap);
182742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return newMap;
183742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        } else {
184742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            return map;
185742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
186742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
187742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
188540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale    private boolean collectPackageProvidersLocked(String packageName,
189540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale            Set<String> filterByClasses, boolean doit, boolean evenPersistent,
1905e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            HashMap<ComponentName, ContentProviderRecord> providers,
1915e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            ArrayList<ContentProviderRecord> result) {
1925e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        boolean didSomething = false;
1935e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        for (ContentProviderRecord provider : providers.values()) {
194540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale            final boolean sameComponent = packageName == null
195540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                    || (provider.info.packageName.equals(packageName)
196540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                        && (filterByClasses == null
197540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                            || filterByClasses.contains(provider.name.getClassName())));
198540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale            if (sameComponent
1995e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
2005e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                if (!doit) {
2015e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                    return true;
2025e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                }
2035e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                didSomething = true;
2045e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                result.add(provider);
2055e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            }
2065e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        }
2075e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        return didSomething;
2085e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn    }
2095e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn
210540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale    boolean collectPackageProvidersLocked(String packageName, Set<String> filterByClasses,
2115e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            boolean doit, boolean evenPersistent, int userId,
2125e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            ArrayList<ContentProviderRecord> result) {
2135ff8ba7ace9b748892a2406995fe3eca87f682d4riddle_hsu        boolean didSomething = false;
2145ff8ba7ace9b748892a2406995fe3eca87f682d4riddle_hsu        if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_OWNER) {
2155ff8ba7ace9b748892a2406995fe3eca87f682d4riddle_hsu            didSomething = collectPackageProvidersLocked(packageName, filterByClasses,
2165ff8ba7ace9b748892a2406995fe3eca87f682d4riddle_hsu                    doit, evenPersistent, mSingletonByClass, result);
2175ff8ba7ace9b748892a2406995fe3eca87f682d4riddle_hsu        }
2185e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        if (!doit && didSomething) {
2195e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            return true;
2205e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        }
2215e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        if (userId == UserHandle.USER_ALL) {
222540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale            for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
223540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                if (collectPackageProvidersLocked(packageName, filterByClasses,
224540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                        doit, evenPersistent, mProvidersByClassPerUser.valueAt(i), result)) {
2255e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                    if (!doit) {
2265e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                        return true;
2275e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                    }
2285e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                    didSomething = true;
2295e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn                }
2305e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn            }
2315e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        } else {
2322d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            HashMap<ComponentName, ContentProviderRecord> items
2332d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    = getProvidersByClass(userId);
2342d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            if (items != null) {
235540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                didSomething |= collectPackageProvidersLocked(packageName, filterByClasses,
236540e123b14ef71f0bfda325e11773c1c510fb8baWale Ogunwale                        doit, evenPersistent, items, result);
2372d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            }
2385e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        }
2395e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn        return didSomething;
2405e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn    }
2415e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn
242390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn    private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage,
243390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) {
244742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
245390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        boolean written = false;
246742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        while (it.hasNext()) {
247742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
248742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            ContentProviderRecord r = e.getValue();
249390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
250390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                continue;
251390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
252390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (needSep) {
253390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                pw.println("");
254390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                needSep = false;
255390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
256390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (header != null) {
257390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                pw.println(header);
258390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                header = null;
259390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
260390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            written = true;
2616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            pw.print("  * ");
2626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            pw.println(r);
2636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            r.dump(pw, "    ", dumpAll);
264742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
265390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        return written;
266742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
267742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
268390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn    private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage,
269390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            String header, boolean needSep, HashMap<String, ContentProviderRecord> map) {
270742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator();
271390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        boolean written = false;
272742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        while (it.hasNext()) {
273742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            Map.Entry<String, ContentProviderRecord> e = it.next();
274742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            ContentProviderRecord r = e.getValue();
275390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
276390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                continue;
277390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
278390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (needSep) {
279390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                pw.println("");
280390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                needSep = false;
281390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
282390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            if (header != null) {
283390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                pw.println(header);
284390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                header = null;
285390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            }
286390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            written = true;
287742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            pw.print("  ");
288742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            pw.print(e.getKey());
289742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            pw.print(": ");
2906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            pw.println(r.toShortString());
291742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
292390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        return written;
293742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
294742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
295390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn    boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) {
296390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        boolean needSep = false;
297390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn
2987d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        if (mSingletonByClass.size() > 0) {
2997ad34e5fb2bc8eda0a64377cedf8a8e899644dd9Dianne Hackborn            needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
300390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                    "  Published single-user content providers (by class):", needSep,
301390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                    mSingletonByClass);
302742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
303742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
3047d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
3057d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
306390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
307390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                    "  Published user " + mProvidersByClassPerUser.keyAt(i)
308390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                            + " content providers (by class):", needSep, map);
309742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
310742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
311742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (dumpAll) {
312390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn            needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
313390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                    "  Single-user authority to provider mappings:", needSep, mSingletonByName);
314742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
315742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            for (int i = 0; i < mProvidersByNamePerUser.size(); i++) {
316390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
317390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                        "  User " + mProvidersByNamePerUser.keyAt(i)
318390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                                + " authority to provider mappings:", needSep,
319390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn                        mProvidersByNamePerUser.valueAt(i));
320742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
321742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
322390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn        return needSep;
323742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani    }
324de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
325de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
326de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            int opti, boolean dumpAll) {
3272d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn        ArrayList<ContentProviderRecord> allProviders = new ArrayList<ContentProviderRecord>();
328de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
329de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
3302d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn        synchronized (mAm) {
3312d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            allProviders.addAll(mSingletonByClass.values());
3322d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            for (int i=0; i<mProvidersByClassPerUser.size(); i++) {
3332d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                allProviders.addAll(mProvidersByClassPerUser.valueAt(i).values());
334de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            }
3352d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn
3362d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            if ("all".equals(name)) {
3372d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                providers.addAll(allProviders);
3382d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn            } else {
3392d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                ComponentName componentName = name != null
3402d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                        ? ComponentName.unflattenFromString(name) : null;
3412d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                int objectId = 0;
3422d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                if (componentName == null) {
3432d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    // Not a '/' separated full component name; maybe an object ID?
3442d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    try {
3452d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                        objectId = Integer.parseInt(name, 16);
3462d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                        name = null;
3472d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                        componentName = null;
3482d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    } catch (RuntimeException e) {
3492d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    }
350de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                }
351de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
3522d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                for (int i=0; i<allProviders.size(); i++) {
3532d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn                    ContentProviderRecord r1 = allProviders.get(i);
354de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    if (componentName != null) {
355de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                        if (r1.name.equals(componentName)) {
356de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                            providers.add(r1);
357de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                        }
358de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    } else if (name != null) {
359de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                        if (r1.name.flattenToString().contains(name)) {
360de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                            providers.add(r1);
361de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                        }
362de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    } else if (System.identityHashCode(r1) == objectId) {
363de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                        providers.add(r1);
364de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    }
365de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                }
366de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            }
367de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        }
368de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
369de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        if (providers.size() <= 0) {
370de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            return false;
371de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        }
372de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
373de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        boolean needSep = false;
374de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        for (int i=0; i<providers.size(); i++) {
375de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            if (needSep) {
376de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                pw.println();
377de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            }
378de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            needSep = true;
379de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
380de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        }
381de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        return true;
382de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen    }
383de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen
384de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen    /**
385de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen     * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
386de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen     * there is a thread associated with the provider.
387de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen     */
388de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen    private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
389de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            final ContentProviderRecord r, String[] args, boolean dumpAll) {
390de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        String innerPrefix = prefix + "  ";
3912d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn        synchronized (mAm) {
392de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            pw.print(prefix); pw.print("PROVIDER ");
393de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    pw.print(r);
394de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    pw.print(" pid=");
395de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    if (r.proc != null) pw.println(r.proc.pid);
396de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    else pw.println("(not running)");
397de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            if (dumpAll) {
3986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                r.dump(pw, innerPrefix, true);
399de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            }
400de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        }
401de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        if (r.proc != null && r.proc.thread != null) {
402de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            pw.println("    Client:");
403de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            pw.flush();
404de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            try {
405de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                TransferPipe tp = new TransferPipe();
406de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                try {
407de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    r.proc.thread.dumpProvider(
408de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                            tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
409de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    tp.setBufferPrefix("      ");
410de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    // Short timeout, since blocking here can
411de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    // deadlock with the application.
412de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    tp.go(fd, 2000);
413de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                } finally {
414de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                    tp.kill();
415de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                }
416de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            } catch (IOException ex) {
417de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                pw.println("      Failure while dumping the provider: " + ex);
418de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            } catch (RemoteException ex) {
419de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen                pw.println("      Got a RemoteException while dumping the service");
420de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen            }
421de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen        }
422de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen    }
423742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani}
424