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