diff options
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 |
commit | 8dcfefd652fa2c5612b3acbc4bf842d2dfb1cf21 (patch) | |
tree | 012fc44dd25c9ab1005d993df0db0b77711fa7fc | |
parent | 402120a2236b294dff9a51461cb22400a6ef67f6 (diff) | |
download | frameworks_base-8dcfefd652fa2c5612b3acbc4bf842d2dfb1cf21.zip frameworks_base-8dcfefd652fa2c5612b3acbc4bf842d2dfb1cf21.tar.gz frameworks_base-8dcfefd652fa2c5612b3acbc4bf842d2dfb1cf21.tar.bz2 |
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.java | 31 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 8 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 3 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 30 |
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 0344d26..ffe7ac9 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 74266cc..001ce57 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 8d127c6..196340e 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 77c2ea0..8f8d8a6 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 3df1698..46a7808 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 */); } } } |