Merge "Support for a Context to "renounce" permissions." into sc-dev

This commit is contained in:
Jeff Sharkey
2021-03-07 19:05:26 +00:00
committed by Android (Google) Code Review
7 changed files with 154 additions and 35 deletions

View File

@@ -10387,6 +10387,7 @@ package android.content {
method public abstract android.content.pm.PackageManager getPackageManager(); method public abstract android.content.pm.PackageManager getPackageManager();
method public abstract String getPackageName(); method public abstract String getPackageName();
method public abstract String getPackageResourcePath(); method public abstract String getPackageResourcePath();
method @Nullable public android.content.ContextParams getParams();
method public abstract android.content.res.Resources getResources(); method public abstract android.content.res.Resources getResources();
method public abstract android.content.SharedPreferences getSharedPreferences(String, int); method public abstract android.content.SharedPreferences getSharedPreferences(String, int);
method @NonNull public final String getString(@StringRes int); method @NonNull public final String getString(@StringRes int);

View File

@@ -228,6 +228,7 @@ package android {
field public static final String REMOTE_DISPLAY_PROVIDER = "android.permission.REMOTE_DISPLAY_PROVIDER"; field public static final String REMOTE_DISPLAY_PROVIDER = "android.permission.REMOTE_DISPLAY_PROVIDER";
field public static final String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES"; field public static final String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES";
field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
field public static final String RENOUNCE_PERMISSIONS = "android.permission.RENOUNCE_PERMISSIONS";
field public static final String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES"; field public static final String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES";
field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE";
field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD";
@@ -2184,6 +2185,14 @@ package android.content {
field public static final String WIFI_SCANNING_SERVICE = "wifiscanner"; field public static final String WIFI_SCANNING_SERVICE = "wifiscanner";
} }
public final class ContextParams {
method @Nullable @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public java.util.Set<java.lang.String> getRenouncedPermissions();
}
public static final class ContextParams.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.ContextParams.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
}
public class ContextWrapper extends android.content.Context { public class ContextWrapper extends android.content.Context {
method public android.content.Context createCredentialProtectedStorageContext(); method public android.content.Context createCredentialProtectedStorageContext();
method @Nullable public java.io.File getPreloadsFileCache(); method @Nullable public java.io.File getPreloadsFileCache();

View File

@@ -24,7 +24,6 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContextParams;
import android.content.AutofillOptions; import android.content.AutofillOptions;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
@@ -32,6 +31,7 @@ import android.content.ContentCaptureOptions;
import android.content.ContentProvider; import android.content.ContentProvider;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.ContextParams;
import android.content.ContextWrapper; import android.content.ContextWrapper;
import android.content.IContentProvider; import android.content.IContentProvider;
import android.content.IIntentReceiver; import android.content.IIntentReceiver;
@@ -221,8 +221,7 @@ class ContextImpl extends Context {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final String mOpPackageName; private final String mOpPackageName;
/** Attribution tag of this context */ private final @NonNull ContextParams mParams;
private final @Nullable String mAttributionTag;
private final @NonNull ResourcesManager mResourcesManager; private final @NonNull ResourcesManager mResourcesManager;
@UnsupportedAppUsage @UnsupportedAppUsage
@@ -470,7 +469,12 @@ class ContextImpl extends Context {
/** @hide */ /** @hide */
@Override @Override
public @Nullable String getAttributionTag() { public @Nullable String getAttributionTag() {
return mAttributionTag; return mParams.getAttributionTag();
}
@Override
public @Nullable ContextParams getParams() {
return mParams;
} }
@Override @Override
@@ -2047,6 +2051,11 @@ class ContextImpl extends Context {
if (permission == null) { if (permission == null) {
throw new IllegalArgumentException("permission is null"); throw new IllegalArgumentException("permission is null");
} }
if (mParams.isRenouncedPermission(permission)
&& pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
Log.v(TAG, "Treating renounced permission " + permission + " as denied");
return PERMISSION_DENIED;
}
return PermissionManager.checkPermission(permission, pid, uid); return PermissionManager.checkPermission(permission, pid, uid);
} }
@@ -2056,6 +2065,11 @@ class ContextImpl extends Context {
if (permission == null) { if (permission == null) {
throw new IllegalArgumentException("permission is null"); throw new IllegalArgumentException("permission is null");
} }
if (mParams.isRenouncedPermission(permission)
&& pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
Log.v(TAG, "Treating renounced permission " + permission + " as denied");
return PERMISSION_DENIED;
}
try { try {
return ActivityManager.getService().checkPermissionWithToken( return ActivityManager.getService().checkPermissionWithToken(
@@ -2093,6 +2107,10 @@ class ContextImpl extends Context {
if (permission == null) { if (permission == null) {
throw new IllegalArgumentException("permission is null"); throw new IllegalArgumentException("permission is null");
} }
if (mParams.isRenouncedPermission(permission)) {
Log.v(TAG, "Treating renounced permission " + permission + " as denied");
return PERMISSION_DENIED;
}
return checkPermission(permission, Process.myPid(), Process.myUid()); return checkPermission(permission, Process.myPid(), Process.myUid());
} }
@@ -2393,8 +2411,9 @@ class ContextImpl extends Context {
LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(), LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE); flags | CONTEXT_REGISTER_PACKAGE);
if (pi != null) { if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, null, null, mToken, ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY, null,
new UserHandle(UserHandle.getUserId(application.uid)), flags, null, null); mToken, new UserHandle(UserHandle.getUserId(application.uid)),
flags, null, null);
final int displayId = getDisplayId(); final int displayId = getDisplayId();
final Integer overrideDisplayId = mForceDisplayOverrideInResources final Integer overrideDisplayId = mForceDisplayOverrideInResources
@@ -2423,14 +2442,14 @@ class ContextImpl extends Context {
if (packageName.equals("system") || packageName.equals("android")) { if (packageName.equals("system") || packageName.equals("android")) {
// The system resources are loaded in every application, so we can safely copy // The system resources are loaded in every application, so we can safely copy
// the context without reloading Resources. // the context without reloading Resources.
return new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, null, return new ContextImpl(this, mMainThread, mPackageInfo, mParams, null,
mToken, user, flags, null, null); mToken, user, flags, null, null);
} }
LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
if (pi != null) { if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, mAttributionTag, null, ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams, null,
mToken, user, flags, null, null); mToken, user, flags, null, null);
final int displayId = getDisplayId(); final int displayId = getDisplayId();
@@ -2469,7 +2488,7 @@ class ContextImpl extends Context {
final String[] paths = mPackageInfo.getSplitPaths(splitName); final String[] paths = mPackageInfo.getSplitPaths(splitName);
final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo,
mAttributionTag, splitName, mToken, mUser, mFlags, classLoader, null); mParams, splitName, mToken, mUser, mFlags, classLoader, null);
context.setResources(ResourcesManager.getInstance().getResources( context.setResources(ResourcesManager.getInstance().getResources(
mToken, mToken,
@@ -2502,7 +2521,7 @@ class ContextImpl extends Context {
overrideConfiguration = displayAdjustedConfig; overrideConfiguration = displayAdjustedConfig;
} }
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
mSplitName, mToken, mUser, mFlags, mClassLoader, null); mSplitName, mToken, mUser, mFlags, mClassLoader, null);
final int displayId = getDisplayId(); final int displayId = getDisplayId();
@@ -2520,7 +2539,7 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("display must not be null"); throw new IllegalArgumentException("display must not be null");
} }
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
mSplitName, mToken, mUser, mFlags, mClassLoader, null); mSplitName, mToken, mUser, mFlags, mClassLoader, null);
final int displayId = display.getDisplayId(); final int displayId = display.getDisplayId();
@@ -2578,7 +2597,7 @@ class ContextImpl extends Context {
ContextImpl createBaseWindowContext(IBinder token, Display display) { ContextImpl createBaseWindowContext(IBinder token, Display display) {
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
mSplitName, token, mUser, mFlags, mClassLoader, null); mSplitName, token, mUser, mFlags, mClassLoader, null);
// Window contexts receive configurations directly from the server and as such do not // Window contexts receive configurations directly from the server and as such do not
// need to override their display in ResourcesManager. // need to override their display in ResourcesManager.
@@ -2609,21 +2628,21 @@ class ContextImpl extends Context {
@NonNull @NonNull
@Override @Override
public Context createContext(@NonNull ContextParams contextParams) { public Context createContext(@NonNull ContextParams params) {
return this; return new ContextImpl(this, mMainThread, mPackageInfo, params, mSplitName,
mToken, mUser, mFlags, mClassLoader, null);
} }
@Override @Override
public @NonNull Context createAttributionContext(@Nullable String attributionTag) { public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
return new ContextImpl(this, mMainThread, mPackageInfo, attributionTag, mSplitName, return createContext(new ContextParams.Builder().setAttributionTag(attributionTag).build());
mToken, mUser, mFlags, mClassLoader, null);
} }
@Override @Override
public Context createDeviceProtectedStorageContext() { public Context createDeviceProtectedStorageContext() {
final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE; | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, mSplitName, return new ContextImpl(this, mMainThread, mPackageInfo, mParams, mSplitName,
mToken, mUser, flags, mClassLoader, null); mToken, mUser, flags, mClassLoader, null);
} }
@@ -2631,7 +2650,7 @@ class ContextImpl extends Context {
public Context createCredentialProtectedStorageContext() { public Context createCredentialProtectedStorageContext() {
final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE) final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
| Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, mSplitName, return new ContextImpl(this, mMainThread, mPackageInfo, mParams, mSplitName,
mToken, mUser, flags, mClassLoader, null); mToken, mUser, flags, mClassLoader, null);
} }
@@ -2805,8 +2824,8 @@ class ContextImpl extends Context {
@UnsupportedAppUsage @UnsupportedAppUsage
static ContextImpl createSystemContext(ActivityThread mainThread) { static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread); LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null, ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
0, null, null); ContextParams.EMPTY, null, null, null, 0, null, null);
context.setResources(packageInfo.getResources()); context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics()); context.mResourcesManager.getDisplayMetrics());
@@ -2823,8 +2842,8 @@ class ContextImpl extends Context {
*/ */
static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) { static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
final LoadedApk packageInfo = systemContext.mPackageInfo; final LoadedApk packageInfo = systemContext.mPackageInfo;
ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null, ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo,
null, null, null, 0, null, null); ContextParams.EMPTY, null, null, null, 0, null, null);
context.setResources(createResources(null, packageInfo, null, displayId, null, context.setResources(createResources(null, packageInfo, null, displayId, null,
packageInfo.getCompatibilityInfo(), null)); packageInfo.getCompatibilityInfo(), null));
context.updateDisplay(displayId); context.updateDisplay(displayId);
@@ -2848,8 +2867,8 @@ class ContextImpl extends Context {
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo, static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) { String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null, ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
0, null, opPackageName); ContextParams.EMPTY, null, null, null, 0, null, opPackageName);
context.setResources(packageInfo.getResources()); context.setResources(packageInfo.getResources());
context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
: CONTEXT_TYPE_NON_UI; : CONTEXT_TYPE_NON_UI;
@@ -2878,7 +2897,7 @@ class ContextImpl extends Context {
} }
} }
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY,
activityInfo.splitName, activityToken, null, 0, classLoader, null); activityInfo.splitName, activityToken, null, 0, classLoader, null);
context.mContextType = CONTEXT_TYPE_ACTIVITY; context.mContextType = CONTEXT_TYPE_ACTIVITY;
@@ -2911,7 +2930,7 @@ class ContextImpl extends Context {
} }
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread, private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String attributionTag, @NonNull LoadedApk packageInfo, @NonNull ContextParams params,
@Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user, @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user,
int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) { int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
mOuterContext = this; mOuterContext = this;
@@ -2966,7 +2985,7 @@ class ContextImpl extends Context {
} }
mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName; mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
mAttributionTag = attributionTag; mParams = Objects.requireNonNull(params);
mContentResolver = new ApplicationContentResolver(this, mainThread); mContentResolver = new ApplicationContentResolver(this, mainThread);
} }

