1 /*
2  * Copyright (C) 2012 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.ide.eclipse.ddms.systrace;
18 
19 import com.android.ddmlib.CollectingOutputReceiver;
20 import com.android.ddmlib.IDevice;
21 
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.jface.operation.IRunnableWithProgress;
24 
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.TimeUnit;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32 
33 public class SystraceVersionDetector implements IRunnableWithProgress {
34     public static final int SYSTRACE_V1 = 1;
35     public static final int SYSTRACE_V2 = 2;
36 
37     private final IDevice mDevice;
38     private List<SystraceTag> mTags;
39 
SystraceVersionDetector(IDevice device)40     public SystraceVersionDetector(IDevice device) {
41         mDevice = device;
42     }
43 
44     @Override
run(IProgressMonitor monitor)45     public void run(IProgressMonitor monitor) throws InvocationTargetException,
46             InterruptedException {
47         monitor.beginTask("Checking systrace version on device..",
48                 IProgressMonitor.UNKNOWN);
49 
50         CountDownLatch setTagLatch = new CountDownLatch(1);
51         CollectingOutputReceiver receiver = new CollectingOutputReceiver(setTagLatch);
52         try {
53             String cmd = "atrace --list_categories";
54             mDevice.executeShellCommand(cmd, receiver);
55             setTagLatch.await(5, TimeUnit.SECONDS);
56         } catch (Exception e) {
57             throw new InvocationTargetException(e);
58         }
59 
60         String shellOutput = receiver.getOutput();
61         mTags = parseSupportedTags(shellOutput);
62 
63         monitor.done();
64     }
65 
getVersion()66     public int getVersion() {
67         if (mTags == null) {
68             return SYSTRACE_V1;
69         } else {
70             return SYSTRACE_V2;
71         }
72     }
73 
getTags()74     public List<SystraceTag> getTags() {
75         return mTags;
76     }
77 
parseSupportedTags(String listCategoriesOutput)78     private List<SystraceTag> parseSupportedTags(String listCategoriesOutput) {
79         if (listCategoriesOutput == null) {
80             return null;
81         }
82 
83         if (listCategoriesOutput.contains("unknown option")) {
84             return null;
85         }
86 
87         String[] categories = listCategoriesOutput.split("\n");
88         List<SystraceTag> tags = new ArrayList<SystraceTag>(categories.length);
89 
90         Pattern p = Pattern.compile("([^-]+) - (.*)"); //$NON-NLS-1$
91         for (String category : categories) {
92             Matcher m = p.matcher(category);
93             if (m.find()) {
94                 tags.add(new SystraceTag(m.group(1).trim(), m.group(2).trim()));
95             }
96         }
97 
98         return tags;
99     }
100 }
101