1 /*
2  * Copyright (C) 2016 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 com.android.tradefed.device;
17 
18 import com.android.ddmlib.IDevice;
19 import com.android.tradefed.command.remote.DeviceDescriptor;
20 import com.android.tradefed.device.connection.DefaultConnection;
21 
22 import java.util.Map;
23 import java.util.regex.Matcher;
24 import java.util.regex.Pattern;
25 
26 /**
27  * Implementation of a {@link ITestDevice} for a full stack android device connected via
28  * adb connect.
29  * Assume the device serial will be in the format <hostname>:<portnumber> in adb.
30  */
31 public class RemoteAndroidDevice extends TestDevice {
32     public static final long WAIT_FOR_ADB_CONNECT = 2 * 60 * 1000;
33 
34     protected static final long RETRY_INTERVAL_MS = 5000;
35     protected static final int MAX_RETRIES = 5;
36     protected static final long DEFAULT_SHORT_CMD_TIMEOUT = 20 * 1000;
37 
38     private static final Pattern IP_PATTERN =
39             Pattern.compile(ManagedTestDeviceFactory.IPADDRESS_PATTERN);
40 
41     /**
42      * Creates a {@link RemoteAndroidDevice}.
43      *
44      * @param device the associated {@link IDevice}
45      * @param stateMonitor the {@link IDeviceStateMonitor} mechanism to use
46      * @param allocationMonitor the {@link IDeviceMonitor} to inform of allocation state changes.
47      */
RemoteAndroidDevice(IDevice device, IDeviceStateMonitor stateMonitor, IDeviceMonitor allocationMonitor)48     public RemoteAndroidDevice(IDevice device, IDeviceStateMonitor stateMonitor,
49             IDeviceMonitor allocationMonitor) {
50         super(device, stateMonitor, allocationMonitor);
51     }
52 
53     /**
54      * Check if the format of the serial is as expected <hostname>:port
55      *
56      * @return true if the format is valid, false otherwise.
57      */
checkSerialFormatValid(String serialString)58     public static boolean checkSerialFormatValid(String serialString) {
59         String[] serial = serialString.split(":");
60         if (serial.length == 2) {
61             // Check first part is an IP
62             Matcher match = IP_PATTERN.matcher(serial[0]);
63             if (!match.find()) {
64                 return false;
65             }
66             // Check second part if a port
67             try {
68                 Integer.parseInt(serial[1]);
69                 return true;
70             } catch (NumberFormatException nfe) {
71                 return false;
72             }
73         }
74         return false;
75     }
76 
77     /**
78      * {@inheritDoc}
79      */
80     @Override
isEncryptionSupported()81     public boolean isEncryptionSupported() {
82         // Prevent device from being encrypted since we won't have a way to decrypt on Remote
83         // devices since fastboot cannot be use remotely
84         return false;
85     }
86 
87     /**
88      * {@inheritDoc}
89      */
90     @Override
getMacAddress()91     public String getMacAddress() {
92         return null;
93     }
94 
95     @Override
getFastbootSerialNumber()96     public String getFastbootSerialNumber() {
97         return "tcp:" + getSerialNumber();
98     }
99 
100     @Override
getDeviceDescriptor(boolean shortDescriptor)101     public DeviceDescriptor getDeviceDescriptor(boolean shortDescriptor) {
102         DeviceDescriptor descriptor = super.getDeviceDescriptor(shortDescriptor);
103         if (getConnection() instanceof DefaultConnection) {
104             String initialSerial = ((DefaultConnection) getConnection()).getInitialSerial();
105             String initialIp = ((DefaultConnection) getConnection()).getInitialIp();
106             Integer initialOffset =
107                     ((DefaultConnection) getConnection()).getInitialDeviceNumOffset();
108             if (initialIp != null || initialOffset != null) {
109                 // Specify ip/offset.
110                 descriptor = new DeviceDescriptor(descriptor, initialIp, initialOffset);
111             }
112         }
113         return descriptor;
114     }
115 
116     @Override
connectToWifiNetwork(Map<String, String> wifiSsidToPsk, boolean scanSsid)117     public boolean connectToWifiNetwork(Map<String, String> wifiSsidToPsk, boolean scanSsid)
118             throws DeviceNotAvailableException {
119         // turn on cmd wifi logic for virtual devices.
120         if (getOptions().isCmdWifiVirtual()) {
121             getOptions().setUseCmdWifi(true);
122         }
123         return super.connectToWifiNetwork(wifiSsidToPsk, scanSsid);
124     }
125 }
126