1/*
2 * Copyright (C) 2011 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
17package com.android.adb;
18
19import android.app.Activity;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.graphics.Rect;
25import android.hardware.usb.UsbDevice;
26import android.hardware.usb.UsbDeviceConnection;
27import android.hardware.usb.UsbInterface;
28import android.hardware.usb.UsbManager;
29import android.os.Bundle;
30import android.os.Handler;
31import android.os.Message;
32import android.util.Log;
33import android.widget.TextView;
34
35/* Main activity for the adb test program */
36public class AdbTestActivity extends Activity {
37
38    private static final String TAG = "AdbTestActivity";
39
40    private TextView mLog;
41    private UsbManager mManager;
42    private UsbDevice mDevice;
43    private UsbDeviceConnection mDeviceConnection;
44    private UsbInterface mInterface;
45    private AdbDevice mAdbDevice;
46
47    private static final int MESSAGE_LOG = 1;
48    private static final int MESSAGE_DEVICE_ONLINE = 2;
49
50    @Override
51    public void onCreate(Bundle savedInstanceState) {
52        super.onCreate(savedInstanceState);
53
54        setContentView(R.layout.adb);
55        mLog = (TextView)findViewById(R.id.log);
56
57        mManager = (UsbManager)getSystemService(Context.USB_SERVICE);
58
59        // check for existing devices
60        for (UsbDevice device :  mManager.getDeviceList().values()) {
61            UsbInterface intf = findAdbInterface(device);
62            if (setAdbInterface(device, intf)) {
63                break;
64            }
65        }
66
67        // listen for new devices
68        IntentFilter filter = new IntentFilter();
69        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
70        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
71        registerReceiver(mUsbReceiver, filter);
72    }
73
74    @Override
75    public void onDestroy() {
76        unregisterReceiver(mUsbReceiver);
77        setAdbInterface(null, null);
78        super.onDestroy();
79    }
80
81    public void log(String s) {
82        Message m = Message.obtain(mHandler, MESSAGE_LOG);
83        m.obj = s;
84        mHandler.sendMessage(m);
85    }
86
87    private void appendLog(String text) {
88        Rect r = new Rect();
89        mLog.getDrawingRect(r);
90        int maxLines = r.height() / mLog.getLineHeight() - 1;
91        text = mLog.getText() + "\n" + text;
92
93        // see how many lines we have
94        int index = text.lastIndexOf('\n');
95        int count = 0;
96        while (index > 0 && count <= maxLines) {
97            count++;
98            index = text.lastIndexOf('\n', index - 1);
99        }
100
101        // truncate to maxLines
102        if (index > 0) {
103            text = text.substring(index + 1);
104        }
105        mLog.setText(text);
106    }
107
108    public void deviceOnline(AdbDevice device) {
109        Message m = Message.obtain(mHandler, MESSAGE_DEVICE_ONLINE);
110        m.obj = device;
111        mHandler.sendMessage(m);
112    }
113
114    private void handleDeviceOnline(AdbDevice device) {
115        log("device online: " + device.getSerial());
116        device.openSocket("shell:exec logcat");
117    }
118
119    // Sets the current USB device and interface
120    private boolean setAdbInterface(UsbDevice device, UsbInterface intf) {
121        if (mDeviceConnection != null) {
122            if (mInterface != null) {
123                mDeviceConnection.releaseInterface(mInterface);
124                mInterface = null;
125            }
126            mDeviceConnection.close();
127            mDevice = null;
128            mDeviceConnection = null;
129        }
130
131        if (device != null && intf != null) {
132            UsbDeviceConnection connection = mManager.openDevice(device);
133            if (connection != null) {
134                log("open succeeded");
135                if (connection.claimInterface(intf, false)) {
136                    log("claim interface succeeded");
137                    mDevice = device;
138                    mDeviceConnection = connection;
139                    mInterface = intf;
140                    mAdbDevice = new AdbDevice(this, mDeviceConnection, intf);
141                    log("call start");
142                    mAdbDevice.start();
143                    return true;
144                } else {
145                    log("claim interface failed");
146                    connection.close();
147                }
148            } else {
149                log("open failed");
150            }
151        }
152
153        if (mDeviceConnection == null && mAdbDevice != null) {
154            mAdbDevice.stop();
155            mAdbDevice = null;
156        }
157        return false;
158    }
159
160    // searches for an adb interface on the given USB device
161    static private UsbInterface findAdbInterface(UsbDevice device) {
162        Log.d(TAG, "findAdbInterface " + device);
163        int count = device.getInterfaceCount();
164        for (int i = 0; i < count; i++) {
165            UsbInterface intf = device.getInterface(i);
166            if (intf.getInterfaceClass() == 255 && intf.getInterfaceSubclass() == 66 &&
167                    intf.getInterfaceProtocol() == 1) {
168                return intf;
169            }
170        }
171        return null;
172    }
173
174    BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
175        public void onReceive(Context context, Intent intent) {
176            String action = intent.getAction();
177
178            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
179                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
180                UsbInterface intf = findAdbInterface(device);
181                if (intf != null) {
182                    log("Found adb interface " + intf);
183                    setAdbInterface(device, intf);
184                }
185            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
186                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
187                String deviceName = device.getDeviceName();
188                if (mDevice != null && mDevice.equals(deviceName)) {
189                    log("adb interface removed");
190                    setAdbInterface(null, null);
191                }
192            }
193        }
194    };
195
196    Handler mHandler = new Handler() {
197        @Override
198        public void handleMessage(Message msg) {
199            switch (msg.what) {
200                case MESSAGE_LOG:
201                    appendLog((String)msg.obj);
202                    break;
203                case MESSAGE_DEVICE_ONLINE:
204                    handleDeviceOnline((AdbDevice)msg.obj);
205                    break;
206            }
207        }
208    };
209}
210
211
212