• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package ohos.devtools.datasources.transport.hdc;
17 
18 import ohos.devtools.datasources.utils.plugin.service.PlugManager;
19 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager;
20 import org.jetbrains.annotations.NotNull;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.ArrayList;
27 import java.util.concurrent.Callable;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.ExecutorService;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.SynchronousQueue;
32 import java.util.concurrent.ThreadPoolExecutor;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.TimeoutException;
35 
36 /**
37  * CmdExecutors
38  *
39  * @since 2021/9/20
40  */
41 public class CmdExecutors {
42     private static final Logger LOGGER = LoggerFactory.getLogger(CmdExecutors.class);
43 
44     static ExecutorService pool =
45         new ThreadPoolExecutor(0, Integer.MAX_VALUE, 3L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
46 
47     /**
48      * executeCommand
49      *
50      * @param command command
51      * @param timeout timeout
52      * @return ExecResult
53      */
executeCommand(ArrayList<String> command, long timeout)54     public ExecResult executeCommand(ArrayList<String> command, long timeout) {
55         if (ProfilerLogManager.isInfoEnabled()) {
56             LOGGER.info("executeCommand");
57         }
58         Process process = null;
59         InputStream pIn = null;
60         InputStream pErr = null;
61         IoStreamConsumer outputGobbler = null;
62         IoStreamConsumer errorGobbler = null;
63         Future<Integer> executeFuture = null;
64         try {
65             process = new ProcessBuilder(command).start();
66             pIn = process.getInputStream();
67             pErr = process.getErrorStream();
68             if (PlugManager.getInstance().getSystemOsName().contains("win") && command.contains("hdc_std")) {
69                 outputGobbler = new IoStreamConsumer(pIn);
70                 errorGobbler = new IoStreamConsumer(pErr);
71             } else {
72                 outputGobbler = new IoReadLineConsumer(pIn);
73                 errorGobbler = new IoReadLineConsumer(pErr);
74             }
75             outputGobbler.start();
76             errorGobbler.start();
77             Callable<Integer> call = new StreamCallBack(process);
78             executeFuture = pool.submit(call);
79             int exitCode = executeFuture.get(timeout, TimeUnit.SECONDS);
80             ArrayList<String> content = outputGobbler.getContent();
81             return new ExecResult(exitCode, content);
82         } catch (InterruptedException exception) {
83             if (ProfilerLogManager.isErrorEnabled()) {
84                 LOGGER.error("command [" + command + "] failed.", exception);
85             }
86             return getExecResult(outputGobbler, errorGobbler, -1);
87         } catch (ExecutionException | IOException | TimeoutException timeoutException) {
88             if (ProfilerLogManager.isErrorEnabled()) {
89                 LOGGER.error("command [" + command + "] failed.", timeoutException);
90             }
91             return getExecResult(outputGobbler, errorGobbler, -2);
92         } finally {
93             if (executeFuture != null) {
94                 executeFuture.cancel(true);
95             }
96             if (process != null) {
97                 process.destroy();
98             }
99         }
100     }
101 
102     class StreamCallBack implements Callable<java.lang.Integer> {
103         Process process;
104 
105         /**
106          * StreamCallBack
107          *
108          * @param process process
109          */
StreamCallBack(Process process)110         public StreamCallBack(Process process) {
111             this.process = process;
112         }
113 
114         @Override
call()115         public java.lang.Integer call() throws Exception {
116             process.waitFor();
117             return process.exitValue();
118         }
119     }
120 
121     /**
122      * executeCommand
123      *
124      * @param command command
125      * @param timeout timeout
126      * @return ExecResult
127      */
executeCommandByLine(ArrayList<String> command, long timeout)128     public ExecResult executeCommandByLine(ArrayList<String> command, long timeout) {
129         if (ProfilerLogManager.isInfoEnabled()) {
130             LOGGER.info("executeCommand");
131         }
132         Process process = null;
133         InputStream pIn = null;
134         InputStream pErr = null;
135         IoReadLineConsumer outputGobbler = null;
136         IoReadLineConsumer errorGobbler = null;
137         Future<Integer> executeFuture = null;
138         try {
139             process = new ProcessBuilder(command).start();
140             Process prcess = process;
141             pIn = process.getInputStream();
142             outputGobbler = new IoReadLineConsumer(pIn);
143             outputGobbler.start();
144             pErr = process.getErrorStream();
145             errorGobbler = new IoReadLineConsumer(pErr);
146             errorGobbler.start();
147             Callable<Integer> call = new StreamCallBack(process);
148             executeFuture = pool.submit(call);
149             int exitCode = executeFuture.get(timeout, TimeUnit.SECONDS);
150             ArrayList<String> content = outputGobbler.getContent();
151             return new ExecResult(exitCode, content);
152         } catch (IOException | TimeoutException | ExecutionException | InterruptedException exception) {
153             if (ProfilerLogManager.isErrorEnabled()) {
154                 LOGGER.error("command [" + command + "] failed.", exception);
155             }
156             return getExecResult(outputGobbler, errorGobbler, -1);
157         } finally {
158             if (executeFuture != null) {
159                 executeFuture.cancel(true);
160             }
161             if (process != null) {
162                 process.destroy();
163             }
164         }
165     }
166 
167     @NotNull
getExecResult(IoStreamConsumer outputGobbler, IoStreamConsumer errorGobbler, int exitCode)168     private ExecResult getExecResult(IoStreamConsumer outputGobbler, IoStreamConsumer errorGobbler, int exitCode) {
169         if (ProfilerLogManager.isInfoEnabled()) {
170             LOGGER.info("getExecResult");
171         }
172         if (errorGobbler.getContent().size() > 0 && outputGobbler.getContent().size() > 0) {
173             ArrayList<String> result = new ArrayList<>();
174             result.addAll(outputGobbler.getContent());
175             result.addAll(errorGobbler.getContent());
176             return new ExecResult(exitCode, result);
177         } else if (errorGobbler.getContent().size() > 0) {
178             return new ExecResult(exitCode, errorGobbler.getContent());
179         } else {
180             return new ExecResult(exitCode, outputGobbler.getContent());
181         }
182     }
183 }