1 /*
2  * Copyright (C) 2023 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.car.cts.utils;
17 
18 import android.util.ArrayMap;
19 
20 import com.android.compatibility.common.util.ShellUtils;
21 
22 import java.util.Map;
23 import java.util.Scanner;
24 import java.util.regex.MatchResult;
25 import java.util.regex.Pattern;
26 
27 /**
28  * Class contains utility methods to dumpsys for car services
29  */
30 public final class DumpUtils {
DumpUtils()31     private DumpUtils() {}
32 
33     /**
34      * Dumps a given CarService by shell command.
35      * It will parse the dump output with ':' or '=' separator and put it into a map with the first
36      * part as a key and the second part as a value.
37      *
38      * @param serviceName Name of service to be dumped.
39      * @return map contains the dump output
40      */
executeDumpShellCommand(String serviceName)41     public static Map<String, String> executeDumpShellCommand(String serviceName) {
42         String output = ShellUtils.runShellCommand(
43                 "dumpsys car_service --services " + serviceName);
44         return parseDumpResult(serviceName, output);
45     }
46 
parseDumpResult(String serviceName, String output)47     private static ArrayMap<String, String> parseDumpResult(String serviceName, String output) {
48         Scanner scanner = new Scanner(output);
49         ArrayMap<String, String> map = new ArrayMap<>();
50         // Pattern to match the title, For example:
51         //   *CarMediaService*
52         Pattern patternHeader = Pattern.compile("\\*" + serviceName + "\\*");
53         // Pattern to match key-value with ':' or '=' as separator. For example:
54         //   mPlayOnBootConfig=2
55         //   MediaConnectorService: com.android.car.media/.service.MediaConnectorService
56         Pattern patternBody = Pattern.compile("\\s*(\\w+)\\s*[:=]\\s*(\\S+)");
57         Pattern currentPattern = patternHeader;
58         while (scanner.hasNextLine()) {
59             scanner.nextLine();
60             String matchedLine = scanner.findInLine(currentPattern);
61             if (matchedLine == null) {
62                 continue;
63             }
64             if (currentPattern == patternHeader) {
65                 currentPattern = patternBody;
66                 continue;
67             }
68             MatchResult match = scanner.match();
69             map.put(match.group(1), match.group(2));
70         }
71         return map;
72     }
73 }
74