diff options
5 files changed, 94 insertions, 47 deletions
diff --git a/core/java/com/android/internal/os/AppIdToPackageMap.java b/core/java/com/android/internal/os/AppIdToPackageMap.java new file mode 100644 index 000000000000..65aa989bbb38 --- /dev/null +++ b/core/java/com/android/internal/os/AppIdToPackageMap.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + + +import android.app.AppGlobals; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.RemoteException; +import android.os.UserHandle; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** Maps AppIds to their package names. */ +public final class AppIdToPackageMap { + private final Map<Integer, String> mAppIdToPackageMap; + + @VisibleForTesting + public AppIdToPackageMap(Map<Integer, String> appIdToPackageMap) { + mAppIdToPackageMap = appIdToPackageMap; + } + + /** Creates a new {@link AppIdToPackageMap} for currently installed packages. */ + public static AppIdToPackageMap getSnapshot() { + List<PackageInfo> packages; + try { + packages = AppGlobals.getPackageManager() + .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_DIRECT_BOOT_AWARE, + UserHandle.USER_SYSTEM).getList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + final Map<Integer, String> map = new HashMap<>(); + for (PackageInfo pkg : packages) { + final int uid = pkg.applicationInfo.uid; + if (pkg.sharedUserId != null && map.containsKey(uid)) { + // Use sharedUserId string as package name if there are collisions + map.put(uid, "shared:" + pkg.sharedUserId); + } else { + map.put(uid, pkg.packageName); + } + } + return new AppIdToPackageMap(map); + } + + /** Maps the AppId to a package name. */ + public String mapAppId(int appId) { + String pkgName = mAppIdToPackageMap.get(appId); + return pkgName == null ? String.valueOf(appId) : pkgName; + } + + /** Maps the UID to a package name. */ + public String mapUid(int uid) { + final int appId = UserHandle.getAppId(uid); + final String pkgName = mAppIdToPackageMap.get(appId); + final String uidStr = UserHandle.formatUid(uid); + return pkgName == null ? uidStr : pkgName + '/' + uidStr; + } +} diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java index ff34036ce7e9..afed31d04b3c 100644 --- a/core/java/com/android/internal/os/BinderCallsStats.java +++ b/core/java/com/android/internal/os/BinderCallsStats.java @@ -22,7 +22,6 @@ import android.os.Binder; import android.os.Process; import android.os.SystemClock; import android.os.ThreadLocalWorkSource; -import android.os.UserHandle; import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.Pair; @@ -356,14 +355,13 @@ public class BinderCallsStats implements BinderInternal.Observer { } /** Writes the collected statistics to the supplied {@link PrintWriter}.*/ - public void dump(PrintWriter pw, Map<Integer, String> appIdToPkgNameMap, boolean verbose) { + public void dump(PrintWriter pw, AppIdToPackageMap packageMap, boolean verbose) { synchronized (mLock) { - dumpLocked(pw, appIdToPkgNameMap, verbose); + dumpLocked(pw, packageMap, verbose); } } - private void dumpLocked(PrintWriter pw, Map<Integer, String> appIdToPkgNameMap, - boolean verbose) { + private void dumpLocked(PrintWriter pw, AppIdToPackageMap packageMap, boolean verbose) { long totalCallsCount = 0; long totalRecordedCallsCount = 0; long totalCpuTime = 0; @@ -397,9 +395,9 @@ public class BinderCallsStats implements BinderInternal.Observer { for (ExportedCallStat e : exportedCallStats) { sb.setLength(0); sb.append(" ") - .append(uidToString(e.callingUid, appIdToPkgNameMap)) + .append(packageMap.mapUid(e.callingUid)) .append(',') - .append(uidToString(e.workSourceUid, appIdToPkgNameMap)) + .append(packageMap.mapUid(e.workSourceUid)) .append(',').append(e.className) .append('#').append(e.methodName) .append(',').append(e.screenInteractive) @@ -420,7 +418,7 @@ public class BinderCallsStats implements BinderInternal.Observer { final List<UidEntry> summaryEntries = verbose ? entries : getHighestValues(entries, value -> value.cpuTimeMicros, 0.9); for (UidEntry entry : summaryEntries) { - String uidStr = uidToString(entry.workSourceUid, appIdToPkgNameMap); + String uidStr = packageMap.mapUid(entry.workSourceUid); pw.println(String.format(" %10d %3.0f%% %8d %8d %s", entry.cpuTimeMicros, 100d * entry.cpuTimeMicros / totalCpuTime, entry.recordedCallCount, entry.callCount, uidStr)); @@ -448,13 +446,6 @@ public class BinderCallsStats implements BinderInternal.Observer { } } - private static String uidToString(int uid, Map<Integer, String> pkgNameMap) { - final int appId = UserHandle.getAppId(uid); - final String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId); - final String uidStr = UserHandle.formatUid(uid); - return pkgName == null ? uidStr : pkgName + '/' + uidStr; - } - protected long getThreadTimeMicro() { return SystemClock.currentThreadTimeMicro(); } diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java index e2618191235d..97942a87da7f 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java @@ -484,7 +484,7 @@ public class BinderCallsStatsTest { bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE); PrintWriter pw = new PrintWriter(new StringWriter()); - bcs.dump(pw, new HashMap<>(), true); + bcs.dump(pw, new AppIdToPackageMap(new HashMap<>()), true); } @Test diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java index 11a2fc9c1e45..13925baa7010 100644 --- a/services/core/java/com/android/server/BinderCallsStatsService.java +++ b/services/core/java/com/android/server/BinderCallsStatsService.java @@ -19,7 +19,6 @@ package com.android.server; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; -import android.app.AppGlobals; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -28,7 +27,6 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Process; -import android.os.RemoteException; import android.os.SystemProperties; import android.os.ThreadLocalWorkSource; import android.os.UserHandle; @@ -39,6 +37,7 @@ import android.util.KeyValueListParser; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.AppIdToPackageMap; import com.android.internal.os.BackgroundThread; import com.android.internal.os.BinderCallsStats; import com.android.internal.os.BinderInternal; @@ -48,9 +47,7 @@ import com.android.internal.os.CachedDeviceState; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class BinderCallsStatsService extends Binder { @@ -82,11 +79,11 @@ public class BinderCallsStatsService extends Binder { mAppIdWhitelist = createAppidWhitelist(context); } - public void dump(PrintWriter pw, Map<Integer, String> appIdToPackageName) { + public void dump(PrintWriter pw, AppIdToPackageMap packageMap) { pw.println("AppIds of apps that can set the work source:"); final ArraySet<Integer> whitelist = mAppIdWhitelist; for (Integer appId : whitelist) { - pw.println("\t- " + appIdToPackageName.getOrDefault(appId, String.valueOf(appId))); + pw.println("\t- " + packageMap.mapAppId(appId)); } } @@ -361,7 +358,7 @@ public class BinderCallsStatsService extends Binder { pw.println("Detailed tracking disabled"); return; } else if ("--dump-worksource-provider".equals(arg)) { - mWorkSourceProvider.dump(pw, getAppIdToPackagesMap()); + mWorkSourceProvider.dump(pw, AppIdToPackageMap.getSnapshot()); return; } else if ("-h".equals(arg)) { pw.println("binder_calls_stats commands:"); @@ -377,28 +374,6 @@ public class BinderCallsStatsService extends Binder { } } } - mBinderCallsStats.dump(pw, getAppIdToPackagesMap(), verbose); - } - - private Map<Integer, String> getAppIdToPackagesMap() { - List<PackageInfo> packages; - try { - packages = AppGlobals.getPackageManager() - .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES, - UserHandle.USER_SYSTEM).getList(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - Map<Integer,String> map = new HashMap<>(); - for (PackageInfo pkg : packages) { - String name = pkg.packageName; - int uid = pkg.applicationInfo.uid; - // Use sharedUserId string as package name if there are collisions - if (pkg.sharedUserId != null && map.containsKey(uid)) { - name = "shared:" + pkg.sharedUserId; - } - map.put(uid, name); - } - return map; + mBinderCallsStats.dump(pw, AppIdToPackageMap.getSnapshot(), verbose); } } diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java index fa3babad639d..cee98c10c7f7 100644 --- a/services/core/java/com/android/server/LooperStatsService.java +++ b/services/core/java/com/android/server/LooperStatsService.java @@ -31,6 +31,7 @@ import android.text.format.DateFormat; import android.util.KeyValueListParser; import android.util.Slog; +import com.android.internal.os.AppIdToPackageMap; import com.android.internal.os.BackgroundThread; import com.android.internal.os.CachedDeviceState; import com.android.internal.os.LooperStats; @@ -92,6 +93,7 @@ public class LooperStatsService extends Binder { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + AppIdToPackageMap packageMap = AppIdToPackageMap.getSnapshot(); pw.print("Start time: "); pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis())); pw.print("On battery time (ms): "); @@ -121,7 +123,7 @@ public class LooperStatsService extends Binder { pw.println(header); for (LooperStats.ExportedEntry entry : entries) { pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", - entry.workSourceUid, + packageMap.mapUid(entry.workSourceUid), entry.threadName, entry.handlerClassName, entry.messageName, |