Loading core/java/android/content/ComponentName.java +10 −0 Original line number Diff line number Diff line Loading @@ -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(); } } core/java/com/android/internal/util/CollectionUtils.java +12 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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. Loading core/java/com/android/internal/util/DumpUtils.java +102 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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()); }; } } core/java/com/android/internal/util/ParseUtils.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * 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; } } core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java 0 → 100644 +128 −0 Original line number Diff line number Diff line /* * 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"))); } } Loading
core/java/android/content/ComponentName.java +10 −0 Original line number Diff line number Diff line Loading @@ -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(); } }
core/java/com/android/internal/util/CollectionUtils.java +12 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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. Loading
core/java/com/android/internal/util/DumpUtils.java +102 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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()); }; } }
core/java/com/android/internal/util/ParseUtils.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * 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; } }
core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java 0 → 100644 +128 −0 Original line number Diff line number Diff line /* * 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"))); } }