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

Commit 48801b0b authored by Svet Ganov's avatar Svet Ganov
Browse files

Hookup renounced permissions

Propagate renounced permissions from context params
to the context attribution source. Throw if one
tries to request at runtime a renounced permission.

Also make the AttributionSource take null for the
setters to ease usage, otherwise folks should always
check for null before calling a builder method.

Additionally, we allow apps that have UPDATE_APP_OPS_STATS
to register arbitrary trusted AttributionSource for
testing. Note that this permission allows abritrary app
op operations, thus we are not relaxing the security
model.

bug: 158792096

Test: atest CtsPermission5TestCases

Change-Id: I4330684bb8695fb998cf31e9363b94ad981ba2cc
parent 567a6884
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -9935,9 +9935,9 @@ package android.content {
  public static final class AttributionSource.Builder {
    ctor public AttributionSource.Builder(int);
    method @NonNull public android.content.AttributionSource build();
    method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@NonNull String);
    method @NonNull public android.content.AttributionSource.Builder setNext(@NonNull android.content.AttributionSource);
    method @NonNull public android.content.AttributionSource.Builder setPackageName(@NonNull String);
    method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String);
    method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
    method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String);
  }
  public abstract class BroadcastReceiver {
+1 −1
Original line number Diff line number Diff line
@@ -2235,7 +2235,7 @@ package android.content {
  }
  public static final class AttributionSource.Builder {
    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.AttributionSource.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
    method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.AttributionSource.Builder setRenouncedPermissions(@Nullable java.util.Set<java.lang.String>);
  }
  public abstract class BroadcastReceiver {
+2 −0
Original line number Diff line number Diff line
@@ -666,6 +666,7 @@ package android.content {
  public final class AttributionSource implements android.os.Parcelable {
    ctor public AttributionSource(int, @Nullable String, @Nullable String);
    ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable android.content.AttributionSource);
    ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable java.util.Set<java.lang.String>, @Nullable android.content.AttributionSource);
  }

  public final class AutofillOptions implements android.os.Parcelable {
@@ -1985,6 +1986,7 @@ package android.permission {

  public final class PermissionManager {
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
    method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource);
  }

}
+3 −18
Original line number Diff line number Diff line
@@ -5254,32 +5254,17 @@ public class Activity extends ContextThemeWrapper
            return;
        }

        List<String> filteredPermissions = null;

        if (!getAttributionSource().getRenouncedPermissions().isEmpty()) {
            final int permissionCount = permissions.length;
            for (int i = 0; i < permissionCount; i++) {
                if (getAttributionSource().getRenouncedPermissions().contains(permissions[i])) {
                    if (filteredPermissions == null) {
                        filteredPermissions = new ArrayList<>(i);
                        for (int j = 0; j < i; j++) {
                            filteredPermissions.add(permissions[i]);
                        }
                    }
                } else if (filteredPermissions != null) {
                    filteredPermissions.add(permissions[i]);
                    throw new IllegalArgumentException("Cannot request renounced permission: "
                            + permissions[i]);
                }
            }
        }

        final Intent intent;
        if (filteredPermissions == null) {
            intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        } else {
            intent = getPackageManager().buildRequestPermissionsIntent(
                    filteredPermissions.toArray(new String[0]));
        }

        final Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
        mHasCurrentPermissionsRequest = true;
    }
+7 −4
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;

class ReceiverRestrictedContext extends ContextWrapper {
@@ -3074,14 +3075,16 @@ class ContextImpl extends Context {

        mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
        mParams = Objects.requireNonNull(params);
        mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource);
        mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource,
                params.getRenouncedPermissions());
        mContentResolver = new ApplicationContentResolver(this, mainThread);
    }

    private @NonNull AttributionSource createAttributionSource(@Nullable String attributionTag,
            @Nullable AttributionSource nextAttributionSource) {
        AttributionSource attributionSource = new AttributionSource(Process.myUid(), mOpPackageName,
                attributionTag, nextAttributionSource);
            @Nullable AttributionSource nextAttributionSource,
            @Nullable Set<String> renouncedPermissions) {
        AttributionSource attributionSource = new AttributionSource(Process.myUid(),
                mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource);
        // If we want to access protected data on behalf of another app we need to
        // tell the OS that we opt in to participate in the attribution chain.
        if (nextAttributionSource != null) {
Loading