Loading services/core/java/com/android/server/am/MemoryStatUtil.java +20 −3 Original line number Diff line number Diff line Loading @@ -123,9 +123,8 @@ public final class MemoryStatUtil { * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); String cmdline = readFileContents(path); return cmdline != null ? cmdline : ""; final String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); return parseCmdlineFromProcfs(readFileContents(path)); } private static String readFileContents(String path) { Loading Loading @@ -210,6 +209,24 @@ public final class MemoryStatUtil { return m.find() ? Long.parseLong(m.group(1)) * BYTES_IN_KILOBYTE : 0; } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after first null byte. */ @VisibleForTesting static String parseCmdlineFromProcfs(String cmdline) { if (cmdline == null) { return ""; } int firstNullByte = cmdline.indexOf("\0"); if (firstNullByte == -1) { return cmdline; } return cmdline.substring(0, firstNullByte); } /** * Returns whether per-app memcg is available on device. */ Loading services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE; import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS; import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.PAGE_SIZE; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; Loading @@ -31,6 +32,7 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.util.Collections; /** Loading Loading @@ -232,4 +234,41 @@ public class MemoryStatUtilTest { assertEquals(0, parseVmHWMFromProcfs(null)); } @Test public void testParseCmdlineFromProcfs_invalidValue() { byte[] nothing = new byte[] {0x00, 0x74, 0x65, 0x73, 0x74}; // \0test assertEquals("", parseCmdlineFromProcfs(bytesToString(nothing))); } @Test public void testParseCmdlineFromProcfs_correctValue_noNullBytes() { assertEquals("com.google.app", parseCmdlineFromProcfs("com.google.app")); } @Test public void testParseCmdlineFromProcfs_correctValue_withNullBytes() { byte[] trailing = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00}; // test\0\0\0 assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing))); // test\0\0test byte[] inside = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74}; assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing))); } @Test public void testParseCmdlineFromProcfs_emptyContents() { assertEquals("", parseCmdlineFromProcfs("")); assertEquals("", parseCmdlineFromProcfs(null)); } private static String bytesToString(byte[] bytes) { ByteArrayOutputStream output = new ByteArrayOutputStream(); output.write(bytes, 0, bytes.length); return output.toString(); } } Loading
services/core/java/com/android/server/am/MemoryStatUtil.java +20 −3 Original line number Diff line number Diff line Loading @@ -123,9 +123,8 @@ public final class MemoryStatUtil { * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); String cmdline = readFileContents(path); return cmdline != null ? cmdline : ""; final String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); return parseCmdlineFromProcfs(readFileContents(path)); } private static String readFileContents(String path) { Loading Loading @@ -210,6 +209,24 @@ public final class MemoryStatUtil { return m.find() ? Long.parseLong(m.group(1)) * BYTES_IN_KILOBYTE : 0; } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after first null byte. */ @VisibleForTesting static String parseCmdlineFromProcfs(String cmdline) { if (cmdline == null) { return ""; } int firstNullByte = cmdline.indexOf("\0"); if (firstNullByte == -1) { return cmdline; } return cmdline.substring(0, firstNullByte); } /** * Returns whether per-app memcg is available on device. */ Loading
services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE; import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS; import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.PAGE_SIZE; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; Loading @@ -31,6 +32,7 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.util.Collections; /** Loading Loading @@ -232,4 +234,41 @@ public class MemoryStatUtilTest { assertEquals(0, parseVmHWMFromProcfs(null)); } @Test public void testParseCmdlineFromProcfs_invalidValue() { byte[] nothing = new byte[] {0x00, 0x74, 0x65, 0x73, 0x74}; // \0test assertEquals("", parseCmdlineFromProcfs(bytesToString(nothing))); } @Test public void testParseCmdlineFromProcfs_correctValue_noNullBytes() { assertEquals("com.google.app", parseCmdlineFromProcfs("com.google.app")); } @Test public void testParseCmdlineFromProcfs_correctValue_withNullBytes() { byte[] trailing = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00}; // test\0\0\0 assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing))); // test\0\0test byte[] inside = new byte[] {0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74}; assertEquals("test", parseCmdlineFromProcfs(bytesToString(trailing))); } @Test public void testParseCmdlineFromProcfs_emptyContents() { assertEquals("", parseCmdlineFromProcfs("")); assertEquals("", parseCmdlineFromProcfs(null)); } private static String bytesToString(byte[] bytes) { ByteArrayOutputStream output = new ByteArrayOutputStream(); output.write(bytes, 0, bytes.length); return output.toString(); } }