1 /*
2  * Copyright (C) 2016 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 
17 package com.android.tradefed.util;
18 
19 import com.android.tradefed.log.LogUtil.CLog;
20 
21 import java.util.ArrayList;
22 import java.util.List;
23 
24 /**
25  * Utility used to parse(USER,PID and NAME) from the "ps" command output
26  */
27 public class PsParser {
28 
29     private static final String LINE_SEPARATOR = "\\n";
30     private static final String PROCESS_INFO_SEPARATOR = "\\s+";
31     private static final String BAD_PID = "bad pid '-A'";
32 
33     /**
34      * Parse username, process id and process name from the ps command output and convert to list of
35      * ProcessInfo objects.
36      *
37      * @param psOutput output of "ps" command.
38      * @return list of processInfo
39      */
getProcesses(String psOutput)40     public static List<ProcessInfo> getProcesses(String psOutput) {
41 
42         List<ProcessInfo> processesInfo = new ArrayList<ProcessInfo>();
43         if (psOutput.isEmpty()) {
44             return processesInfo;
45         }
46         String processLines[] = psOutput.split(LINE_SEPARATOR);
47 
48         /*
49          * (ps -A || ps) command prints "bad pid '-A'" as first line before the ps header in
50          * N and older builds so skip the first two lines.
51          */
52         int startLineNum = 1;
53         if (processLines[0].equals(BAD_PID)) {
54             startLineNum = 2;
55         }
56 
57         /*
58          * Sample output:
59          * USER PID PPID VSZ    RSS   WCHAN      PC  S NAME
60          * root   1   0  11140  1848  epoll_wait  0  S init
61          *
62          * Not collecting information other than USER,PID and NAME because they are
63          * not always printed for all the processess.
64          */
65         for (int lineCount = startLineNum; lineCount < processLines.length; lineCount++) {
66             String processInfoStr[] = processLines[lineCount].split(PROCESS_INFO_SEPARATOR);
67             CLog.i(processLines[lineCount]);
68             ProcessInfo psInfo = new ProcessInfo(processInfoStr[0],
69                     Integer.parseInt(processInfoStr[1]), processInfoStr[processInfoStr.length - 1]);
70             processesInfo.add(psInfo);
71         }
72         return processesInfo;
73     }
74 
75 }
76 
77