243 lines
8.9 KiB
Java
243 lines
8.9 KiB
Java
/*
|
|
* Copyright (C) 2021 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 android.content;
|
|
|
|
import static android.permission.flags.Flags.FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.FlaggedApi;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.RequiresPermission;
|
|
import android.annotation.SystemApi;
|
|
import android.app.ActivityThread;
|
|
import android.content.pm.PackageManager;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* This class represents rules around how a context being created via
|
|
* {@link Context#createContext} should behave.
|
|
*
|
|
* <p>One of the dimensions to customize is how permissions should behave.
|
|
* For example, you can specify how permission accesses from a context should
|
|
* be attributed in the platform's permission tracking system.
|
|
*
|
|
* <p>The two main types of attribution are: against an attribution tag which
|
|
* is an arbitrary string your app specifies for the purposes of tracking permission
|
|
* accesses from a given portion of your app; against another package and optionally
|
|
* its attribution tag if you are accessing the data on behalf of another app and
|
|
* you will be passing that data to this app, recursively. Both attributions are
|
|
* not mutually exclusive.
|
|
*
|
|
* @see Context#createContext(ContextParams)
|
|
* @see AttributionSource
|
|
*/
|
|
public final class ContextParams {
|
|
private final @Nullable String mAttributionTag;
|
|
private final @Nullable AttributionSource mNext;
|
|
private final @NonNull Set<String> mRenouncedPermissions;
|
|
private final boolean mShouldRegisterAttributionSource;
|
|
|
|
/** {@hide} */
|
|
public static final ContextParams EMPTY = new ContextParams.Builder().build();
|
|
|
|
private ContextParams(@Nullable String attributionTag,
|
|
@Nullable AttributionSource next,
|
|
@Nullable Set<String> renouncedPermissions,
|
|
boolean shouldRegister) {
|
|
mAttributionTag = attributionTag;
|
|
mNext = next;
|
|
mRenouncedPermissions = (renouncedPermissions != null)
|
|
? renouncedPermissions : Collections.emptySet();
|
|
mShouldRegisterAttributionSource = shouldRegister;
|
|
}
|
|
|
|
/**
|
|
* @return The attribution tag.
|
|
*/
|
|
@Nullable
|
|
public String getAttributionTag() {
|
|
return mAttributionTag;
|
|
}
|
|
|
|
/**
|
|
* @return The set of permissions to treat as renounced.
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
|
|
public @NonNull Set<String> getRenouncedPermissions() {
|
|
return mRenouncedPermissions;
|
|
}
|
|
|
|
/** @hide */
|
|
public boolean isRenouncedPermission(@NonNull String permission) {
|
|
return mRenouncedPermissions.contains(permission);
|
|
}
|
|
|
|
/**
|
|
* @return The receiving attribution source.
|
|
*/
|
|
@Nullable
|
|
public AttributionSource getNextAttributionSource() {
|
|
return mNext;
|
|
}
|
|
|
|
/**
|
|
* @return Whether the attribution source associated with the Context being created should be
|
|
* registered.
|
|
*/
|
|
@NonNull
|
|
@FlaggedApi(FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE)
|
|
public boolean shouldRegisterAttributionSource() {
|
|
return mShouldRegisterAttributionSource;
|
|
}
|
|
|
|
/**
|
|
* Builder for creating a {@link ContextParams}.
|
|
*/
|
|
public static final class Builder {
|
|
private @Nullable String mAttributionTag;
|
|
private @NonNull Set<String> mRenouncedPermissions = Collections.emptySet();
|
|
private @Nullable AttributionSource mNext;
|
|
private boolean mShouldRegisterAttributionSource;
|
|
|
|
/**
|
|
* Create a new builder.
|
|
* <p>
|
|
* This is valuable when you are interested in having explicit control
|
|
* over every sub-parameter, and don't want to inherit any values from
|
|
* an existing Context.
|
|
* <p>
|
|
* Developers should strongly consider using
|
|
* {@link #Builder(ContextParams)} instead of this constructor, since
|
|
* that will will automatically inherit any new sub-parameters added in
|
|
* future platform releases.
|
|
*/
|
|
public Builder() {
|
|
}
|
|
|
|
/**
|
|
* Create a new builder that inherits all sub-parameters by default.
|
|
* <p>
|
|
* This is valuable when you are only interested in overriding specific
|
|
* sub-parameters, and want to preserve all other parameters. Setting a
|
|
* specific sub-parameter on the returned builder will override any
|
|
* inherited value.
|
|
*/
|
|
public Builder(@NonNull ContextParams params) {
|
|
Objects.requireNonNull(params);
|
|
mAttributionTag = params.mAttributionTag;
|
|
mRenouncedPermissions = params.mRenouncedPermissions;
|
|
mNext = params.mNext;
|
|
}
|
|
|
|
/**
|
|
* Sets an attribution tag against which to track permission accesses.
|
|
*
|
|
* @param attributionTag The attribution tag.
|
|
* @return This builder.
|
|
*/
|
|
@NonNull
|
|
public Builder setAttributionTag(@Nullable String attributionTag) {
|
|
mAttributionTag = attributionTag;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the attribution source for the app on whose behalf you are doing the work.
|
|
*
|
|
* @param next The permission identity of the receiving app.
|
|
* @return This builder.
|
|
*
|
|
* @see AttributionSource
|
|
*/
|
|
@NonNull
|
|
public Builder setNextAttributionSource(@Nullable AttributionSource next) {
|
|
mNext = next;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the attribution source associated with the context created from these params
|
|
* should be registered.
|
|
*
|
|
* @param shouldRegister Whether the attribution source associated with the Context being
|
|
* created should be registered.
|
|
*/
|
|
@NonNull
|
|
@FlaggedApi(FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE)
|
|
public Builder setShouldRegisterAttributionSource(boolean shouldRegister) {
|
|
mShouldRegisterAttributionSource = shouldRegister;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets permissions which have been voluntarily "renounced" by the
|
|
* calling app.
|
|
* <p>
|
|
* Interactions performed through services obtained from 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. Additionally, this
|
|
* mechanism only applies to calls made through services obtained via
|
|
* {@link Context#getSystemService}; it has no effect on static or raw
|
|
* Binder calls.
|
|
*
|
|
* @param renouncedPermissions The set of permissions to treat as
|
|
* renounced, which is as if not granted.
|
|
* @return This builder.
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
|
|
public @NonNull Builder setRenouncedPermissions(
|
|
@Nullable Set<String> renouncedPermissions) {
|
|
// This is not a security check but a fail fast - the OS enforces the permission too
|
|
if (renouncedPermissions != null && !renouncedPermissions.isEmpty()
|
|
&& ActivityThread.currentApplication().checkSelfPermission(Manifest.permission
|
|
.RENOUNCE_PERMISSIONS) != PackageManager.PERMISSION_GRANTED) {
|
|
throw new SecurityException("Renouncing permissions requires: "
|
|
+ Manifest.permission.RENOUNCE_PERMISSIONS);
|
|
}
|
|
mRenouncedPermissions = renouncedPermissions;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance.
|
|
*
|
|
* @return The new instance.
|
|
*/
|
|
@NonNull
|
|
public ContextParams build() {
|
|
return new ContextParams(mAttributionTag, mNext,
|
|
mRenouncedPermissions, mShouldRegisterAttributionSource);
|
|
}
|
|
}
|
|
}
|