Loading cmds/am/src/com/android/commands/am/Am.java +2 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,8 @@ public class Am extends BaseCommand { instrument.userId = parseUserArg(nextArgRequired()); } else if (opt.equals("--abi")) { instrument.abi = nextArgRequired(); } else if (opt.equals("--no-restart")) { instrument.noRestart = true; } else { System.err.println("Error: Unknown option: " + opt); return; Loading cmds/am/src/com/android/commands/am/Instrument.java +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.commands.am; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART; import android.app.IActivityManager; import android.app.IInstrumentationWatcher; Loading Loading @@ -89,6 +90,7 @@ public class Instrument { public boolean disableTestApiChecks = true; public boolean disableIsolatedStorage = false; public String abi = null; public boolean noRestart = false; public int userId = UserHandle.USER_CURRENT; public Bundle args = new Bundle(); // Required Loading Loading @@ -514,6 +516,9 @@ public class Instrument { if (disableIsolatedStorage) { flags |= INSTR_FLAG_DISABLE_ISOLATED_STORAGE; } if (noRestart) { flags |= INSTR_FLAG_NO_RESTART; } if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId, abi)) { throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); Loading core/java/android/app/ActivityManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,12 @@ public class ActivityManager { */ public static final int INSTR_FLAG_DISABLE_TEST_API_CHECKS = 1 << 2; /** * Do not restart the target process when starting or finishing instrumentation. * @hide */ public static final int INSTR_FLAG_NO_RESTART = 1 << 3; static final class UidObserver extends IUidObserver.Stub { final OnUidImportanceListener mListener; final Context mContext; Loading core/java/android/app/ActivityThread.java +145 −68 Original line number Diff line number Diff line Loading @@ -381,6 +381,7 @@ public final class ActivityThread extends ClientTransactionHandler { String mInstrumentedAppDir = null; String[] mInstrumentedSplitAppDirs = null; String mInstrumentedLibDir = null; boolean mInstrumentingWithoutRestart; boolean mSystemThread = false; boolean mSomeActivitiesChanged = false; /* package */ boolean mHiddenApiWarningShown = false; Loading Loading @@ -1774,6 +1775,19 @@ public final class ActivityThread extends ClientTransactionHandler { key.mLock.notifyAll(); } } @Override public void instrumentWithoutRestart(ComponentName instrumentationName, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, ApplicationInfo targetInfo) { AppBindData data = new AppBindData(); data.instrumentationName = instrumentationName; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.instrumentationUiAutomationConnection = instrumentationUiConnection; data.appInfo = targetInfo; sendMessage(H.INSTRUMENT_WITHOUT_RESTART, data); } } private @NonNull SafeCancellationTransport createSafeCancellationTransport( Loading Loading @@ -1879,6 +1893,9 @@ public final class ActivityThread extends ClientTransactionHandler { public static final int PURGE_RESOURCES = 161; public static final int ATTACH_STARTUP_AGENTS = 162; public static final int INSTRUMENT_WITHOUT_RESTART = 170; public static final int FINISH_INSTRUMENTATION_WITHOUT_RESTART = 171; String codeToString(int code) { if (DEBUG_MESSAGES) { switch (code) { Loading Loading @@ -1921,6 +1938,9 @@ public final class ActivityThread extends ClientTransactionHandler { case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PURGE_RESOURCES: return "PURGE_RESOURCES"; case ATTACH_STARTUP_AGENTS: return "ATTACH_STARTUP_AGENTS"; case INSTRUMENT_WITHOUT_RESTART: return "INSTRUMENT_WITHOUT_RESTART"; case FINISH_INSTRUMENTATION_WITHOUT_RESTART: return "FINISH_INSTRUMENTATION_WITHOUT_RESTART"; } } return Integer.toString(code); Loading Loading @@ -2102,6 +2122,12 @@ public final class ActivityThread extends ClientTransactionHandler { case ATTACH_STARTUP_AGENTS: handleAttachStartupAgents((String) msg.obj); break; case INSTRUMENT_WITHOUT_RESTART: handleInstrumentWithoutRestart((AppBindData) msg.obj); break; case FINISH_INSTRUMENTATION_WITHOUT_RESTART: handleFinishInstrumentationWithoutRestart(); break; } Object obj = msg.obj; if (obj instanceof SomeArgs) { Loading Loading @@ -6500,32 +6526,7 @@ public final class ActivityThread extends ClientTransactionHandler { // setting up the app context. final InstrumentationInfo ii; if (data.instrumentationName != null) { try { ii = new ApplicationPackageManager( null, getPackageManager(), getPermissionManager()) .getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } // Warn of potential ABI mismatches. if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi) || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) { Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: " + "package[" + data.appInfo.packageName + "]: " + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi + " instrumentation[" + ii.packageName + "]: " + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); ii = prepareInstrumentation(data); } else { ii = null; } Loading Loading @@ -6554,48 +6555,7 @@ public final class ActivityThread extends ClientTransactionHandler { // Continue loading instrumentation. if (ii != null) { ApplicationInfo instrApp; try { instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, UserHandle.myUserId()); } catch (RemoteException e) { instrApp = null; } if (instrApp == null) { instrApp = new ApplicationInfo(); } ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); // The test context's op package name == the target app's op package name, because // the app ops manager checks the op package name against the real calling UID, // which is what the target package name is associated with. final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName()); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection); if (mProfiler.profileFile != null && !ii.handleProfiling && mProfiler.profileFd == null) { mProfiler.handlingProfiling = true; final File file = new File(mProfiler.profileFile); file.getParentFile().mkdirs(); Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } initInstrumentation(ii, data, appContext); } else { mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); Loading Loading @@ -6686,6 +6646,120 @@ public final class ActivityThread extends ClientTransactionHandler { } } private void handleInstrumentWithoutRestart(AppBindData data) { try { data.compatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); mInstrumentingWithoutRestart = true; final InstrumentationInfo ii = prepareInstrumentation(data); final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); initInstrumentation(ii, data, appContext); try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { throw new RuntimeException( "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } } catch (Exception e) { Slog.e(TAG, "Error in handleInstrumentWithoutRestart", e); } } private InstrumentationInfo prepareInstrumentation(AppBindData data) { final InstrumentationInfo ii; try { ii = new ApplicationPackageManager( null, getPackageManager(), getPermissionManager()) .getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } // Warn of potential ABI mismatches. if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi) || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) { Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: " + "package[" + data.appInfo.packageName + "]: " + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi + " instrumentation[" + ii.packageName + "]: " + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); return ii; } private void initInstrumentation( InstrumentationInfo ii, AppBindData data, ContextImpl appContext) { ApplicationInfo instrApp; try { instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, UserHandle.myUserId()); } catch (RemoteException e) { instrApp = null; } if (instrApp == null) { instrApp = new ApplicationInfo(); } ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); // The test context's op package name == the target app's op package name, because // the app ops manager checks the op package name against the real calling UID, // which is what the target package name is associated with. final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName()); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection); if (mProfiler.profileFile != null && !ii.handleProfiling && mProfiler.profileFd == null) { mProfiler.handlingProfiling = true; final File file = new File(mProfiler.profileFile); file.getParentFile().mkdirs(); Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } } private void handleFinishInstrumentationWithoutRestart() { mInstrumentation.onDestroy(); mInstrumentationPackageName = null; mInstrumentationAppDir = null; mInstrumentationSplitAppDirs = null; mInstrumentationLibDir = null; mInstrumentedAppDir = null; mInstrumentedSplitAppDirs = null; mInstrumentedLibDir = null; mInstrumentingWithoutRestart = false; } /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { IActivityManager am = ActivityManager.getService(); if (mProfiler.profileFile != null && mProfiler.handlingProfiling Loading @@ -6699,6 +6773,9 @@ public final class ActivityThread extends ClientTransactionHandler { } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } if (mInstrumentingWithoutRestart) { sendMessage(H.FINISH_INSTRUMENTATION_WITHOUT_RESTART, null); } } @UnsupportedAppUsage Loading core/java/android/app/IApplicationThread.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -150,4 +150,9 @@ oneway interface IApplicationThread { in RemoteCallback resultCallback); void notifyContentProviderPublishStatus(in ContentProviderHolder holder, String auth, int userId, boolean published); void instrumentWithoutRestart(in ComponentName instrumentationName, in Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, in ApplicationInfo targetInfo); } Loading
cmds/am/src/com/android/commands/am/Am.java +2 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,8 @@ public class Am extends BaseCommand { instrument.userId = parseUserArg(nextArgRequired()); } else if (opt.equals("--abi")) { instrument.abi = nextArgRequired(); } else if (opt.equals("--no-restart")) { instrument.noRestart = true; } else { System.err.println("Error: Unknown option: " + opt); return; Loading
cmds/am/src/com/android/commands/am/Instrument.java +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.commands.am; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART; import android.app.IActivityManager; import android.app.IInstrumentationWatcher; Loading Loading @@ -89,6 +90,7 @@ public class Instrument { public boolean disableTestApiChecks = true; public boolean disableIsolatedStorage = false; public String abi = null; public boolean noRestart = false; public int userId = UserHandle.USER_CURRENT; public Bundle args = new Bundle(); // Required Loading Loading @@ -514,6 +516,9 @@ public class Instrument { if (disableIsolatedStorage) { flags |= INSTR_FLAG_DISABLE_ISOLATED_STORAGE; } if (noRestart) { flags |= INSTR_FLAG_NO_RESTART; } if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId, abi)) { throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); Loading
core/java/android/app/ActivityManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,12 @@ public class ActivityManager { */ public static final int INSTR_FLAG_DISABLE_TEST_API_CHECKS = 1 << 2; /** * Do not restart the target process when starting or finishing instrumentation. * @hide */ public static final int INSTR_FLAG_NO_RESTART = 1 << 3; static final class UidObserver extends IUidObserver.Stub { final OnUidImportanceListener mListener; final Context mContext; Loading
core/java/android/app/ActivityThread.java +145 −68 Original line number Diff line number Diff line Loading @@ -381,6 +381,7 @@ public final class ActivityThread extends ClientTransactionHandler { String mInstrumentedAppDir = null; String[] mInstrumentedSplitAppDirs = null; String mInstrumentedLibDir = null; boolean mInstrumentingWithoutRestart; boolean mSystemThread = false; boolean mSomeActivitiesChanged = false; /* package */ boolean mHiddenApiWarningShown = false; Loading Loading @@ -1774,6 +1775,19 @@ public final class ActivityThread extends ClientTransactionHandler { key.mLock.notifyAll(); } } @Override public void instrumentWithoutRestart(ComponentName instrumentationName, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, ApplicationInfo targetInfo) { AppBindData data = new AppBindData(); data.instrumentationName = instrumentationName; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.instrumentationUiAutomationConnection = instrumentationUiConnection; data.appInfo = targetInfo; sendMessage(H.INSTRUMENT_WITHOUT_RESTART, data); } } private @NonNull SafeCancellationTransport createSafeCancellationTransport( Loading Loading @@ -1879,6 +1893,9 @@ public final class ActivityThread extends ClientTransactionHandler { public static final int PURGE_RESOURCES = 161; public static final int ATTACH_STARTUP_AGENTS = 162; public static final int INSTRUMENT_WITHOUT_RESTART = 170; public static final int FINISH_INSTRUMENTATION_WITHOUT_RESTART = 171; String codeToString(int code) { if (DEBUG_MESSAGES) { switch (code) { Loading Loading @@ -1921,6 +1938,9 @@ public final class ActivityThread extends ClientTransactionHandler { case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PURGE_RESOURCES: return "PURGE_RESOURCES"; case ATTACH_STARTUP_AGENTS: return "ATTACH_STARTUP_AGENTS"; case INSTRUMENT_WITHOUT_RESTART: return "INSTRUMENT_WITHOUT_RESTART"; case FINISH_INSTRUMENTATION_WITHOUT_RESTART: return "FINISH_INSTRUMENTATION_WITHOUT_RESTART"; } } return Integer.toString(code); Loading Loading @@ -2102,6 +2122,12 @@ public final class ActivityThread extends ClientTransactionHandler { case ATTACH_STARTUP_AGENTS: handleAttachStartupAgents((String) msg.obj); break; case INSTRUMENT_WITHOUT_RESTART: handleInstrumentWithoutRestart((AppBindData) msg.obj); break; case FINISH_INSTRUMENTATION_WITHOUT_RESTART: handleFinishInstrumentationWithoutRestart(); break; } Object obj = msg.obj; if (obj instanceof SomeArgs) { Loading Loading @@ -6500,32 +6526,7 @@ public final class ActivityThread extends ClientTransactionHandler { // setting up the app context. final InstrumentationInfo ii; if (data.instrumentationName != null) { try { ii = new ApplicationPackageManager( null, getPackageManager(), getPermissionManager()) .getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } // Warn of potential ABI mismatches. if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi) || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) { Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: " + "package[" + data.appInfo.packageName + "]: " + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi + " instrumentation[" + ii.packageName + "]: " + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); ii = prepareInstrumentation(data); } else { ii = null; } Loading Loading @@ -6554,48 +6555,7 @@ public final class ActivityThread extends ClientTransactionHandler { // Continue loading instrumentation. if (ii != null) { ApplicationInfo instrApp; try { instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, UserHandle.myUserId()); } catch (RemoteException e) { instrApp = null; } if (instrApp == null) { instrApp = new ApplicationInfo(); } ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); // The test context's op package name == the target app's op package name, because // the app ops manager checks the op package name against the real calling UID, // which is what the target package name is associated with. final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName()); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection); if (mProfiler.profileFile != null && !ii.handleProfiling && mProfiler.profileFd == null) { mProfiler.handlingProfiling = true; final File file = new File(mProfiler.profileFile); file.getParentFile().mkdirs(); Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } initInstrumentation(ii, data, appContext); } else { mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); Loading Loading @@ -6686,6 +6646,120 @@ public final class ActivityThread extends ClientTransactionHandler { } } private void handleInstrumentWithoutRestart(AppBindData data) { try { data.compatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); mInstrumentingWithoutRestart = true; final InstrumentationInfo ii = prepareInstrumentation(data); final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); initInstrumentation(ii, data, appContext); try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { throw new RuntimeException( "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } } catch (Exception e) { Slog.e(TAG, "Error in handleInstrumentWithoutRestart", e); } } private InstrumentationInfo prepareInstrumentation(AppBindData data) { final InstrumentationInfo ii; try { ii = new ApplicationPackageManager( null, getPackageManager(), getPermissionManager()) .getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } // Warn of potential ABI mismatches. if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi) || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) { Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: " + "package[" + data.appInfo.packageName + "]: " + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi + " instrumentation[" + ii.packageName + "]: " + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); return ii; } private void initInstrumentation( InstrumentationInfo ii, AppBindData data, ContextImpl appContext) { ApplicationInfo instrApp; try { instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, UserHandle.myUserId()); } catch (RemoteException e) { instrApp = null; } if (instrApp == null) { instrApp = new ApplicationInfo(); } ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); // The test context's op package name == the target app's op package name, because // the app ops manager checks the op package name against the real calling UID, // which is what the target package name is associated with. final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName()); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection); if (mProfiler.profileFile != null && !ii.handleProfiling && mProfiler.profileFd == null) { mProfiler.handlingProfiling = true; final File file = new File(mProfiler.profileFile); file.getParentFile().mkdirs(); Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); } } private void handleFinishInstrumentationWithoutRestart() { mInstrumentation.onDestroy(); mInstrumentationPackageName = null; mInstrumentationAppDir = null; mInstrumentationSplitAppDirs = null; mInstrumentationLibDir = null; mInstrumentedAppDir = null; mInstrumentedSplitAppDirs = null; mInstrumentedLibDir = null; mInstrumentingWithoutRestart = false; } /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { IActivityManager am = ActivityManager.getService(); if (mProfiler.profileFile != null && mProfiler.handlingProfiling Loading @@ -6699,6 +6773,9 @@ public final class ActivityThread extends ClientTransactionHandler { } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } if (mInstrumentingWithoutRestart) { sendMessage(H.FINISH_INSTRUMENTATION_WITHOUT_RESTART, null); } } @UnsupportedAppUsage Loading
core/java/android/app/IApplicationThread.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -150,4 +150,9 @@ oneway interface IApplicationThread { in RemoteCallback resultCallback); void notifyContentProviderPublishStatus(in ContentProviderHolder holder, String auth, int userId, boolean published); void instrumentWithoutRestart(in ComponentName instrumentationName, in Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, in ApplicationInfo targetInfo); }