• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotations.VisibleForTesting;
19 import com.android.ddmlib.IDevice;
20 import com.android.tradefed.device.DeviceManager.FastbootDevice;
21 import com.android.tradefed.device.IDeviceSelection.BaseDeviceType;
22 import com.android.tradefed.device.cloud.ManagedRemoteDevice;
23 import com.android.tradefed.device.cloud.NestedDeviceStateMonitor;
24 import com.android.tradefed.device.cloud.NestedRemoteDevice;
25 import com.android.tradefed.device.cloud.RemoteAndroidVirtualDevice;
26 import com.android.tradefed.device.cloud.VmRemoteDevice;
27 import com.android.tradefed.util.IRunUtil;
28 import com.android.tradefed.util.RunUtil;
29 import com.android.tradefed.util.SystemUtil;
30 
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.Set;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36 
37 /**
38  * Factory to create the different kind of devices that can be monitored by Tf
39  */
40 public class ManagedTestDeviceFactory implements IManagedTestDeviceFactory {
41 
42     public static final String NOTIFY_AS_NATIVE = "NOTIFY_AS_NATIVE";
43     public static final String IPADDRESS_PATTERN =
44             "((^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
45                     + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
46                     + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
47                     + "([01]?\\d\\d?|2[0-4]\\d|25[0-5]))|(localhost)){1}";
48 
49     protected boolean mFastbootEnabled;
50     protected IDeviceManager mDeviceManager;
51     protected IDeviceMonitor mAllocationMonitor;
52     protected static final String CHECK_PM_CMD = "ls %s";
53     protected static final String EXPECTED_RES = "/system/bin/pm";
54     protected static final String EXPECTED_ERROR = "No such file or directory";
55     protected static final long FRAMEWORK_CHECK_SLEEP_MS = 500;
56     protected static final int FRAMEWORK_CHECK_MAX_RETRY = 3;
57 
ManagedTestDeviceFactory(boolean fastbootEnabled, IDeviceManager deviceManager, IDeviceMonitor allocationMonitor)58     public ManagedTestDeviceFactory(boolean fastbootEnabled, IDeviceManager deviceManager,
59             IDeviceMonitor allocationMonitor) {
60         mFastbootEnabled = fastbootEnabled;
61         mDeviceManager = deviceManager;
62         mAllocationMonitor = allocationMonitor;
63     }
64 
65     @Override
createRequestedDevice(IDevice idevice, IDeviceSelection options)66     public IManagedTestDevice createRequestedDevice(IDevice idevice, IDeviceSelection options) {
67         IManagedTestDevice testDevice = null;
68         if (BaseDeviceType.NATIVE_DEVICE.equals(options.getBaseDeviceTypeRequested())) {
69             testDevice =
70                     new NativeDevice(
71                             idevice,
72                             new NativeDeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
73                             mAllocationMonitor);
74             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
75         } else {
76             // Default to-go device is Android full stack device.
77             testDevice =
78                     new TestDevice(
79                             idevice,
80                             new DeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
81                             mAllocationMonitor);
82             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
83         }
84         return testDevice;
85     }
86 
87     /**
88      * {@inheritDoc}
89      */
90     @Override
createDevice(IDevice idevice)91     public IManagedTestDevice createDevice(IDevice idevice) {
92         IManagedTestDevice testDevice = null;
93         if (idevice instanceof VmRemoteDevice) {
94             testDevice =
95                     new ManagedRemoteDevice(
96                             idevice,
97                             new DeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
98                             mAllocationMonitor);
99             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
100         } else if (idevice instanceof RemoteAvdIDevice) {
101             testDevice =
102                     new RemoteAndroidVirtualDevice(
103                             idevice,
104                             new DeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
105                             mAllocationMonitor);
106             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
107         } else if (idevice instanceof StubLocalAndroidVirtualDevice) {
108             // Virtual device to be launched by TradeFed locally.
109             testDevice =
110                     new LocalAndroidVirtualDevice(
111                             idevice,
112                             new DeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
113                             mAllocationMonitor);
114         } else if (isTcpDeviceSerial(idevice.getSerialNumber())) {
115             if (isRemoteEnvironment()) {
116                 // If we are in a remote environment, treat the device as such
117                 testDevice =
118                         new NestedRemoteDevice(
119                                 idevice,
120                                 new NestedDeviceStateMonitor(
121                                         mDeviceManager, idevice, mFastbootEnabled),
122                                 mAllocationMonitor);
123             } else {
124                 Set<String> nativeSerials = new HashSet<>();
125                 if (System.getenv(NOTIFY_AS_NATIVE) != null) {
126                     nativeSerials.addAll(Arrays.asList(System.getenv(NOTIFY_AS_NATIVE).split(",")));
127                 }
128                 if (nativeSerials.contains(idevice.getSerialNumber())) {
129                     testDevice =
130                             new NativeDevice(
131                                     idevice,
132                                     new NativeDeviceStateMonitor(
133                                             mDeviceManager, idevice, mFastbootEnabled),
134                                     mAllocationMonitor);
135                 } else {
136                     // Handle device connected via 'adb connect'
137                     testDevice =
138                             new RemoteAndroidDevice(
139                                     idevice,
140                                     new DeviceStateMonitor(
141                                             mDeviceManager, idevice, mFastbootEnabled),
142                                     mAllocationMonitor);
143                     testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
144                 }
145             }
146         } else {
147             // Default to-go device is Android full stack device.
148             testDevice = new TestDevice(idevice,
149                     new DeviceStateMonitor(mDeviceManager, idevice, mFastbootEnabled),
150                     mAllocationMonitor);
151         }
152 
153         if (idevice instanceof FastbootDevice) {
154             if (((FastbootDevice) idevice).isFastbootD()) {
155                 testDevice.setDeviceState(TestDeviceState.FASTBOOTD);
156             } else {
157                 testDevice.setDeviceState(TestDeviceState.FASTBOOT);
158             }
159         } else if (idevice instanceof StubDevice) {
160             testDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
161         }
162         testDevice.setFastbootEnabled(mFastbootEnabled);
163         testDevice.setFastbootPath(mDeviceManager.getFastbootPath());
164         return testDevice;
165     }
166 
167     /** Return the default {@link IRunUtil} instance. */
168     @VisibleForTesting
getRunUtil()169     protected IRunUtil getRunUtil() {
170         return RunUtil.getDefault();
171     }
172 
173     /**
174      * Return true if we are currently running in a remote environment. This will alter the device
175      * behavior.
176      */
177     @VisibleForTesting
isRemoteEnvironment()178     protected boolean isRemoteEnvironment() {
179         return SystemUtil.isRemoteEnvironment();
180     }
181 
182     /** Create a {@link CollectingOutputReceiver}. */
183     @VisibleForTesting
createOutputReceiver()184     protected CollectingOutputReceiver createOutputReceiver() {
185         return new CollectingOutputReceiver();
186     }
187 
188     /**
189      * {@inheritDoc}
190      */
191     @Override
setFastbootEnabled(boolean enable)192     public void setFastbootEnabled(boolean enable) {
193         mFastbootEnabled = enable;
194     }
195 
196     /**
197      * Helper to device if it's a serial from a remotely connected device. serial format of tcp
198      * device is <ip or locahost>:<port>
199      */
isTcpDeviceSerial(String serial)200     public static boolean isTcpDeviceSerial(String serial) {
201         final String remotePattern = IPADDRESS_PATTERN + "(:)([0-9]{2,5})(\\b)";
202         Pattern pattern = Pattern.compile(remotePattern);
203         Matcher match = pattern.matcher(serial.trim());
204         if (match.find()) {
205             return true;
206         }
207         return false;
208     }
209 }
210