如何从框架 ui 代码中可靠地调试日志记录?
How to do debug logging robustly from framework ui code?
我正在调查 android 的视图遍历和测量缓存的行为,
使用 AOSP 源代码和模拟器。
我想从每个函数发出调试日志消息
View.measure(), View.layout(), View.draw(),
来自调用它们的所有进程。
听起来很简单,对吧?但是我还没有找到可靠的机制。
我尝试了什么:
标准日志记录机制:java.util.Log(并使用 logcat 查看)。
失败:当消息过多时随机丢弃消息。
创建并附加到目录中的文件
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).
失败:这仅适用于某些进程(那些 WRITE_EXTERNAL_STORAGE
许可,大概)。
正在目录 view.getContext().getCacheDir().
中创建并附加到文件
FAIL:调用 getCacheDir() 在 system_process 中失败,原因是:
"java.lang.RuntimeException: No data directory found for package android".
正在目录 view.getContext().getExternalCacheDir().getExternalCacheDir().
中创建并追加文件
失败:这似乎适用于除 system_process 之外的所有进程,
其中 getExternalCacheDir() returns /storage/emulated/0/Android/data/android/cache,
但是尝试写入其中的文件会出现 AccessDeniedException。
在目录 view.getContext().getExternalFilesDir(null).
中创建并附加文件
失败:与 (4) 相同的结果,除了目录名称以 "files" 而不是 "cache" 结尾。
正在 /data/local/tmp.
中创建并附加到文件
失败:在所有进程中出现 AccessDeniedException。
我该如何记录日志?
我会对以下任一方面的具体解决方案感兴趣:
- 破解 AOSP 源代码以防止 java.util.Log 丢失消息
- 编写一个替代的日志守护进程,它不会丢弃消息
并且必须在系统启动期间可用(以便它可用于 system_process 和 com.android.systemui 等进程)。
- 随便找一个
directory/file 允许 system_process 写入
(我认为这是我找不到此类文件的唯一过程)
- 破解 AOSP 源代码使其 system_process
写入某些文件的权限。
关于Logcatwhite/black列表:
android logcat logs chatty module line expire message
如果你想把日志堆到外部存储,你可以手动授予权限:
How do I use adb grant or adb revoke?
您真的要记录 android 的视图遍历行为并测量跨所有进程的缓存吗?从大量日志开始并不是一个好的解决方案。我认为。
更新: DefaultPermissionGrantPolicy.java
public void grantDefaultPermissions(int userId) {
grantPermissionsToSysComponentsAndPrivApps(userId);
grantDefaultSystemHandlerPermissions(userId);
grantDefaultPermissionExceptions(userId);
grantWriteExternalPermissionsToAllApps(userId); // added.
}
private void grantWriteExternalPermissionsToAllApps(int userId) {
synchronized (mService.mPackages) {
for (PackageParser.Package pkg : mService.mPackages.values()) {
Set<String> permissions = new ArraySet<>();
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
grantRuntimePermissionsLPw(pkg, permissions, true, userId);
}
}
}
此代码将授予对所有包的 WRITE_EXTERNAL_STORAGE 权限。未经测试。不能推荐。
我发现每个进程显然都可以在其中创建文件和写入以下目录;因此,让每个进程在各自的目录中为其 logging/tracing 创建一个文件。
显然有两种情况必须完全分开处理。
- "system_process"(又名 "system_server" 又名 "system")(与 "com.android.system.ui" 不同)可以写入:
- Environment.getDataDirectory() = "/数据"
- Environment.getDownloadCacheDirectory() = "/data/cache"
- Environment.getDataSystemDirectory() = "/data/system"
- 创建 UI 的所有其他进程都可以写入:
- context.getExternalCacheDir() = "/storage/emulated/0/Android/data/app.name.appears.here/cache"
- context.getExternalFilesDir(null) = "/storage/emulated/0/Android/data/app.name.appears.here/files"
- context.getCacheDir() = "/data/user/0/app.name.appears.here/cache" 或 "/data/user_de/0/app.name.appears.here/cache
- context.getFilesDir() = "/data/user/0/app.name.appears.here/files" 或 "/data/user_de/0/app.name.appears.here/files
注意:上面列出的字符串文字是我在从 AOSP 源构建的模拟器上观察到 return 的每个函数;我不认为 hard-code 他们是安全的。
我正在调查 android 的视图遍历和测量缓存的行为, 使用 AOSP 源代码和模拟器。
我想从每个函数发出调试日志消息 View.measure(), View.layout(), View.draw(), 来自调用它们的所有进程。
听起来很简单,对吧?但是我还没有找到可靠的机制。
我尝试了什么:
标准日志记录机制:java.util.Log(并使用 logcat 查看)。
失败:当消息过多时随机丢弃消息。
创建并附加到目录中的文件 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).
失败:这仅适用于某些进程(那些 WRITE_EXTERNAL_STORAGE 许可,大概)。
正在目录 view.getContext().getCacheDir().
中创建并附加到文件FAIL:调用 getCacheDir() 在 system_process 中失败,原因是: "java.lang.RuntimeException: No data directory found for package android".
正在目录 view.getContext().getExternalCacheDir().getExternalCacheDir().
中创建并追加文件失败:这似乎适用于除 system_process 之外的所有进程, 其中 getExternalCacheDir() returns /storage/emulated/0/Android/data/android/cache, 但是尝试写入其中的文件会出现 AccessDeniedException。
在目录 view.getContext().getExternalFilesDir(null).
中创建并附加文件失败:与 (4) 相同的结果,除了目录名称以 "files" 而不是 "cache" 结尾。
正在 /data/local/tmp.
中创建并附加到文件失败:在所有进程中出现 AccessDeniedException。
我该如何记录日志?
我会对以下任一方面的具体解决方案感兴趣:
- 破解 AOSP 源代码以防止 java.util.Log 丢失消息
- 编写一个替代的日志守护进程,它不会丢弃消息 并且必须在系统启动期间可用(以便它可用于 system_process 和 com.android.systemui 等进程)。
- 随便找一个 directory/file 允许 system_process 写入 (我认为这是我找不到此类文件的唯一过程)
- 破解 AOSP 源代码使其 system_process 写入某些文件的权限。
关于Logcatwhite/black列表:
android logcat logs chatty module line expire message
如果你想把日志堆到外部存储,你可以手动授予权限:
How do I use adb grant or adb revoke?
您真的要记录 android 的视图遍历行为并测量跨所有进程的缓存吗?从大量日志开始并不是一个好的解决方案。我认为。
更新: DefaultPermissionGrantPolicy.java
public void grantDefaultPermissions(int userId) {
grantPermissionsToSysComponentsAndPrivApps(userId);
grantDefaultSystemHandlerPermissions(userId);
grantDefaultPermissionExceptions(userId);
grantWriteExternalPermissionsToAllApps(userId); // added.
}
private void grantWriteExternalPermissionsToAllApps(int userId) {
synchronized (mService.mPackages) {
for (PackageParser.Package pkg : mService.mPackages.values()) {
Set<String> permissions = new ArraySet<>();
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
grantRuntimePermissionsLPw(pkg, permissions, true, userId);
}
}
}
此代码将授予对所有包的 WRITE_EXTERNAL_STORAGE 权限。未经测试。不能推荐。
我发现每个进程显然都可以在其中创建文件和写入以下目录;因此,让每个进程在各自的目录中为其 logging/tracing 创建一个文件。 显然有两种情况必须完全分开处理。
- "system_process"(又名 "system_server" 又名 "system")(与 "com.android.system.ui" 不同)可以写入:
- Environment.getDataDirectory() = "/数据"
- Environment.getDownloadCacheDirectory() = "/data/cache"
- Environment.getDataSystemDirectory() = "/data/system"
- 创建 UI 的所有其他进程都可以写入:
- context.getExternalCacheDir() = "/storage/emulated/0/Android/data/app.name.appears.here/cache"
- context.getExternalFilesDir(null) = "/storage/emulated/0/Android/data/app.name.appears.here/files"
- context.getCacheDir() = "/data/user/0/app.name.appears.here/cache" 或 "/data/user_de/0/app.name.appears.here/cache
- context.getFilesDir() = "/data/user/0/app.name.appears.here/files" 或 "/data/user_de/0/app.name.appears.here/files
注意:上面列出的字符串文字是我在从 AOSP 源构建的模拟器上观察到 return 的每个函数;我不认为 hard-code 他们是安全的。