1/*
2 * Copyright (C) 2010 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 */
16package com.android.hosttest;
17
18import com.android.ddmlib.AndroidDebugBridge;
19import com.android.ddmlib.IDevice;
20import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
21
22
23/**
24 * A helper class that can connect to a ddmlib {@link IDevice}
25 */
26public class DeviceConnector {
27
28    /**
29     * The maximum time to wait for a device to be connected.
30     */
31    private static final int MAX_WAIT_DEVICE_TIME = 5000;
32
33    /**
34     * Initializes DDMS library, and connects to specified Android device
35     *
36     * @param deviceSerial the device serial to connect to. If <code>null</code> connect to first
37     * discovered device.
38     *
39     * @return the {@link IDevice} found
40     * @throws IllegalArgumentException if no device cannot be found.
41     */
42    public IDevice connectToDevice(String deviceSerial) {
43        // initialize DDMS with no clientSupport aka debugger support
44        AndroidDebugBridge.init(false /* clientSupport */);
45        AndroidDebugBridge adbBridge = AndroidDebugBridge.createBridge();
46        for (IDevice device : adbBridge.getDevices()) {
47            if (deviceSerial == null) {
48                return device;
49            } else if (deviceSerial.equals(device.getSerialNumber())) {
50                return device;
51            }
52        }
53        // TODO: get some sort of logger interface as param instead
54        System.out.println("Waiting for device...");
55        NewDeviceListener listener = new NewDeviceListener(deviceSerial);
56        AndroidDebugBridge.addDeviceChangeListener(listener);
57        IDevice device = listener.waitForDevice(MAX_WAIT_DEVICE_TIME);
58        AndroidDebugBridge.removeDeviceChangeListener(listener);
59        if (device == null) {
60            throw new IllegalArgumentException("Could not connect to device");
61        } else {
62            System.out.println(String.format("Connected to %s", device.getSerialNumber()));
63        }
64        return device;
65    }
66
67    /**
68     * Listener for new Android devices
69     */
70    private static class NewDeviceListener implements IDeviceChangeListener {
71        private IDevice mDevice;
72        private String mSerial;
73
74        public NewDeviceListener(String serial) {
75            mSerial = serial;
76        }
77
78        public void deviceChanged(IDevice device, int changeMask) {
79        }
80
81        public void deviceConnected(IDevice device) {
82            if (mSerial == null) {
83                setDevice(device);
84            } else if (mSerial.equals(device.getSerialNumber())) {
85                setDevice(device);
86            }
87        }
88
89        private synchronized void setDevice(IDevice device) {
90            mDevice = device;
91            notify();
92        }
93
94        public void deviceDisconnected(IDevice device) {
95        }
96
97        public IDevice waitForDevice(long waitTime) {
98            synchronized(this) {
99                if (mDevice == null) {
100                    try {
101                        wait(waitTime);
102                    } catch (InterruptedException e) {
103                        System.out.println("Waiting for device interrupted");
104                    }
105                }
106            }
107            return mDevice;
108        }
109    }
110}
111