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

Commit ece9be58 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Offer to filter broadcasts based on CompatChanges."

parents 075254e1 895e4562
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ package android.app {
  }

  public class BroadcastOptions {
    method public int getMaxManifestReceiverApiLevel();
    method public void setMaxManifestReceiverApiLevel(int);
    method @Deprecated public int getMaxManifestReceiverApiLevel();
    method @Deprecated public void setMaxManifestReceiverApiLevel(int);
  }

  public abstract class HomeVisibilityListener {
+2 −0
Original line number Diff line number Diff line
@@ -724,12 +724,14 @@ package android.app {
  }
  public class BroadcastOptions {
    method public void clearRequireCompatChange();
    method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
    method public static android.app.BroadcastOptions makeBasic();
    method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
    method public void setDontSendToRestrictedApps(boolean);
    method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
    method public void setRequireAllOfPermissions(@Nullable String[]);
    method public void setRequireCompatChange(long, boolean);
    method public void setRequireNoneOfPermissions(@Nullable String[]);
    method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String);
    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
+5 −2
Original line number Diff line number Diff line
@@ -248,12 +248,15 @@ package android.app {

  public class BroadcastOptions {
    ctor public BroadcastOptions(@NonNull android.os.Bundle);
    method public int getMaxManifestReceiverApiLevel();
    method @Deprecated public int getMaxManifestReceiverApiLevel();
    method public long getTemporaryAppAllowlistDuration();
    method @Nullable public String getTemporaryAppAllowlistReason();
    method public int getTemporaryAppAllowlistReasonCode();
    method public int getTemporaryAppAllowlistType();
    method public void setMaxManifestReceiverApiLevel(int);
    method @Deprecated public void setMaxManifestReceiverApiLevel(int);
    method public boolean testRequireCompatChange(int);
    field public static final long CHANGE_ALWAYS_DISABLED = 210856463L; // 0xc916a0fL
    field public static final long CHANGE_ALWAYS_ENABLED = 209888056L; // 0xc82a338L
  }

  public class DownloadManager {
+136 −0
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledSince;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerExemptionManager;
@@ -45,6 +50,35 @@ public class BroadcastOptions extends ComponentOptions {
    private boolean mAllowBackgroundActivityStarts;
    private String[] mRequireAllOfPermissions;
    private String[] mRequireNoneOfPermissions;
    private long mRequireCompatChangeId = CHANGE_INVALID;
    private boolean mRequireCompatChangeEnabled = true;

    /**
     * Change ID which is invalid.
     *
     * @hide
     */
    public static final long CHANGE_INVALID = Long.MIN_VALUE;

    /**
     * Change ID which is always enabled, for testing purposes.
     *
     * @hide
     */
    @TestApi
    @ChangeId
    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
    public static final long CHANGE_ALWAYS_ENABLED = 209888056L;

    /**
     * Change ID which is always disabled, for testing purposes.
     *
     * @hide
     */
    @TestApi
    @ChangeId
    @Disabled
    public static final long CHANGE_ALWAYS_DISABLED = 210856463L;

    /**
     * How long to temporarily put an app on the power allowlist when executing this broadcast
@@ -100,6 +134,18 @@ public class BroadcastOptions extends ComponentOptions {
    public static final String KEY_REQUIRE_NONE_OF_PERMISSIONS =
            "android:broadcast.requireNoneOfPermissions";

    /**
     * Corresponds to {@link #setRequireCompatChange(long, boolean)}
     */
    private static final String KEY_REQUIRE_COMPAT_CHANGE_ID =
            "android:broadcast.requireCompatChangeId";

    /**
     * Corresponds to {@link #setRequireCompatChange(long, boolean)}
     */
    private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED =
            "android:broadcast.requireCompatChangeEnabled";

    /**
     * @hide
     * @deprecated Use {@link android.os.PowerExemptionManager#
@@ -150,6 +196,8 @@ public class BroadcastOptions extends ComponentOptions {
                false);
        mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS);
        mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS);
        mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID);
        mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true);
    }

    /**
@@ -270,16 +318,32 @@ public class BroadcastOptions extends ComponentOptions {
     * Set the minimum target API level of receivers of the broadcast.  If an application
     * is targeting an API level less than this, the broadcast will not be delivered to
     * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
     *
     * @deprecated to give developers the most flexibility during beta releases,
     *             we strongly encourage using {@link ChangeId} instead of
     *             target SDK checks; callers should use
     *             {@link #setRequireCompatChange(long, boolean)} instead,
     *             possibly combined with
     *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
     * @hide
     */
    @Deprecated
    public void setMinManifestReceiverApiLevel(int apiLevel) {
        mMinManifestReceiverApiLevel = apiLevel;
    }

    /**
     * Return {@link #setMinManifestReceiverApiLevel}.
     *
     * @deprecated to give developers the most flexibility during beta releases,
     *             we strongly encourage using {@link ChangeId} instead of
     *             target SDK checks; callers should use
     *             {@link #setRequireCompatChange(long, boolean)} instead,
     *             possibly combined with
     *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
     * @hide
     */
    @Deprecated
    public int getMinManifestReceiverApiLevel() {
        return mMinManifestReceiverApiLevel;
    }
@@ -288,20 +352,36 @@ public class BroadcastOptions extends ComponentOptions {
     * Set the maximum target API level of receivers of the broadcast.  If an application
     * is targeting an API level greater than this, the broadcast will not be delivered to
     * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
     *
     * @deprecated to give developers the most flexibility during beta releases,
     *             we strongly encourage using {@link ChangeId} instead of
     *             target SDK checks; callers should use
     *             {@link #setRequireCompatChange(long, boolean)} instead,
     *             possibly combined with
     *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
     * @hide
     */
    @TestApi
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @Deprecated
    public void setMaxManifestReceiverApiLevel(int apiLevel) {
        mMaxManifestReceiverApiLevel = apiLevel;
    }

    /**
     * Return {@link #setMaxManifestReceiverApiLevel}.
     *
     * @deprecated to give developers the most flexibility during beta releases,
     *             we strongly encourage using {@link ChangeId} instead of
     *             target SDK checks; callers should use
     *             {@link #setRequireCompatChange(long, boolean)} instead,
     *             possibly combined with
     *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
     * @hide
     */
    @TestApi
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @Deprecated
    public int getMaxManifestReceiverApiLevel() {
        return mMaxManifestReceiverApiLevel;
    }
@@ -378,6 +458,58 @@ public class BroadcastOptions extends ComponentOptions {
        mRequireNoneOfPermissions = excludedPermissions;
    }

    /**
     * When set, this broadcast will only be delivered to apps which have the
     * given {@link ChangeId} in the given state.
     * <p>
     * Each {@link BroadcastOptions} instance supports only a single
     * {@link ChangeId} requirement, so any subsequent calls will override any
     * previously defined requirement.
     * <p>
     * This requirement applies to both manifest registered and runtime
     * registered receivers.
     *
     * @param changeId the {@link ChangeId} to inspect
     * @param enabled the required enabled state of the inspected
     *            {@link ChangeId} for this broadcast to be delivered
     * @see CompatChanges#isChangeEnabled
     * @see #clearRequireCompatChange()
     */
    public void setRequireCompatChange(long changeId, boolean enabled) {
        mRequireCompatChangeId = changeId;
        mRequireCompatChangeEnabled = enabled;
    }

    /**
     * Clear any previously defined requirement for this broadcast requested via
     * {@link #setRequireCompatChange(long, boolean)}.
     */
    public void clearRequireCompatChange() {
        mRequireCompatChangeId = CHANGE_INVALID;
        mRequireCompatChangeEnabled = true;
    }

    /** {@hide} */
    public long getRequireCompatChangeId() {
        return mRequireCompatChangeId;
    }

    /**
     * Test if the given app meets the {@link ChangeId} state required by this
     * broadcast, if any.
     *
     * @hide
     */
    @TestApi
    public boolean testRequireCompatChange(int uid) {
        if (mRequireCompatChangeId != CHANGE_INVALID) {
            return CompatChanges.isChangeEnabled(mRequireCompatChangeId,
                    uid) == mRequireCompatChangeEnabled;
        } else {
            return true;
        }
    }

    /**
     * Returns the created options as a Bundle, which can be passed to
     * {@link android.content.Context#sendBroadcast(android.content.Intent)
@@ -413,6 +545,10 @@ public class BroadcastOptions extends ComponentOptions {
        if (mRequireNoneOfPermissions != null) {
            b.putStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS, mRequireNoneOfPermissions);
        }
        if (mRequireCompatChangeId != CHANGE_INVALID) {
            b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId);
            b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled);
        }
        return b.isEmpty() ? null : b;
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -632,6 +632,12 @@ public final class BroadcastQueue {
    private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
            BroadcastFilter filter, boolean ordered, int index) {
        boolean skip = false;
        if (r.options != null && !r.options.testRequireCompatChange(filter.owningUid)) {
            Slog.w(TAG, "Compat change filtered: broadcasting " + r.intent.toString()
                    + " to uid " + filter.owningUid + " due to compat change "
                    + r.options.getRequireCompatChangeId());
            skip = true;
        }
        if (!mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid,
                filter.packageName, filter.owningUid)) {
            Slog.w(TAG, "Association not allowed: broadcasting "
@@ -1407,6 +1413,13 @@ public final class BroadcastQueue {
                    + "] broadcasting " + broadcastDescription(r, component));
            skip = true;
        }
        if (brOptions != null &&
                !brOptions.testRequireCompatChange(info.activityInfo.applicationInfo.uid)) {
            Slog.w(TAG, "Compat change filtered: broadcasting " + broadcastDescription(r, component)
                    + " to uid " + info.activityInfo.applicationInfo.uid + " due to compat change "
                    + r.options.getRequireCompatChangeId());
            skip = true;
        }
        if (!skip && !mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid,
                component.getPackageName(), info.activityInfo.applicationInfo.uid)) {
            Slog.w(TAG, "Association not allowed: broadcasting "