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.services.distribute; 17 18 import ohos.devtools.datasources.transport.grpc.SystemTraceHelper; 19 import ohos.devtools.datasources.transport.hdc.HdcWrapper; 20 import ohos.devtools.datasources.utils.device.entity.DeviceIPPortInfo; 21 import ohos.devtools.datasources.utils.device.entity.DeviceType; 22 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 23 import ohos.devtools.views.distributed.bean.DistributedParams; 24 import ohos.devtools.views.layout.utils.TraceStreamerUtils; 25 import org.apache.commons.lang.StringUtils; 26 import org.apache.logging.log4j.LogManager; 27 import org.apache.logging.log4j.Logger; 28 29 import java.util.ArrayList; 30 import java.util.Comparator; 31 import java.util.List; 32 import java.util.Optional; 33 import java.util.concurrent.Callable; 34 import java.util.concurrent.ExecutionException; 35 import java.util.concurrent.ExecutorService; 36 import java.util.concurrent.Future; 37 import java.util.concurrent.LinkedBlockingQueue; 38 import java.util.concurrent.ThreadPoolExecutor; 39 import java.util.concurrent.TimeUnit; 40 41 import static ohos.devtools.datasources.transport.hdc.HdcCmdList.HDC_GET_TIME; 42 import static ohos.devtools.datasources.transport.hdc.HdcCmdList.HDC_HAS_TRACE_FILE_INFO; 43 import static ohos.devtools.datasources.transport.hdc.HdcCmdList.HDC_PULL_TRACE_FILE; 44 import static ohos.devtools.datasources.transport.hdc.HdcCmdList.TRACE_STREAMER_LOAD; 45 import static ohos.devtools.datasources.transport.hdc.HdcStdCmdList.HDC_STD_GET_TIME; 46 import static ohos.devtools.datasources.transport.hdc.HdcStdCmdList.HDC_STD_HAS_TRACE_FILE_INFO; 47 import static ohos.devtools.datasources.transport.hdc.HdcStdCmdList.HDC_STD_PULL_TRACE_FILE; 48 import static ohos.devtools.datasources.transport.hdc.HdcWrapper.conversionCommand; 49 import static ohos.devtools.datasources.utils.device.entity.DeviceType.LEAN_HOS_DEVICE; 50 import static ohos.devtools.views.common.Constant.IS_SUPPORT_NEW_HDC; 51 52 /** 53 * DistributedManager 54 * 55 * @since 2021/9/20 56 */ 57 public class DistributedManager { 58 private static final Logger LOGGER = LogManager.getLogger(DistributedManager.class); 59 private static final String FULL_PERFETTO_STR = 60 "power;ability;ace;app;audio;binder_lock;camera;database;distributeddatamgr;gfx;graphic;hal;" 61 + "i2c;idle;input;mdfs;memreclaim;network;nnapi;notification;ohos;res;rro;rs;sm;ss;vibrator;video;view;" 62 + "webview;wm;zaudio;zcamera;zimage;zmedia"; 63 private static final String LEAN_PERFETTO_STR = 64 "ability;ace;app;distributeddatamgr;freq;graphic;idle;irq;mdfs;mmc;notification;ohos;pagecache;sync;" 65 + "workq;zaudio;zcamera;zimage;zmedia"; 66 private static final int NUMBER_OF_TIMES = 10; 67 68 private final DistributeDevice firstDevice; 69 private final DistributeDevice secondDevice; 70 private final int maxDurationParam = 10; 71 private int firstFileSize; 72 private int secondFileSize; 73 private long firstStartTime; 74 private long secondStartTime; 75 private boolean isTest = false; 76 private final ExecutorService executorService = 77 new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); 78 79 /** 80 * DistributedManager 81 * 82 * @param firstDevice firstDevice 83 * @param secondDevice secondDevice 84 */ DistributedManager(DistributeDevice firstDevice, DistributeDevice secondDevice)85 public DistributedManager(DistributeDevice firstDevice, DistributeDevice secondDevice) { 86 this.firstDevice = firstDevice; 87 this.secondDevice = secondDevice; 88 } 89 90 /** 91 * startCollecting 92 * 93 * @return boolean 94 */ startCollecting()95 public boolean startCollecting() { 96 if (ProfilerLogManager.isInfoEnabled()) { 97 LOGGER.info("startCollecting"); 98 } 99 Future<Optional<TimeCalibrationBean>> firstDeviceTimeBeanOpt = 100 executorService.submit(new TimeCalibrationDevice(firstDevice)); 101 Future<Optional<TimeCalibrationBean>> secondDeviceTimeBeanOpt = 102 executorService.submit(new TimeCalibrationDevice(secondDevice)); 103 try { 104 Optional<TimeCalibrationBean> firstDeviceCalibrationBean = firstDeviceTimeBeanOpt.get(); 105 Optional<TimeCalibrationBean> secondDeviceCalibrationBean = secondDeviceTimeBeanOpt.get(); 106 107 if (firstDeviceCalibrationBean.isPresent() && secondDeviceCalibrationBean.isPresent()) { 108 TimeCalibrationBean firstDeviceCalibration = firstDeviceCalibrationBean.get(); 109 TimeCalibrationBean secondDeviceCalibration = secondDeviceCalibrationBean.get(); 110 long realPc1Time = firstDeviceCalibration.getPcTime() + (firstDeviceCalibration.getUseTime() / 2); 111 long realPc2Time = secondDeviceCalibration.getPcTime() + (secondDeviceCalibration.getUseTime() / 2); 112 long timeDifference = realPc1Time - realPc2Time; 113 if (timeDifference == 0) { 114 // 时间一致不需要同步 115 firstStartTime = firstDeviceCalibration.getDeviceTime(); 116 secondStartTime = secondDeviceCalibration.getDeviceTime(); 117 } else if (timeDifference < 0) { 118 firstStartTime = firstDeviceCalibration.getDeviceTime(); 119 secondStartTime = secondDeviceCalibration.getDeviceTime() + timeDifference; 120 } else { 121 firstStartTime = firstDeviceCalibration.getDeviceTime() + timeDifference; 122 secondStartTime = secondDeviceCalibration.getDeviceTime(); 123 } 124 } 125 Future<String> firstResult = executorService.submit(new CollectingCallBack(firstDevice)); 126 Future<String> secondResult = executorService.submit(new CollectingCallBack(secondDevice)); 127 String firstString = firstResult.get(); 128 String secondString = secondResult.get(); 129 if (StringUtils.equals(firstString, "0") || StringUtils.equals(secondString, "0")) { 130 if (ProfilerLogManager.isInfoEnabled()) { 131 LOGGER.info("startSession failed"); 132 } 133 return false; 134 } else { 135 firstDevice.setSessionId(firstString); 136 secondDevice.setSessionId(secondString); 137 return true; 138 } 139 } catch (InterruptedException | ExecutionException exception) { 140 if (ProfilerLogManager.isErrorEnabled()) { 141 LOGGER.error("start Collect Failed ", exception); 142 } 143 return false; 144 } 145 } 146 147 class TimeCalibrationDevice implements Callable<Optional<TimeCalibrationBean>> { 148 private final DistributeDevice distributeDevice; 149 150 /** 151 * TimeCalibrationDevice 152 * 153 * @param distributeDevice distributeDevice 154 */ TimeCalibrationDevice(DistributeDevice distributeDevice)155 public TimeCalibrationDevice(DistributeDevice distributeDevice) { 156 this.distributeDevice = distributeDevice; 157 } 158 159 @Override call()160 public Optional<TimeCalibrationBean> call() throws Exception { 161 return calibrationEquipmentTime(distributeDevice); 162 } 163 calibrationEquipmentTime(DistributeDevice distributeDevice)164 private Optional<TimeCalibrationBean> calibrationEquipmentTime(DistributeDevice distributeDevice) { 165 List<TimeCalibrationBean> timeBeans = new ArrayList<>(); 166 for (int count = 0; count < NUMBER_OF_TIMES; count++) { 167 TimeCalibrationBean timeCalibrationBean = getDeviceTime(distributeDevice); 168 timeBeans.add(timeCalibrationBean); 169 } 170 LOGGER.info("timeBeans {}", timeBeans); 171 return timeBeans.stream().sorted(Comparator.comparingLong(TimeCalibrationBean::getUseTime)).findFirst(); 172 } 173 } 174 175 /** 176 * hasFile 177 * 178 * @return boolean 179 */ hasFile()180 public boolean hasFile() { 181 if (ProfilerLogManager.isInfoEnabled()) { 182 LOGGER.info("hasFile"); 183 } 184 DeviceIPPortInfo firstInfo = firstDevice.getDeviceIPPortInfo(); 185 DeviceIPPortInfo secondInfo = secondDevice.getDeviceIPPortInfo(); 186 ArrayList<String> firstFormat; 187 if (IS_SUPPORT_NEW_HDC && firstInfo.getDeviceType() == LEAN_HOS_DEVICE) { 188 firstFormat = 189 conversionCommand(HDC_STD_HAS_TRACE_FILE_INFO, firstInfo.getDeviceID(), getTraceFilePath(firstDevice)); 190 } else { 191 firstFormat = 192 conversionCommand(HDC_HAS_TRACE_FILE_INFO, firstInfo.getDeviceID(), getTraceFilePath(firstDevice)); 193 } 194 String firstResult = HdcWrapper.getInstance().execCmdBy(firstFormat); 195 ArrayList<String> secondFrom; 196 if (IS_SUPPORT_NEW_HDC && secondInfo.getDeviceType() == LEAN_HOS_DEVICE) { 197 secondFrom = conversionCommand(HDC_STD_HAS_TRACE_FILE_INFO, secondInfo.getDeviceID(), 198 getTraceFilePath(secondDevice)); 199 } else { 200 secondFrom = 201 conversionCommand(HDC_HAS_TRACE_FILE_INFO, secondInfo.getDeviceID(), getTraceFilePath(secondDevice)); 202 } 203 String secondResult = HdcWrapper.getInstance().execCmdBy(secondFrom); 204 if (!firstFormat.isEmpty() && !secondFrom.isEmpty()) { 205 String[] firstFileArray = firstResult.split("\t"); 206 String[] secondFileArray = secondResult.split("\t"); 207 if (firstFileSize != 0 && firstFileSize == Integer.valueOf(firstFileArray[0]) && secondFileSize != 0 208 && secondFileSize == Integer.valueOf(secondFileArray[0])) { 209 return true; 210 } else { 211 firstFileSize = Integer.valueOf(firstFileArray[0]); 212 secondFileSize = Integer.valueOf(secondFileArray[0]); 213 return false; 214 } 215 } 216 return false; 217 } 218 219 /** 220 * pullTraceFile 221 * 222 * @return boolean 223 */ pullTraceFile()224 public boolean pullTraceFile() { 225 if (ProfilerLogManager.isInfoEnabled()) { 226 LOGGER.info("pullTraceFile"); 227 } 228 DeviceIPPortInfo firstInfo = firstDevice.getDeviceIPPortInfo(); 229 DeviceIPPortInfo secondInfo = secondDevice.getDeviceIPPortInfo(); 230 String secondTraceFilePath; 231 String firstTraceFilePath; 232 if (isTest) { 233 firstTraceFilePath = getTestTraceFilePath(firstDevice); 234 secondTraceFilePath = getTestTraceFilePath(secondDevice); 235 } else { 236 firstTraceFilePath = getTraceFilePath(firstDevice); 237 secondTraceFilePath = getTraceFilePath(secondDevice); 238 } 239 ArrayList pullFirstTraceFile; 240 if (IS_SUPPORT_NEW_HDC && firstInfo.getDeviceType() == LEAN_HOS_DEVICE) { 241 pullFirstTraceFile = conversionCommand(HDC_STD_PULL_TRACE_FILE, firstInfo.getDeviceID(), firstTraceFilePath, 242 TraceStreamerUtils.getInstance().getCreateFileDir()); 243 } else { 244 pullFirstTraceFile = conversionCommand(HDC_PULL_TRACE_FILE, firstInfo.getDeviceID(), firstTraceFilePath, 245 TraceStreamerUtils.getInstance().getCreateFileDir()); 246 } 247 if (ProfilerLogManager.isInfoEnabled()) { 248 LOGGER.info("pullFirstTraceFile {}", pullFirstTraceFile); 249 } 250 HdcWrapper.getInstance().getHdcStringResult(pullFirstTraceFile); 251 ArrayList pullSecondTraceFile; 252 if (IS_SUPPORT_NEW_HDC && secondInfo.getDeviceType() == LEAN_HOS_DEVICE) { 253 pullSecondTraceFile = 254 conversionCommand(HDC_STD_PULL_TRACE_FILE, secondInfo.getDeviceID(), secondTraceFilePath, 255 TraceStreamerUtils.getInstance().getCreateFileDir()); 256 } else { 257 pullSecondTraceFile = conversionCommand(HDC_PULL_TRACE_FILE, secondInfo.getDeviceID(), secondTraceFilePath, 258 TraceStreamerUtils.getInstance().getCreateFileDir()); 259 } 260 if (ProfilerLogManager.isInfoEnabled()) { 261 LOGGER.info("pullSecondTraceFile {}", pullSecondTraceFile); 262 } 263 HdcWrapper.getInstance().getHdcStringResult(pullSecondTraceFile); 264 return true; 265 } 266 267 /** 268 * analysisFileTraceFile 269 * 270 * @return boolean 271 */ analysisFileTraceFile()272 public boolean analysisFileTraceFile() { 273 if (ProfilerLogManager.isInfoEnabled()) { 274 LOGGER.info("analysisFileTraceFile"); 275 } 276 String firstTraceFile; 277 String secondTraceFile; 278 if (isTest) { 279 firstTraceFile = getTestTraceFile(firstDevice); 280 secondTraceFile = getTestTraceFile(secondDevice); 281 } else { 282 firstTraceFile = getTraceFile(firstDevice); 283 secondTraceFile = getTraceFile(secondDevice); 284 } 285 String baseDir = TraceStreamerUtils.getInstance().getBaseDir(); 286 String fileDir = TraceStreamerUtils.getInstance().getCreateFileDir(); 287 String traceStreamerApp = TraceStreamerUtils.getInstance().getTraceStreamerApp(); 288 String dbPathFirst = TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(firstDevice)); 289 ArrayList firstList = 290 conversionCommand(TRACE_STREAMER_LOAD, baseDir + traceStreamerApp, fileDir + firstTraceFile, dbPathFirst); 291 HdcWrapper.getInstance().getHdcStringResult(firstList); 292 String dbPathSecond = TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(secondDevice)); 293 ArrayList secondList = 294 conversionCommand(TRACE_STREAMER_LOAD, baseDir + traceStreamerApp, fileDir + secondTraceFile, dbPathSecond); 295 HdcWrapper.getInstance().getHdcStringResult(secondList); 296 return true; 297 } 298 299 /** 300 * getDistributedParams 301 * 302 * @return DistributedParams 303 */ getDistributedParams()304 public DistributedParams getDistributedParams() { 305 if (ProfilerLogManager.isInfoEnabled()) { 306 LOGGER.info("getDistributedParams"); 307 } 308 DeviceIPPortInfo deviceIPPortInfo = firstDevice.getDeviceIPPortInfo(); 309 DeviceIPPortInfo secondDeviceIPPortInfo = secondDevice.getDeviceIPPortInfo(); 310 String processName = firstDevice.getProcessName(); 311 String secondName = secondDevice.getProcessName(); 312 String pid = processName.substring(processName.lastIndexOf("(") + 1, processName.lastIndexOf(")")); 313 String secondPid = secondName.substring(secondName.lastIndexOf("(") + 1, secondName.lastIndexOf(")")); 314 if (isTest) { 315 return new DistributedParams.Builder().setDeviceNameA(deviceIPPortInfo.getDeviceName()) 316 .setDeviceNameB(secondDeviceIPPortInfo.getDeviceName()) 317 .setPathA(TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(firstDevice))) 318 .setPathB(TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(secondDevice))) 319 .setPkgNameA(processName).setPkgNameB(secondName).setProcessIdA(27521).setProcessIdB(1155).build(); 320 } 321 return new DistributedParams.Builder().setDeviceNameA(deviceIPPortInfo.getDeviceName()) 322 .setDeviceNameB(secondDeviceIPPortInfo.getDeviceName()) 323 .setPathA(TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(firstDevice))) 324 .setPathB(TraceStreamerUtils.getInstance().getDbPath(getTraceDBName(secondDevice))).setPkgNameA(processName) 325 .setPkgNameB(secondName).setProcessIdA(Integer.parseInt(pid)).setProcessIdB(Integer.parseInt(secondPid)) 326 .setOffsetA(firstStartTime).setOffsetB(secondStartTime).build(); 327 } 328 getTraceFilePath(DistributeDevice distributeDevice)329 private String getTraceFilePath(DistributeDevice distributeDevice) { 330 if (ProfilerLogManager.isInfoEnabled()) { 331 LOGGER.info("getTraceFilePath"); 332 } 333 return "/data/local/tmp/" + getTraceFile(distributeDevice); 334 } 335 getTestTraceFilePath(DistributeDevice distributeDevice)336 private String getTestTraceFilePath(DistributeDevice distributeDevice) { 337 if (ProfilerLogManager.isInfoEnabled()) { 338 LOGGER.info("getTestTraceFilePath"); 339 } 340 return "/data/local/tmp/" + getTestTraceFile(distributeDevice); 341 } 342 getTraceFile(DistributeDevice distributeDevice)343 private String getTraceFile(DistributeDevice distributeDevice) { 344 if (ProfilerLogManager.isInfoEnabled()) { 345 LOGGER.info("getTraceFile"); 346 } 347 DeviceIPPortInfo deviceIPPortInfo = distributeDevice.getDeviceIPPortInfo(); 348 String processName = distributeDevice.getProcessName(); 349 String pid = processName.substring(processName.lastIndexOf("(") + 1, processName.lastIndexOf(")")); 350 return deviceIPPortInfo.getDeviceName() + pid + ".bytrace"; 351 } 352 getTestTraceFile(DistributeDevice distributeDevice)353 private String getTestTraceFile(DistributeDevice distributeDevice) { 354 if (ProfilerLogManager.isInfoEnabled()) { 355 LOGGER.info("getTestTraceFile"); 356 } 357 if (distributeDevice.equals(firstDevice)) { 358 return "fbs_dev_1.trace"; 359 } else { 360 return "fbs_dev_2.trace"; 361 } 362 } 363 getTraceDBName(DistributeDevice distributeDevice)364 private String getTraceDBName(DistributeDevice distributeDevice) { 365 if (ProfilerLogManager.isInfoEnabled()) { 366 LOGGER.info("getTraceDBName"); 367 } 368 DeviceIPPortInfo deviceIPPortInfo = distributeDevice.getDeviceIPPortInfo(); 369 String processName = distributeDevice.getProcessName(); 370 String pid = processName.substring(processName.lastIndexOf("(") + 1, processName.lastIndexOf(")")); 371 return deviceIPPortInfo.getDeviceName() + pid + ".db"; 372 } 373 374 /** 375 * cancelCollection 376 */ cancelCollection()377 public void cancelCollection() { 378 if (ProfilerLogManager.isInfoEnabled()) { 379 LOGGER.info("cancelCollection"); 380 } 381 SystemTraceHelper systemTraceHelper = SystemTraceHelper.getSingleton(); 382 systemTraceHelper.stopSession(firstDevice.getDeviceIPPortInfo(), firstDevice.getSessionId()); 383 systemTraceHelper.cancelActionDestroySession(firstDevice.getDeviceIPPortInfo(), firstDevice.getSessionId()); 384 systemTraceHelper.stopSession(secondDevice.getDeviceIPPortInfo(), secondDevice.getSessionId()); 385 systemTraceHelper.cancelActionDestroySession(secondDevice.getDeviceIPPortInfo(), secondDevice.getSessionId()); 386 } 387 388 /** 389 * stopCollection 390 */ stopCollection()391 public void stopCollection() { 392 if (ProfilerLogManager.isInfoEnabled()) { 393 LOGGER.info("stopCollection"); 394 } 395 SystemTraceHelper systemTraceHelper = SystemTraceHelper.getSingleton(); 396 systemTraceHelper.stopSession(firstDevice.getDeviceIPPortInfo(), firstDevice.getSessionId()); 397 systemTraceHelper.cancelActionDestroySession(firstDevice.getDeviceIPPortInfo(), firstDevice.getSessionId()); 398 systemTraceHelper.stopSession(secondDevice.getDeviceIPPortInfo(), secondDevice.getSessionId()); 399 systemTraceHelper.cancelActionDestroySession(secondDevice.getDeviceIPPortInfo(), secondDevice.getSessionId()); 400 401 } 402 403 /** 404 * getMaxDurationParam 405 * 406 * @return int 407 */ getMaxDurationParam()408 public int getMaxDurationParam() { 409 return maxDurationParam; 410 } 411 412 /** 413 * CollectingCallBack 414 */ 415 class CollectingCallBack implements Callable<String> { 416 private final DistributeDevice distributeDevice; 417 418 /** 419 * CollectingCallBack 420 * 421 * @param distributeDevice distributeDevice 422 */ CollectingCallBack(DistributeDevice distributeDevice)423 public CollectingCallBack(DistributeDevice distributeDevice) { 424 this.distributeDevice = distributeDevice; 425 } 426 427 @Override call()428 public String call() throws Exception { 429 String outPutPath = getTraceFilePath(distributeDevice); 430 String perfettoString; 431 if (distributeDevice.getDeviceIPPortInfo().getDeviceType() == DeviceType.FULL_HOS_DEVICE) { 432 perfettoString = FULL_PERFETTO_STR; 433 } else { 434 perfettoString = LEAN_PERFETTO_STR; 435 } 436 return SystemTraceHelper.getSingleton() 437 .createSessionByTraceRequest(distributeDevice.getDeviceIPPortInfo(), perfettoString, maxDurationParam, 438 10, outPutPath, false); 439 } 440 } 441 getDeviceTime(DistributeDevice distributeDevice)442 private TimeCalibrationBean getDeviceTime(DistributeDevice distributeDevice) { 443 ArrayList<String> cmd; 444 if (IS_SUPPORT_NEW_HDC && distributeDevice.getDeviceIPPortInfo().getDeviceType() == LEAN_HOS_DEVICE) { 445 cmd = conversionCommand(HDC_STD_GET_TIME, distributeDevice.getDeviceIPPortInfo().getDeviceID()); 446 } else { 447 cmd = conversionCommand(HDC_GET_TIME, distributeDevice.getDeviceIPPortInfo().getDeviceID()); 448 } 449 long pcTime = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()); 450 String deviceTime = HdcWrapper.getInstance().execCmdBy(cmd); 451 long endTime = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()); 452 TimeCalibrationBean timeCalibrationBean = new TimeCalibrationBean(); 453 timeCalibrationBean.setPcTime(pcTime); 454 timeCalibrationBean.setEndTime(endTime); 455 timeCalibrationBean.setDeviceTime(Long.parseLong(deviceTime)); 456 return timeCalibrationBean; 457 } 458 459 class TimeCalibrationBean { 460 private long pcTime; 461 private long endTime; 462 private long deviceTime; 463 464 /** 465 * getPcTime 466 * 467 * @return long 468 */ getPcTime()469 public long getPcTime() { 470 return pcTime; 471 } 472 473 /** 474 * setPcTime 475 * 476 * @param pcTime pcTime 477 */ setPcTime(long pcTime)478 public void setPcTime(long pcTime) { 479 this.pcTime = pcTime; 480 } 481 482 /** 483 * getEndTime 484 * 485 * @return long 486 */ getEndTime()487 public long getEndTime() { 488 return endTime; 489 } 490 491 /** 492 * setEndTime 493 * 494 * @param endTime endTime 495 */ setEndTime(long endTime)496 public void setEndTime(long endTime) { 497 this.endTime = endTime; 498 } 499 500 /** 501 * getDeviceTime 502 * 503 * @return long 504 */ getDeviceTime()505 public long getDeviceTime() { 506 return deviceTime; 507 } 508 509 /** 510 * setDeviceTime 511 * 512 * @param deviceTime deviceTime 513 */ setDeviceTime(long deviceTime)514 public void setDeviceTime(long deviceTime) { 515 this.deviceTime = deviceTime; 516 } 517 518 /** 519 * getUseTime 520 * 521 * @return long 522 */ getUseTime()523 public long getUseTime() { 524 return endTime - pcTime; 525 } 526 527 @Override toString()528 public String toString() { 529 return "TimeCalibrationBean{" + "pcTime=" + pcTime + ", endTime=" + endTime + ", deviceTime=" + deviceTime 530 + ", useTime=" + (endTime - pcTime) + '}'; 531 } 532 } 533 534 /** 535 * Result 536 */ 537 class Result { 538 private String sessionId; 539 private String StartTime; 540 541 /** 542 * Result 543 * 544 * @param sessionId sessionId 545 * @param startTime startTime 546 */ Result(String sessionId, String startTime)547 public Result(String sessionId, String startTime) { 548 this.sessionId = sessionId; 549 StartTime = startTime; 550 } 551 552 /** 553 * getSessionId 554 * 555 * @return String 556 */ getSessionId()557 public String getSessionId() { 558 return sessionId; 559 } 560 561 /** 562 * getStartTime 563 * 564 * @return String 565 */ getStartTime()566 public String getStartTime() { 567 return StartTime; 568 } 569 } 570 571 } 572