Home | History | Annotate | Download | only in DemoKit
      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 
     66 		public SwitchMsg(byte sw, byte state) {
     67 			this.sw = sw;
     68 			this.state = state;
     69 		}
     70 
     71 		public byte getSw() {
     72 			return sw;
     73 		}
     74 
     75 		public byte getState() {
     76 			return state;
     77 		}
     78 	}
     79 
     80 	protected class TemperatureMsg {
     81 		private int temperature;
     82 
     83 		public TemperatureMsg(int temperature) {
     84 			this.temperature = temperature;
     85 		}
     86 
     87 		public int getTemperature() {
     88 			return temperature;
     89 		}
     90 	}
     91 
     92 	protected class LightMsg {
     93 		private int light;
     94 
     95 		public LightMsg(int light) {
     96 			this.light = light;
     97 		}
     98 
     99 		public int getLight() {
    100 			return light;
    101 		}
    102 	}
    103 
    104 	protected class JoyMsg {
    105 		private int x;
    106 		private int y;
    107 
    108 		public JoyMsg(int x, int y) {
    109 			this.x = x;
    110 			this.y = y;
    111 		}
    112 
    113 		public int getX() {
    114 			return x;
    115 		}
    116 
    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
    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
    170 	public Object onRetainNonConfigurationInstance() {
    171 		if (mAccessory != null) {
    172 			return mAccessory;
    173 		} else {
    174 			return super.onRetainNonConfigurationInstance();
    175 		}
    176 	}
    177 
    178 	@Override
    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
    207 	public void onPause() {
    208 		super.onPause();
    209 		closeAccessory();
    210 	}
    211 
    212 	@Override
    213 	public void onDestroy() {
    214 		unregisterReceiver(mUsbReceiver);
    215 		super.onDestroy();
    216 	}
    217 
    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 
    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 
    248 	protected void enableControls(boolean enable) {
    249 	}
    250 
    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 
    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 
    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 
    369 	protected void handleJoyMessage(JoyMsg j) {
    370 	}
    371 
    372 	protected void handleLightMessage(LightMsg l) {
    373 	}
    374 
    375 	protected void handleTemperatureMessage(TemperatureMsg t) {
    376 	}
    377 
    378 	protected void handleSwitchMessage(SwitchMsg o) {
    379 	}
    380 
    381 	public void onStartTrackingTouch(SeekBar seekBar) {
    382 	}
    383 
    384 	public void onStopTrackingTouch(SeekBar seekBar) {
    385 	}
    386 }
    387