出于研究目的,我正在修改Android SystemServer代码。
我要完成什么?
每当有对SystemServer(Binder服务器进程)的调用时,我想知道Binder客户端进程上该调用的来源;更具体地说-我的应用程序中的源文件(例如文件,类,方法等)。
例如,考虑我的应用中的以下代码:
public class ClipboardReaderService extends Service {
private ClipboardManager mClipboardManager;
private ClipboardManager.OnPrimaryClipChangedListener mListener =
new ClipboardManager.OnPrimaryClipChangedListener() {
@Override
public void onPrimaryClipChanged() {
String clipContent = mClipboardManager.getPrimaryClip().
getItemAt(0).getText().toString();
Log.i(TAG, "Clipboard content: " + clipContent);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mClipboardManager = (ClipboardManager)
getSystemService(CLIPBOARD_SERVICE);
mClipboardManager.addPrimaryClipChangedListener(mListener);
return START_STICKY;
}
}
使用活页夹,SystemServer中的相应函数被调用(这是我的代码应该去的地方):
public ClipData getPrimaryClip(String pkg) {
synchronized (this) {
if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD,
Binder.getCallingUid(), pkg)
!= AppOpsManager.MODE_ALLOWED || isDeviceLocked()) {
return null;
}
// My code goes here - How can I get the caller method?
addActiveOwnerLocked(Binder.getCallingUid(), pkg);
return getClipboard().primaryClip;
}
}
如上所述,我可以更改SystemServer中的代码,并且希望提取客户端的调用源。
到目前为止我尝试过什么?
到目前为止,我一直在尝试提取客户端调用堆栈,因为我想要的信息应该在其底部。
Thread.currentThread().getStackTrace()
打印堆栈-当然,这是行不通的,因为我打印了SystemServer的堆栈,所以看不到clinet端的调用。getAllStackTraces()
打印所有活动线程的堆栈跟踪-再次,我看不到客户端线程,因为它们存在于单独的JVM中。setPrimaryClip
函数中)打印堆栈-确实按预期打印了客户端调用堆栈。实际上,我可以将调用堆栈作为附加参数传递给SystemServer,但是随后我将不得不为每个服务中的每个函数(例如NotificationManager)执行此操作,并且我正在寻找更全面的解决方案。Binder.getCallingPid()
获取调用者uid并从/ proc / $ pid / stack中读取堆栈-这也不起作用,因为/ proc / $ pid / stack仅显示内核堆栈。