diff options
Diffstat (limited to 'tools/tradefed-host/src/com/android/afwtest/tradefed/utils/AdbShellUtils.java')
-rw-r--r-- | tools/tradefed-host/src/com/android/afwtest/tradefed/utils/AdbShellUtils.java | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tools/tradefed-host/src/com/android/afwtest/tradefed/utils/AdbShellUtils.java b/tools/tradefed-host/src/com/android/afwtest/tradefed/utils/AdbShellUtils.java new file mode 100644 index 0000000..50e7706 --- /dev/null +++ b/tools/tradefed-host/src/com/android/afwtest/tradefed/utils/AdbShellUtils.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2017 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. + */ + +package com.android.afwtest.tradefed.utils; + +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.ITestDevice; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility class containing methods related to executing various ADB Shell commands. + */ +public final class AdbShellUtils { + + /** Prevent class from instantiation. */ + private AdbShellUtils() { + } + + /** + * Gets process list currently running on the device grouped by user. + * + * @param testDevice device to get process list from. + * @return {@link Map} of user ids to a {@link Set} of process ids run by the user. + * @throws DeviceNotAvailableException if device became unavailable during the execution of + * the method. + */ + public static Set<ProcessInfo> getPS(ITestDevice testDevice) + throws DeviceNotAvailableException { + Set<ProcessInfo> result = new HashSet<>(); + String psOutput = testDevice.executeShellCommand("ps -e"); + for (String line : psOutput.split("\n")) { + if (line.contains("USER")) { + continue; + } + + String[] columns = line.split("\\s+"); + String user = columns[0]; + long pid = Long.parseLong(columns[1]); + long ppid = Long.parseLong(columns[2]); + String name = columns[8]; + + result.add(new ProcessInfo(user, pid, ppid, name)); + } + return result; + } + + /** + * Gets memory consumption information about processes currently running on the device. + * + * @param testDevice device to get memory information from. + * @return {@link Map} of process ids to total PSS of the process. + * @throws DeviceNotAvailableException if device became unavailable during the execution of + * the method. + */ + public static Map<Long, Long> getMemoryInfo(ITestDevice testDevice) + throws DeviceNotAvailableException { + Map<Long, Long> result = new HashMap<>(); + String miOutput = testDevice.executeShellCommand("su system dumpsys meminfo -c"); + for (String line : miOutput.split("\n")) { + String[] columns = line.split(","); + if (columns[0].equals("proc")) { + long pid = Long.parseLong(columns[3]); + long pss = Long.parseLong(columns[4]); + result.put(pid, pss); + } + } + return result; + } + + /** + * Class representing information about process retrieved from ps command. + */ + public static final class ProcessInfo { + + /** + * {@link Pattern} of Android user name that encodes user id and activity id. + */ + private static final Pattern APP_PROCESS_USER_PATTERN = Pattern.compile("u(\\d+)_a\\d+"); + + private final String mUser; + private final long mPID; + private final long mPPID; + private final String mName; + + private ProcessInfo(String user, long pid, long ppid, String name) { + this.mUser = user; + this.mPID = pid; + this.mPPID = ppid; + this.mName = name; + } + + /** + * Gets user name running the process. + * + * @return user name running the process. + */ + public String getUser() { + return mUser; + } + + /** + * Gets the id of the process. + * + * @return the id of the process. + */ + public long getPID() { + return mPID; + } + + /** + * Gets the id of the parent of the process. + * + * @return the id of the parent of the process. + */ + public long getPPID() { + return mPPID; + } + + /** + * Get the name of the process. + * + * @return the name of the process. + */ + public String getName() { + return mName; + } + + /** + * Gets the id if Android user running the process, or -1 of the process is run by + * the system. + * + * @return the id if Android user running the process, or -1 of the process is run by + * the system. + */ + public long getAndroidUserId() { + long userId = -1; + Matcher matcher = APP_PROCESS_USER_PATTERN.matcher(mName); + if (matcher.find()) { + userId = Long.parseLong(matcher.group(1)); + } + return userId; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ProcessInfo that = (ProcessInfo) o; + return mPID == that.mPID && + mPPID == that.mPPID && + Objects.equals(mUser, that.mUser) && + Objects.equals(mName, that.mName); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hash(mUser, mPID, mPPID, mName); + } + } +} |