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 
17 package com.android.adb;
18 
19 import android.app.Activity;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.graphics.Rect;
25 import android.hardware.usb.UsbDevice;
26 import android.hardware.usb.UsbDeviceConnection;
27 import android.hardware.usb.UsbInterface;
28 import android.hardware.usb.UsbManager;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.Message;
32 import android.util.Log;
33 import android.widget.TextView;
34 
35 /* Main activity for the adb test program */
36 public 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
onCreate(Bundle savedInstanceState)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
onDestroy()75     public void onDestroy() {
76         unregisterReceiver(mUsbReceiver);
77         setAdbInterface(null, null);
78         super.onDestroy();
79     }
80 
log(String s)81     public void log(String s) {
82         Message m = Message.obtain(mHandler, MESSAGE_LOG);
83         m.obj = s;
84         mHandler.sendMessage(m);
85     }
86 
appendLog(String text)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 
deviceOnline(AdbDevice device)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 
handleDeviceOnline(AdbDevice device)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
setAdbInterface(UsbDevice device, UsbInterface intf)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
findAdbInterface(UsbDevice 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