summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Narayan Kamath <narayan@google.com> 2014-05-15 18:12:59 +0100
committer Narayan Kamath <narayan@google.com> 2014-05-16 10:30:00 +0100
commit8dcfefd652fa2c5612b3acbc4bf842d2dfb1cf21 (patch)
tree012fc44dd25c9ab1005d993df0db0b77711fa7fc
parent402120a2236b294dff9a51461cb22400a6ef67f6 (diff)
Support an ABI flag for instrumentation.
Allows us to choose what ABI a process uses when launching it with "adb shell am instrument", for eg. adb shell am instrument --abi arm64-v8a component/runner Note that we only perform very basic validation of the ABI. In general, there is no guarantee that the app will launch with the instruction set we choose, for eg. if it has native libraries that are for a different ABI. bug: 14453227 Change-Id: Ifb7e89b53675080dc87941091ee5ac360f218d7f
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java31
-rw-r--r--core/java/android/app/ActivityManagerNative.java8
-rw-r--r--core/java/android/app/ContextImpl.java3
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java30
5 files changed, 55 insertions, 20 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 0344d261fd35..ffe7ac992060 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -33,6 +33,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -43,6 +44,8 @@ import android.util.AndroidException;
import android.view.IWindowManager;
import com.android.internal.os.BaseCommand;
+import dalvik.system.VMRuntime;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -91,7 +94,11 @@ public class Am extends BaseCommand {
" am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
" [--user <USER_ID> | current]\n" +
- " [--no-window-animation] <COMPONENT>\n" +
+ " [--no-window-animation]\n" +
+ " [--abi <ABI>]\n : Launch the instrumented process with the " +
+ " selected ABI. This assumes that the process supports the" +
+ " selected ABI." +
+ " <COMPONENT>\n" +
" am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
" am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
" am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
@@ -813,6 +820,7 @@ public class Am extends BaseCommand {
Bundle args = new Bundle();
String argKey = null, argValue = null;
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+ String abi = null;
String opt;
while ((opt=nextOption()) != null) {
@@ -831,6 +839,8 @@ public class Am extends BaseCommand {
no_window_animation = true;
} else if (opt.equals("--user")) {
userId = parseUserArg(nextArgRequired());
+ } else if (opt.equals("--abi")) {
+ abi = nextArgRequired();
} else {
System.err.println("Error: Unknown option: " + opt);
return;
@@ -861,7 +871,24 @@ public class Am extends BaseCommand {
wm.setAnimationScale(1, 0.0f);
}
- if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId)) {
+ if (abi != null) {
+ final String[] supportedAbis = Build.SUPPORTED_ABIS;
+ boolean matched = false;
+ for (String supportedAbi : supportedAbis) {
+ if (supportedAbi.equals(abi)) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ throw new AndroidException(
+ "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
+ }
+ }
+
+ if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
+ abi)) {
throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 74266ccf58a2..001ce57ad755 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -914,7 +914,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
b = data.readStrongBinder();
IUiAutomationConnection c = IUiAutomationConnection.Stub.asInterface(b);
int userId = data.readInt();
- boolean res = startInstrumentation(className, profileFile, fl, arguments, w, c, userId);
+ String abiOverride = data.readString();
+ boolean res = startInstrumentation(className, profileFile, fl, arguments, w, c, userId,
+ abiOverride);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -3173,7 +3175,8 @@ class ActivityManagerProxy implements IActivityManager
public boolean startInstrumentation(ComponentName className, String profileFile,
int flags, Bundle arguments, IInstrumentationWatcher watcher,
- IUiAutomationConnection connection, int userId) throws RemoteException {
+ IUiAutomationConnection connection, int userId, String instructionSet)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3184,6 +3187,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
data.writeStrongBinder(connection != null ? connection.asBinder() : null);
data.writeInt(userId);
+ data.writeString(instructionSet);
mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
reply.readException();
boolean res = reply.readInt() != 0;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8d127c6e381a..196340e32d4d 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1611,7 +1611,8 @@ class ContextImpl extends Context {
arguments.setAllowFds(false);
}
return ActivityManagerNative.getDefault().startInstrumentation(
- className, profileFile, 0, arguments, null, null, getUserId());
+ className, profileFile, 0, arguments, null, null, getUserId(),
+ null /* ABI override */);
} catch (RemoteException e) {
// System has crashed, nothing we can do.
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 77c2ea0c1694..8f8d8a6dfbc8 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -172,7 +172,8 @@ public interface IActivityManager extends IInterface {
public boolean startInstrumentation(ComponentName className, String profileFile,
int flags, Bundle arguments, IInstrumentationWatcher watcher,
- IUiAutomationConnection connection, int userId) throws RemoteException;
+ IUiAutomationConnection connection, int userId,
+ String abiOverride) throws RemoteException;
public void finishInstrumentation(IApplicationThread target,
int resultCode, Bundle results) throws RemoteException;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3df1698bb1f5..46a78085cc4f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2686,7 +2686,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return app;
}
- startProcessLocked(app, hostingType, hostingNameStr);
+ startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
return (app.pid != 0) ? app : null;
}
@@ -2695,7 +2695,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private final void startProcessLocked(ProcessRecord app,
- String hostingType, String hostingNameStr) {
+ String hostingType, String hostingNameStr, String abiOverride) {
if (app.pid > 0 && app.pid != MY_PID) {
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
@@ -2780,7 +2780,7 @@ public final class ActivityManagerService extends ActivityManagerNative
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
- String requiredAbi = app.info.cpuAbi;
+ String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
if (requiredAbi == null) {
requiredAbi = Build.SUPPORTED_ABIS[0];
}
@@ -4804,7 +4804,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.persistent && !app.isolated) {
if (!callerWillRestart) {
- addAppLocked(app.info, false);
+ addAppLocked(app.info, false, null /* ABI override */);
} else {
needRestart = true;
}
@@ -4912,7 +4912,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
- startProcessLocked(app, "link fail", processName);
+ startProcessLocked(app, "link fail", processName, null /* ABI override */);
return false;
}
@@ -5005,7 +5005,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
- startProcessLocked(app, "bind fail", processName);
+ startProcessLocked(app, "bind fail", processName, null /* ABI override */);
return false;
}
@@ -5174,7 +5174,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int ip=0; ip<NP; ip++) {
if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
+ procs.get(ip));
- startProcessLocked(procs.get(ip), "on-hold", null);
+ startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
}
}
@@ -8175,7 +8175,8 @@ public final class ActivityManagerService extends ActivityManagerNative
return new ProcessRecord(stats, info, proc, uid);
}
- final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
+ final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
+ String abiOverride) {
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(info.processName, info.uid, true);
@@ -8210,7 +8211,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
- startProcessLocked(app, "added application", app.processName);
+ startProcessLocked(app, "added application", app.processName,
+ abiOverride);
}
return app;
@@ -9396,7 +9398,7 @@ public final class ActivityManagerService extends ActivityManagerNative
= (ApplicationInfo)apps.get(i);
if (info != null &&
!info.packageName.equals("android")) {
- addAppLocked(info, false);
+ addAppLocked(info, false, null /* ABI override */);
}
}
}
@@ -12562,7 +12564,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// We have components that still need to be running in the
// process, so re-launch it.
mProcessNames.put(app.processName, app.uid, app);
- startProcessLocked(app, "restart", app.processName);
+ startProcessLocked(app, "restart", app.processName, null /* ABI override */);
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
synchronized (mPidsSelfLocked) {
@@ -13850,7 +13852,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public boolean startInstrumentation(ComponentName className,
String profileFile, int flags, Bundle arguments,
IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
- int userId) {
+ int userId, String abiOverride) {
enforceNotIsolatedCaller("startInstrumentation");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, true, "startInstrumentation", null);
@@ -13899,7 +13901,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Instrumentation can kill and relaunch even persistent processes
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
"start instr");
- ProcessRecord app = addAppLocked(ai, false);
+ ProcessRecord app = addAppLocked(ai, false, abiOverride);
app.instrumentationClass = className;
app.instrumentationInfo = ai;
app.instrumentationProfileFile = profileFile;
@@ -15829,7 +15831,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.persistent) {
if (app.persistent) {
- addAppLocked(app.info, false);
+ addAppLocked(app.info, false, null /* ABI override */);
}
}
}