diff options
author | Mike Lockwood <lockwood@android.com> | 2011-02-28 17:45:08 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-02-28 17:45:08 -0800 |
commit | eb3885d69255dbb8880d2518fff750997b7025cf (patch) | |
tree | 99271989a386d69254f1e3fe22819475c9b16122 /libs | |
parent | c93f67c2b746a6247744c8b50e8a1d5a566694c9 (diff) | |
parent | 27555315629ffce59a19bd03ba51a8323cc864b0 (diff) | |
download | frameworks_base-eb3885d69255dbb8880d2518fff750997b7025cf.zip frameworks_base-eb3885d69255dbb8880d2518fff750997b7025cf.tar.gz frameworks_base-eb3885d69255dbb8880d2518fff750997b7025cf.tar.bz2 |
Merge "USB accessory support library"
Diffstat (limited to 'libs')
-rw-r--r-- | libs/usb/Android.mk | 27 | ||||
-rw-r--r-- | libs/usb/src/com/google/android/usb/UsbAccessory.java | 96 | ||||
-rw-r--r-- | libs/usb/src/com/google/android/usb/UsbManager.java | 127 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/Android.mk | 15 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/AndroidManifest.xml | 23 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/README.txt | 10 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/accessorychat/Android.mk | 34 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c | 174 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/res/layout/accessory_chat.xml | 47 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/res/xml/accessory_filter.xml | 18 | ||||
-rw-r--r-- | libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java | 153 |
11 files changed, 724 insertions, 0 deletions
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk new file mode 100644 index 0000000..d0ef6f0 --- /dev/null +++ b/libs/usb/Android.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2008 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under,src) + +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE:= com.google.android.usb + +include $(BUILD_JAVA_LIBRARY) diff --git a/libs/usb/src/com/google/android/usb/UsbAccessory.java b/libs/usb/src/com/google/android/usb/UsbAccessory.java new file mode 100644 index 0000000..91095f3 --- /dev/null +++ b/libs/usb/src/com/google/android/usb/UsbAccessory.java @@ -0,0 +1,96 @@ +/* + * 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.google.android.usb; + +/** + * A class representing a USB accessory. + */ +public final class UsbAccessory { + + private final String mManufacturer; + private final String mModel; + private final String mType; + private final String mVersion; + + /* package */ UsbAccessory(android.hardware.UsbAccessory accessory) { + mManufacturer = accessory.getManufacturer(); + mModel = accessory.getModel(); + mType = accessory.getType(); + mVersion = accessory.getVersion(); + } + + /** + * Returns the manufacturer of the accessory. + * + * @return the accessory manufacturer + */ + public String getManufacturer() { + return mManufacturer; + } + + /** + * Returns the model name of the accessory. + * + * @return the accessory model + */ + public String getModel() { + return mModel; + } + + /** + * Returns the type of the accessory. + * + * @return the accessory type + */ + public String getType() { + return mType; + } + + /** + * Returns the version of the accessory. + * + * @return the accessory version + */ + public String getVersion() { + return mVersion; + } + + private static boolean compare(String s1, String s2) { + if (s1 == null) return (s2 == null); + return s1.equals(s2); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UsbAccessory) { + UsbAccessory accessory = (UsbAccessory)obj; + return (compare(mManufacturer, accessory.getManufacturer()) && + compare(mModel, accessory.getModel()) && + compare(mType, accessory.getType()) && + compare(mVersion, accessory.getVersion())); + } + return false; + } + + @Override + public String toString() { + return "UsbAccessory[mManufacturer=" + mManufacturer + + ", mModel=" + mModel + + ", mType=" + mType + + ", mVersion=" + mVersion + "]"; + } +} diff --git a/libs/usb/src/com/google/android/usb/UsbManager.java b/libs/usb/src/com/google/android/usb/UsbManager.java new file mode 100644 index 0000000..1b9bff9 --- /dev/null +++ b/libs/usb/src/com/google/android/usb/UsbManager.java @@ -0,0 +1,127 @@ +/* + * 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.google.android.usb; + +import android.content.Context; +import android.content.Intent; +import android.hardware.IUsbManager; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; + +/** + * This class allows you to access the state of USB, both in host and device mode. + * + * <p>You can obtain an instance of this class by calling {@link #getInstance} + * + */ +public class UsbManager { + private static final String TAG = "UsbManager"; + + /** + * Broadcast Action: A broadcast for USB accessory attached event. + * + * This intent is sent when a USB accessory is attached. + * Call {@link #getAccessory(android.content.Intent)} to retrieve the + * {@link com.google.android.usb.UsbAccessory} for the attached accessory. + */ + public static final String ACTION_USB_ACCESSORY_ATTACHED = + "android.hardware.action.USB_ACCESSORY_ATTACHED"; + + /** + * Broadcast Action: A broadcast for USB accessory detached event. + * + * This intent is sent when a USB accessory is detached. + * Call {@link #getAccessory(android.content.Intent)} to retrieve the + * {@link com.google.android.usb.UsbAccessory} for the attached accessory that was detached. + */ + public static final String ACTION_USB_ACCESSORY_DETACHED = + "android.hardware.action.USB_ACCESSORY_DETACHED"; + + private final IUsbManager mService; + + private UsbManager(IUsbManager service) { + mService = service; + } + + /** + * Returns a new instance of this class. + * + * @return UsbManager instance. + */ + public static UsbManager getInstance() { + IBinder b = ServiceManager.getService(Context.USB_SERVICE); + return new UsbManager(IUsbManager.Stub.asInterface(b)); + } + + /** + * Returns the {@link com.google.android.usb.UsbAccessory} for + * a {@link #ACTION_USB_ACCESSORY_ATTACHED} or {@link #ACTION_USB_ACCESSORY_ATTACHED} + * broadcast Intent + * + * @return UsbAccessory for the broadcast. + */ + public static UsbAccessory getAccessory(Intent intent) { + android.hardware.UsbAccessory accessory = + intent.getParcelableExtra(android.hardware.UsbManager.EXTRA_ACCESSORY); + if (accessory == null) { + return null; + } else { + return new UsbAccessory(accessory); + } + } + + /** + * Returns a list of currently attached USB accessories. + * (in the current implementation there can be at most one) + * + * @return list of USB accessories, or null if none are attached. + */ + public UsbAccessory[] getAccessoryList() { + try { + android.hardware.UsbAccessory accessory = mService.getCurrentAccessory(); + if (accessory == null) { + return null; + } else { + return new UsbAccessory[] { new UsbAccessory(accessory) }; + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in getAccessoryList" , e); + return null; + } + } + + /** + * Opens a file descriptor for reading and writing data to the USB accessory. + * + * @param accessory the USB accessory to open + * @return file descriptor, or null if the accessor could not be opened. + */ + public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { + try { + return mService.openAccessory(new android.hardware.UsbAccessory( + accessory.getManufacturer(),accessory.getModel(), + accessory.getType(), accessory.getVersion())); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in openAccessory" , e); + return null; + } + } +} diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk new file mode 100644 index 0000000..b854569 --- /dev/null +++ b/libs/usb/tests/AccessoryChat/Android.mk @@ -0,0 +1,15 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AccessoryChatGB + +LOCAL_JAVA_LIBRARIES := com.google.android.usb + +# Force an old SDK version to make sure we aren't using newer UsbManager APIs +LOCAL_SDK_VERSION := 8 + +include $(BUILD_PACKAGE) diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml new file mode 100644 index 0000000..b63999c --- /dev/null +++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml @@ -0,0 +1,23 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.accessorychat"> + + <application> + <uses-library android:name="com.google.android.usb" /> + + <activity android:name="AccessoryChat" android:label="Accessory Chat GB"> + <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.action.USB_ACCESSORY_ATTACHED" /> + </intent-filter> + + <meta-data android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" + android:resource="@xml/accessory_filter" /> + </activity> + </application> + <uses-sdk android:minSdkVersion="8" /> +</manifest> diff --git a/libs/usb/tests/AccessoryChat/README.txt b/libs/usb/tests/AccessoryChat/README.txt new file mode 100644 index 0000000..d2ce11e --- /dev/null +++ b/libs/usb/tests/AccessoryChat/README.txt @@ -0,0 +1,10 @@ +This is a test app for the USB accessory APIs. It consists of two parts: + +AccessoryChat - A Java app with a chat-like UI that sends and receives strings + via the UsbAccessory class. + +accessorychat - A C command-line program that communicates with AccessoryChat. + This program behaves as if it were a USB accessory. + It builds both for the host (Linux PC) and as an android + command line program, which will work if run as root on an + android device with USB host support diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk new file mode 100644 index 0000000..300224a --- /dev/null +++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk @@ -0,0 +1,34 @@ +LOCAL_PATH:= $(call my-dir) + +# Build for Linux (desktop) host +ifeq ($(HOST_OS),linux) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := accessorychat.c + +LOCAL_MODULE := accessorychat + +LOCAL_C_INCLUDES += bionic/libc/kernel/common +LOCAL_STATIC_LIBRARIES := libusbhost libcutils +LOCAL_LDLIBS += -lpthread +LOCAL_CFLAGS := -g -O0 + +include $(BUILD_HOST_EXECUTABLE) + +endif + +# Build for device +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := accessorychat.c + +LOCAL_MODULE := accessorychat + +LOCAL_SHARED_LIBRARIES := libusbhost libcutils + +include $(BUILD_EXECUTABLE) diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c new file mode 100644 index 0000000..94cc0ce --- /dev/null +++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread.h> + +#include <usbhost/usbhost.h> +#include <linux/usb/f_accessory.h> + +struct usb_device *sDevice = NULL; + +static void* read_thread(void* arg) { + int endpoint = (int)arg; + int ret = 0; + + while (sDevice && ret >= 0) { + char buffer[16384]; + + ret = usb_device_bulk_transfer(sDevice, endpoint, buffer, sizeof(buffer), 1000); + if (ret < 0 && errno == ETIMEDOUT) + ret = 0; + if (ret > 0) { + fwrite(buffer, 1, ret, stdout); + printf("\n"); + fflush(stdout); + } + } + + return NULL; +} + +static void* write_thread(void* arg) { + int endpoint = (int)arg; + int ret = 0; + + while (ret >= 0) { + char buffer[16384]; + char *line = fgets(buffer, sizeof(buffer), stdin); + if (!line || !sDevice) + break; + ret = usb_device_bulk_transfer(sDevice, endpoint, line, strlen(line), 1000); + } + + return NULL; +} + +static void send_string(struct usb_device *device, int index, const char* string) { + int ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR, + ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 0); +} + +static int usb_device_added(const char *devname, void* client_data) { + struct usb_descriptor_header* desc; + struct usb_descriptor_iter iter; + uint16_t vendorId, productId; + int ret; + pthread_t th; + + struct usb_device *device = usb_device_open(devname); + if (!device) { + fprintf(stderr, "usb_device_open failed\n"); + return 0; + } + + vendorId = usb_device_get_vendor_id(device); + productId = usb_device_get_product_id(device); + + if (vendorId == 0x18D1 || vendorId == 0x22B8) { + if (!sDevice && (productId == 0x2D00 || productId == 0x2D01)) { + struct usb_descriptor_header* desc; + struct usb_descriptor_iter iter; + struct usb_interface_descriptor *intf = NULL; + struct usb_endpoint_descriptor *ep1 = NULL; + struct usb_endpoint_descriptor *ep2 = NULL; + + printf("Found android device in accessory mode\n"); + sDevice = device; + + usb_descriptor_iter_init(device, &iter); + while ((desc = usb_descriptor_iter_next(&iter)) != NULL && (!intf || !ep1 || !ep2)) { + if (desc->bDescriptorType == USB_DT_INTERFACE) { + intf = (struct usb_interface_descriptor *)desc; + } else if (desc->bDescriptorType == USB_DT_ENDPOINT) { + if (ep1) + ep2 = (struct usb_endpoint_descriptor *)desc; + else + ep1 = (struct usb_endpoint_descriptor *)desc; + } + } + + if (!intf) { + fprintf(stderr, "interface not found\n"); + exit(1); + } + if (!ep1 || !ep2) { + fprintf(stderr, "endpoints not found\n"); + exit(1); + } + + if (usb_device_claim_interface(device, intf->bInterfaceNumber)) { + fprintf(stderr, "usb_device_claim_interface failed errno: %d\n", errno); + exit(1); + } + + if ((ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { + pthread_create(&th, NULL, read_thread, (void *)ep1->bEndpointAddress); + pthread_create(&th, NULL, write_thread, (void *)ep2->bEndpointAddress); + } else { + pthread_create(&th, NULL, read_thread, (void *)ep2->bEndpointAddress); + pthread_create(&th, NULL, write_thread, (void *)ep1->bEndpointAddress); + } + } else { + printf("Found possible android device - attempting to switch to accessory mode\n"); + + send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc."); + send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat"); + send_string(device, ACCESSORY_STRING_TYPE, "Sample Program"); + send_string(device, ACCESSORY_STRING_VERSION, "1.0"); + + ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR, + ACCESSORY_START, 0, 0, 0, 0, 0); + return 0; + } + } + + if (device != sDevice) + usb_device_close(device); + + return 0; +} + +static int usb_device_removed(const char *devname, void* client_data) { + if (sDevice && !strcmp(usb_device_get_name(sDevice), devname)) { + usb_device_close(sDevice); + sDevice = NULL; + // exit when we are disconnected + return 1; + } + return 0; +} + + +int main(int argc, char* argv[]) { + struct usb_host_context* context = usb_host_init(); + if (!context) { + fprintf(stderr, "usb_host_init failed"); + return 1; + } + + // this will never return so it is safe to pass thiz directly + usb_host_run(context, usb_device_added, usb_device_removed, NULL, NULL); + return 0; +} diff --git a/libs/usb/tests/AccessoryChat/res/layout/accessory_chat.xml b/libs/usb/tests/AccessoryChat/res/layout/accessory_chat.xml new file mode 100644 index 0000000..596ecbf --- /dev/null +++ b/libs/usb/tests/AccessoryChat/res/layout/accessory_chat.xml @@ -0,0 +1,47 @@ +<?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" + > + + <ScrollView android:id="@+id/scroll" + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="1" + > + <TextView android:id="@+id/log" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="25dp" + android:textSize="12sp" + android:textColor="#ffffffff" + /> + </ScrollView> + + <EditText android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:capitalize="sentences" + android:autoText="true" + android:singleLine="true" + /> + +</LinearLayout> + + diff --git a/libs/usb/tests/AccessoryChat/res/xml/accessory_filter.xml b/libs/usb/tests/AccessoryChat/res/xml/accessory_filter.xml new file mode 100644 index 0000000..588946f --- /dev/null +++ b/libs/usb/tests/AccessoryChat/res/xml/accessory_filter.xml @@ -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-accessory manufacturer="Google, Inc." model="AccessoryChat" type="Sample Program" version="1.0" /> +</resources> diff --git a/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java new file mode 100644 index 0000000..0a5701c --- /dev/null +++ b/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java @@ -0,0 +1,153 @@ +/* + * 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.google.android.accessorychat; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.util.Log; +import android.widget.EditText; +import android.widget.TextView; + +import com.google.android.usb.UsbAccessory; +import com.google.android.usb.UsbManager; + +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class AccessoryChat extends Activity implements Runnable, TextView.OnEditorActionListener { + + private static final String TAG = "AccessoryChat"; + TextView mLog; + EditText mEditText; + ParcelFileDescriptor mFileDescriptor; + FileInputStream mInputStream; + FileOutputStream mOutputStream; + + private static final int MESSAGE_LOG = 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.accessory_chat); + mLog = (TextView)findViewById(R.id.log); + mEditText = (EditText)findViewById(R.id.message); + mEditText.setOnEditorActionListener(this); + } + + @Override + public void onResume() { + super.onResume(); + + Intent intent = getIntent(); + Log.d(TAG, "intent: " + intent); + UsbManager manager = UsbManager.getInstance(); + UsbAccessory[] accessories = manager.getAccessoryList(); + UsbAccessory accessory = (accessories == null ? null : accessories[0]); + if (accessory != null) { + mFileDescriptor = manager.openAccessory(accessory); + if (mFileDescriptor != null) { + FileDescriptor fd = mFileDescriptor.getFileDescriptor(); + mInputStream = new FileInputStream(fd); + mOutputStream = new FileOutputStream(fd); + Thread thread = new Thread(null, this, "AccessoryChat"); + thread.start(); + } else { + Log.d(TAG, "openAccessory fail"); + } + } else { + Log.d(TAG, "mAccessory is null"); + } + } + + @Override + public void onPause() { + super.onPause(); + if (mFileDescriptor != null) { + try { + mFileDescriptor.close(); + } catch (IOException e) { + } finally { + mFileDescriptor = null; + } + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE && mOutputStream != null) { + try { + mOutputStream.write(v.getText().toString().getBytes()); + } catch (IOException e) { + Log.e(TAG, "write failed", e); + } + v.setText(""); + return true; + } + Log.d(TAG, "onEditorAction " + actionId + " event: " + event); + return false; + } + + public void run() { + int ret = 0; + byte[] buffer = new byte[16384]; + while (ret >= 0) { + try { + ret = mInputStream.read(buffer); + } catch (IOException e) { + break; + } + + if (ret > 0) { + Message m = Message.obtain(mHandler, MESSAGE_LOG); + String text = new String(buffer, 0, ret); + Log.d(TAG, "chat: " + text); + m.obj = text; + mHandler.sendMessage(m); + } + } + Log.d(TAG, "thread out"); + } + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_LOG: + mLog.setText(mLog.getText() + "\n" + (String)msg.obj); + break; + } + } + }; +} + + |