diff --git a/api/current.txt b/api/current.txt
index eac0653297341..39097e77971d3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -203,7 +203,6 @@ package android {
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@ package android {
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -4804,6 +4804,7 @@ package android.app {
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4828,6 +4829,7 @@ package android.app {
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -9903,6 +9905,7 @@ package android.content.pm {
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public class LabeledIntent extends android.content.Intent {
diff --git a/api/system-current.txt b/api/system-current.txt
index 3b2ad3fd44a17..781600fd1776a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -315,7 +315,6 @@ package android {
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1386,6 +1385,7 @@ package android {
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -4964,6 +4964,7 @@ package android.app {
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4988,6 +4989,7 @@ package android.app {
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -10358,6 +10360,7 @@ package android.content.pm {
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public final class IntentFilterVerificationInfo implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index bfb0d14455efc..f07420a6a95b0 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -203,7 +203,6 @@ package android {
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@ package android {
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -4814,6 +4814,7 @@ package android.app {
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4838,6 +4839,7 @@ package android.app {
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -9931,6 +9933,7 @@ package android.content.pm {
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public class LabeledIntent extends android.content.Intent {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 3cc6282d6ab3d..99ae96df01eb5 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -145,6 +145,7 @@ interface IActivityManager {
int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
in IUiAutomationConnection connection, int userId,
in String abiOverride);
+ void addInstrumentationResults(in IApplicationThread target, in Bundle results);
void finishInstrumentation(in IApplicationThread target, int resultCode,
in Bundle results);
/**
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index b1bdea1cb5026..4db29fb5a72ac 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -186,11 +186,25 @@ public class Instrumentation {
}
}
}
-
+
+ /**
+ * Report some results in the middle of instrumentation execution. Later results (including
+ * those provided by {@link #finish}) will be combined with {@link Bundle#putAll}.
+ */
+ public void addResults(Bundle results) {
+ IActivityManager am = ActivityManager.getService();
+ try {
+ am.addInstrumentationResults(mThread.getApplicationThread(), results);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
/**
* Terminate instrumentation of the application. This will cause the
* application process to exit, removing this instrumentation from the next
- * time the application is started.
+ * time the application is started. If multiple processes are currently running
+ * for this instrumentation, all of those processes will be killed.
*
* @param resultCode Overall success/failure of instrumentation.
* @param results Any results to send back to the code that started the
@@ -277,6 +291,18 @@ public class Instrumentation {
return mAppContext;
}
+ /**
+ * Return the name of the process this instrumentation is running in. Note this should
+ * only be used for testing and debugging. If you are thinking about using this to,
+ * for example, conditionalize what is initialized in an Application class, it is strongly
+ * recommended to instead use lazy initialization (such as a getter for the state that
+ * only creates it when requested). This can greatly reduce the work your process does
+ * when created for secondary things, such as to receive a broadcast.
+ */
+ public String getProcessName() {
+ return mThread.getProcessName();
+ }
+
/**
* Check whether this instrumentation was started with profiling enabled.
*
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index a135d8f11acd9..59c5307301709 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -33,6 +33,13 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
*/
public String targetPackage;
+ /**
+ * Names of the process(es) this instrumentation will run in. If not specified, only
+ * runs in the main process of the targetPackage. Can either be a comma-separated list
+ * of process names or '*' for any process that launches to run targetPackage code.
+ */
+ public String targetProcess;
+
/**
* Full path to the base APK for this application.
*/
@@ -113,6 +120,7 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
public InstrumentationInfo(InstrumentationInfo orig) {
super(orig);
targetPackage = orig.targetPackage;
+ targetProcess = orig.targetProcess;
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
splitNames = orig.splitNames;
@@ -141,6 +149,7 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
public void writeToParcel(Parcel dest, int parcelableFlags) {
super.writeToParcel(dest, parcelableFlags);
dest.writeString(targetPackage);
+ dest.writeString(targetProcess);
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
dest.writeStringArray(splitNames);
@@ -170,6 +179,7 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
private InstrumentationInfo(Parcel source) {
super(source);
targetPackage = source.readString();
+ targetProcess = source.readString();
sourceDir = source.readString();
publicSourceDir = source.readString();
splitNames = source.readStringArray();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ff928a0dd81dd..e5dfe5425cd19 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1623,6 +1623,7 @@ public class PackageParser {
return parseApkLite(apkPath, parser, attrs, flags, signatures, certificates);
} catch (XmlPullParserException | IOException | RuntimeException e) {
+ Slog.w(TAG, "Failed to parse " + apkPath, e);
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
"Failed to parse " + apkPath, e);
} finally {
@@ -3160,6 +3161,10 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
a.info.targetPackage = str != null ? str.intern() : null;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_targetProcess);
+ a.info.targetProcess = str != null ? str.intern() : null;
+
a.info.handleProfiling = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestInstrumentation_handleProfiling,
false);
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 6d0fdb6033ec5..92ef17edec7cc 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -885,6 +885,12 @@
will run against. -->
+
+
+
+
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d795d80f52daa..1b48469b100e9 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2777,7 +2777,7 @@
-
+
diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java
new file mode 100644
index 0000000000000..84e4ea9d0ee8d
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.IInstrumentationWatcher;
+import android.app.IUiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.util.PrintWriterPrinter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class ActiveInstrumentation {
+ final ActivityManagerService mService;
+
+ // Class installed to instrument app
+ ComponentName mClass;
+
+ // All process names that should be instrumented
+ String[] mTargetProcesses;
+
+ // The application being instrumented
+ ApplicationInfo mTargetInfo;
+
+ // Where to save profiling
+ String mProfileFile;
+
+ // Who is waiting
+ IInstrumentationWatcher mWatcher;
+
+ // Connection to use the UI introspection APIs.
+ IUiAutomationConnection mUiAutomationConnection;
+
+ // As given to us
+ Bundle mArguments;
+
+ // Any intermediate results that have been collected.
+ Bundle mCurResults;
+
+ // Copy of instrumentationClass.
+ ComponentName mResultClass;
+
+ // Contains all running processes that have active instrumentation.
+ final ArrayList mRunningProcesses = new ArrayList<>();
+
+ // Set to true when we have told the watcher the instrumentation is finished.
+ boolean mFinished;
+
+ ActiveInstrumentation(ActivityManagerService service) {
+ mService = service;
+ }
+
+ void removeProcess(ProcessRecord proc) {
+ mFinished = true;
+ mRunningProcesses.remove(proc);
+ if (mRunningProcesses.size() == 0) {
+ mService.mActiveInstrumentation.remove(this);
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("ActiveInstrumentation{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(' ');
+ sb.append(mClass.toShortString());
+ if (mFinished) {
+ sb.append(" FINISHED");
+ }
+ sb.append(" ");
+ sb.append(mRunningProcesses.size());
+ sb.append(" procs");
+ sb.append('}');
+ return sb.toString();
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mClass="); pw.print(mClass);
+ pw.print(" mFinished="); pw.println(mFinished);
+ pw.print(prefix); pw.println("mRunningProcesses:");
+ for (int i=0; i mActiveInstrumentation = new ArrayList<>();
+
+ public final IntentFirewall mIntentFirewall;
// Whether we should show our dialogs (ANR, crash, etc) or just perform their
// default action automatically. Important for devices without direct input
@@ -3926,7 +3928,7 @@ public class ActivityManagerService extends IActivityManager.Stub
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
- if (app == null || app.instrumentationClass == null) {
+ if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
@@ -5092,9 +5094,9 @@ public class ActivityManagerService extends IActivityManager.Stub
app.activities.clear();
- if (app.instrumentationClass != null) {
+ if (app.instr != null) {
Slog.w(TAG, "Crash of app " + app.processName
- + " running instrumentation " + app.instrumentationClass);
+ + " running instrumentation " + app.instr.mClass);
Bundle info = new Bundle();
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
@@ -5227,7 +5229,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// Clean up already done if the process has been re-started.
if (app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
- boolean doLowMem = app.instrumentationClass == null;
+ boolean doLowMem = app.instr == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
@@ -6383,7 +6385,7 @@ public class ActivityManagerService extends IActivityManager.Stub
handleAppDiedLocked(app, willRestart, allowRestart);
if (willRestart) {
removeLruProcessLocked(app);
- addAppLocked(app.info, false, null /* ABI override */);
+ addAppLocked(app.info, null, false, null /* ABI override */);
}
} else {
mRemovedProcesses.add(app);
@@ -6559,7 +6561,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mWaitForDebugger = mOrigWaitForDebugger;
}
}
- String profileFile = app.instrumentationProfileFile;
+ String profileFile = app.instr != null ? app.instr.mProfileFile : null;
ParcelFileDescriptor profileFd = null;
int samplingInterval = 0;
boolean profileAutoStop = false;
@@ -6587,14 +6589,13 @@ public class ActivityManagerService extends IActivityManager.Stub
|| (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
}
- if (app.instrumentationClass != null) {
- notifyPackageUse(app.instrumentationClass.getPackageName(),
+ if (app.instr != null) {
+ notifyPackageUse(app.instr.mClass.getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
+ processName + " with config " + getGlobalConfiguration());
- ApplicationInfo appInfo = app.instrumentationInfo != null
- ? app.instrumentationInfo : app.info;
+ ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null) {
profileFd = profileFd.dup();
@@ -6614,16 +6615,57 @@ public class ActivityManagerService extends IActivityManager.Stub
.getSerial();
// }
+ // Check if this is a secondary process that should be incorporated into some
+ // currently active instrumentation. (Note we do this AFTER all of the profiling
+ // stuff above because profiling can currently happen only in the primary
+ // instrumentation process.)
+ if (mActiveInstrumentation.size() > 0 && app.instr == null) {
+ for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
+ ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
+ if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
+ if (aInstr.mTargetProcesses.length == 0) {
+ // This is the wildcard mode, where every process brought up for
+ // the target instrumentation should be included.
+ if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
+ app.instr = aInstr;
+ aInstr.mRunningProcesses.add(app);
+ }
+ } else {
+ for (String proc : aInstr.mTargetProcesses) {
+ if (proc.equals(app.processName)) {
+ app.instr = aInstr;
+ aInstr.mRunningProcesses.add(app);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
- thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
- profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
- app.instrumentationUiAutomationConnection, testMode,
- mBinderTransactionTrackingEnabled, enableTrackAllocation,
- isRestrictedBackupMode || !normalMode, app.persistent,
- new Configuration(getGlobalConfiguration()), app.compat,
- getCommonServicesLocked(app.isolated),
- mCoreSettingsObserver.getCoreSettingsLocked(),
- buildSerial);
+ if (app.instr != null) {
+ thread.bindApplication(processName, appInfo, providers,
+ app.instr.mClass,
+ profilerInfo, app.instr.mArguments,
+ app.instr.mWatcher,
+ app.instr.mUiAutomationConnection, testMode,
+ mBinderTransactionTrackingEnabled, enableTrackAllocation,
+ isRestrictedBackupMode || !normalMode, app.persistent,
+ new Configuration(getGlobalConfiguration()), app.compat,
+ getCommonServicesLocked(app.isolated),
+ mCoreSettingsObserver.getCoreSettingsLocked(),
+ buildSerial);
+ } else {
+ thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
+ null, null, null, testMode,
+ mBinderTransactionTrackingEnabled, enableTrackAllocation,
+ isRestrictedBackupMode || !normalMode, app.persistent,
+ new Configuration(getGlobalConfiguration()), app.compat,
+ getCommonServicesLocked(app.isolated),
+ mCoreSettingsObserver.getCoreSettingsLocked(),
+ buildSerial);
+ }
checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
updateLruProcessLocked(app, false, null);
@@ -11595,7 +11637,7 @@ public class ActivityManagerService extends IActivityManager.Stub
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
if (!"android".equals(app.packageName)) {
- addAppLocked(app, false, null /* ABI override */);
+ addAppLocked(app, null, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
@@ -11783,17 +11825,18 @@ public class ActivityManagerService extends IActivityManager.Stub
return false;
}
- final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
+ final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
String abiOverride) {
ProcessRecord app;
if (!isolated) {
- app = getProcessRecordLocked(info.processName, info.uid, true);
+ app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
+ info.uid, true);
} else {
app = null;
}
if (app == null) {
- app = newProcessRecordLocked(info, null, isolated, 0);
+ app = newProcessRecordLocked(info, customProcess, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
@@ -11814,7 +11857,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
- startProcessLocked(app, "added application", app.processName, abiOverride,
+ startProcessLocked(app, "added application",
+ customProcess != null ? customProcess : app.processName, abiOverride,
null /* entryPoint */, null /* entryPointArgs */);
}
@@ -12269,11 +12313,11 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
synchronized (mPidsSelfLocked) {
final int callingPid = Binder.getCallingPid();
- ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
- if (precessRecord == null) {
+ ProcessRecord proc = mPidsSelfLocked.get(callingPid);
+ if (proc == null) {
throw new SecurityException("Unknown process: " + callingPid);
}
- if (precessRecord.instrumentationUiAutomationConnection == null) {
+ if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
throw new SecurityException("Only an instrumentation process "
+ "with a UiAutomation can call setUserIsMonkey");
}
@@ -12330,7 +12374,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
- if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
+ if (r != null && (r.instr != null || r.usingWrapper)) {
return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
}
return KEY_DISPATCHING_TIMEOUT;
@@ -12391,7 +12435,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return false;
}
- if (proc.instrumentationClass != null) {
+ if (proc.instr != null) {
Bundle info = new Bundle();
info.putString("shortMsg", "keyDispatchingTimedOut");
info.putString("longMsg", annotation);
@@ -14901,8 +14945,31 @@ public class ActivityManagerService extends IActivityManager.Stub
printed = true;
needSep = true;
}
- pw.println(String.format("%sIsolated #%2d: %s",
- " ", i, r.toString()));
+ pw.print(" Isolated #"); pw.print(i); pw.print(": ");
+ pw.println(r);
+ }
+ }
+
+ if (mActiveInstrumentation.size() > 0) {
+ boolean printed = false;
+ for (int i=0; i curReceivers = new ArraySet();// receivers currently running in the app
long lastWakeTime; // How long proc held wake lock at last check
@@ -248,19 +242,8 @@ final class ProcessRecord {
pw.println("}");
}
pw.print(prefix); pw.print("compat="); pw.println(compat);
- if (instrumentationClass != null || instrumentationProfileFile != null
- || instrumentationArguments != null) {
- pw.print(prefix); pw.print("instrumentationClass=");
- pw.print(instrumentationClass);
- pw.print(" instrumentationProfileFile=");
- pw.println(instrumentationProfileFile);
- pw.print(prefix); pw.print("instrumentationArguments=");
- pw.println(instrumentationArguments);
- pw.print(prefix); pw.print("instrumentationInfo=");
- pw.println(instrumentationInfo);
- if (instrumentationInfo != null) {
- instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + " ");
- }
+ if (instr != null) {
+ pw.print(prefix); pw.print("instr="); pw.println(instr);
}
pw.print(prefix); pw.print("thread="); pw.println(thread);
pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e30bd5d966727..e5640c7e08c18 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -309,6 +309,7 @@ public class PackageParserTest {
// Sanity check for InstrumentationInfo.
assertEquals(a.info.targetPackage, b.info.targetPackage);
+ assertEquals(a.info.targetProcess, b.info.targetProcess);
assertEquals(a.info.sourceDir, b.info.sourceDir);
assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
}