android设备创建driver时指定固定的端口
							parent
							
								
									2fa3e721df
								
							
						
					
					
						commit
						5de13aaf46
					
				| 
						 | 
					@ -24,5 +24,7 @@ public class DeviceInfo{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private String resolution;  //分辨率
 | 
					    private String resolution;  //分辨率
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private int forwardPort;  //android在appium自动化时的adb转发端口
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Map<String,String> otherInfo;
 | 
					    private Map<String,String> otherInfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,15 +230,23 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
 | 
				
			||||||
        return desiredCapabilities;
 | 
					        return desiredCapabilities;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private AndroidMobileDeviceDriver createAndroidDriver(URL appiumServerUrl, String deviceId, Map<String, String> others) {
 | 
					    private AndroidMobileDeviceDriver createAndroidDriver(URL appiumServerUrl, String upperUrl, String deviceId, Map<String, String> others) {
 | 
				
			||||||
        AndroidMobileDeviceDriver driver = null;
 | 
					 | 
				
			||||||
        DesiredCapabilities capabilities = initAndroidCapabilities(deviceId, others);
 | 
					        DesiredCapabilities capabilities = initAndroidCapabilities(deviceId, others);
 | 
				
			||||||
 | 
					        AndroidMobileDeviceDriver driver = null;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            driver = new AndroidMobileDeviceDriver(appiumServerUrl, capabilities);
 | 
					            driver = new AndroidMobileDeviceDriver(appiumServerUrl, capabilities);
 | 
				
			||||||
            return driver;
 | 
					 | 
				
			||||||
        } catch (SessionNotCreatedException e) {
 | 
					        } catch (SessionNotCreatedException e) {
 | 
				
			||||||
            log.error("设备未连接到上位机", e);
 | 
					            log.error("Driver创建失败,设备连接失败", e);
 | 
				
			||||||
            throw new ExecuteException("设备无法初始化,请将设备重新拔插后再试");
 | 
					            String errorMessage = String.format("the local port #%s is busy", deviceInfo.getForwardPort());
 | 
				
			||||||
 | 
					            if (e.getMessage().contains(errorMessage)) {
 | 
				
			||||||
 | 
					                log.warn("设备【{}】adb转发的端口【{}】被占用了,释放了重新来", deviceId, deviceInfo.getForwardPort());
 | 
				
			||||||
 | 
					                boolean success = AndroidUtil.releaseAdbForwardPort(this.remoteAddress, deviceId);
 | 
				
			||||||
 | 
					                if (success) {
 | 
				
			||||||
 | 
					                    driver = new AndroidMobileDeviceDriver(appiumServerUrl, capabilities);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    log.warn("设备【{}】adb转发的端口【{}】被占用了,没有释放成功", deviceId, deviceInfo.getForwardPort());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } catch (WebDriverException e) {
 | 
					        } catch (WebDriverException e) {
 | 
				
			||||||
            log.warn("设备【{}】Driver创建失败,重新试一次", deviceId, e);
 | 
					            log.warn("设备【{}】Driver创建失败,重新试一次", deviceId, e);
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
| 
						 | 
					@ -254,6 +262,30 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
 | 
				
			||||||
        return driver;
 | 
					        return driver;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//    private AndroidMobileDeviceDriver createAndroidDriver(URL appiumServerUrl, String deviceId, Map<String, String> others) {
 | 
				
			||||||
 | 
					//        AndroidMobileDeviceDriver driver = null;
 | 
				
			||||||
 | 
					//        DesiredCapabilities capabilities = initAndroidCapabilities(deviceId, others);
 | 
				
			||||||
 | 
					//        try {
 | 
				
			||||||
 | 
					//            driver = new AndroidMobileDeviceDriver(appiumServerUrl, capabilities);
 | 
				
			||||||
 | 
					//            return driver;
 | 
				
			||||||
 | 
					//        } catch (SessionNotCreatedException e) {
 | 
				
			||||||
 | 
					//            log.error("设备未连接到上位机", e);
 | 
				
			||||||
 | 
					//            throw new ExecuteException("设备无法初始化,请将设备重新拔插后再试");
 | 
				
			||||||
 | 
					//        } catch (WebDriverException e) {
 | 
				
			||||||
 | 
					//            log.warn("设备【{}】Driver创建失败,重新试一次", deviceId, e);
 | 
				
			||||||
 | 
					//            try {
 | 
				
			||||||
 | 
					//                Thread.sleep(1500);
 | 
				
			||||||
 | 
					//            } catch (InterruptedException interruptedException) {
 | 
				
			||||||
 | 
					//                log.warn("设备【{}】移除应用时driver出现问题,重新执行。。。。。", deviceInfo.getDeviceId());
 | 
				
			||||||
 | 
					//                throw new ExecuteException("执行取消");
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//            driver = new AndroidMobileDeviceDriver(appiumServerUrl, capabilities);
 | 
				
			||||||
 | 
					//        } catch (Exception e) {
 | 
				
			||||||
 | 
					//            log.error("设备驱动创建失败", e);
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					//        return driver;
 | 
				
			||||||
 | 
					//    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private DesiredCapabilities initAndroidCapabilities(String deviceId, Map<String, String> others) {
 | 
					    private DesiredCapabilities initAndroidCapabilities(String deviceId, Map<String, String> others) {
 | 
				
			||||||
        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
 | 
					        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
 | 
				
			||||||
        desiredCapabilities.setCapability(DEVICE_NAME, deviceId);  //设备id
 | 
					        desiredCapabilities.setCapability(DEVICE_NAME, deviceId);  //设备id
 | 
				
			||||||
| 
						 | 
					@ -262,6 +294,7 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
 | 
				
			||||||
        desiredCapabilities.setCapability("appium:noSign", true);
 | 
					        desiredCapabilities.setCapability("appium:noSign", true);
 | 
				
			||||||
        desiredCapabilities.setCapability("appium:skipServerInstallation", false);
 | 
					        desiredCapabilities.setCapability("appium:skipServerInstallation", false);
 | 
				
			||||||
        desiredCapabilities.setCapability("appium:skipUnlock", true);
 | 
					        desiredCapabilities.setCapability("appium:skipUnlock", true);
 | 
				
			||||||
 | 
					        desiredCapabilities.setCapability("appium:systemPort", deviceInfo.getForwardPort());
 | 
				
			||||||
        boolean noReset = true;
 | 
					        boolean noReset = true;
 | 
				
			||||||
        boolean unicodeKeyboard = false;
 | 
					        boolean unicodeKeyboard = false;
 | 
				
			||||||
        boolean resetKeyboard = true;
 | 
					        boolean resetKeyboard = true;
 | 
				
			||||||
| 
						 | 
					@ -769,7 +802,7 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void appRestart(String appPackage, String appName) {
 | 
					    private void appRestart(String appPackage, String appName) {
 | 
				
			||||||
        if (Thread.currentThread().isInterrupted()) {
 | 
					        if (Thread.currentThread().isInterrupted()) {
 | 
				
			||||||
            log.warn("设备【{}】启动app时前停止。。。。。。。。。。", deviceInfo.getDeviceId());
 | 
					            log.warn("设备【{}】重启app时前停止。。。。。。。。。。", deviceInfo.getDeviceId());
 | 
				
			||||||
            throw new ExecuteException("执行停止");
 | 
					            throw new ExecuteException("执行停止");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        boolean appInstalled = isAppInstalled(appPackage);
 | 
					        boolean appInstalled = isAppInstalled(appPackage);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,8 +51,17 @@ public class DeviceConnectionManager implements DeviceConnectionService {
 | 
				
			||||||
                deviceInfo.setSystemVersion(((Map)(data.get("cdMobileDevice"))).get("platformVersion").toString());
 | 
					                deviceInfo.setSystemVersion(((Map)(data.get("cdMobileDevice"))).get("platformVersion").toString());
 | 
				
			||||||
                deviceInfo.setResolution(((Map)(data.get("cdDeviceModel"))).get("resolution").toString());
 | 
					                deviceInfo.setResolution(((Map)(data.get("cdDeviceModel"))).get("resolution").toString());
 | 
				
			||||||
                deviceInfo.setPort(((Map)(data.get("cdDeviceCtrl"))).get("ctrlPort").toString());
 | 
					                deviceInfo.setPort(((Map)(data.get("cdDeviceCtrl"))).get("ctrlPort").toString());
 | 
				
			||||||
                if ("1".equals(deviceInfo.getPlatform())) {
 | 
					                if ("1".equals(deviceInfo.getPlatform())) {  //ios
 | 
				
			||||||
                    deviceInfo.setWdaAddress(((Map)(data.get("deviceInfo"))).get("wdaUrl").toString());
 | 
					                    Map deviceMap = (Map) data.get("deviceInfo");
 | 
				
			||||||
 | 
					                    Object wdaUrl = deviceMap.get("wdaUrl");
 | 
				
			||||||
 | 
					                    if (null != wdaUrl) {
 | 
				
			||||||
 | 
					                        deviceInfo.setWdaAddress(wdaUrl + "");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else if ("0".equals(deviceInfo.getPlatform())){   //android
 | 
				
			||||||
 | 
					                    Map deviceMap = (Map) data.get("deviceInfo");
 | 
				
			||||||
 | 
					                    Object forwardPort = deviceMap.get("forwardPort");
 | 
				
			||||||
 | 
					                    log.debug("拿到设备【{}】在上位机用于adb转发的端口:{}",deviceInfo.getDeviceId(),forwardPort);
 | 
				
			||||||
 | 
					                    deviceInfo.setForwardPort(Integer.parseInt(forwardPort+""));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {    // pc设备
 | 
					            } else {    // pc设备
 | 
				
			||||||
                deviceInfo.setMobile(false);
 | 
					                deviceInfo.setMobile(false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,19 @@ public class AndroidUtil {
 | 
				
			||||||
    private static final String END_RECORD_URL = "http://%s/engine/endRecord";
 | 
					    private static final String END_RECORD_URL = "http://%s/engine/endRecord";
 | 
				
			||||||
    private static final String INSTALL_APP = "http://%s/engine/installApp";
 | 
					    private static final String INSTALL_APP = "http://%s/engine/installApp";
 | 
				
			||||||
    private static final String ACTIVE_APP = "http://%s/engine/activeApp";
 | 
					    private static final String ACTIVE_APP = "http://%s/engine/activeApp";
 | 
				
			||||||
 | 
					    private static final String RELEASE_ADB_FORWARD_PORT = "http://%s/engine/releaseAdbForwardPort";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean releaseAdbForwardPort(String remoteAddress,String deviceId){
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            DebuggerDeviceInfo info = new DebuggerDeviceInfo();
 | 
				
			||||||
 | 
					            info.setDeviceId(deviceId);
 | 
				
			||||||
 | 
					            HttpEntity<DebuggerDeviceInfo> entity = new HttpEntity<>(info);
 | 
				
			||||||
 | 
					            return HttpUtils.doPost(String.format(RELEASE_ADB_FORWARD_PORT, remoteAddress),entity, Boolean.class);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            logger.error("清除数据失败,原因:{}",e);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean cleanAppData(String remoteAddress,String deviceId,String appPackage){
 | 
					    public static boolean cleanAppData(String remoteAddress,String deviceId,String appPackage){
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -314,4 +314,9 @@ public class EngineController {
 | 
				
			||||||
        return iosService.terminateApp(info.getDeviceId(), info.getAppPackage());
 | 
					        return iosService.terminateApp(info.getDeviceId(), info.getAppPackage());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @PostMapping("/releaseAdbForwardPort")
 | 
				
			||||||
 | 
					    public boolean releaseAdbForwardPort(@RequestBody DebuggerDeviceInfo info){
 | 
				
			||||||
 | 
					        return androidService.releaseAdbForwardPort(info.getDeviceId());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +9,10 @@ import net.northking.cctp.upperComputer.driver.adb.AndroidDeviceListener;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
import org.slf4j.LoggerFactory;
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
import org.springframework.util.CollectionUtils;
 | 
					import org.springframework.util.CollectionUtils;
 | 
				
			||||||
 | 
					import org.springframework.util.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.websocket.Session;
 | 
					import javax.websocket.Session;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.*;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.concurrent.ConcurrentHashMap;
 | 
					import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +34,15 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Adb adb;
 | 
					    private Adb adb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 初始的端口
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private int initPort = 8200;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Properties phonePortProperties = new Properties();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final String portFileName = "androidPhonePort.properties";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final static Logger logger = LoggerFactory.getLogger(AndroidDeviceManager.class);
 | 
					    private final static Logger logger = LoggerFactory.getLogger(AndroidDeviceManager.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -74,10 +84,6 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
        deviceSystemIsReady.put(serial, status);
 | 
					        deviceSystemIsReady.put(serial, status);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public boolean getDeviceSystemStatus(String serial) {
 | 
					 | 
				
			||||||
        return deviceSystemIsReady.get(serial);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void shutdown() {
 | 
					    public void shutdown() {
 | 
				
			||||||
| 
						 | 
					@ -108,6 +114,7 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void run() {
 | 
					    public void run() {
 | 
				
			||||||
 | 
					        readAndroidForwardPortProperty();
 | 
				
			||||||
        while (!isInterrupted()) {
 | 
					        while (!isInterrupted()) {
 | 
				
			||||||
            startAdbServer();
 | 
					            startAdbServer();
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
| 
						 | 
					@ -141,8 +148,9 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
            for (AdbDevice adbDevice : onlineDevices) {
 | 
					            for (AdbDevice adbDevice : onlineDevices) {
 | 
				
			||||||
                logger.info("新上来设备:{}", JSON.toJSONString(adbDevice));
 | 
					                logger.info("新上来设备:{}", JSON.toJSONString(adbDevice));
 | 
				
			||||||
                if (AdbDevice.State.Device == adbDevice.state) {
 | 
					                if (AdbDevice.State.Device == adbDevice.state) {
 | 
				
			||||||
 | 
					                    Integer forwardPort = saveDeviceForwardPort(adbDevice.getSerial());
 | 
				
			||||||
                    //注册并启动agent
 | 
					                    //注册并启动agent
 | 
				
			||||||
                    AndroidDeviceInitThread androidDeviceInitThread = new AndroidDeviceInitThread(adb,adbDevice);
 | 
					                    AndroidDeviceInitThread androidDeviceInitThread = new AndroidDeviceInitThread(adb,adbDevice,forwardPort);
 | 
				
			||||||
                    androidDeviceInitThread.start();
 | 
					                    androidDeviceInitThread.start();
 | 
				
			||||||
                    onlineDeviceInitMap.put(adbDevice.getSerial(), androidDeviceInitThread);
 | 
					                    onlineDeviceInitMap.put(adbDevice.getSerial(), androidDeviceInitThread);
 | 
				
			||||||
                    publishDeviceOnlineToWebConnection(adbDevice.getSerial());
 | 
					                    publishDeviceOnlineToWebConnection(adbDevice.getSerial());
 | 
				
			||||||
| 
						 | 
					@ -164,7 +172,17 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Integer saveDeviceForwardPort(String serial) {
 | 
				
			||||||
 | 
					        String value = this.phonePortProperties.getProperty(serial);
 | 
				
			||||||
 | 
					        if (StringUtils.hasText(value)) {
 | 
				
			||||||
 | 
					            logger.info("设备【】已经上过线,分配过adb转发端口,端口为:{}.............", serial, value);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            doPropertiesWrite(serial);
 | 
				
			||||||
 | 
					            value = this.phonePortProperties.getProperty(serial);
 | 
				
			||||||
 | 
					            logger.info("设备【】第一次来,分配adb转发端口,端口为:{}.............", serial,value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return Integer.parseInt(value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 检查哪些设备上线,下线,持有状态不变
 | 
					     * 检查哪些设备上线,下线,持有状态不变
 | 
				
			||||||
| 
						 | 
					@ -232,16 +250,6 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
        return list;
 | 
					        return list;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void offlineDevice(String serial) {
 | 
					 | 
				
			||||||
        synchronized (onlineDeviceInitMap){
 | 
					 | 
				
			||||||
            AndroidDeviceInitThread initThread = onlineDeviceInitMap.remove(serial);
 | 
					 | 
				
			||||||
            if (null != initThread && initThread.isAlive() && !initThread.isInterrupted()) {
 | 
					 | 
				
			||||||
                logger.info("设备【{}】初始化线程准备退出",serial);
 | 
					 | 
				
			||||||
                initThread.exit();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void stopWebScreen(String udid, Session session) {
 | 
					    public void stopWebScreen(String udid, Session session) {
 | 
				
			||||||
| 
						 | 
					@ -251,4 +259,74 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void readAndroidForwardPortProperty() {
 | 
				
			||||||
 | 
					        String property = System.getProperty("user.dir");
 | 
				
			||||||
 | 
					        File file = new File(property + File.separatorChar + portFileName);
 | 
				
			||||||
 | 
					        logger.info("开始读取已经存在的android手机对应的端口,读取文件:{}", file.getAbsolutePath());
 | 
				
			||||||
 | 
					        if (!file.exists()) {
 | 
				
			||||||
 | 
					            logger.warn("android手机端口映射文件不存在,新建《{}》文件",portFileName);
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                boolean newFile = file.createNewFile();
 | 
				
			||||||
 | 
					                if (!newFile) {
 | 
				
			||||||
 | 
					                    logger.warn("android端口映射文件【{}】创建失败", file.getAbsolutePath());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (IOException e) {
 | 
				
			||||||
 | 
					                logger.warn("新建android手机端口映射文件失败", e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            FileInputStream inputStream = null;
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                inputStream = new FileInputStream(file);
 | 
				
			||||||
 | 
					                phonePortProperties.load(inputStream);
 | 
				
			||||||
 | 
					            } catch (FileNotFoundException e) {
 | 
				
			||||||
 | 
					                logger.warn("android手机端口映射文件不存在");
 | 
				
			||||||
 | 
					            } catch (IOException e) {
 | 
				
			||||||
 | 
					                logger.warn("读取android手机端口映射配置文件失败");
 | 
				
			||||||
 | 
					            } finally {
 | 
				
			||||||
 | 
					                if (null != inputStream) {
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        inputStream.close();
 | 
				
			||||||
 | 
					                    } catch (IOException e) {
 | 
				
			||||||
 | 
					                        logger.warn("关闭流出错", e);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            logger.info("android手机端口映射文件加载完成,加载内容:");
 | 
				
			||||||
 | 
					            for (Object key : phonePortProperties.keySet()) {
 | 
				
			||||||
 | 
					                String port = phonePortProperties.getProperty(key + "");
 | 
				
			||||||
 | 
					                int forwardPort = Integer.parseInt(port);
 | 
				
			||||||
 | 
					                logger.info("手机:{},adb映射的端口为:{}", key, port);
 | 
				
			||||||
 | 
					                if (initPort < forwardPort) {
 | 
				
			||||||
 | 
					                    initPort = forwardPort;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private synchronized int getForwardPort() {
 | 
				
			||||||
 | 
					        this.initPort++;
 | 
				
			||||||
 | 
					        return this.initPort;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private synchronized void doPropertiesWrite(String deviceId) {
 | 
				
			||||||
 | 
					        this.phonePortProperties.setProperty(deviceId, getForwardPort()+"");  //存好分配的端口
 | 
				
			||||||
 | 
					        String property = System.getProperty("user.dir");
 | 
				
			||||||
 | 
					        File file = new File(property + File.separatorChar + portFileName);
 | 
				
			||||||
 | 
					        FileOutputStream fileOutputStream = null;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            fileOutputStream = new FileOutputStream(file);
 | 
				
			||||||
 | 
					            this.phonePortProperties.store(fileOutputStream, "android设备adb转发端口的映射关系");
 | 
				
			||||||
 | 
					        } catch (IOException e) {
 | 
				
			||||||
 | 
					            logger.warn("写入端口映射文件失败");
 | 
				
			||||||
 | 
					        }finally {
 | 
				
			||||||
 | 
					            if (null != fileOutputStream) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    fileOutputStream.close();
 | 
				
			||||||
 | 
					                } catch (IOException e) {
 | 
				
			||||||
 | 
					                    e.printStackTrace();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,8 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String defaultXcodePath = "/Applications/Xcode.app";
 | 
					    public String defaultXcodePath = "/Applications/Xcode.app";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final String portFileName = "iosPhonePort.properties";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 初始的端口
 | 
					     * 初始的端口
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					@ -165,17 +167,17 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void readIosPhoneProperty() {
 | 
					    private void readIosPhoneProperty() {
 | 
				
			||||||
        String property = System.getProperty("user.dir");
 | 
					        String property = System.getProperty("user.dir");
 | 
				
			||||||
        File file = new File(property + "/phonePort.properties");
 | 
					        File file = new File(property + File.separatorChar + portFileName);
 | 
				
			||||||
        logger.info("开始读取已经存在的手机端口和wda端口映射,读取文件:{}", file.getAbsolutePath());
 | 
					        logger.info("开始读取已经存在的ios手机端口和wda端口映射,读取文件:{}", file.getAbsolutePath());
 | 
				
			||||||
        if (!file.exists()) {
 | 
					        if (!file.exists()) {
 | 
				
			||||||
            logger.warn("手机端口映射文件不存在,新建《phonePort.properties》文件");
 | 
					            logger.warn("ios手机端口映射文件不存在,新建《{}》文件", portFileName);
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                boolean newFile = file.createNewFile();
 | 
					                boolean newFile = file.createNewFile();
 | 
				
			||||||
                if (!newFile) {
 | 
					                if (!newFile) {
 | 
				
			||||||
                    logger.warn("端口映射文件【{}】创建失败", file.getAbsolutePath());
 | 
					                    logger.warn("ios手机端口映射文件【{}】创建失败", file.getAbsolutePath());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } catch (IOException e) {
 | 
					            } catch (IOException e) {
 | 
				
			||||||
                logger.warn("新建端口映射文件失败", e);
 | 
					                logger.warn("新建ios手机端口映射文件失败", e);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            FileInputStream inputStream = null;
 | 
					            FileInputStream inputStream = null;
 | 
				
			||||||
| 
						 | 
					@ -183,9 +185,9 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
                inputStream = new FileInputStream(file);
 | 
					                inputStream = new FileInputStream(file);
 | 
				
			||||||
                phonePortProperties.load(inputStream);
 | 
					                phonePortProperties.load(inputStream);
 | 
				
			||||||
            } catch (FileNotFoundException e) {
 | 
					            } catch (FileNotFoundException e) {
 | 
				
			||||||
                logger.warn("手机端口映射文件不存在");
 | 
					                logger.warn("ios手机端口映射文件不存在");
 | 
				
			||||||
            } catch (IOException e) {
 | 
					            } catch (IOException e) {
 | 
				
			||||||
                logger.warn("读取手机端口映射配置文件失败");
 | 
					                logger.warn("读取ios手机端口映射配置文件失败");
 | 
				
			||||||
            } finally {
 | 
					            } finally {
 | 
				
			||||||
                if (null != inputStream) {
 | 
					                if (null != inputStream) {
 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
| 
						 | 
					@ -195,7 +197,7 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            logger.info("手机端口映射文件加载完成,加载内容:");
 | 
					            logger.info("ios手机端口映射文件加载完成,加载内容:");
 | 
				
			||||||
            for (Object key : phonePortProperties.keySet()) {
 | 
					            for (Object key : phonePortProperties.keySet()) {
 | 
				
			||||||
                String port = phonePortProperties.getProperty(key + "");
 | 
					                String port = phonePortProperties.getProperty(key + "");
 | 
				
			||||||
                PhoneEntity entity = new PhoneEntity();
 | 
					                PhoneEntity entity = new PhoneEntity();
 | 
				
			||||||
| 
						 | 
					@ -216,6 +218,7 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 拿最大新设备的代理端口
 | 
					     * 拿最大新设备的代理端口
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
| 
						 | 
					@ -245,11 +248,21 @@ public class IOSDeviceManager extends AbstractDeviceManager {
 | 
				
			||||||
    private synchronized void doPropertiesWrite(String key, String value) {
 | 
					    private synchronized void doPropertiesWrite(String key, String value) {
 | 
				
			||||||
        this.phonePortProperties.setProperty(key, value);  //存好分配的端口
 | 
					        this.phonePortProperties.setProperty(key, value);  //存好分配的端口
 | 
				
			||||||
        String property = System.getProperty("user.dir");
 | 
					        String property = System.getProperty("user.dir");
 | 
				
			||||||
        File file = new File(property + "/phonePort.properties");
 | 
					        File file = new File(property + File.separatorChar + portFileName);
 | 
				
			||||||
 | 
					        FileOutputStream fileOutputStream = null;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            this.phonePortProperties.store(new FileOutputStream(file), "IOS设备WDA映射关系");
 | 
					            fileOutputStream = new FileOutputStream(file);
 | 
				
			||||||
 | 
					            this.phonePortProperties.store(fileOutputStream, "IOS设备WDA端口映射关系");
 | 
				
			||||||
        } catch (IOException e) {
 | 
					        } catch (IOException e) {
 | 
				
			||||||
            logger.warn("写入端口映射文件失败");
 | 
					            logger.warn("写入端口映射文件失败");
 | 
				
			||||||
 | 
					        }finally {
 | 
				
			||||||
 | 
					            if (null != fileOutputStream) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    fileOutputStream.close();
 | 
				
			||||||
 | 
					                } catch (IOException e) {
 | 
				
			||||||
 | 
					                    e.printStackTrace();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,11 +53,14 @@ public class AndroidDeviceInitThread extends Thread {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private AgentThread agentThread;
 | 
					    private AgentThread agentThread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Integer forwardPort;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private int time = 1;
 | 
					    private int time = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public AndroidDeviceInitThread(Adb adb, AdbDevice adbDevice) {
 | 
					    public AndroidDeviceInitThread(Adb adb, AdbDevice adbDevice, Integer forwardPort) {
 | 
				
			||||||
        this.adb = adb;
 | 
					        this.adb = adb;
 | 
				
			||||||
        this.adbDevice = adbDevice;
 | 
					        this.adbDevice = adbDevice;
 | 
				
			||||||
 | 
					        this.forwardPort = forwardPort;
 | 
				
			||||||
        setName(adbDevice.getSerial());
 | 
					        setName(adbDevice.getSerial());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -415,6 +418,7 @@ public class AndroidDeviceInitThread extends Thread {
 | 
				
			||||||
        wifiTransport.close();
 | 
					        wifiTransport.close();
 | 
				
			||||||
        deviceInfo.put("wifiStatus", wifiStatus);
 | 
					        deviceInfo.put("wifiStatus", wifiStatus);
 | 
				
			||||||
        deviceInfo.put("scale", 1.0);
 | 
					        deviceInfo.put("scale", 1.0);
 | 
				
			||||||
 | 
					        deviceInfo.put("forwardPort", forwardPort);
 | 
				
			||||||
        return deviceInfo;
 | 
					        return deviceInfo;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,6 +449,10 @@ public class AndroidDeviceInitThread extends Thread {
 | 
				
			||||||
        return agentStatus;
 | 
					        return agentStatus;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Integer getForwardPort(){
 | 
				
			||||||
 | 
					        return forwardPort;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private class AgentThread extends Thread {
 | 
					    private class AgentThread extends Thread {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,4 +129,9 @@ public abstract class AbstractDebuggerService implements DebuggerService {
 | 
				
			||||||
    public String[] stopRecordDevicePer(DebuggerDeviceInfo info) {
 | 
					    public String[] stopRecordDevicePer(DebuggerDeviceInfo info) {
 | 
				
			||||||
        return new String[0];
 | 
					        return new String[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean releaseAdbForwardPort(String deviceId) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,6 +168,50 @@ public class AndroidDebuggerServiceImpl extends AbstractDebuggerService {
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean releaseAdbForwardPort(String deviceId) {
 | 
				
			||||||
 | 
					        AndroidDeviceInitThread androidInitThread = AndroidDeviceManager.getInstance().getAndroidInitThread(deviceId);
 | 
				
			||||||
 | 
					        if (null == androidInitThread || !androidInitThread.isAlive() || androidInitThread.isInterrupted()) {
 | 
				
			||||||
 | 
					            logger.warn("当前设备【{}】不在线", deviceId);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Integer forwardPort = androidInitThread.getForwardPort();
 | 
				
			||||||
 | 
					        List<String> cmd = new ArrayList<>();
 | 
				
			||||||
 | 
					        cmd.add("adb");
 | 
				
			||||||
 | 
					        cmd.add("-s");
 | 
				
			||||||
 | 
					        cmd.add(deviceId);
 | 
				
			||||||
 | 
					        cmd.add("forward");
 | 
				
			||||||
 | 
					        cmd.add("--remove");
 | 
				
			||||||
 | 
					        cmd.add("tcp:"+forwardPort);
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            Process start = new ProcessBuilder(cmd).redirectErrorStream(true).start();
 | 
				
			||||||
 | 
					            InputStream inputStream = start.getInputStream();
 | 
				
			||||||
 | 
					            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
 | 
				
			||||||
 | 
					            StringBuilder builder = new StringBuilder();
 | 
				
			||||||
 | 
					            String line;
 | 
				
			||||||
 | 
					            while ((line = reader.readLine()) != null) {
 | 
				
			||||||
 | 
					                logger.debug("执行设备【{}】释放adb转发端口打印:{}",deviceId,line);
 | 
				
			||||||
 | 
					                builder.append(line);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            String result = builder.toString();
 | 
				
			||||||
 | 
					            String notUseFlag = String.format("listener 'tcp:%s' not found", forwardPort);
 | 
				
			||||||
 | 
					            if (StringUtils.isBlank(result)) {
 | 
				
			||||||
 | 
					                logger.info("设备【{}】adb端口:{}释放成功", deviceId, forwardPort);
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            } else if (result.contains(notUseFlag)) {
 | 
				
			||||||
 | 
					                logger.info("设备【{}】adb端口:{}没有被adb占用", deviceId, forwardPort);
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                logger.info("设备【{}】adb端口:{}被其他程序占用,请杀掉无关的程序", deviceId, forwardPort);
 | 
				
			||||||
 | 
					                logger.debug("详情:{}",result);
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (IOException e) {
 | 
				
			||||||
 | 
					            logger.error("执行移除设备【{}】adb转发端口报错了",deviceId,e);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean terminateApp(String deviceId, String appPackage) {
 | 
					    public boolean terminateApp(String deviceId, String appPackage) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,4 +51,6 @@ public interface DebuggerService {
 | 
				
			||||||
    String[] stopRecordDevicePer(DebuggerDeviceInfo info);
 | 
					    String[] stopRecordDevicePer(DebuggerDeviceInfo info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    boolean terminateApp(String deviceId, String appPackage);
 | 
					    boolean terminateApp(String deviceId, String appPackage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    boolean releaseAdbForwardPort(String deviceId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -737,27 +737,28 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
 | 
				
			||||||
        logger.info("应用总大小:{}", totalSpace);
 | 
					        logger.info("应用总大小:{}", totalSpace);
 | 
				
			||||||
        FileInputStream fileInputStream = new FileInputStream(appFile);
 | 
					        FileInputStream fileInputStream = new FileInputStream(appFile);
 | 
				
			||||||
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
 | 
					        DecimalFormat decimalFormat = new DecimalFormat("#.00");
 | 
				
			||||||
        boolean push = AndroidDeviceManager.getInstance().getAdb().push(adbDevice, fileInputStream, Integer.parseInt(appFile.lastModified() / 1000 + ""), 777, "/data/local/tmp/tmp_install.apk", new PushBytesCountCallback() {
 | 
					        boolean push = AndroidDeviceManager.getInstance().getAdb().push(adbDevice, fileInputStream, Integer.parseInt(appFile.lastModified() / 1000 + ""), 777, "/data/local/tmp/tmp_install.apk", null);
 | 
				
			||||||
            private double percentOld = 0;
 | 
					//                new PushBytesCountCallback() {
 | 
				
			||||||
            private long oldTime = System.currentTimeMillis();
 | 
					//            private double percentOld = 0;
 | 
				
			||||||
 | 
					//            private long oldTime = System.currentTimeMillis();
 | 
				
			||||||
            @Override
 | 
					//
 | 
				
			||||||
            public void onSendBytes(long totalCount) {
 | 
					//            @Override
 | 
				
			||||||
                Double percent = totalCount / totalSpace.doubleValue() * 100;
 | 
					//            public void onSendBytes(long totalCount) {
 | 
				
			||||||
                String format = decimalFormat.format(percent);
 | 
					//                Double percent = totalCount / totalSpace.doubleValue() * 100;
 | 
				
			||||||
                double percentNew = Double.parseDouble(format);
 | 
					//                String format = decimalFormat.format(percent);
 | 
				
			||||||
                logger.debug("传输大小:{},总大小:{}", totalCount, totalSpace);
 | 
					//                double percentNew = Double.parseDouble(format);
 | 
				
			||||||
                long nowTime = System.currentTimeMillis();
 | 
					//                logger.debug("传输大小:{},总大小:{}", totalCount, totalSpace);
 | 
				
			||||||
                if (percentNew - percentOld > 5 && nowTime - oldTime > 1000) {
 | 
					//                long nowTime = System.currentTimeMillis();
 | 
				
			||||||
                    logger.debug("传输进度:{}", format);
 | 
					//                if (percentNew - percentOld > 5 && nowTime - oldTime > 1000) {
 | 
				
			||||||
                    Map<String, Object> result = new HashMap<>();
 | 
					//                    logger.debug("传输进度:{}", format);
 | 
				
			||||||
                    result.put("percent", percentNew / 2);
 | 
					//                    Map<String, Object> result = new HashMap<>();
 | 
				
			||||||
                    percentOld = percentNew;
 | 
					//                    result.put("percent", percentNew / 2);
 | 
				
			||||||
                    oldTime = nowTime;
 | 
					//                    percentOld = percentNew;
 | 
				
			||||||
                    SessionUtils.sendContinuousData(session, request, result, "应用安装进度");
 | 
					//                    oldTime = nowTime;
 | 
				
			||||||
                }
 | 
					//                    SessionUtils.sendContinuousData(session, request, result, "应用安装进度");
 | 
				
			||||||
            }
 | 
					//                }
 | 
				
			||||||
        });
 | 
					//            }
 | 
				
			||||||
 | 
					//        });
 | 
				
			||||||
        if (push) {
 | 
					        if (push) {
 | 
				
			||||||
            Map<String, Object> result = new HashMap<>();
 | 
					            Map<String, Object> result = new HashMap<>();
 | 
				
			||||||
            result.put("percent", 50);
 | 
					            result.put("percent", 50);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue