Add package name to DDM APNM packet

DDM APNM currently only reports the application/process name. For
services that need to know the underlying package name, those
services need to manually resolve the process's UID and map it to
the package name via the shell - a slow and error-prone process.

This change adds the package name to the APNM packet so users of
newer versions of DDMLib can directly get the package name.

Test: manual

Change-Id: I92517d5bb641cc263c0d58db667b00e67fc5e58b
This commit is contained in:
Chester Hsieh
2019-11-12 12:01:54 -08:00
parent 95f4a3449d
commit ab720ee161
3 changed files with 60 additions and 19 deletions

View File

@@ -6248,6 +6248,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// send up app name; do this *before* waiting for debugger
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
data.appInfo.packageName,
UserHandle.myUserId());
VMRuntime.setProcessPackageName(data.appInfo.packageName);

View File

@@ -17,10 +17,12 @@
package android.ddm;
import android.annotation.UnsupportedAppUsage;
import android.util.Log;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
import android.util.Log;
import java.nio.ByteBuffer;
@@ -31,7 +33,7 @@ public class DdmHandleAppName extends ChunkHandler {
public static final int CHUNK_APNM = type("APNM");
private volatile static String mAppName = "";
private static volatile Names sNames = new Names("", "");
private static DdmHandleAppName mInstance = new DdmHandleAppName();
@@ -65,46 +67,82 @@ public class DdmHandleAppName extends ChunkHandler {
/**
* Sets all names to the same name.
*/
@UnsupportedAppUsage
public static void setAppName(String name, int userId) {
setAppName(name, name, userId);
}
/**
* Set the application name. Called when we get named, which may be
* before or after DDMS connects. For the latter we need to send up
* an APNM message.
*/
@UnsupportedAppUsage
public static void setAppName(String name, int userId) {
if (name == null || name.length() == 0)
return;
public static void setAppName(String appName, String pkgName, int userId) {
if (appName == null || appName.isEmpty() || pkgName == null || pkgName.isEmpty()) return;
mAppName = name;
sNames = new Names(appName, pkgName);
// if DDMS is already connected, send the app name up
sendAPNM(name, userId);
sendAPNM(appName, pkgName, userId);
}
@UnsupportedAppUsage
public static String getAppName() {
return mAppName;
public static Names getNames() {
return sNames;
}
/*
/**
* Send an APNM (APplication NaMe) chunk.
*/
private static void sendAPNM(String appName, int userId) {
private static void sendAPNM(String appName, String pkgName, int userId) {
if (false)
Log.v("ddm", "Sending app name");
ByteBuffer out = ByteBuffer.allocate(
4 /* appName's length */
+ appName.length()*2 /* appName */
+ 4 /* userId */);
+ appName.length() * 2 /* appName */
+ 4 /* userId */
+ 4 /* pkgName's length */
+ pkgName.length() * 2 /* pkgName */);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(appName.length());
putString(out, appName);
out.putInt(userId);
out.putInt(pkgName.length());
putString(out, pkgName);
Chunk chunk = new Chunk(CHUNK_APNM, out);
DdmServer.sendChunk(chunk);
}
/**
* A class that encapsulates the app and package names into a single
* instance, effectively synchronizing the two names.
*/
static final class Names {
private final String mAppName;
private final String mPkgName;
private Names(String appName, String pkgName) {
mAppName = appName;
mPkgName = pkgName;
}
public String getAppName() {
return mAppName;
}
public String getPkgName() {
return mPkgName;
}
}
}

View File

@@ -126,10 +126,9 @@ public class DdmHandleHello extends ChunkHandler {
String vmVersion = System.getProperty("java.vm.version", "?");
String vmIdent = vmName + " v" + vmVersion;
//String appName = android.app.ActivityThread.currentPackageName();
//if (appName == null)
// appName = "unknown";
String appName = DdmHandleAppName.getAppName();
DdmHandleAppName.Names names = DdmHandleAppName.getNames();
String appName = names.getAppName();
String pkgName = names.getPkgName();
VMRuntime vmRuntime = VMRuntime.getRuntime();
String instructionSetDescription =
@@ -142,12 +141,13 @@ public class DdmHandleHello extends ChunkHandler {
+ (vmRuntime.isCheckJniEnabled() ? "true" : "false");
boolean isNativeDebuggable = vmRuntime.isNativeDebuggable();
ByteBuffer out = ByteBuffer.allocate(28
ByteBuffer out = ByteBuffer.allocate(32
+ vmIdent.length() * 2
+ appName.length() * 2
+ instructionSetDescription.length() * 2
+ vmFlags.length() * 2
+ 1);
+ 1
+ pkgName.length() * 2);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(CLIENT_PROTOCOL_VERSION);
out.putInt(android.os.Process.myPid());
@@ -161,6 +161,8 @@ public class DdmHandleHello extends ChunkHandler {
out.putInt(vmFlags.length());
putString(out, vmFlags);
out.put((byte)(isNativeDebuggable ? 1 : 0));
out.putInt(pkgName.length());
putString(out, pkgName);
Chunk reply = new Chunk(CHUNK_HELO, out);