Add flag to AMS.startInstrumentation() to disable hidden API checks
Some tests need to use hidden APIs to check the internal state of
the framework. For those special use cases, we add a new flag to
ActivityManagerService.startInstrumentation that enables to start
instrumented processes without hidden API enforcement. Individual
test harnesses can change their Am command to request the exemption.
Bug: 64382372
Test: adb shell am instrument --no-hidden-api-checks <component>
adb logcat | grep 'Accessing hidden'
Merged-In: I1d734a95423fae90dae63ff09d5f606495830905
Change-Id: Ifbb0d19d95737a9f601b11e20352cdc11f0ca5b6
This commit is contained in:
@@ -167,6 +167,8 @@ public class Am extends BaseCommand {
|
||||
} else if (opt.equals("--no_window_animation")
|
||||
|| opt.equals("--no-window-animation")) {
|
||||
instrument.noWindowAnimation = true;
|
||||
} else if (opt.equals("--no-hidden-api-checks")) {
|
||||
instrument.disableHiddenApiChecks = true;
|
||||
} else if (opt.equals("--user")) {
|
||||
instrument.userId = parseUserArg(nextArgRequired());
|
||||
} else if (opt.equals("--abi")) {
|
||||
|
||||
@@ -52,12 +52,17 @@ public class Instrument {
|
||||
public boolean rawMode = false;
|
||||
public boolean proto = false;
|
||||
public boolean noWindowAnimation = false;
|
||||
public boolean disableHiddenApiChecks = false;
|
||||
public String abi = null;
|
||||
public int userId = UserHandle.USER_CURRENT;
|
||||
public Bundle args = new Bundle();
|
||||
// Required
|
||||
public String componentNameArg;
|
||||
|
||||
// Disable hidden API checks for the newly started instrumentation.
|
||||
// Must be kept in sync with ActivityManagerService.
|
||||
private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
|
||||
|
||||
/**
|
||||
* Construct the instrument command runner.
|
||||
*/
|
||||
@@ -416,7 +421,8 @@ public class Instrument {
|
||||
}
|
||||
|
||||
// Start the instrumentation
|
||||
if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
|
||||
int flags = disableHiddenApiChecks ? INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS : 0;
|
||||
if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId,
|
||||
abi)) {
|
||||
throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
|
||||
}
|
||||
|
||||
@@ -533,6 +533,10 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
// How long we wait until we timeout on key dispatching during instrumentation.
|
||||
static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
|
||||
|
||||
// Disable hidden API checks for the newly started instrumentation.
|
||||
// Must be kept in sync with Am.
|
||||
private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
|
||||
|
||||
// How long to wait in getAssistContextExtras for the activity and foreground services
|
||||
// to respond with the result.
|
||||
static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
|
||||
@@ -3813,6 +3817,13 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
|
||||
private final void startProcessLocked(ProcessRecord app, String hostingType,
|
||||
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
|
||||
startProcessLocked(app, hostingType, hostingNameStr, false /* disableHiddenApiChecks */,
|
||||
null /* abiOverride */, null /* entryPoint */, null /* entryPointArgs */);
|
||||
}
|
||||
|
||||
private final void startProcessLocked(ProcessRecord app, String hostingType,
|
||||
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride,
|
||||
String entryPoint, String[] entryPointArgs) {
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
if (app.pid > 0 && app.pid != MY_PID) {
|
||||
checkTime(startTime, "startProcess: removing from pids map");
|
||||
@@ -3933,7 +3944,9 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
|
||||
}
|
||||
|
||||
if (!app.info.isAllowedToUseHiddenApi() && !mHiddenApiBlacklist.isDisabled()) {
|
||||
if (!app.info.isAllowedToUseHiddenApi() &&
|
||||
!disableHiddenApiChecks &&
|
||||
!mHiddenApiBlacklist.isDisabled()) {
|
||||
// This app is not allowed to use undocumented and private APIs, or blacklisting is
|
||||
// enabled. Set up its runtime with the appropriate flag.
|
||||
runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
|
||||
@@ -12456,6 +12469,12 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
|
||||
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
|
||||
String abiOverride) {
|
||||
return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
|
||||
abiOverride);
|
||||
}
|
||||
|
||||
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
|
||||
boolean disableHiddenApiChecks, String abiOverride) {
|
||||
ProcessRecord app;
|
||||
if (!isolated) {
|
||||
app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
|
||||
@@ -12487,8 +12506,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
|
||||
mPersistentStartingProcesses.add(app);
|
||||
startProcessLocked(app, "added application",
|
||||
customProcess != null ? customProcess : app.processName, abiOverride,
|
||||
null /* entryPoint */, null /* entryPointArgs */);
|
||||
customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
|
||||
abiOverride, null /* entryPoint */, null /* entryPointArgs */);
|
||||
}
|
||||
|
||||
return app;
|
||||
@@ -20153,7 +20172,10 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
// Instrumentation can kill and relaunch even persistent processes
|
||||
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
|
||||
"start instr");
|
||||
ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
|
||||
boolean disableHiddenApiChecks =
|
||||
(flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
|
||||
ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
|
||||
abiOverride);
|
||||
app.instr = activeInstr;
|
||||
activeInstr.mFinished = false;
|
||||
activeInstr.mRunningProcesses.add(app);
|
||||
|
||||
@@ -2729,7 +2729,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" specified then send to all users.");
|
||||
pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
|
||||
pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
|
||||
pw.println(" [--user <USER_ID> | current]");
|
||||
pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
|
||||
pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
|
||||
pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
|
||||
pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
|
||||
@@ -2744,6 +2744,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" test runners.");
|
||||
pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
|
||||
pw.println(" current user if not specified.");
|
||||
pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
|
||||
pw.println(" --no-window-animation: turn off window animations while running.");
|
||||
pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
|
||||
pw.println(" This assumes that the process supports the selected ABI.");
|
||||
|
||||
Reference in New Issue
Block a user