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; 34742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 35742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani/** 36742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * Keeps track of content providers by authority (name) and class. It separates the mapping by 37742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani * user and ones that are not user-specific (system providers). 38742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani */ 39be4e6aaa0252dd7da28b7aa85beba982538efa46Dianne Hackbornpublic final class ProviderMap { 40742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 41742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani private static final String TAG = "ProviderMap"; 42742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 43742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani private static final boolean DBG = false; 44742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 452d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn private final ActivityManagerService mAm; 462d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn 477d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn private final HashMap<String, ContentProviderRecord> mSingletonByName 48742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani = new HashMap<String, ContentProviderRecord>(); 497d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn private final HashMap<ComponentName, ContentProviderRecord> mSingletonByClass 50742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani = new HashMap<ComponentName, ContentProviderRecord>(); 51742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 52742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani private final SparseArray<HashMap<String, ContentProviderRecord>> mProvidersByNamePerUser 53742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani = new SparseArray<HashMap<String, ContentProviderRecord>>(); 54742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani private final SparseArray<HashMap<ComponentName, ContentProviderRecord>> mProvidersByClassPerUser 55742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani = new SparseArray<HashMap<ComponentName, ContentProviderRecord>>(); 56742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 572d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn ProviderMap(ActivityManagerService am) { 582d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn mAm = am; 592d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn } 602d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn 61742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord getProviderByName(String name) { 62742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return getProviderByName(name, -1); 63742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 64742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 65742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord getProviderByName(String name, int userId) { 66742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) { 67742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "getProviderByName: " + name + " , callingUid = " + Binder.getCallingUid()); 68742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 69742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani // Try to find it in the global list 707d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn ContentProviderRecord record = mSingletonByName.get(name); 71742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (record != null) { 72742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return record; 73742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 74742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 75742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani // Check the current user's list 76742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return getProvidersByName(userId).get(name); 77742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 78742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 79742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord getProviderByClass(ComponentName name) { 80742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return getProviderByClass(name, -1); 81742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 82742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 83742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord getProviderByClass(ComponentName name, int userId) { 84742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) { 85742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "getProviderByClass: " + name + ", callingUid = " + Binder.getCallingUid()); 86742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 87742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani // Try to find it in the global list 887d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn ContentProviderRecord record = mSingletonByClass.get(name); 89742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (record != null) { 90742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return record; 91742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 92742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 93742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani // Check the current user's list 94742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return getProvidersByClass(userId).get(name); 95742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 96742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 97742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani void putProviderByName(String name, ContentProviderRecord record) { 98742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) { 99742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "putProviderByName: " + name + " , callingUid = " + Binder.getCallingUid() 100742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani + ", record uid = " + record.appInfo.uid); 101742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 1027d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn if (record.singleton) { 1037d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn mSingletonByName.put(name, record); 104742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 105f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn final int userId = UserHandle.getUserId(record.appInfo.uid); 106742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani getProvidersByName(userId).put(name, record); 107742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 108742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 109742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 110742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani void putProviderByClass(ComponentName name, ContentProviderRecord record) { 111742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) { 112742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "putProviderByClass: " + name + " , callingUid = " + Binder.getCallingUid() 113742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani + ", record uid = " + record.appInfo.uid); 114742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 1157d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn if (record.singleton) { 1167d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn mSingletonByClass.put(name, record); 117742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 118f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn final int userId = UserHandle.getUserId(record.appInfo.uid); 119742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani getProvidersByClass(userId).put(name, record); 120742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 121742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 122742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 1234120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn void removeProviderByName(String name, int userId) { 1247d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn if (mSingletonByName.containsKey(name)) { 125742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) 126742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "Removing from globalByName name=" + name); 1277d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn mSingletonByName.remove(name); 128742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 1294120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); 130742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) 131742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, 1324120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn "Removing from providersByName name=" + name + " user=" + userId); 1334120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn HashMap<String, ContentProviderRecord> map = getProvidersByName(userId); 1348809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan // map returned by getProvidersByName wouldn't be null 1358809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan map.remove(name); 1368809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan if (map.size() == 0) { 1374120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mProvidersByNamePerUser.remove(userId); 1388809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan } 139742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 140742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 141742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 1424120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn void removeProviderByClass(ComponentName name, int userId) { 1437d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn if (mSingletonByClass.containsKey(name)) { 144742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) 145742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, "Removing from globalByClass name=" + name); 1467d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn mSingletonByClass.remove(name); 147742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 1484120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); 149742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (DBG) 150742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Slog.i(TAG, 1514120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn "Removing from providersByClass name=" + name + " user=" + userId); 1524120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(userId); 1538809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan // map returned by getProvidersByClass wouldn't be null 1548809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan map.remove(name); 1558809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan if (map.size() == 0) { 1564120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mProvidersByClassPerUser.remove(userId); 1578809004bc5125d48a1bbfc292509514374cc4fceVairavan Srinivasan } 158742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 159742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 160742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 1614120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn private HashMap<String, ContentProviderRecord> getProvidersByName(int userId) { 1624120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); 163742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani final HashMap<String, ContentProviderRecord> map = mProvidersByNamePerUser.get(userId); 164742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (map == null) { 165742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani HashMap<String, ContentProviderRecord> newMap = new HashMap<String, ContentProviderRecord>(); 166742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani mProvidersByNamePerUser.put(userId, newMap); 167742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return newMap; 168742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 169742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return map; 170742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 171742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 172742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 1734120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int userId) { 1744120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn if (userId < 0) throw new IllegalArgumentException("Bad user " + userId); 1754120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn final HashMap<ComponentName, ContentProviderRecord> map 1764120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn = mProvidersByClassPerUser.get(userId); 177742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (map == null) { 1784120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn HashMap<ComponentName, ContentProviderRecord> newMap 1794120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn = new HashMap<ComponentName, ContentProviderRecord>(); 180742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani mProvidersByClassPerUser.put(userId, newMap); 181742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return newMap; 182742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } else { 183742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return map; 184742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 185742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 186742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 1875e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn private boolean collectForceStopProvidersLocked(String name, int appId, 1885e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn boolean doit, boolean evenPersistent, int userId, 1895e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn HashMap<ComponentName, ContentProviderRecord> providers, 1905e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn ArrayList<ContentProviderRecord> result) { 1915e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn boolean didSomething = false; 1925e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn for (ContentProviderRecord provider : providers.values()) { 1935e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if ((name == null || provider.info.packageName.equals(name)) 1945e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 1955e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if (!doit) { 1965e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn return true; 1975e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 1985e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn didSomething = true; 1995e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn result.add(provider); 2005e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2015e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2025e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn return didSomething; 2035e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2045e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn 2055e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn boolean collectForceStopProviders(String name, int appId, 2065e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn boolean doit, boolean evenPersistent, int userId, 2075e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn ArrayList<ContentProviderRecord> result) { 2085e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn boolean didSomething = collectForceStopProvidersLocked(name, appId, doit, 2095e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn evenPersistent, userId, mSingletonByClass, result); 2105e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if (!doit && didSomething) { 2115e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn return true; 2125e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2135e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if (userId == UserHandle.USER_ALL) { 2145e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn for (int i=0; i<mProvidersByClassPerUser.size(); i++) { 2155e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if (collectForceStopProvidersLocked(name, appId, doit, evenPersistent, 2165e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn userId, mProvidersByClassPerUser.valueAt(i), result)) { 2175e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn if (!doit) { 2185e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn return true; 2195e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2205e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn didSomething = true; 2215e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2225e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2235e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } else { 2242d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn HashMap<ComponentName, ContentProviderRecord> items 2252d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn = getProvidersByClass(userId); 2262d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn if (items != null) { 2272d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn didSomething |= collectForceStopProvidersLocked(name, appId, doit, 2282d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn evenPersistent, userId, items, result); 2292d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn } 2305e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2315e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn return didSomething; 2325e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn } 2335e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn 234390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage, 235390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) { 236742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator(); 237390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn boolean written = false; 238742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani while (it.hasNext()) { 239742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Map.Entry<ComponentName, ContentProviderRecord> e = it.next(); 240742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord r = e.getValue(); 241390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 242390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn continue; 243390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 244390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (needSep) { 245390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn pw.println(""); 246390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn needSep = false; 247390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 248390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (header != null) { 249390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn pw.println(header); 250390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn header = null; 251390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 252390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn written = true; 2536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn pw.print(" * "); 2546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn pw.println(r); 2556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn r.dump(pw, " ", dumpAll); 256742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 257390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn return written; 258742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 259742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 260390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage, 261390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn String header, boolean needSep, HashMap<String, ContentProviderRecord> map) { 262742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator(); 263390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn boolean written = false; 264742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani while (it.hasNext()) { 265742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani Map.Entry<String, ContentProviderRecord> e = it.next(); 266742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani ContentProviderRecord r = e.getValue(); 267390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 268390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn continue; 269390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 270390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (needSep) { 271390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn pw.println(""); 272390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn needSep = false; 273390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 274390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (header != null) { 275390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn pw.println(header); 276390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn header = null; 277390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 278390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn written = true; 279742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani pw.print(" "); 280742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani pw.print(e.getKey()); 281742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani pw.print(": "); 2826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn pw.println(r.toShortString()); 283742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 284390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn return written; 285742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 286742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 287390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) { 288390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn boolean needSep = false; 289390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn 2907d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn if (mSingletonByClass.size() > 0) { 2917ad34e5fb2bc8eda0a64377cedf8a8e899644dd9Dianne Hackborn needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage, 292390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn " Published single-user content providers (by class):", needSep, 293390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn mSingletonByClass); 294742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 295742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 2967d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn for (int i = 0; i < mProvidersByClassPerUser.size(); i++) { 2977d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i); 298390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage, 299390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn " Published user " + mProvidersByClassPerUser.keyAt(i) 300390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn + " content providers (by class):", needSep, map); 301742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 302742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 303742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani if (dumpAll) { 304390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn needSep |= dumpProvidersByNameLocked(pw, dumpPackage, 305390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn " Single-user authority to provider mappings:", needSep, mSingletonByName); 306742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 307742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani for (int i = 0; i < mProvidersByNamePerUser.size(); i++) { 308390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn needSep |= dumpProvidersByNameLocked(pw, dumpPackage, 309390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn " User " + mProvidersByNamePerUser.keyAt(i) 310390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn + " authority to provider mappings:", needSep, 311390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn mProvidersByNamePerUser.valueAt(i)); 312742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 313742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 314390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn return needSep; 315742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani } 316de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 317de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 318de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen int opti, boolean dumpAll) { 3192d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn ArrayList<ContentProviderRecord> allProviders = new ArrayList<ContentProviderRecord>(); 320de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 321de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 3222d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn synchronized (mAm) { 3232d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn allProviders.addAll(mSingletonByClass.values()); 3242d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn for (int i=0; i<mProvidersByClassPerUser.size(); i++) { 3252d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn allProviders.addAll(mProvidersByClassPerUser.valueAt(i).values()); 326de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 3272d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn 3282d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn if ("all".equals(name)) { 3292d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn providers.addAll(allProviders); 3302d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn } else { 3312d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn ComponentName componentName = name != null 3322d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn ? ComponentName.unflattenFromString(name) : null; 3332d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn int objectId = 0; 3342d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn if (componentName == null) { 3352d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn // Not a '/' separated full component name; maybe an object ID? 3362d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn try { 3372d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn objectId = Integer.parseInt(name, 16); 3382d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn name = null; 3392d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn componentName = null; 3402d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn } catch (RuntimeException e) { 3412d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn } 342de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 343de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 3442d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn for (int i=0; i<allProviders.size(); i++) { 3452d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn ContentProviderRecord r1 = allProviders.get(i); 346de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (componentName != null) { 347de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (r1.name.equals(componentName)) { 348de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen providers.add(r1); 349de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 350de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } else if (name != null) { 351de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (r1.name.flattenToString().contains(name)) { 352de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen providers.add(r1); 353de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 354de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } else if (System.identityHashCode(r1) == objectId) { 355de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen providers.add(r1); 356de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 357de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 358de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 359de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 360de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 361de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (providers.size() <= 0) { 362de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen return false; 363de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 364de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 365de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen boolean needSep = false; 366de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen for (int i=0; i<providers.size(); i++) { 367de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (needSep) { 368de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.println(); 369de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 370de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen needSep = true; 371de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen dumpProvider("", fd, pw, providers.get(i), args, dumpAll); 372de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 373de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen return true; 374de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 375de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen 376de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen /** 377de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if 378de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen * there is a thread associated with the provider. 379de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen */ 380de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw, 381de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen final ContentProviderRecord r, String[] args, boolean dumpAll) { 382de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen String innerPrefix = prefix + " "; 3832d1b37819112274f538d1886c379ff337eb0d9edDianne Hackborn synchronized (mAm) { 384de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.print(prefix); pw.print("PROVIDER "); 385de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.print(r); 386de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.print(" pid="); 387de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (r.proc != null) pw.println(r.proc.pid); 388de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen else pw.println("(not running)"); 389de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (dumpAll) { 3906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn r.dump(pw, innerPrefix, true); 391de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 392de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 393de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen if (r.proc != null && r.proc.thread != null) { 394de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.println(" Client:"); 395de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.flush(); 396de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen try { 397de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen TransferPipe tp = new TransferPipe(); 398de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen try { 399de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen r.proc.thread.dumpProvider( 400de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args); 401de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen tp.setBufferPrefix(" "); 402de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen // Short timeout, since blocking here can 403de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen // deadlock with the application. 404de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen tp.go(fd, 2000); 405de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } finally { 406de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen tp.kill(); 407de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 408de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } catch (IOException ex) { 409de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.println(" Failure while dumping the provider: " + ex); 410de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } catch (RemoteException ex) { 411de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen pw.println(" Got a RemoteException while dumping the service"); 412de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 413de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 414de7408c94e09a34fe0779ee894c64b4315aec17cMarco Nelissen } 415742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani} 416