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.google.android.DemoKit; 18 19 import java.io.FileDescriptor; 20 import java.io.FileInputStream; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 24 import android.app.Activity; 25 import android.app.PendingIntent; 26 import android.content.BroadcastReceiver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.os.Bundle; 31 import android.os.Handler; 32 import android.os.Message; 33 import android.os.ParcelFileDescriptor; 34 import android.util.Log; 35 import android.widget.SeekBar; 36 37 import com.android.future.usb.UsbAccessory; 38 import com.android.future.usb.UsbManager; 39 40 public class DemoKitActivity extends Activity implements Runnable { 41 private static final String TAG = "DemoKit"; 42 43 private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION"; 44 45 private UsbManager mUsbManager; 46 private PendingIntent mPermissionIntent; 47 private boolean mPermissionRequestPending; 48 49 UsbAccessory mAccessory; 50 ParcelFileDescriptor mFileDescriptor; 51 FileInputStream mInputStream; 52 FileOutputStream mOutputStream; 53 54 private static final int MESSAGE_SWITCH = 1; 55 private static final int MESSAGE_TEMPERATURE = 2; 56 private static final int MESSAGE_LIGHT = 3; 57 private static final int MESSAGE_JOY = 4; 58 59 public static final byte LED_SERVO_COMMAND = 2; 60 public static final byte RELAY_COMMAND = 3; 61 62 protected class SwitchMsg { 63 private byte sw; 64 private byte state; 65 SwitchMsg(byte sw, byte state)66 public SwitchMsg(byte sw, byte state) { 67 this.sw = sw; 68 this.state = state; 69 } 70 getSw()71 public byte getSw() { 72 return sw; 73 } 74 getState()75 public byte getState() { 76 return state; 77 } 78 } 79 80 protected class TemperatureMsg { 81 private int temperature; 82 TemperatureMsg(int temperature)83 public TemperatureMsg(int temperature) { 84 this.temperature = temperature; 85 } 86 getTemperature()87 public int getTemperature() { 88 return temperature; 89 } 90 } 91 92 protected class LightMsg { 93 private int light; 94 LightMsg(int light)95 public LightMsg(int light) { 96 this.light = light; 97 } 98 getLight()99 public int getLight() { 100 return light; 101 } 102 } 103 104 protected class JoyMsg { 105 private int x; 106 private int y; 107 JoyMsg(int x, int y)108 public JoyMsg(int x, int y) { 109 this.x = x; 110 this.y = y; 111 } 112 getX()113 public int getX() { 114 return x; 115 } 116 getY()117 public int getY() { 118 return y; 119 } 120 } 121 122 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 123 @Override 124 public void onReceive(Context context, Intent intent) { 125 String action = intent.getAction(); 126 if (ACTION_USB_PERMISSION.equals(action)) { 127 synchronized (this) { 128 UsbAccessory accessory = UsbManager.getAccessory(intent); 129 if (intent.getBooleanExtra( 130 UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 131 openAccessory(accessory); 132 } else { 133 Log.d(TAG, "permission denied for accessory " 134 + accessory); 135 } 136 mPermissionRequestPending = false; 137 } 138 } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { 139 UsbAccessory accessory = UsbManager.getAccessory(intent); 140 if (accessory != null && accessory.equals(mAccessory)) { 141 closeAccessory(); 142 } 143 } 144 } 145 }; 146 147 /** Called when the activity is first created. */ 148 @Override onCreate(Bundle savedInstanceState)149 public void onCreate(Bundle savedInstanceState) { 150 super.onCreate(savedInstanceState); 151 152 mUsbManager = UsbManager.getInstance(this); 153 mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( 154 ACTION_USB_PERMISSION), 0); 155 IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 156 filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); 157 registerReceiver(mUsbReceiver, filter); 158 159 if (getLastNonConfigurationInstance() != null) { 160 mAccessory = (UsbAccessory) getLastNonConfigurationInstance(); 161 openAccessory(mAccessory); 162 } 163 164 setContentView(R.layout.main); 165 166 enableControls(false); 167 } 168 169 @Override onRetainNonConfigurationInstance()170 public Object onRetainNonConfigurationInstance() { 171 if (mAccessory != null) { 172 return mAccessory; 173 } else { 174 return super.onRetainNonConfigurationInstance(); 175 } 176 } 177 178 @Override onResume()179 public void onResume() { 180 super.onResume(); 181 182 Intent intent = getIntent(); 183 if (mInputStream != null && mOutputStream != null) { 184 return; 185 } 186 187 UsbAccessory[] accessories = mUsbManager.getAccessoryList(); 188 UsbAccessory accessory = (accessories == null ? null : accessories[0]); 189 if (accessory != null) { 190 if (mUsbManager.hasPermission(accessory)) { 191 openAccessory(accessory); 192 } else { 193 synchronized (mUsbReceiver) { 194 if (!mPermissionRequestPending) { 195 mUsbManager.requestPermission(accessory, 196 mPermissionIntent); 197 mPermissionRequestPending = true; 198 } 199 } 200 } 201 } else { 202 Log.d(TAG, "mAccessory is null"); 203 } 204 } 205 206 @Override onPause()207 public void onPause() { 208 super.onPause(); 209 closeAccessory(); 210 } 211 212 @Override onDestroy()213 public void onDestroy() { 214 unregisterReceiver(mUsbReceiver); 215 super.onDestroy(); 216 } 217 openAccessory(UsbAccessory accessory)218 private void openAccessory(UsbAccessory accessory) { 219 mFileDescriptor = mUsbManager.openAccessory(accessory); 220 if (mFileDescriptor != null) { 221 mAccessory = accessory; 222 FileDescriptor fd = mFileDescriptor.getFileDescriptor(); 223 mInputStream = new FileInputStream(fd); 224 mOutputStream = new FileOutputStream(fd); 225 Thread thread = new Thread(null, this, "DemoKit"); 226 thread.start(); 227 Log.d(TAG, "accessory opened"); 228 enableControls(true); 229 } else { 230 Log.d(TAG, "accessory open fail"); 231 } 232 } 233 closeAccessory()234 private void closeAccessory() { 235 enableControls(false); 236 237 try { 238 if (mFileDescriptor != null) { 239 mFileDescriptor.close(); 240 } 241 } catch (IOException e) { 242 } finally { 243 mFileDescriptor = null; 244 mAccessory = null; 245 } 246 } 247 enableControls(boolean enable)248 protected void enableControls(boolean enable) { 249 } 250 composeInt(byte hi, byte lo)251 private int composeInt(byte hi, byte lo) { 252 int val = (int) hi & 0xff; 253 val *= 256; 254 val += (int) lo & 0xff; 255 return val; 256 } 257 run()258 public void run() { 259 int ret = 0; 260 byte[] buffer = new byte[16384]; 261 int i; 262 263 while (ret >= 0) { 264 try { 265 ret = mInputStream.read(buffer); 266 } catch (IOException e) { 267 break; 268 } 269 270 i = 0; 271 while (i < ret) { 272 int len = ret - i; 273 274 switch (buffer[i]) { 275 case 0x1: 276 if (len >= 3) { 277 Message m = Message.obtain(mHandler, MESSAGE_SWITCH); 278 m.obj = new SwitchMsg(buffer[i + 1], buffer[i + 2]); 279 mHandler.sendMessage(m); 280 } 281 i += 3; 282 break; 283 284 case 0x4: 285 if (len >= 3) { 286 Message m = Message.obtain(mHandler, 287 MESSAGE_TEMPERATURE); 288 m.obj = new TemperatureMsg(composeInt(buffer[i + 1], 289 buffer[i + 2])); 290 mHandler.sendMessage(m); 291 } 292 i += 3; 293 break; 294 295 case 0x5: 296 if (len >= 3) { 297 Message m = Message.obtain(mHandler, MESSAGE_LIGHT); 298 m.obj = new LightMsg(composeInt(buffer[i + 1], 299 buffer[i + 2])); 300 mHandler.sendMessage(m); 301 } 302 i += 3; 303 break; 304 305 case 0x6: 306 if (len >= 3) { 307 Message m = Message.obtain(mHandler, MESSAGE_JOY); 308 m.obj = new JoyMsg(buffer[i + 1], buffer[i + 2]); 309 mHandler.sendMessage(m); 310 } 311 i += 3; 312 break; 313 314 default: 315 Log.d(TAG, "unknown msg: " + buffer[i]); 316 i = len; 317 break; 318 } 319 } 320 321 } 322 } 323 324 Handler mHandler = new Handler() { 325 @Override 326 public void handleMessage(Message msg) { 327 switch (msg.what) { 328 case MESSAGE_SWITCH: 329 SwitchMsg o = (SwitchMsg) msg.obj; 330 handleSwitchMessage(o); 331 break; 332 333 case MESSAGE_TEMPERATURE: 334 TemperatureMsg t = (TemperatureMsg) msg.obj; 335 handleTemperatureMessage(t); 336 break; 337 338 case MESSAGE_LIGHT: 339 LightMsg l = (LightMsg) msg.obj; 340 handleLightMessage(l); 341 break; 342 343 case MESSAGE_JOY: 344 JoyMsg j = (JoyMsg) msg.obj; 345 handleJoyMessage(j); 346 break; 347 348 } 349 } 350 }; 351 sendCommand(byte command, byte target, int value)352 public void sendCommand(byte command, byte target, int value) { 353 byte[] buffer = new byte[3]; 354 if (value > 255) 355 value = 255; 356 357 buffer[0] = command; 358 buffer[1] = target; 359 buffer[2] = (byte) value; 360 if (mOutputStream != null && buffer[1] != -1) { 361 try { 362 mOutputStream.write(buffer); 363 } catch (IOException e) { 364 Log.e(TAG, "write failed", e); 365 } 366 } 367 } 368 handleJoyMessage(JoyMsg j)369 protected void handleJoyMessage(JoyMsg j) { 370 } 371 handleLightMessage(LightMsg l)372 protected void handleLightMessage(LightMsg l) { 373 } 374 handleTemperatureMessage(TemperatureMsg t)375 protected void handleTemperatureMessage(TemperatureMsg t) { 376 } 377 handleSwitchMessage(SwitchMsg o)378 protected void handleSwitchMessage(SwitchMsg o) { 379 } 380 onStartTrackingTouch(SeekBar seekBar)381 public void onStartTrackingTouch(SeekBar seekBar) { 382 } 383 onStopTrackingTouch(SeekBar seekBar)384 public void onStopTrackingTouch(SeekBar seekBar) { 385 } 386 } 387