我正在开发Android的第三方库,并且需要能够判断我是否以具有所需权限的特权进程运行,或者我是否生活在具有受限制权限的隔离进程中,如AndroidManifest.xml文件:
<service android:name="mySandboxedService" android:permission="com.android.chrome.permission.CHILD_SERVICE" android:exported="false" android:process=":sandboxed_process0" android:isolatedProcess="true" />
原因是我正在尝试做的某些事情,例如获取正在运行的应用程序进程(以及其他各种事物)的数量,如果它们被隔离,将抛出RuntimeException。如果不作为独立进程运行,此代码将成功运行,但如果进程被隔离,则将抛出RTE:
ActivityManager aM = (ActivityManager) context.getSystemService(android.content.Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> l = null;
try {
l = aM.getRunningAppProcesses();
} catch (RuntimeException e) {
Log.w(LOGTAG, "Isolated process not allowed allowed to call getRunningAppProcesses, cannot get number of running apps.");
}
来自我的logcat:
java.lang.SecurityException: Isolated process not allowed to call getRunningAppProcesses
有没有人知道我可以检查当前进程以查看它是否被隔离或特权的方式?我在这里查看了Android Service文档,但它没有提供太多信息。
我的最终目标是从主特权线程初始化我的应用程序,然后忽略可能创建的各种沙盒进程的所有启动调用。我不想在那些中运行,但我的钩子在Application.onCreate中,并且为每个进程调用,沙盒或不沙箱。
我已经考虑过将这些检查之一添加到我的初始化并捕获RTE的想法。但如果有一个公共API,我宁愿使用它。
答案 0 :(得分:4)
可以检查正在运行的进程的uid,以查看它们是否属于隔离进程的范围。
int AID_ISOLATED_START = 99000;
int AID_ISOLATED_END = 99999;
int uid = Process.myUid();
if (uid >= AID_ISOLATED_START && uid <= AID_ISOLATED_END) {
Log.i(TAG, "This is from an isolated process");
}
过程范围信息源:https://android.googlesource.com/platform/system/sepolicy/+/master/public/isolated_app.te
编辑:发现以上内容在Android 8.1及更低版本上不可靠。 另一种方法是尝试访问特权API,并查看是否引发异常。
try {
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
activityManager.getRunningAppProcesses();
} catch (SecurityException e) {
Log.i(TAG, "This is from an isolated process");
}
在另一个答案中指出,Android Pie / 9(API 28)为此引入了新的API。参见https://developer.android.com/reference/android/os/Process#isIsolated()
答案 1 :(得分:0)
API 28(Android Pie / 9)引入了一种新方法来检查当前进程是否是一个独立的进程:Process#isIsolated。
请注意,此方法已添加到API 16的Process类中,但是一直隐藏到API28。因此,可以使用以下方法检查该流程是否被隔离(实际上Chrome app performs this check是这样) :
@SuppressLint("NewApi")
public boolean isIsolated() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return false;
}
return android.os.Process.isIsolated();
}
检查UID是否在{99000,99999}范围内(如已接受的答案所示)将在多用户/配置文件环境中为并非主要用户/所有用户/配置文件产生不正确的结果-因为其UID将以匹配的用户ID作为前缀(用户10的隔离进程的示例UID将为1099013)。