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

Commit f38a1d3d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Restrict access to instant app data in usage stats" into oc-dev

parents 97bcf59f ad623015
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -15,10 +15,13 @@
 */
package android.app.usage;

import android.annotation.IntDef;
import android.content.res.Configuration;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;

@@ -28,6 +31,12 @@ import java.util.List;
 */
public final class UsageEvents implements Parcelable {

    /** @hide */
    public static final String INSTANT_APP_PACKAGE_NAME = "android.instant_app";

    /** @hide */
    public static final String INSTANT_APP_CLASS_NAME = "android.instant_class";

    /**
     * An event representing a state change for a component.
     */
@@ -91,6 +100,17 @@ public final class UsageEvents implements Parcelable {
         */
        public static final int CHOOSER_ACTION = 9;

        /** @hide */
        public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;

        /** @hide */
        @IntDef(flag = true,
                value = {
                        FLAG_IS_PACKAGE_INSTANT_APP,
                })
        @Retention(RetentionPolicy.SOURCE)
        public @interface EventFlags {}

        /**
         * {@hide}
         */
@@ -145,6 +165,27 @@ public final class UsageEvents implements Parcelable {
         */
        public String[] mContentAnnotations;

        /** @hide */
        @EventFlags
        public int mFlags;

        public Event() {
        }

        /** @hide */
        public Event(Event orig) {
            mPackage = orig.mPackage;
            mClass = orig.mClass;
            mTimeStamp = orig.mTimeStamp;
            mEventType = orig.mEventType;
            mConfiguration = orig.mConfiguration;
            mShortcutId = orig.mShortcutId;
            mAction = orig.mAction;
            mContentType = orig.mContentType;
            mContentAnnotations = orig.mContentAnnotations;
            mFlags = orig.mFlags;
        }

        /**
         * The package name of the source of this event.
         */
@@ -196,6 +237,20 @@ public final class UsageEvents implements Parcelable {
        public String getShortcutId() {
            return mShortcutId;
        }

        /** @hide */
        public Event getObfuscatedIfInstantApp() {
            if ((mFlags & FLAG_IS_PACKAGE_INSTANT_APP) == 0) {
                return this;
            }
            final Event ret = new Event(this);
            ret.mPackage = INSTANT_APP_PACKAGE_NAME;
            ret.mClass = INSTANT_APP_CLASS_NAME;

            // Note there are other string fields too, but they're for app shortcuts and choosers,
            // which instant apps can't use anyway, so there's no need to hide them.
            return ret;
        }
    }

    // Only used when creating the resulting events. Not used for reading/unparceling.
+11 −0
Original line number Diff line number Diff line
@@ -85,6 +85,17 @@ public final class UsageStats implements Parcelable {
        mChooserCounts = stats.mChooserCounts;
    }

    /**
     * {@hide}
     */
    public UsageStats getObfuscatedForInstantApp() {
        final UsageStats ret = new UsageStats(this);

        ret.mPackageName = UsageEvents.INSTANT_APP_PACKAGE_NAME;

        return ret;
    }

    public String getPackageName() {
        return mPackageName;
    }
+7 −2
Original line number Diff line number Diff line
@@ -127,7 +127,12 @@ public abstract class UsageStatsManagerInternal {

    public abstract void applyRestoredPayload(int user, String key, byte[] payload);

    /* Cache Quota Service API */
    /**
     * Return usage stats.
     *
     * @param obfuscateInstantApps whether instant app package names need to be obfuscated in the
     *     result.
     */
    public abstract List<UsageStats> queryUsageStatsForUser(
            int userId, int interval, long beginTime, long endTime);
            int userId, int interval, long beginTime, long endTime, boolean obfuscateInstantApps);
}
+3 −0
Original line number Diff line number Diff line
@@ -341,4 +341,7 @@ public abstract class PackageManagerInternal {
     * Return the taget SDK version for the app with the given UID.
     */
    public abstract int getUidTargetSdkVersion(int uid);

    /** Whether the binder caller can access instant apps. */
    public abstract boolean canAccessInstantApps(int callingUid);
}
+34 −7
Original line number Diff line number Diff line
@@ -3480,6 +3480,31 @@ public class PackageManagerService extends IPackageManager.Stub
        return cur;
    }
    /**
     * Returns whether or not a full application can see an instant application.
     * <p>
     * Currently, there are three cases in which this can occur:
     * <ol>
     * <li>The calling application is a "special" process. The special
     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
     *     and {@code 0}</li>
     * <li>The calling application has the permission
     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
     * <li>[TODO] The calling application is the default launcher on the
     *     system partition.</li>
     * </ol>
     */
    private boolean canAccessInstantApps(int callingUid) {
        final boolean isSpecialProcess =
                callingUid == Process.SYSTEM_UID
                        || callingUid == Process.SHELL_UID
                        || callingUid == 0;
        final boolean allowMatchInstant =
                isSpecialProcess
                        || mContext.checkCallingOrSelfPermission(
                        android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
        return allowMatchInstant;
    }
    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
        if (!sUserManager.exists(userId)) return null;
        if (ps == null) {
@@ -3489,19 +3514,15 @@ public class PackageManagerService extends IPackageManager.Stub
        if (p == null) {
            return null;
        }
        final int callingUid =  Binder.getCallingUid();
        // Filter out ephemeral app metadata:
        //   * The system/shell/root can see metadata for any app
        //   * An installed app can see metadata for 1) other installed apps
        //     and 2) ephemeral apps that have explicitly interacted with it
        //   * Ephemeral apps can only see their own data and exposed installed apps
        //   * Holding a signature permission allows seeing instant apps
        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
        if (callingAppId != Process.SYSTEM_UID
                && callingAppId != Process.SHELL_UID
                && callingAppId != Process.ROOT_UID
                && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
                        Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
            final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
        if (!canAccessInstantApps(callingUid)) {
            final String instantAppPackageName = getInstantAppPackageName(callingUid);
            if (instantAppPackageName != null) {
                // ephemeral apps can only get information on themselves or
                // installed apps that are exposed.
@@ -3512,6 +3533,7 @@ public class PackageManagerService extends IPackageManager.Stub
            } else {
                if (ps.getInstantApp(userId)) {
                    // only get access to the ephemeral app if we've been granted access
                    final int callingAppId = UserHandle.getAppId(callingUid);
                    if (!mInstantAppRegistry.isInstantAccessGranted(
                            userId, callingAppId, ps.appId)) {
                        return null;
@@ -23844,6 +23866,11 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                return getUidTargetSdkVersionLockedLPr(uid);
            }
        }
        @Override
        public boolean canAccessInstantApps(int callingUid) {
            return PackageManagerService.this.canAccessInstantApps(callingUid);
        }
    }
    @Override
Loading