1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.edi.cts; 17 18 import com.android.compatibility.common.util.DeviceInfo; 19 import com.android.compatibility.common.util.HostInfoStore; 20 import com.android.tradefed.device.ITestDevice; 21 import com.android.tradefed.log.LogUtil.CLog; 22 import com.android.tradefed.util.CommandResult; 23 24 import java.util.regex.Matcher; 25 import java.util.regex.Pattern; 26 27 /** 28 * System native device info collector. 29 */ 30 public class NativeDeviceInfo extends DeviceInfo { 31 collectMemCG(ITestDevice device, HostInfoStore store)32 private void collectMemCG(ITestDevice device, HostInfoStore store) throws Exception { 33 CommandResult commandResult = device.executeShellV2Command("grep memory /proc/cgroups"); 34 35 store.startGroup("memcg"); 36 if (commandResult.getExitCode() == 0) { 37 String[] tokens = commandResult.getStdout().split("\\s+"); 38 boolean memcg_enabled = tokens[3].equals("1"); 39 store.addResult("enabled", memcg_enabled); 40 if (memcg_enabled) store.addResult("version", tokens[1].equals("0") ? "2" : "1"); 41 } else if (commandResult.getExitCode() == 1) { // "memory" not found by grep 42 store.addResult("version", -3); 43 } else if (commandResult.getStderr().contains("No such file")) { 44 store.addResult("version", -1); 45 } else if (commandResult.getStderr().contains("Permission denied")) { 46 store.addResult("version", -2); 47 } 48 store.endGroup(); 49 } 50 collectMGLRU(ITestDevice device, HostInfoStore store)51 private void collectMGLRU(ITestDevice device, HostInfoStore store) throws Exception { 52 CommandResult commandResult = device.executeShellV2Command( 53 "cat /sys/kernel/mm/lru_gen/enabled"); 54 55 if (commandResult.getExitCode() == 0) { 56 store.addResult("mglru_enabled", Integer.decode(commandResult.getStdout().trim())); 57 } else if (commandResult.getStderr().contains("No such file")) { 58 store.addResult("mglru_enabled", -1); 59 } else if (commandResult.getStderr().contains("Permission denied")) { 60 store.addResult("mglru_enabled", -2); 61 } 62 } 63 64 @Override collectDeviceInfo(HostInfoStore store)65 protected void collectDeviceInfo(HostInfoStore store) throws Exception { 66 ITestDevice device = getDevice(); 67 CommandResult commandResult = device.executeShellV2Command("cat /proc/self/maps"); 68 if (!commandResult.getStderr().isEmpty()) { 69 CLog.w("Warnings occurred when running cat:\n%s", commandResult.getStderr()); 70 } 71 if (commandResult.getExitCode() == null) { 72 throw new NullPointerException("cat command exit code is null"); 73 } 74 if (commandResult.getExitCode() != 0) { 75 throw new IllegalStateException( 76 String.format("cat commaned returned %d: %s", commandResult.getExitCode(), 77 commandResult.getStderr())); 78 } 79 String stdout = commandResult.getStdout(); 80 if (stdout == null) { 81 throw new NullPointerException("cat command resulted in no output"); 82 } 83 84 String allocatorName; 85 if (stdout.indexOf(":scudo:") != -1) { 86 allocatorName = "scudo"; 87 } else { 88 allocatorName = "jemalloc"; 89 } 90 91 // Check for the bitness of the device. A device that supports 92 // both 32 bits and 64 bits is assumed to be whatever the shell 93 // user runs as. 94 // On 32 bit devices, the format of the entries is: 95 // beace000-beaf0000 rw-p 00000000 00:00 0 [stack] 96 // On 64 bit devices, the format of the entries is: 97 // 7ffdc13000-7ffdc35000 rw-p 00000000 00:00 0 [stack] 98 // This pattern looks for an entry that contains only 8 hex digits 99 // in the first and second map address to indicate 32 bit devices. 100 Pattern mapPattern = Pattern.compile("^[0-9a-f]{8,8}-[0-9a-f]{8,8} "); 101 Matcher matcher = mapPattern.matcher(stdout); 102 if (matcher.find()) { 103 allocatorName += "32"; 104 } else { 105 allocatorName += "64"; 106 } 107 108 if (device.getBooleanProperty("ro.config.low_ram", false)) { 109 allocatorName += "_lowmemory"; 110 } 111 store.addResult("allocator", allocatorName); 112 113 collectMemCG(device, store); 114 collectMGLRU(device, store); 115 } 116 } 117