Merge "Add testAPI to get adopted shell permissions." into sc-dev

This commit is contained in:
Kholoud Mohamed
2021-04-06 16:50:05 +00:00
committed by Android (Google) Code Review
8 changed files with 104 additions and 0 deletions

View File

@@ -355,11 +355,13 @@ package android.app {
public final class UiAutomation {
method public void destroy();
method @NonNull public android.os.ParcelFileDescriptor[] executeShellCommandRwe(@NonNull String);
method @NonNull public java.util.Set<java.lang.String> getAdoptedShellPermissions();
method @Deprecated public boolean grantRuntimePermission(String, String, android.os.UserHandle);
method public boolean injectInputEvent(@NonNull android.view.InputEvent, boolean, boolean);
method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
method public void syncInputTransactions();
method public void syncInputTransactions(boolean);
field @NonNull public static final java.util.Set<java.lang.String> ALL_PERMISSIONS;
}
public class UiModeManager {

View File

@@ -571,6 +571,12 @@ interface IActivityManager {
*/
void stopDelegateShellPermissionIdentity();
/**
* Method for the shell UID to get currently adopted permissions for an active instrumentation.
* An active instrumentation is one running and started from the shell.
*/
List<String> getDelegatedShellPermissions();
/** Returns a file descriptor that'll be closed when the system server process dies. */
ParcelFileDescriptor getLifeMonitor();

View File

@@ -24,6 +24,8 @@ import android.view.WindowContentFrameStats;
import android.view.WindowAnimationFrameStats;
import android.os.ParcelFileDescriptor;
import java.util.List;
/**
* This interface contains privileged operations a shell program can perform
* on behalf of an instrumentation that it runs. These operations require
@@ -54,4 +56,5 @@ interface IUiAutomationConnection {
oneway void shutdown();
void executeShellCommandWithStderr(String command, in ParcelFileDescriptor sink,
in ParcelFileDescriptor source, in ParcelFileDescriptor stderrSink);
List<String> getAdoptedShellPermissions();
}

View File

@@ -43,6 +43,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
@@ -66,7 +67,9 @@ import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;
/**
@@ -160,6 +163,16 @@ public final class UiAutomation {
*/
public static final int FLAG_DONT_USE_ACCESSIBILITY = 0x00000002;
/**
* Returned by {@link #getAdoptedShellPermissions} to indicate that all permissions have been
* adopted using {@link #adoptShellPermissionIdentity}.
*
* @hide
*/
@TestApi
@NonNull
public static final Set<String> ALL_PERMISSIONS = Set.of("_ALL_PERMISSIONS_");
private final Object mLock = new Object();
private final ArrayList<AccessibilityEvent> mEventQueue = new ArrayList<AccessibilityEvent>();
@@ -498,6 +511,25 @@ public final class UiAutomation {
}
}
/**
* Returns a list of adopted shell permissions using {@link #adoptShellPermissionIdentity},
* returns and empty set if no permissions are adopted and {@link #ALL_PERMISSIONS} if all
* permissions are adopted.
*
* @hide
*/
@TestApi
@NonNull
public Set<String> getAdoptedShellPermissions() {
try {
final List<String> permissions = mUiAutomationConnection.getAdoptedShellPermissions();
return permissions == null ? ALL_PERMISSIONS : new ArraySet<>(permissions);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error getting adopted shell permissions", re);
return Collections.emptySet();
}
}
/**
* Performs a global action. Such an action can be performed at any moment
* regardless of the current application or user location in that application.

View File

@@ -49,6 +49,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
/**
* This is a remote object that is passed from the shell to an instrumentation
@@ -340,6 +341,22 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
}
}
@Override
@Nullable
public List<String> getAdoptedShellPermissions() throws RemoteException {
synchronized (mLock) {
throwIfCalledByNotTrustedUidLocked();
throwIfShutdownLocked();
throwIfNotConnectedLocked();
}
final long identity = Binder.clearCallingIdentity();
try {
return mActivityManager.getDelegatedShellPermissions();
} finally {
Binder.restoreCallingIdentity(identity);
}
}
public class Repeater implements Runnable {
// Continuously read readFrom and write back to writeTo until EOF is encountered
private final InputStream readFrom;

View File

@@ -16548,6 +16548,17 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
@Override
public List<String> getDelegatedShellPermissions() {
if (UserHandle.getCallingAppId() != Process.SHELL_UID
&& UserHandle.getCallingAppId() != Process.ROOT_UID) {
throw new SecurityException("Only the shell can get delegated permissions");
}
synchronized (mProcLock) {
return getPermissionManagerInternal().getDelegatedShellPermissions();
}
}
private class ShellDelegate implements CheckOpsDelegate {
private final int mTargetUid;
@Nullable

View File

@@ -2085,6 +2085,16 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
@Nullable
private List<String> getDelegatedShellPermissionsInternal() {
synchronized (mLock) {
if (mCheckPermissionDelegate == null) {
return Collections.EMPTY_LIST;
}
return mCheckPermissionDelegate.getDelegatedPermissionNames();
}
}
private void setCheckPermissionDelegateLocked(@Nullable CheckPermissionDelegate delegate) {
if (delegate != null || mCheckPermissionDelegate != null) {
PackageManager.invalidatePackageInfoCache();
@@ -5041,6 +5051,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
stopShellPermissionIdentityDelegationInternal();
}
@Override
@NonNull
public List<String> getDelegatedShellPermissions() {
return getDelegatedShellPermissionsInternal();
}
@Override
public void onUserCreated(@UserIdInt int userId) {
Preconditions.checkArgumentNonNegative(userId, "userId");
@@ -5234,6 +5250,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*/
int checkUidPermission(int uid, @NonNull String permissionName,
BiFunction<Integer, String, Integer> superImpl);
/**
* @return list of delegated permissions
*/
List<String> getDelegatedPermissionNames();
}
private class ShellDelegate implements CheckPermissionDelegate {
@@ -5284,6 +5305,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return superImpl.apply(uid, permissionName);
}
@Override
public List<String> getDelegatedPermissionNames() {
return mDelegatedPermissionNames == null
? null
: new ArrayList<>(mDelegatedPermissionNames);
}
private boolean isDelegatedPermission(@NonNull String permissionName) {
// null permissions means all permissions are targeted
return mDelegatedPermissionNames == null

View File

@@ -183,6 +183,11 @@ public interface PermissionManagerServiceInternal extends PermissionManagerInter
//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
void stopShellPermissionIdentityDelegation();
/**
* Get all delegated shell permissions.
*/
@NonNull List<String> getDelegatedShellPermissions();
/**
* Read legacy permissions from legacy permission settings.
*