Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbdf5df9 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Split provider / service dumpsys into platform and non-platform" into pi-dev

parents 7468d361 0b575a3c
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -396,4 +396,14 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
        mPackage = pkg;
        mPackage = pkg;
        mClass = in.readString();
        mClass = in.readString();
    }
    }

    /**
     * Interface for classes associated with a component name.
     * @hide
     */
    @FunctionalInterface
    public interface WithComponentName {
        /** Return the associated component name. */
        ComponentName getComponentName();
    }
}
}
+12 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.Stream;


/**
/**
@@ -84,6 +85,17 @@ public class CollectionUtils {
        return emptyIfNull(result);
        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
     * Returns a list of items resulting from applying the given function to each element of the
     * provided list.
     * provided list.
+102 −0
Original line number Original line Diff line number Diff line
@@ -16,18 +16,25 @@


package com.android.internal.util;
package com.android.internal.util;


import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Slog;
import android.util.Slog;


import java.io.PrintWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.StringWriter;
import java.util.Objects;
import java.util.function.Predicate;


/**
/**
 * Helper functions for dumping the state of system services.
 * 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 {
public final class DumpUtils {
    private static final String TAG = "DumpUtils";
    private static final String TAG = "DumpUtils";
@@ -153,4 +160,99 @@ public final class DumpUtils {
            PrintWriter pw) {
            PrintWriter pw) {
        return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, 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 −0
Original line number Original line 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;
    }
}
+128 −0
Original line number Original line 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