script-astra/Android/Sdk/sources/android-35/android/app/ComponentCaller.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

179 lines
7.9 KiB
Java

/*
* Copyright (C) 2024 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.app;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.Process;
import java.util.Objects;
/**
* Represents the app that launched the component. See below for the APIs available on the component
* caller.
*
* <p><b>Note</b>, that in {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} only
* {@link Activity} has access to {@link ComponentCaller} instances.
*
* @see Activity#getInitialCaller()
*/
@FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
public final class ComponentCaller {
private final IBinder mActivityToken;
private final IBinder mCallerToken;
/**
* @hide
*/
public ComponentCaller(@Nullable IBinder activityToken, @Nullable IBinder callerToken) {
mActivityToken = activityToken;
mCallerToken = callerToken;
}
/**
* Returns the uid of this component caller.
*
* <p><b>Note</b>, in {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} only
* {@link Activity} has access to {@link ComponentCaller} instances.
* <p>
* <h3>Requirements for {@link Activity} callers</h3>
*
* <p>In order to receive the calling app's uid, at least one of the following has to be met:
* <ul>
* <li>The calling app must call {@link ActivityOptions#setShareIdentityEnabled(boolean)}
* with a value of {@code true} and launch this activity with the resulting
* {@code ActivityOptions}.
* <li>The launched activity has the same uid as the calling app.
* <li>The launched activity is running in a package that is signed with the same key used
* to sign the platform (typically only system packages such as Settings will meet this
* requirement).
* </ul>
* These are the same requirements for {@link #getPackage()}; if any of these are met, then
* these methods can be used to obtain the uid and package name of the calling app. If none are
* met, then {@link Process#INVALID_UID} is returned.
*
* <p>Note, even if the above conditions are not met, the calling app's identity may still be
* available from {@link Activity#getCallingPackage()} if this activity was started with
* {@code Activity#startActivityForResult} to allow validation of the result's recipient.
*
* @return the uid of the calling app or {@link Process#INVALID_UID} if the current component
* cannot access the identity of the calling app or the caller is invalid
*
* @see ActivityOptions#setShareIdentityEnabled(boolean)
* @see Activity#getLaunchedFromUid()
*/
public int getUid() {
return ActivityClient.getInstance().getActivityCallerUid(mActivityToken, mCallerToken);
}
/**
* Returns the package name of this component caller.
*
* <p><b>Note</b>, in {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} only
* {@link Activity} has access to {@link ComponentCaller} instances.
* <p>
* <h3>Requirements for {@link Activity} callers</h3>
*
* <p>In order to receive the calling app's package name, at least one of the following has to
* be met:
* <ul>
* <li>The calling app must call {@link ActivityOptions#setShareIdentityEnabled(boolean)}
* with a value of {@code true} and launch this activity with the resulting
* {@code ActivityOptions}.
* <li>The launched activity has the same uid as the calling app.
* <li>The launched activity is running in a package that is signed with the same key used
* to sign the platform (typically only system packages such as Settings will meet this
* meet this requirement).
* </ul>
* These are the same requirements for {@link #getUid()}; if any of these are met, then these
* methods can be used to obtain the uid and package name of the calling app. If none are met,
* then {@code null} is returned.
*
* <p>Note, even if the above conditions are not met, the calling app's identity may still be
* available from {@link Activity#getCallingPackage()} if this activity was started with
* {@code Activity#startActivityForResult} to allow validation of the result's recipient.
*
* @return the package name of the calling app or null if the current component cannot access
* the identity of the calling app or the caller is invalid
*
* @see ActivityOptions#setShareIdentityEnabled(boolean)
* @see Activity#getLaunchedFromPackage()
*/
@Nullable
public String getPackage() {
return ActivityClient.getInstance().getActivityCallerPackage(mActivityToken, mCallerToken);
}
/**
* Determines whether this component caller had access to a specific content URI at launch time.
* Apps can use this API to validate content URIs coming from other apps.
*
* <p><b>Note</b>, in {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} only
* {@link Activity} has access to {@link ComponentCaller} instances.
*
* <p>Before using this method, note the following:
* <ul>
* <li>You must have access to the supplied URI, otherwise it will throw a
* {@link SecurityException}.
* <li>This is not a real time check, i.e. the permissions have been computed at launch
* time.
* <li>This method will return the correct result for content URIs passed at launch time,
* specifically the ones from {@link Intent#getData()}, {@link Intent#EXTRA_STREAM}, and
* {@link Intent#getClipData()} in the intent of {@code startActivity(intent)}. For others,
* it will throw an {@link IllegalArgumentException}.
* </ul>
*
* @param uri The content uri that is being checked
* @param modeFlags The access modes to check
* @return {@link PackageManager#PERMISSION_GRANTED} if this activity caller is allowed to
* access that uri, or {@link PackageManager#PERMISSION_DENIED} if it is not
* @throws IllegalArgumentException if uri is a non-content URI or it wasn't passed at launch in
* {@link Intent#getData()}, {@link Intent#EXTRA_STREAM}, and
* {@link Intent#getClipData()}
* @throws SecurityException if you don't have access to uri
*
* @see android.content.Context#checkContentUriPermissionFull(Uri, int, int, int)
*/
@PackageManager.PermissionResult
public int checkContentUriPermission(@NonNull Uri uri, @Intent.AccessUriMode int modeFlags) {
return ActivityClient.getInstance().checkActivityCallerContentUriPermission(mActivityToken,
mCallerToken, uri, modeFlags);
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj instanceof ComponentCaller other)) {
return false;
}
return this.mActivityToken == other.mActivityToken
&& this.mCallerToken == other.mCallerToken;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + Objects.hashCode(mActivityToken);
result = 31 * result + Objects.hashCode(mCallerToken);
return result;
}
}