View File

@@ -888,6 +888,14 @@ public abstract class Context {
return getAttributionTag(); return getAttributionTag();
} }
/**
* Return the set of parameters which this Context was created with, if it
* was created via {@link #createContext(ContextParams)}.
*/
public @Nullable ContextParams getParams() {
return null;
}
/** Return the full application info for this context's package. */ /** Return the full application info for this context's package. */
public abstract ApplicationInfo getApplicationInfo(); public abstract ApplicationInfo getApplicationInfo();

View File

@@ -18,6 +18,13 @@ package android.content;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
/** /**
* This class represents rules around how a context being created via * This class represents rules around how a context being created via
@@ -48,9 +55,19 @@ import android.annotation.Nullable;
* @see Context#createContext(ContextParams) * @see Context#createContext(ContextParams)
*/ */
public final class ContextParams { public final class ContextParams {
private final String mAttributionTag;
private final String mReceiverPackage;
private final String mReceiverAttributionTag;
private final Set<String> mRenouncedPermissions;
private ContextParams() { /** {@hide} */
/* hide ctor */ public static final ContextParams EMPTY = new ContextParams.Builder().build();
private ContextParams(@NonNull ContextParams.Builder builder) {
mAttributionTag = builder.mAttributionTag;
mReceiverPackage = builder.mReceiverPackage;
mReceiverAttributionTag = builder.mReceiverAttributionTag;
mRenouncedPermissions = builder.mRenouncedPermissions;
} }
/** /**
@@ -58,7 +75,7 @@ public final class ContextParams {
*/ */
@Nullable @Nullable
public String getAttributionTag() { public String getAttributionTag() {
return null; return mAttributionTag;
} }
/** /**
@@ -66,7 +83,7 @@ public final class ContextParams {
*/ */
@Nullable @Nullable
public String getReceiverPackage() { public String getReceiverPackage() {
return null; return mReceiverPackage;
} }
/** /**
@@ -74,13 +91,33 @@ public final class ContextParams {
*/ */
@Nullable @Nullable
public String getReceiverAttributionTag() { public String getReceiverAttributionTag() {
return null; return mReceiverAttributionTag;
}
/**
* @return The set of permissions to treat as renounced.
* @hide
*/
@SystemApi
@SuppressLint("NullableCollection")
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
public @Nullable Set<String> getRenouncedPermissions() {
return mRenouncedPermissions;
}
/** @hide */
public boolean isRenouncedPermission(@NonNull String permission) {
return mRenouncedPermissions != null && mRenouncedPermissions.contains(permission);
} }
/** /**
* Builder for creating a {@link ContextParams}. * Builder for creating a {@link ContextParams}.
*/ */
public static final class Builder { public static final class Builder {
private String mAttributionTag;
private String mReceiverPackage;
private String mReceiverAttributionTag;
private Set<String> mRenouncedPermissions;
/** /**
* Sets an attribution tag against which to track permission accesses. * Sets an attribution tag against which to track permission accesses.
@@ -90,6 +127,7 @@ public final class ContextParams {
*/ */
@NonNull @NonNull
public Builder setAttributionTag(@NonNull String attributionTag) { public Builder setAttributionTag(@NonNull String attributionTag) {
mAttributionTag = Objects.requireNonNull(attributionTag);
return this; return this;
} }
@@ -104,18 +142,46 @@ public final class ContextParams {
@NonNull @NonNull
public Builder setReceiverPackage(@NonNull String packageName, public Builder setReceiverPackage(@NonNull String packageName,
@Nullable String attributionTag) { @Nullable String attributionTag) {
mReceiverPackage = Objects.requireNonNull(packageName);
mReceiverAttributionTag = attributionTag;
return this; return this;
} }
/** /**
* Creates a new instance. You need to either specify an attribution tag * Sets permissions which have been voluntarily "renounced" by the
* or a receiver package or both. * calling app.
* <p>
* Interactions performed through the created Context will ideally be
* treated as if these "renounced" permissions have not actually been
* granted to the app, regardless of their actual grant status.
* <p>
* This is designed for use by separate logical components within an app
* which have no intention of interacting with data or services that are
* protected by the renounced permissions.
* <p>
* Note that only {@link PermissionInfo#PROTECTION_DANGEROUS}
* permissions are supported by this mechanism.
*
* @param renouncedPermissions The set of permissions to treat as
* renounced.
* @return This builder.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
public @NonNull Builder setRenouncedPermissions(@NonNull Set<String> renouncedPermissions) {
mRenouncedPermissions = Collections.unmodifiableSet(renouncedPermissions);
return this;
}
/**
* Creates a new instance.
* *
* @return The new instance. * @return The new instance.
*/ */
@NonNull @NonNull
public ContextParams build() { public ContextParams build() {
return new ContextParams(); return new ContextParams(this);
} }
} }
} }

View File

@@ -171,6 +171,11 @@ public class ContextWrapper extends Context {
return mBase.getAttributionTag(); return mBase.getAttributionTag();
} }
@Override
public @Nullable ContextParams getParams() {
return mBase.getParams();
}
@Override @Override
public ApplicationInfo getApplicationInfo() { public ApplicationInfo getApplicationInfo() {
return mBase.getApplicationInfo(); return mBase.getApplicationInfo();
@@ -1044,6 +1049,12 @@ public class ContextWrapper extends Context {
return mBase.createWindowContext(display, type, options); return mBase.createWindowContext(display, type, options);
} }
@Override
@NonNull
public Context createContext(@NonNull ContextParams contextParams) {
return mBase.createContext(contextParams);
}
@Override @Override
public @NonNull Context createAttributionContext(@Nullable String attributionTag) { public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
return mBase.createAttributionContext(attributionTag); return mBase.createAttributionContext(attributionTag);

View File

@@ -5561,6 +5561,11 @@
<permission android:name="android.permission.READ_PEOPLE_DATA" <permission android:name="android.permission.READ_PEOPLE_DATA"
android:protectionLevel="signature|appPredictor|recents"/> android:protectionLevel="signature|appPredictor|recents"/>
<!-- @hide @SystemApi Allows a logical component within an application to
temporarily renounce a set of otherwise granted permissions. -->
<permission android:name="android.permission.RENOUNCE_PERMISSIONS"
android:protectionLevel="signature|privileged" />
<!-- Attribution for Geofencing service. --> <!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/> <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. --> <!-- Attribution for Country Detector. -->