upload android base code part7
This commit is contained in:
parent
4e516ec6ed
commit
841ae54672
25229 changed files with 1709508 additions and 0 deletions
12
android/development/samples/USB/AdbTest/Android.mk
Normal file
12
android/development/samples/USB/AdbTest/Android.mk
Normal file
|
@ -0,0 +1,12 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := samples
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_PACKAGE_NAME := AdbTest
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
include $(BUILD_PACKAGE)
|
24
android/development/samples/USB/AdbTest/AndroidManifest.xml
Normal file
24
android/development/samples/USB/AdbTest/AndroidManifest.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.adb">
|
||||
|
||||
<uses-feature android:name="android.hardware.usb.host" />
|
||||
<uses-sdk android:minSdkVersion="12" />
|
||||
|
||||
<application>
|
||||
<activity android:name="AdbTestActivity" android:label="ADB Test">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/device_filter" />
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
11
android/development/samples/USB/AdbTest/README.txt
Normal file
11
android/development/samples/USB/AdbTest/README.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
AdbTest is a sample program that implements a subset of the adb USB protocol.
|
||||
Currently it only implements the "adb logcat" command and displays the log
|
||||
output in a text view and only allows connecting to one device at a time.
|
||||
However the support classes are structured in a way that would allow
|
||||
connecting to multiple devices and running multiple adb commands simultaneously.
|
||||
|
||||
This program serves as an example of the following USB host features:
|
||||
|
||||
- Matching devices based on interface class, subclass and protocol (see device_filter.xml)
|
||||
|
||||
- Asynchronous IO on bulk endpoints
|
13
android/development/samples/USB/AdbTest/_index.html
Normal file
13
android/development/samples/USB/AdbTest/_index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<p>AdbTest is a sample program that implements a subset of the <code>adb</code> USB protocol.
|
||||
Currently it only implements the <code>adb logcat</code> command and displays the log
|
||||
output in a text view and only allows connecting to one device at a time.
|
||||
However, the support classes are structured in a way that would allow
|
||||
connecting to multiple devices and running multiple <code>adb</code> commands simultaneously.</p>
|
||||
|
||||
<p>This program serves as an example of the following USB host features:</p>
|
||||
|
||||
<ul>
|
||||
<li>Matching devices based on interface class, subclass and protocol (see <code>device_filter.xml</code>)</li>
|
||||
|
||||
<li>Asynchronous IO on bulk endpoints</li>
|
||||
</ul>
|
11
android/development/samples/USB/AdbTest/default.properties
Normal file
11
android/development/samples/USB/AdbTest/default.properties
Normal file
|
@ -0,0 +1,11 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-12
|
33
android/development/samples/USB/AdbTest/res/layout/adb.xml
Normal file
33
android/development/samples/USB/AdbTest/res/layout/adb.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView android:id="@+id/log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="25dp"
|
||||
android:textSize="18sp"
|
||||
android:textColor="#ffffffff"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<usb-device class="255" subclass="66" protocol="1" />
|
||||
</resources>
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.adb;
|
||||
|
||||
import android.hardware.usb.UsbConstants;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/* This class represents a USB device that supports the adb protocol. */
|
||||
public class AdbDevice {
|
||||
|
||||
private final AdbTestActivity mActivity;
|
||||
private final UsbDeviceConnection mDeviceConnection;
|
||||
private final UsbEndpoint mEndpointOut;
|
||||
private final UsbEndpoint mEndpointIn;
|
||||
|
||||
private String mSerial;
|
||||
|
||||
// pool of requests for the OUT endpoint
|
||||
private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>();
|
||||
// pool of requests for the IN endpoint
|
||||
private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>();
|
||||
// list of currently opened sockets
|
||||
private final SparseArray<AdbSocket> mSockets = new SparseArray<AdbSocket>();
|
||||
private int mNextSocketId = 1;
|
||||
|
||||
private final WaiterThread mWaiterThread = new WaiterThread();
|
||||
|
||||
public AdbDevice(AdbTestActivity activity, UsbDeviceConnection connection,
|
||||
UsbInterface intf) {
|
||||
mActivity = activity;
|
||||
mDeviceConnection = connection;
|
||||
mSerial = connection.getSerial();
|
||||
|
||||
UsbEndpoint epOut = null;
|
||||
UsbEndpoint epIn = null;
|
||||
// look for our bulk endpoints
|
||||
for (int i = 0; i < intf.getEndpointCount(); i++) {
|
||||
UsbEndpoint ep = intf.getEndpoint(i);
|
||||
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
|
||||
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
|
||||
epOut = ep;
|
||||
} else {
|
||||
epIn = ep;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (epOut == null || epIn == null) {
|
||||
throw new IllegalArgumentException("not all endpoints found");
|
||||
}
|
||||
mEndpointOut = epOut;
|
||||
mEndpointIn = epIn;
|
||||
}
|
||||
|
||||
// return device serial number
|
||||
public String getSerial() {
|
||||
return mSerial;
|
||||
}
|
||||
|
||||
// get an OUT request from our pool
|
||||
public UsbRequest getOutRequest() {
|
||||
synchronized(mOutRequestPool) {
|
||||
if (mOutRequestPool.isEmpty()) {
|
||||
UsbRequest request = new UsbRequest();
|
||||
request.initialize(mDeviceConnection, mEndpointOut);
|
||||
return request;
|
||||
} else {
|
||||
return mOutRequestPool.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return an OUT request to the pool
|
||||
public void releaseOutRequest(UsbRequest request) {
|
||||
synchronized (mOutRequestPool) {
|
||||
mOutRequestPool.add(request);
|
||||
}
|
||||
}
|
||||
|
||||
// get an IN request from the pool
|
||||
public UsbRequest getInRequest() {
|
||||
synchronized(mInRequestPool) {
|
||||
if (mInRequestPool.isEmpty()) {
|
||||
UsbRequest request = new UsbRequest();
|
||||
request.initialize(mDeviceConnection, mEndpointIn);
|
||||
return request;
|
||||
} else {
|
||||
return mInRequestPool.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mWaiterThread.start();
|
||||
connect();
|
||||
}
|
||||
|
||||
public AdbSocket openSocket(String destination) {
|
||||
AdbSocket socket;
|
||||
synchronized (mSockets) {
|
||||
int id = mNextSocketId++;
|
||||
socket = new AdbSocket(this, id);
|
||||
mSockets.put(id, socket);
|
||||
}
|
||||
if (socket.open(destination)) {
|
||||
return socket;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private AdbSocket getSocket(int id) {
|
||||
synchronized (mSockets) {
|
||||
return mSockets.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
public void socketClosed(AdbSocket socket) {
|
||||
synchronized (mSockets) {
|
||||
mSockets.remove(socket.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// send a connect command
|
||||
private void connect() {
|
||||
AdbMessage message = new AdbMessage();
|
||||
message.set(AdbMessage.A_CNXN, AdbMessage.A_VERSION, AdbMessage.MAX_PAYLOAD, "host::\0");
|
||||
message.write(this);
|
||||
}
|
||||
|
||||
// handle connect response
|
||||
private void handleConnect(AdbMessage message) {
|
||||
if (message.getDataString().startsWith("device:")) {
|
||||
log("connected");
|
||||
mActivity.deviceOnline(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
synchronized (mWaiterThread) {
|
||||
mWaiterThread.mStop = true;
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch a message from the device
|
||||
void dispatchMessage(AdbMessage message) {
|
||||
int command = message.getCommand();
|
||||
switch (command) {
|
||||
case AdbMessage.A_SYNC:
|
||||
log("got A_SYNC");
|
||||
break;
|
||||
case AdbMessage.A_CNXN:
|
||||
handleConnect(message);
|
||||
break;
|
||||
case AdbMessage.A_OPEN:
|
||||
case AdbMessage.A_OKAY:
|
||||
case AdbMessage.A_CLSE:
|
||||
case AdbMessage.A_WRTE:
|
||||
AdbSocket socket = getSocket(message.getArg1());
|
||||
if (socket == null) {
|
||||
log("ERROR socket not found");
|
||||
} else {
|
||||
socket.handleMessage(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void log(String s) {
|
||||
mActivity.log(s);
|
||||
}
|
||||
|
||||
|
||||
private class WaiterThread extends Thread {
|
||||
public boolean mStop;
|
||||
|
||||
public void run() {
|
||||
// start out with a command read
|
||||
AdbMessage currentCommand = new AdbMessage();
|
||||
AdbMessage currentData = null;
|
||||
// FIXME error checking
|
||||
currentCommand.readCommand(getInRequest());
|
||||
|
||||
while (true) {
|
||||
synchronized (this) {
|
||||
if (mStop) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
UsbRequest request = mDeviceConnection.requestWait();
|
||||
if (request == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
AdbMessage message = (AdbMessage)request.getClientData();
|
||||
request.setClientData(null);
|
||||
AdbMessage messageToDispatch = null;
|
||||
|
||||
if (message == currentCommand) {
|
||||
int dataLength = message.getDataLength();
|
||||
// read data if length > 0
|
||||
if (dataLength > 0) {
|
||||
message.readData(getInRequest(), dataLength);
|
||||
currentData = message;
|
||||
} else {
|
||||
messageToDispatch = message;
|
||||
}
|
||||
currentCommand = null;
|
||||
} else if (message == currentData) {
|
||||
messageToDispatch = message;
|
||||
currentData = null;
|
||||
}
|
||||
|
||||
if (messageToDispatch != null) {
|
||||
// queue another read first
|
||||
currentCommand = new AdbMessage();
|
||||
currentCommand.readCommand(getInRequest());
|
||||
|
||||
// then dispatch the current message
|
||||
dispatchMessage(messageToDispatch);
|
||||
}
|
||||
|
||||
// put request back into the appropriate pool
|
||||
if (request.getEndpoint() == mEndpointOut) {
|
||||
releaseOutRequest(request);
|
||||
} else {
|
||||
synchronized (mInRequestPool) {
|
||||
mInRequestPool.add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.adb;
|
||||
|
||||
import android.hardware.usb.UsbRequest;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/* This class encapsulates and adb command packet */
|
||||
public class AdbMessage {
|
||||
|
||||
// command names
|
||||
public static final int A_SYNC = 0x434e5953;
|
||||
public static final int A_CNXN = 0x4e584e43;
|
||||
public static final int A_OPEN = 0x4e45504f;
|
||||
public static final int A_OKAY = 0x59414b4f;
|
||||
public static final int A_CLSE = 0x45534c43;
|
||||
public static final int A_WRTE = 0x45545257;
|
||||
|
||||
// ADB protocol version
|
||||
public static final int A_VERSION = 0x01000000;
|
||||
|
||||
public static final int MAX_PAYLOAD = 4096;
|
||||
|
||||
private final ByteBuffer mMessageBuffer;
|
||||
private final ByteBuffer mDataBuffer;
|
||||
|
||||
public AdbMessage() {
|
||||
mMessageBuffer = ByteBuffer.allocate(24);
|
||||
mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD);
|
||||
mMessageBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
mDataBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
// sets the fields in the command header
|
||||
public void set(int command, int arg0, int arg1, byte[] data) {
|
||||
mMessageBuffer.putInt(0, command);
|
||||
mMessageBuffer.putInt(4, arg0);
|
||||
mMessageBuffer.putInt(8, arg1);
|
||||
mMessageBuffer.putInt(12, (data == null ? 0 : data.length));
|
||||
mMessageBuffer.putInt(16, (data == null ? 0 : checksum(data)));
|
||||
mMessageBuffer.putInt(20, command ^ 0xFFFFFFFF);
|
||||
if (data != null) {
|
||||
mDataBuffer.put(data, 0, data.length);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(int command, int arg0, int arg1) {
|
||||
set(command, arg0, arg1, (byte[])null);
|
||||
}
|
||||
public void set(int command, int arg0, int arg1, String data) {
|
||||
// add trailing zero
|
||||
data += "\0";
|
||||
set(command, arg0, arg1, data.getBytes());
|
||||
}
|
||||
|
||||
// returns the command's message ID
|
||||
public int getCommand() {
|
||||
return mMessageBuffer.getInt(0);
|
||||
}
|
||||
|
||||
// returns command's first argument
|
||||
public int getArg0() {
|
||||
return mMessageBuffer.getInt(4);
|
||||
}
|
||||
|
||||
// returns command's second argument
|
||||
public int getArg1() {
|
||||
return mMessageBuffer.getInt(8);
|
||||
}
|
||||
|
||||
// returns command's data buffer
|
||||
public ByteBuffer getData() {
|
||||
return mDataBuffer;
|
||||
}
|
||||
|
||||
// returns command's data length
|
||||
public int getDataLength() {
|
||||
return mMessageBuffer.getInt(12);
|
||||
}
|
||||
|
||||
// returns command's data as a string
|
||||
public String getDataString() {
|
||||
int length = getDataLength();
|
||||
if (length == 0) return null;
|
||||
// trim trailing zero
|
||||
return new String(mDataBuffer.array(), 0, length - 1);
|
||||
}
|
||||
|
||||
|
||||
public boolean write(AdbDevice device) {
|
||||
synchronized (device) {
|
||||
UsbRequest request = device.getOutRequest();
|
||||
request.setClientData(this);
|
||||
if (request.queue(mMessageBuffer, 24)) {
|
||||
int length = getDataLength();
|
||||
if (length > 0) {
|
||||
request = device.getOutRequest();
|
||||
request.setClientData(this);
|
||||
if (request.queue(mDataBuffer, length)) {
|
||||
return true;
|
||||
} else {
|
||||
device.releaseOutRequest(request);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
device.releaseOutRequest(request);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean readCommand(UsbRequest request) {
|
||||
request.setClientData(this);
|
||||
return request.queue(mMessageBuffer, 24);
|
||||
}
|
||||
|
||||
public boolean readData(UsbRequest request, int length) {
|
||||
request.setClientData(this);
|
||||
return request.queue(mDataBuffer, length);
|
||||
}
|
||||
|
||||
private static String extractString(ByteBuffer buffer, int offset, int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
bytes[i] = buffer.get(offset++);
|
||||
}
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String commandName = extractString(mMessageBuffer, 0, 4);
|
||||
int dataLength = getDataLength();
|
||||
String result = "Adb Message: " + commandName + " arg0: " + getArg0() +
|
||||
" arg1: " + getArg1() + " dataLength: " + dataLength;
|
||||
if (dataLength > 0) {
|
||||
result += (" data: \"" + getDataString() + "\"");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int checksum(byte[] data) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int x = data[i];
|
||||
// dang, no unsigned ints in java
|
||||
if (x < 0) x += 256;
|
||||
result += x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.adb;
|
||||
|
||||
/* This class represents an adb socket. adb supports multiple independent
|
||||
* socket connections to a single device. Typically a socket is created
|
||||
* for each adb command that is executed.
|
||||
*/
|
||||
public class AdbSocket {
|
||||
|
||||
private final AdbDevice mDevice;
|
||||
private final int mId;
|
||||
private int mPeerId;
|
||||
|
||||
public AdbSocket(AdbDevice device, int id) {
|
||||
mDevice = device;
|
||||
mId = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public boolean open(String destination) {
|
||||
AdbMessage message = new AdbMessage();
|
||||
message.set(AdbMessage.A_OPEN, mId, 0, destination);
|
||||
if (! message.write(mDevice)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void handleMessage(AdbMessage message) {
|
||||
switch (message.getCommand()) {
|
||||
case AdbMessage.A_OKAY:
|
||||
mPeerId = message.getArg0();
|
||||
synchronized (this) {
|
||||
notify();
|
||||
}
|
||||
break;
|
||||
case AdbMessage.A_WRTE:
|
||||
mDevice.log(message.getDataString());
|
||||
sendReady();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendReady() {
|
||||
AdbMessage message = new AdbMessage();
|
||||
message.set(AdbMessage.A_OKAY, mId, mPeerId);
|
||||
message.write(mDevice);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.adb;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
/* Main activity for the adb test program */
|
||||
public class AdbTestActivity extends Activity {
|
||||
|
||||
private static final String TAG = "AdbTestActivity";
|
||||
|
||||
private TextView mLog;
|
||||
private UsbManager mManager;
|
||||
private UsbDevice mDevice;
|
||||
private UsbDeviceConnection mDeviceConnection;
|
||||
private UsbInterface mInterface;
|
||||
private AdbDevice mAdbDevice;
|
||||
|
||||
private static final int MESSAGE_LOG = 1;
|
||||
private static final int MESSAGE_DEVICE_ONLINE = 2;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.adb);
|
||||
mLog = (TextView)findViewById(R.id.log);
|
||||
|
||||
mManager = (UsbManager)getSystemService(Context.USB_SERVICE);
|
||||
|
||||
// check for existing devices
|
||||
for (UsbDevice device : mManager.getDeviceList().values()) {
|
||||
UsbInterface intf = findAdbInterface(device);
|
||||
if (setAdbInterface(device, intf)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// listen for new devices
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
|
||||
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
|
||||
registerReceiver(mUsbReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
unregisterReceiver(mUsbReceiver);
|
||||
setAdbInterface(null, null);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
public void log(String s) {
|
||||
Message m = Message.obtain(mHandler, MESSAGE_LOG);
|
||||
m.obj = s;
|
||||
mHandler.sendMessage(m);
|
||||
}
|
||||
|
||||
private void appendLog(String text) {
|
||||
Rect r = new Rect();
|
||||
mLog.getDrawingRect(r);
|
||||
int maxLines = r.height() / mLog.getLineHeight() - 1;
|
||||
text = mLog.getText() + "\n" + text;
|
||||
|
||||
// see how many lines we have
|
||||
int index = text.lastIndexOf('\n');
|
||||
int count = 0;
|
||||
while (index > 0 && count <= maxLines) {
|
||||
count++;
|
||||
index = text.lastIndexOf('\n', index - 1);
|
||||
}
|
||||
|
||||
// truncate to maxLines
|
||||
if (index > 0) {
|
||||
text = text.substring(index + 1);
|
||||
}
|
||||
mLog.setText(text);
|
||||
}
|
||||
|
||||
public void deviceOnline(AdbDevice device) {
|
||||
Message m = Message.obtain(mHandler, MESSAGE_DEVICE_ONLINE);
|
||||
m.obj = device;
|
||||
mHandler.sendMessage(m);
|
||||
}
|
||||
|
||||
private void handleDeviceOnline(AdbDevice device) {
|
||||
log("device online: " + device.getSerial());
|
||||
device.openSocket("shell:exec logcat");
|
||||
}
|
||||
|
||||
// Sets the current USB device and interface
|
||||
private boolean setAdbInterface(UsbDevice device, UsbInterface intf) {
|
||||
if (mDeviceConnection != null) {
|
||||
if (mInterface != null) {
|
||||
mDeviceConnection.releaseInterface(mInterface);
|
||||
mInterface = null;
|
||||
}
|
||||
mDeviceConnection.close();
|
||||
mDevice = null;
|
||||
mDeviceConnection = null;
|
||||
}
|
||||
|
||||
if (device != null && intf != null) {
|
||||
UsbDeviceConnection connection = mManager.openDevice(device);
|
||||
if (connection != null) {
|
||||
log("open succeeded");
|
||||
if (connection.claimInterface(intf, false)) {
|
||||
log("claim interface succeeded");
|
||||
mDevice = device;
|
||||
mDeviceConnection = connection;
|
||||
mInterface = intf;
|
||||
mAdbDevice = new AdbDevice(this, mDeviceConnection, intf);
|
||||
log("call start");
|
||||
mAdbDevice.start();
|
||||
return true;
|
||||
} else {
|
||||
log("claim interface failed");
|
||||
connection.close();
|
||||
}
|
||||
} else {
|
||||
log("open failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (mDeviceConnection == null && mAdbDevice != null) {
|
||||
mAdbDevice.stop();
|
||||
mAdbDevice = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// searches for an adb interface on the given USB device
|
||||
static private UsbInterface findAdbInterface(UsbDevice device) {
|
||||
Log.d(TAG, "findAdbInterface " + device);
|
||||
int count = device.getInterfaceCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
UsbInterface intf = device.getInterface(i);
|
||||
if (intf.getInterfaceClass() == 255 && intf.getInterfaceSubclass() == 66 &&
|
||||
intf.getInterfaceProtocol() == 1) {
|
||||
return intf;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
|
||||
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
|
||||
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||
UsbInterface intf = findAdbInterface(device);
|
||||
if (intf != null) {
|
||||
log("Found adb interface " + intf);
|
||||
setAdbInterface(device, intf);
|
||||
}
|
||||
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
|
||||
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||
String deviceName = device.getDeviceName();
|
||||
if (mDevice != null && mDevice.equals(deviceName)) {
|
||||
log("adb interface removed");
|
||||
setAdbInterface(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MESSAGE_LOG:
|
||||
appendLog((String)msg.obj);
|
||||
break;
|
||||
case MESSAGE_DEVICE_ONLINE:
|
||||
handleDeviceOnline((AdbDevice)msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
1
android/development/samples/USB/Android.mk
Normal file
1
android/development/samples/USB/Android.mk
Normal file
|
@ -0,0 +1 @@
|
|||
include $(call all-subdir-makefiles)
|
12
android/development/samples/USB/MissileLauncher/Android.mk
Normal file
12
android/development/samples/USB/MissileLauncher/Android.mk
Normal file
|
@ -0,0 +1,12 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := samples
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_PACKAGE_NAME := MissileLauncher
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
include $(BUILD_PACKAGE)
|
|
@ -0,0 +1,25 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.missilelauncher">
|
||||
|
||||
<uses-feature android:name="android.hardware.usb.host" />
|
||||
<uses-sdk android:minSdkVersion="12" />
|
||||
|
||||
<application>
|
||||
<activity android:name="MissileLauncherActivity"
|
||||
android:label="Missile Launcher"
|
||||
android:screenOrientation="nosensor">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/device_filter" />
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
13
android/development/samples/USB/MissileLauncher/README.txt
Normal file
13
android/development/samples/USB/MissileLauncher/README.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
MissileLauncher is a simple program that controls Dream Cheeky USB missile launchers.
|
||||
You control the left/right/up/down orientation of the launcher using the accelerometer.
|
||||
Tilt the tablet to change the direction of the launcher.
|
||||
Pressing the "Fire" button will fire one missile.
|
||||
|
||||
This program serves as an example of the following USB host features:
|
||||
|
||||
- filtering for multiple devices based on vendor and product IDs (see device_filter.xml)
|
||||
|
||||
- Sending control requests on endpoint zero that contain data
|
||||
|
||||
- Receiving packets on an interrupt endpoint using a thread that calls
|
||||
UsbRequest.queue and UsbDeviceConnection.requestWait()
|
11
android/development/samples/USB/MissileLauncher/_index.html
Normal file
11
android/development/samples/USB/MissileLauncher/_index.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<p>MissileLauncher is a simple program that controls Dream Cheeky USB missile launchers.
|
||||
You control the left/right/up/down orientation of the launcher using the accelerometer.
|
||||
Tilt the tablet to change the direction of the launcher. Pressing the <strong>Fire</strong> button will fire one missile.</p>
|
||||
|
||||
<p>This program serves as an example of the following USB host features:</p>
|
||||
<ul>
|
||||
<li>filtering for multiple devices based on vendor and product IDs (see <code>device_filter.xml</code>)</li>
|
||||
<li>Sending control requests on endpoint zero that contain data</li>
|
||||
<li>Receiving packets on an interrupt endpoint using a thread that calls
|
||||
{@link android.hardware.usb.UsbRequest#queue queue()} and {@link android.hardware.usb.UsbDeviceConnection#requestWait requestWait()}.</li>
|
||||
</p>
|
|
@ -0,0 +1,11 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-12
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<Button android:id="@+id/fire"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:layout_marginLeft="25dp"
|
||||
android:layout_marginRight="25dp"
|
||||
android:textSize="36sp"
|
||||
android:text="@string/fire">
|
||||
</Button>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<string name="fire">Fire!</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- vendor and product ID for Dream Cheeky USB Missle Launcher -->
|
||||
<usb-device vendor-id="2689" product-id="1793" />
|
||||
<!-- vendor and product ID for Dream Cheeky Wireless USB Missle Launcher -->
|
||||
<usb-device vendor-id="2689" product-id="65281" />
|
||||
</resources>
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.missilelauncher;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.usb.UsbConstants;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class MissileLauncherActivity extends Activity
|
||||
implements View.OnClickListener, Runnable {
|
||||
|
||||
private static final String TAG = "MissileLauncherActivity";
|
||||
|
||||
private Button mFire;
|
||||
private UsbManager mUsbManager;
|
||||
private UsbDevice mDevice;
|
||||
private UsbDeviceConnection mConnection;
|
||||
private UsbEndpoint mEndpointIntr;
|
||||
private SensorManager mSensorManager;
|
||||
private Sensor mGravitySensor;
|
||||
|
||||
// USB control commands
|
||||
private static final int COMMAND_UP = 1;
|
||||
private static final int COMMAND_DOWN = 2;
|
||||
private static final int COMMAND_RIGHT = 4;
|
||||
private static final int COMMAND_LEFT = 8;
|
||||
private static final int COMMAND_FIRE = 16;
|
||||
private static final int COMMAND_STOP = 32;
|
||||
private static final int COMMAND_STATUS = 64;
|
||||
|
||||
// constants for accelerometer orientation
|
||||
private static final int TILT_LEFT = 1;
|
||||
private static final int TILT_RIGHT = 2;
|
||||
private static final int TILT_UP = 4;
|
||||
private static final int TILT_DOWN = 8;
|
||||
private static final double THRESHOLD = 5.0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.launcher);
|
||||
mFire = (Button)findViewById(R.id.fire);
|
||||
mFire.setOnClickListener(this);
|
||||
|
||||
mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
|
||||
|
||||
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
|
||||
mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mSensorManager.unregisterListener(mGravityListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mSensorManager.registerListener(mGravityListener, mGravitySensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL);
|
||||
|
||||
Intent intent = getIntent();
|
||||
Log.d(TAG, "intent: " + intent);
|
||||
String action = intent.getAction();
|
||||
|
||||
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
|
||||
setDevice(device);
|
||||
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
|
||||
if (mDevice != null && mDevice.equals(device)) {
|
||||
setDevice(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void setDevice(UsbDevice device) {
|
||||
Log.d(TAG, "setDevice " + device);
|
||||
if (device.getInterfaceCount() != 1) {
|
||||
Log.e(TAG, "could not find interface");
|
||||
return;
|
||||
}
|
||||
UsbInterface intf = device.getInterface(0);
|
||||
// device should have one endpoint
|
||||
if (intf.getEndpointCount() != 1) {
|
||||
Log.e(TAG, "could not find endpoint");
|
||||
return;
|
||||
}
|
||||
// endpoint should be of type interrupt
|
||||
UsbEndpoint ep = intf.getEndpoint(0);
|
||||
if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
|
||||
Log.e(TAG, "endpoint is not interrupt type");
|
||||
return;
|
||||
}
|
||||
mDevice = device;
|
||||
mEndpointIntr = ep;
|
||||
if (device != null) {
|
||||
UsbDeviceConnection connection = mUsbManager.openDevice(device);
|
||||
if (connection != null && connection.claimInterface(intf, true)) {
|
||||
Log.d(TAG, "open SUCCESS");
|
||||
mConnection = connection;
|
||||
Thread thread = new Thread(this);
|
||||
thread.start();
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "open FAIL");
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendCommand(int control) {
|
||||
synchronized (this) {
|
||||
if (control != COMMAND_STATUS) {
|
||||
Log.d(TAG, "sendMove " + control);
|
||||
}
|
||||
if (mConnection != null) {
|
||||
byte[] message = new byte[1];
|
||||
message[0] = (byte)control;
|
||||
// Send command via a control request on endpoint zero
|
||||
mConnection.controlTransfer(0x21, 0x9, 0x200, 0, message, message.length, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v == mFire) {
|
||||
sendCommand(COMMAND_FIRE);
|
||||
}
|
||||
}
|
||||
|
||||
private int mLastValue = 0;
|
||||
|
||||
SensorEventListener mGravityListener = new SensorEventListener() {
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
|
||||
// compute current tilt
|
||||
int value = 0;
|
||||
if (event.values[0] < -THRESHOLD) {
|
||||
value += TILT_LEFT;
|
||||
} else if (event.values[0] > THRESHOLD) {
|
||||
value += TILT_RIGHT;
|
||||
}
|
||||
if (event.values[1] < -THRESHOLD) {
|
||||
value += TILT_UP;
|
||||
} else if (event.values[1] > THRESHOLD) {
|
||||
value += TILT_DOWN;
|
||||
}
|
||||
|
||||
if (value != mLastValue) {
|
||||
mLastValue = value;
|
||||
// send motion command if the tilt changed
|
||||
switch (value) {
|
||||
case TILT_LEFT:
|
||||
sendCommand(COMMAND_LEFT);
|
||||
break;
|
||||
case TILT_RIGHT:
|
||||
sendCommand(COMMAND_RIGHT);
|
||||
break;
|
||||
case TILT_UP:
|
||||
sendCommand(COMMAND_UP);
|
||||
break;
|
||||
case TILT_DOWN:
|
||||
sendCommand(COMMAND_DOWN);
|
||||
break;
|
||||
default:
|
||||
sendCommand(COMMAND_STOP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// ignore
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1);
|
||||
UsbRequest request = new UsbRequest();
|
||||
request.initialize(mConnection, mEndpointIntr);
|
||||
byte status = -1;
|
||||
while (true) {
|
||||
// queue a request on the interrupt endpoint
|
||||
request.queue(buffer, 1);
|
||||
// send poll status command
|
||||
sendCommand(COMMAND_STATUS);
|
||||
// wait for status event
|
||||
if (mConnection.requestWait() == request) {
|
||||
byte newStatus = buffer.get(0);
|
||||
if (newStatus != status) {
|
||||
Log.d(TAG, "got status " + newStatus);
|
||||
status = newStatus;
|
||||
if ((status & COMMAND_FIRE) != 0) {
|
||||
// stop firing
|
||||
sendCommand(COMMAND_STOP);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "requestWait failed, exiting");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
1
android/development/samples/USB/_index.html
Normal file
1
android/development/samples/USB/_index.html
Normal file
|
@ -0,0 +1 @@
|
|||
<p>A set of samples that demonstrate how to use various features of the USB APIs.</p>
|
Loading…
Add table
Add a link
Reference in a new issue