Merge "Split provider / service dumpsys into platform and non-platform" into pi-dev
This commit is contained in:
@@ -396,4 +396,14 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
|
||||
mPackage = pkg;
|
||||
mClass = in.readString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for classes associated with a component name.
|
||||
* @hide
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface WithComponentName {
|
||||
/** Return the associated component name. */
|
||||
ComponentName getComponentName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@@ -84,6 +85,17 @@ public class CollectionUtils {
|
||||
return emptyIfNull(result);
|
||||
}
|
||||
|
||||
/** Add all elements matching {@code predicate} in {@code source} to {@code dest}. */
|
||||
public static <T> void addIf(@Nullable List<T> source, @NonNull Collection<? super T> dest,
|
||||
@Nullable Predicate<? super T> predicate) {
|
||||
for (int i = 0; i < size(source); i++) {
|
||||
final T item = source.get(i);
|
||||
if (predicate.test(item)) {
|
||||
dest.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of items resulting from applying the given function to each element of the
|
||||
* provided list.
|
||||
|
||||
@@ -16,18 +16,25 @@
|
||||
|
||||
package com.android.internal.util;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Helper functions for dumping the state of system services.
|
||||
* Test:
|
||||
atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java
|
||||
*/
|
||||
public final class DumpUtils {
|
||||
private static final String TAG = "DumpUtils";
|
||||
@@ -153,4 +160,99 @@ public final class DumpUtils {
|
||||
PrintWriter pw) {
|
||||
return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, pw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isPlatformPackage(@Nullable String packageName) {
|
||||
return (packageName != null)
|
||||
&& (packageName.equals("android")
|
||||
|| packageName.startsWith("android.")
|
||||
|| packageName.startsWith("com.android."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isPlatformPackage(@Nullable ComponentName cname) {
|
||||
return (cname != null) && isPlatformPackage(cname.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isPlatformPackage(@Nullable ComponentName.WithComponentName wcn) {
|
||||
return (wcn != null) && isPlatformPackage(wcn.getComponentName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is NOT considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isNonPlatformPackage(@Nullable String packageName) {
|
||||
return (packageName != null) && !isPlatformPackage(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is NOT considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isNonPlatformPackage(@Nullable ComponentName cname) {
|
||||
return (cname != null) && isNonPlatformPackage(cname.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a package name is NOT considered to be part of the platform.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isNonPlatformPackage(@Nullable ComponentName.WithComponentName wcn) {
|
||||
return (wcn != null) && !isPlatformPackage(wcn.getComponentName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for dumping providers and services. Return a predicate for a given filter string.
|
||||
* @hide
|
||||
*/
|
||||
public static <TRec extends ComponentName.WithComponentName> Predicate<TRec> filterRecord(
|
||||
@Nullable String filterString) {
|
||||
|
||||
if (TextUtils.isEmpty(filterString)) {
|
||||
return rec -> false;
|
||||
}
|
||||
|
||||
// Dump all?
|
||||
if ("all".equals(filterString)) {
|
||||
return Objects::nonNull;
|
||||
}
|
||||
|
||||
// Dump all platform?
|
||||
if ("all-platform".equals(filterString)) {
|
||||
return DumpUtils::isPlatformPackage;
|
||||
}
|
||||
|
||||
// Dump all non-platform?
|
||||
if ("all-non-platform".equals(filterString)) {
|
||||
return DumpUtils::isNonPlatformPackage;
|
||||
}
|
||||
|
||||
// Is the filter a component name? If so, do an exact match.
|
||||
final ComponentName filterCname = ComponentName.unflattenFromString(filterString);
|
||||
if (filterCname != null) {
|
||||
// Do exact component name check.
|
||||
return rec -> (rec != null) && filterCname.equals(rec.getComponentName());
|
||||
}
|
||||
|
||||
// Otherwise, do a partial match against the component name.
|
||||
// Also if the filter is a hex-decimal string, do the object ID match too.
|
||||
final int id = ParseUtils.parseIntWithBase(filterString, 16, -1);
|
||||
return rec -> {
|
||||
final ComponentName cn = rec.getComponentName();
|
||||
return ((id != -1) && (System.identityHashCode(rec) == id))
|
||||
|| cn.flattenToString().toLowerCase().contains(filterString.toLowerCase());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
98
core/java/com/android/internal/util/ParseUtils.java
Normal file
98
core/java/com/android/internal/util/ParseUtils.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Various numeric -> strings conversion.
|
||||
*
|
||||
* Test:
|
||||
atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java
|
||||
*/
|
||||
public final class ParseUtils {
|
||||
private ParseUtils() {
|
||||
}
|
||||
|
||||
/** Parse a value as a base-10 integer. */
|
||||
public static int parseInt(@Nullable String value, int defValue) {
|
||||
return parseIntWithBase(value, 10, defValue);
|
||||
}
|
||||
|
||||
/** Parse a value as an integer of a given base. */
|
||||
public static int parseIntWithBase(@Nullable String value, int base, int defValue) {
|
||||
if (value == null) {
|
||||
return defValue;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value, base);
|
||||
} catch (NumberFormatException e) {
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a value as a base-10 long. */
|
||||
public static long parseLong(@Nullable String value, long defValue) {
|
||||
return parseLongWithBase(value, 10, defValue);
|
||||
}
|
||||
|
||||
/** Parse a value as a long of a given base. */
|
||||
public static long parseLongWithBase(@Nullable String value, int base, long defValue) {
|
||||
if (value == null) {
|
||||
return defValue;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value, base);
|
||||
} catch (NumberFormatException e) {
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a value as a float. */
|
||||
public static float parseFloat(@Nullable String value, float defValue) {
|
||||
if (value == null) {
|
||||
return defValue;
|
||||
}
|
||||
try {
|
||||
return Float.parseFloat(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a value as a double. */
|
||||
public static double parseDouble(@Nullable String value, double defValue) {
|
||||
if (value == null) {
|
||||
return defValue;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a value as a boolean. */
|
||||
public static boolean parseBoolean(@Nullable String value, boolean defValue) {
|
||||
if ("true".equals(value)) {
|
||||
return true;
|
||||
}
|
||||
if ("false".equals(value)) {
|
||||
return false;
|
||||
}
|
||||
return parseInt(value, defValue ? 1 : 0) != 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import static com.android.internal.util.DumpUtils.filterRecord;
|
||||
import static com.android.internal.util.DumpUtils.isNonPlatformPackage;
|
||||
import static com.android.internal.util.DumpUtils.isPlatformPackage;
|
||||
|
||||
import android.content.ComponentName;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Run with:
|
||||
atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/DumpTest.java
|
||||
*/
|
||||
public class DumpUtilsTest extends TestCase {
|
||||
|
||||
private static ComponentName cn(String componentName) {
|
||||
if (componentName == null) {
|
||||
return null;
|
||||
}
|
||||
return ComponentName.unflattenFromString(componentName);
|
||||
}
|
||||
|
||||
private static ComponentName.WithComponentName wcn(String componentName) {
|
||||
if (componentName == null) {
|
||||
return null;
|
||||
}
|
||||
return () -> cn(componentName);
|
||||
}
|
||||
|
||||
public void testIsPlatformPackage() {
|
||||
assertTrue(isPlatformPackage("android"));
|
||||
assertTrue(isPlatformPackage("android.abc"));
|
||||
assertTrue(isPlatformPackage("com.android.abc"));
|
||||
|
||||
assertFalse(isPlatformPackage((String) null));
|
||||
assertFalse(isPlatformPackage("com.google"));
|
||||
|
||||
assertTrue(isPlatformPackage(cn("android/abc")));
|
||||
assertTrue(isPlatformPackage(cn("android.abc/abc")));
|
||||
assertTrue(isPlatformPackage(cn("com.android.def/abc")));
|
||||
|
||||
assertFalse(isPlatformPackage(cn(null)));
|
||||
assertFalse(isPlatformPackage(cn("com.google.def/abc")));
|
||||
|
||||
assertTrue(isPlatformPackage(wcn("android/abc")));
|
||||
assertTrue(isPlatformPackage(wcn("android.abc/abc")));
|
||||
assertTrue(isPlatformPackage(wcn("com.android.def/abc")));
|
||||
|
||||
assertFalse(isPlatformPackage(wcn(null)));
|
||||
assertFalse(isPlatformPackage(wcn("com.google.def/abc")));
|
||||
}
|
||||
|
||||
public void testIsNonPlatformPackage() {
|
||||
assertFalse(isNonPlatformPackage("android"));
|
||||
assertFalse(isNonPlatformPackage("android.abc"));
|
||||
assertFalse(isNonPlatformPackage("com.android.abc"));
|
||||
|
||||
assertFalse(isNonPlatformPackage((String) null));
|
||||
assertTrue(isNonPlatformPackage("com.google"));
|
||||
|
||||
assertFalse(isNonPlatformPackage(cn("android/abc")));
|
||||
assertFalse(isNonPlatformPackage(cn("android.abc/abc")));
|
||||
assertFalse(isNonPlatformPackage(cn("com.android.def/abc")));
|
||||
|
||||
assertFalse(isNonPlatformPackage(cn(null)));
|
||||
assertTrue(isNonPlatformPackage(cn("com.google.def/abc")));
|
||||
|
||||
assertFalse(isNonPlatformPackage(wcn("android/abc")));
|
||||
assertFalse(isNonPlatformPackage(wcn("android.abc/abc")));
|
||||
assertFalse(isNonPlatformPackage(wcn("com.android.def/abc")));
|
||||
|
||||
assertFalse(isNonPlatformPackage(wcn(null)));
|
||||
assertTrue(isNonPlatformPackage(wcn("com.google.def/abc")));
|
||||
}
|
||||
|
||||
public void testFilterRecord() {
|
||||
assertFalse(filterRecord(null).test(wcn("com.google.p/abc")));
|
||||
assertFalse(filterRecord(null).test(wcn("com.android.p/abc")));
|
||||
|
||||
assertTrue(filterRecord("all").test(wcn("com.google.p/abc")));
|
||||
assertTrue(filterRecord("all").test(wcn("com.android.p/abc")));
|
||||
assertFalse(filterRecord("all").test(wcn(null)));
|
||||
|
||||
assertFalse(filterRecord("all-platform").test(wcn("com.google.p/abc")));
|
||||
assertTrue(filterRecord("all-platform").test(wcn("com.android.p/abc")));
|
||||
assertFalse(filterRecord("all-platform").test(wcn(null)));
|
||||
|
||||
assertTrue(filterRecord("all-non-platform").test(wcn("com.google.p/abc")));
|
||||
assertFalse(filterRecord("all-non-platform").test(wcn("com.android.p/abc")));
|
||||
assertFalse(filterRecord("all-non-platform").test(wcn(null)));
|
||||
|
||||
// Partial string match.
|
||||
assertTrue(filterRecord("abc").test(wcn("com.google.p/.abc")));
|
||||
assertFalse(filterRecord("abc").test(wcn("com.google.p/.def")));
|
||||
assertTrue(filterRecord("com").test(wcn("com.google.p/.xyz")));
|
||||
|
||||
// Full component name match.
|
||||
assertTrue(filterRecord("com.google/com.google.abc").test(wcn("com.google/.abc")));
|
||||
assertFalse(filterRecord("com.google/com.google.abc").test(wcn("com.google/.abc.def")));
|
||||
|
||||
|
||||
// Hex ID match
|
||||
ComponentName.WithComponentName component = wcn("com.google/.abc");
|
||||
|
||||
assertTrue(filterRecord(
|
||||
Integer.toHexString(System.identityHashCode(component))).test(component));
|
||||
// Same component name, but different ID, no match.
|
||||
assertFalse(filterRecord(
|
||||
Integer.toHexString(System.identityHashCode(component))).test(
|
||||
wcn("com.google/.abc")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Run with:
|
||||
atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java
|
||||
*/
|
||||
public class ParseUtilsTest extends TestCase {
|
||||
public void testParseInt() {
|
||||
assertEquals(1, ParseUtils.parseInt(null, 1));
|
||||
assertEquals(1, ParseUtils.parseInt("", 1));
|
||||
assertEquals(1, ParseUtils.parseInt("1x", 1));
|
||||
assertEquals(2, ParseUtils.parseInt("2", 1));
|
||||
|
||||
assertEquals(2, ParseUtils.parseInt("+2", 1));
|
||||
assertEquals(-2, ParseUtils.parseInt("-2", 1));
|
||||
}
|
||||
|
||||
public void testParseIntWithBase() {
|
||||
assertEquals(1, ParseUtils.parseIntWithBase(null, 10, 1));
|
||||
assertEquals(1, ParseUtils.parseIntWithBase("", 10, 1));
|
||||
assertEquals(1, ParseUtils.parseIntWithBase("1x", 10, 1));
|
||||
assertEquals(2, ParseUtils.parseIntWithBase("2", 10, 1));
|
||||
assertEquals(10, ParseUtils.parseIntWithBase("10", 10, 1));
|
||||
assertEquals(3, ParseUtils.parseIntWithBase("10", 3, 1));
|
||||
|
||||
assertEquals(3, ParseUtils.parseIntWithBase("+10", 3, 1));
|
||||
assertEquals(-3, ParseUtils.parseIntWithBase("-10", 3, 1));
|
||||
}
|
||||
|
||||
public void testParseLong() {
|
||||
assertEquals(1L, ParseUtils.parseLong(null, 1));
|
||||
assertEquals(1L, ParseUtils.parseLong("", 1));
|
||||
assertEquals(1L, ParseUtils.parseLong("1x", 1));
|
||||
assertEquals(2L, ParseUtils.parseLong("2", 1));
|
||||
}
|
||||
|
||||
public void testParseLongWithBase() {
|
||||
assertEquals(1L, ParseUtils.parseLongWithBase(null, 10, 1));
|
||||
assertEquals(1L, ParseUtils.parseLongWithBase("", 10, 1));
|
||||
assertEquals(1L, ParseUtils.parseLongWithBase("1x", 10, 1));
|
||||
assertEquals(2L, ParseUtils.parseLongWithBase("2", 10, 1));
|
||||
assertEquals(10L, ParseUtils.parseLongWithBase("10", 10, 1));
|
||||
assertEquals(3L, ParseUtils.parseLongWithBase("10", 3, 1));
|
||||
|
||||
assertEquals(3L, ParseUtils.parseLongWithBase("+10", 3, 1));
|
||||
assertEquals(-3L, ParseUtils.parseLongWithBase("-10", 3, 1));
|
||||
|
||||
assertEquals(10_000_000_000L, ParseUtils.parseLongWithBase("+10000000000", 10, 1));
|
||||
assertEquals(-10_000_000_000L, ParseUtils.parseLongWithBase("-10000000000", 10, 1));
|
||||
|
||||
assertEquals(10_000_000_000L, ParseUtils.parseLongWithBase(null, 10, 10_000_000_000L));
|
||||
}
|
||||
|
||||
public void testParseFloat() {
|
||||
assertEquals(0.5f, ParseUtils.parseFloat(null, 0.5f));
|
||||
assertEquals(0.5f, ParseUtils.parseFloat("", 0.5f));
|
||||
assertEquals(0.5f, ParseUtils.parseFloat("1x", 0.5f));
|
||||
assertEquals(1.5f, ParseUtils.parseFloat("1.5", 0.5f));
|
||||
}
|
||||
|
||||
public void testParseDouble() {
|
||||
assertEquals(0.5, ParseUtils.parseDouble(null, 0.5));
|
||||
assertEquals(0.5, ParseUtils.parseDouble("", 0.5));
|
||||
assertEquals(0.5, ParseUtils.parseDouble("1x", 0.5));
|
||||
assertEquals(1.5, ParseUtils.parseDouble("1.5", 0.5));
|
||||
}
|
||||
|
||||
public void testParseBoolean() {
|
||||
assertEquals(false, ParseUtils.parseBoolean(null, false));
|
||||
assertEquals(true, ParseUtils.parseBoolean(null, true));
|
||||
|
||||
assertEquals(false, ParseUtils.parseBoolean("", false));
|
||||
assertEquals(true, ParseUtils.parseBoolean("", true));
|
||||
|
||||
assertEquals(true, ParseUtils.parseBoolean("true", false));
|
||||
assertEquals(true, ParseUtils.parseBoolean("true", true));
|
||||
|
||||
assertEquals(false, ParseUtils.parseBoolean("false", false));
|
||||
assertEquals(false, ParseUtils.parseBoolean("false", true));
|
||||
|
||||
assertEquals(true, ParseUtils.parseBoolean("1", false));
|
||||
assertEquals(true, ParseUtils.parseBoolean("1", true));
|
||||
|
||||
assertEquals(false, ParseUtils.parseBoolean("0", false));
|
||||
assertEquals(false, ParseUtils.parseBoolean("0", true));
|
||||
}
|
||||
}
|
||||
@@ -24,15 +24,19 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.ServiceStartArgs;
|
||||
import android.content.ComponentName.WithComponentName;
|
||||
import android.content.IIntentSender;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
@@ -55,6 +59,8 @@ import com.android.internal.messages.nano.SystemMessageProto;
|
||||
import com.android.internal.notification.SystemNotificationChannels;
|
||||
import com.android.internal.os.BatteryStatsImpl;
|
||||
import com.android.internal.os.TransferPipe;
|
||||
import com.android.internal.util.CollectionUtils;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.util.FastPrintWriter;
|
||||
import com.android.server.AppStateTracker;
|
||||
import com.android.server.LocalServices;
|
||||
@@ -4063,57 +4069,26 @@ public final class ActiveServices {
|
||||
* - the first arg isn't the flattened component name of an existing service:
|
||||
* dump all services whose component contains the first arg as a substring
|
||||
*/
|
||||
protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
|
||||
int opti, boolean dumpAll) {
|
||||
ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
|
||||
protected boolean dumpService(FileDescriptor fd, PrintWriter pw, final String name,
|
||||
String[] args, int opti, boolean dumpAll) {
|
||||
final ArrayList<ServiceRecord> services = new ArrayList<>();
|
||||
|
||||
final Predicate<ServiceRecord> filter = DumpUtils.filterRecord(name);
|
||||
|
||||
synchronized (mAm) {
|
||||
int[] users = mAm.mUserController.getUsers();
|
||||
if ("all".equals(name)) {
|
||||
for (int user : users) {
|
||||
ServiceMap smap = mServiceMap.get(user);
|
||||
if (smap == null) {
|
||||
continue;
|
||||
}
|
||||
ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
|
||||
for (int i=0; i<alls.size(); i++) {
|
||||
ServiceRecord r1 = alls.valueAt(i);
|
||||
services.add(r1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ComponentName componentName = name != null
|
||||
? ComponentName.unflattenFromString(name) : null;
|
||||
int objectId = 0;
|
||||
if (componentName == null) {
|
||||
// Not a '/' separated full component name; maybe an object ID?
|
||||
try {
|
||||
objectId = Integer.parseInt(name, 16);
|
||||
name = null;
|
||||
componentName = null;
|
||||
} catch (RuntimeException e) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int user : users) {
|
||||
ServiceMap smap = mServiceMap.get(user);
|
||||
if (smap == null) {
|
||||
continue;
|
||||
}
|
||||
ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
|
||||
for (int i=0; i<alls.size(); i++) {
|
||||
ServiceRecord r1 = alls.valueAt(i);
|
||||
if (componentName != null) {
|
||||
if (r1.name.equals(componentName)) {
|
||||
services.add(r1);
|
||||
}
|
||||
} else if (name != null) {
|
||||
if (r1.name.flattenToString().contains(name)) {
|
||||
services.add(r1);
|
||||
}
|
||||
} else if (System.identityHashCode(r1) == objectId) {
|
||||
services.add(r1);
|
||||
}
|
||||
for (int user : users) {
|
||||
ServiceMap smap = mServiceMap.get(user);
|
||||
if (smap == null) {
|
||||
continue;
|
||||
}
|
||||
ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
|
||||
for (int i=0; i<alls.size(); i++) {
|
||||
ServiceRecord r1 = alls.valueAt(i);
|
||||
|
||||
if (filter.test(r1)) {
|
||||
services.add(r1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4123,6 +4098,9 @@ public final class ActiveServices {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sort by component name.
|
||||
services.sort(Comparator.comparing(WithComponentName::getComponentName));
|
||||
|
||||
boolean needSep = false;
|
||||
for (int i=0; i<services.size(); i++) {
|
||||
if (needSep) {
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
final class ContentProviderRecord {
|
||||
final class ContentProviderRecord implements ComponentName.WithComponentName {
|
||||
final ActivityManagerService service;
|
||||
public final ProviderInfo info;
|
||||
final int uid;
|
||||
@@ -260,4 +260,8 @@ final class ContentProviderRecord {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentName getComponentName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,22 +17,28 @@
|
||||
package com.android.server.am;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ComponentName.WithComponentName;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import com.android.internal.os.TransferPipe;
|
||||
import com.android.internal.util.CollectionUtils;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Keeps track of content providers by authority (name) and class. It separates the mapping by
|
||||
@@ -325,7 +331,9 @@ public final class ProviderMap {
|
||||
|
||||
private ArrayList<ContentProviderRecord> getProvidersForName(String name) {
|
||||
ArrayList<ContentProviderRecord> allProviders = new ArrayList<ContentProviderRecord>();
|
||||
ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
|
||||
final ArrayList<ContentProviderRecord> ret = new ArrayList<>();
|
||||
|
||||
final Predicate<ContentProviderRecord> filter = DumpUtils.filterRecord(name);
|
||||
|
||||
synchronized (mAm) {
|
||||
allProviders.addAll(mSingletonByClass.values());
|
||||
@@ -333,39 +341,11 @@ public final class ProviderMap {
|
||||
allProviders.addAll(mProvidersByClassPerUser.valueAt(i).values());
|
||||
}
|
||||
|
||||
if ("all".equals(name)) {
|
||||
providers.addAll(allProviders);
|
||||
} else {
|
||||
ComponentName componentName = name != null
|
||||
? ComponentName.unflattenFromString(name) : null;
|
||||
int objectId = 0;
|
||||
if (componentName == null) {
|
||||
// Not a '/' separated full component name; maybe an object ID?
|
||||
try {
|
||||
objectId = Integer.parseInt(name, 16);
|
||||
name = null;
|
||||
componentName = null;
|
||||
} catch (RuntimeException e) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<allProviders.size(); i++) {
|
||||
ContentProviderRecord r1 = allProviders.get(i);
|
||||
if (componentName != null) {
|
||||
if (r1.name.equals(componentName)) {
|
||||
providers.add(r1);
|
||||
}
|
||||
} else if (name != null) {
|
||||
if (r1.name.flattenToString().contains(name)) {
|
||||
providers.add(r1);
|
||||
}
|
||||
} else if (System.identityHashCode(r1) == objectId) {
|
||||
providers.add(r1);
|
||||
}
|
||||
}
|
||||
}
|
||||
CollectionUtils.addIf(allProviders, ret, filter);
|
||||
}
|
||||
return providers;
|
||||
// Sort by component name.
|
||||
ret.sort(Comparator.comparing(WithComponentName::getComponentName));
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
|
||||
|
||||
@@ -56,7 +56,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA
|
||||
/**
|
||||
* A running application service.
|
||||
*/
|
||||
final class ServiceRecord extends Binder {
|
||||
final class ServiceRecord extends Binder implements ComponentName.WithComponentName {
|
||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM;
|
||||
|
||||
// Maximum number of delivery attempts before giving up.
|
||||
@@ -757,4 +757,8 @@ final class ServiceRecord extends Binder {
|
||||
.append(' ').append(shortName).append('}');
|
||||
return stringName = sb.toString();
|
||||
}
|
||||
|
||||
public ComponentName getComponentName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user