Loading services/core/java/com/android/server/am/PhantomProcessList.java +11 −24 Original line number Diff line number Diff line Loading @@ -112,23 +112,10 @@ public final class PhantomProcessList { private final ActivityManagerService mService; private final Handler mKillHandler; private static final int CGROUP_V1 = 0; private static final int CGROUP_V2 = 1; private static final String[] CGROUP_PATH_PREFIXES = { "/acct/uid_" /* cgroup v1 */, "/sys/fs/cgroup/uid_" /* cgroup v2 */ }; private static final String CGROUP_PID_PREFIX = "/pid_"; private static final String CGROUP_PROCS = "/cgroup.procs"; @VisibleForTesting int mCgroupVersion = CGROUP_V1; PhantomProcessList(final ActivityManagerService service) { mService = service; mKillHandler = service.mProcessList.sKillHandler; mInjector = new Injector(); probeCgroupVersion(); } @VisibleForTesting Loading Loading @@ -157,9 +144,15 @@ public final class PhantomProcessList { final int appPid = app.getPid(); InputStream input = mCgroupProcsFds.get(appPid); if (input == null) { final String path = getCgroupFilePath(app.info.uid, appPid); String path = null; try { path = getCgroupFilePath(app.info.uid, appPid); input = mInjector.openCgroupProcs(path); } catch (IllegalArgumentException e) { if (DEBUG_PROCESSES) { Slog.w(TAG, "Unable to obtain cgroup.procs path ", e); } return; } catch (FileNotFoundException | SecurityException e) { if (DEBUG_PROCESSES) { Slog.w(TAG, "Unable to open " + path, e); Loading Loading @@ -207,18 +200,9 @@ public final class PhantomProcessList { } } private void probeCgroupVersion() { for (int i = CGROUP_PATH_PREFIXES.length - 1; i >= 0; i--) { if ((new File(CGROUP_PATH_PREFIXES[i] + Process.SYSTEM_UID)).exists()) { mCgroupVersion = i; break; } } } @VisibleForTesting String getCgroupFilePath(int uid, int pid) { return CGROUP_PATH_PREFIXES[mCgroupVersion] + uid + CGROUP_PID_PREFIX + pid + CGROUP_PROCS; return nativeGetCgroupProcsPath(uid, pid); } static String getProcessName(int pid) { Loading Loading @@ -630,4 +614,7 @@ public final class PhantomProcessList { return PhantomProcessList.getProcessName(pid); } } private static native String nativeGetCgroupProcsPath(int uid, int pid) throws IllegalArgumentException; } services/core/jni/Android.bp +8 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ cc_library_static { ":lib_oomConnection_native", ":lib_anrTimer_native", ":lib_lazilyRegisteredServices_native", ":lib_phantomProcessList_native", ], include_dirs: [ Loading Loading @@ -265,3 +266,10 @@ filegroup { "com_android_server_vr_VrManagerService.cpp", ], } filegroup { name: "lib_phantomProcessList_native", srcs: [ "com_android_server_am_PhantomProcessList.cpp", ], } services/core/jni/com_android_server_am_PhantomProcessList.cpp 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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. */ #include <jni.h> #include <nativehelper/JNIHelp.h> #include <processgroup/processgroup.h> namespace android { namespace { jstring getCgroupProcsPath(JNIEnv* env, jobject clazz, jint uid, jint pid) { if (uid < 0) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "uid is negative: %d", uid); return nullptr; } std::string path; if (!CgroupGetAttributePathForProcess("CgroupProcs", uid, pid, path)) { path.clear(); } return env->NewStringUTF(path.c_str()); } const JNINativeMethod sMethods[] = { {"nativeGetCgroupProcsPath", "(II)Ljava/lang/String;", (void*)getCgroupProcsPath}, }; } // anonymous namespace int register_android_server_am_PhantomProcessList(JNIEnv* env) { const char* className = "com/android/server/am/PhantomProcessList"; return jniRegisterNativeMethods(env, className, sMethods, NELEM(sMethods)); } } // namespace android No newline at end of file services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ int register_com_android_server_display_DisplayControl(JNIEnv* env); int register_com_android_server_SystemClockTime(JNIEnv* env); int register_android_server_display_smallAreaDetectionController(JNIEnv* env); int register_com_android_server_accessibility_BrailleDisplayConnection(JNIEnv* env); int register_android_server_am_PhantomProcessList(JNIEnv* env); // Note: Consider adding new JNI entrypoints for optional services to // LazyJniRegistrar instead, and relying on lazy registration. Loading Loading @@ -139,5 +140,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_com_android_server_SystemClockTime(env); register_android_server_display_smallAreaDetectionController(env); register_com_android_server_accessibility_BrailleDisplayConnection(env); register_android_server_am_PhantomProcessList(env); return JNI_VERSION_1_4; } services/tests/mockingservicestests/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_library_shared { ":lib_freezer_native", ":lib_oomConnection_native", ":lib_lazilyRegisteredServices_native", ":lib_phantomProcessList_native", "onload.cpp", ], Loading Loading
services/core/java/com/android/server/am/PhantomProcessList.java +11 −24 Original line number Diff line number Diff line Loading @@ -112,23 +112,10 @@ public final class PhantomProcessList { private final ActivityManagerService mService; private final Handler mKillHandler; private static final int CGROUP_V1 = 0; private static final int CGROUP_V2 = 1; private static final String[] CGROUP_PATH_PREFIXES = { "/acct/uid_" /* cgroup v1 */, "/sys/fs/cgroup/uid_" /* cgroup v2 */ }; private static final String CGROUP_PID_PREFIX = "/pid_"; private static final String CGROUP_PROCS = "/cgroup.procs"; @VisibleForTesting int mCgroupVersion = CGROUP_V1; PhantomProcessList(final ActivityManagerService service) { mService = service; mKillHandler = service.mProcessList.sKillHandler; mInjector = new Injector(); probeCgroupVersion(); } @VisibleForTesting Loading Loading @@ -157,9 +144,15 @@ public final class PhantomProcessList { final int appPid = app.getPid(); InputStream input = mCgroupProcsFds.get(appPid); if (input == null) { final String path = getCgroupFilePath(app.info.uid, appPid); String path = null; try { path = getCgroupFilePath(app.info.uid, appPid); input = mInjector.openCgroupProcs(path); } catch (IllegalArgumentException e) { if (DEBUG_PROCESSES) { Slog.w(TAG, "Unable to obtain cgroup.procs path ", e); } return; } catch (FileNotFoundException | SecurityException e) { if (DEBUG_PROCESSES) { Slog.w(TAG, "Unable to open " + path, e); Loading Loading @@ -207,18 +200,9 @@ public final class PhantomProcessList { } } private void probeCgroupVersion() { for (int i = CGROUP_PATH_PREFIXES.length - 1; i >= 0; i--) { if ((new File(CGROUP_PATH_PREFIXES[i] + Process.SYSTEM_UID)).exists()) { mCgroupVersion = i; break; } } } @VisibleForTesting String getCgroupFilePath(int uid, int pid) { return CGROUP_PATH_PREFIXES[mCgroupVersion] + uid + CGROUP_PID_PREFIX + pid + CGROUP_PROCS; return nativeGetCgroupProcsPath(uid, pid); } static String getProcessName(int pid) { Loading Loading @@ -630,4 +614,7 @@ public final class PhantomProcessList { return PhantomProcessList.getProcessName(pid); } } private static native String nativeGetCgroupProcsPath(int uid, int pid) throws IllegalArgumentException; }
services/core/jni/Android.bp +8 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ cc_library_static { ":lib_oomConnection_native", ":lib_anrTimer_native", ":lib_lazilyRegisteredServices_native", ":lib_phantomProcessList_native", ], include_dirs: [ Loading Loading @@ -265,3 +266,10 @@ filegroup { "com_android_server_vr_VrManagerService.cpp", ], } filegroup { name: "lib_phantomProcessList_native", srcs: [ "com_android_server_am_PhantomProcessList.cpp", ], }
services/core/jni/com_android_server_am_PhantomProcessList.cpp 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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. */ #include <jni.h> #include <nativehelper/JNIHelp.h> #include <processgroup/processgroup.h> namespace android { namespace { jstring getCgroupProcsPath(JNIEnv* env, jobject clazz, jint uid, jint pid) { if (uid < 0) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "uid is negative: %d", uid); return nullptr; } std::string path; if (!CgroupGetAttributePathForProcess("CgroupProcs", uid, pid, path)) { path.clear(); } return env->NewStringUTF(path.c_str()); } const JNINativeMethod sMethods[] = { {"nativeGetCgroupProcsPath", "(II)Ljava/lang/String;", (void*)getCgroupProcsPath}, }; } // anonymous namespace int register_android_server_am_PhantomProcessList(JNIEnv* env) { const char* className = "com/android/server/am/PhantomProcessList"; return jniRegisterNativeMethods(env, className, sMethods, NELEM(sMethods)); } } // namespace android No newline at end of file
services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ int register_com_android_server_display_DisplayControl(JNIEnv* env); int register_com_android_server_SystemClockTime(JNIEnv* env); int register_android_server_display_smallAreaDetectionController(JNIEnv* env); int register_com_android_server_accessibility_BrailleDisplayConnection(JNIEnv* env); int register_android_server_am_PhantomProcessList(JNIEnv* env); // Note: Consider adding new JNI entrypoints for optional services to // LazyJniRegistrar instead, and relying on lazy registration. Loading Loading @@ -139,5 +140,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_com_android_server_SystemClockTime(env); register_android_server_display_smallAreaDetectionController(env); register_com_android_server_accessibility_BrailleDisplayConnection(env); register_android_server_am_PhantomProcessList(env); return JNI_VERSION_1_4; }
services/tests/mockingservicestests/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_library_shared { ":lib_freezer_native", ":lib_oomConnection_native", ":lib_lazilyRegisteredServices_native", ":lib_phantomProcessList_native", "onload.cpp", ], Loading