127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood/* 227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * Copyright (C) 2011 The Android Open Source Project 327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * 427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * you may not use this file except in compliance with the License. 627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * You may obtain a copy of the License at 727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * 827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * 1027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * See the License for the specific language governing permissions and 1427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood * limitations under the License. 1527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood */ 1627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 17b547fc297f24ce2d74fc86ef2a79a4424b6b4c59Mike Lockwoodpackage com.android.accessorychat; 1827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 1927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.app.Activity; 20580b64111788fd312697d4fe60017127877dadf4Mike Lockwoodimport android.app.PendingIntent; 2127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.content.BroadcastReceiver; 2227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.content.Context; 2327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.content.Intent; 24580b64111788fd312697d4fe60017127877dadf4Mike Lockwoodimport android.content.IntentFilter; 2527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.os.Bundle; 2627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.os.Handler; 2727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.os.Message; 2827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.os.ParcelFileDescriptor; 2927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.view.KeyEvent; 3027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.view.View; 3127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.view.inputmethod.EditorInfo; 3227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.util.Log; 3327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.widget.EditText; 3427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport android.widget.TextView; 3527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 36c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilsonimport android.hardware.usb.UsbManager; 37c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilsonimport android.hardware.usb.UsbAccessory; 3827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 3927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport java.io.FileDescriptor; 4027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport java.io.FileInputStream; 4127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport java.io.FileOutputStream; 4227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodimport java.io.IOException; 4327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 4427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwoodpublic class AccessoryChat extends Activity implements Runnable, TextView.OnEditorActionListener { 4527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 4627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood private static final String TAG = "AccessoryChat"; 47580b64111788fd312697d4fe60017127877dadf4Mike Lockwood 48580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private static final String ACTION_USB_PERMISSION = 49580b64111788fd312697d4fe60017127877dadf4Mike Lockwood "com.android.accessorychat.action.USB_PERMISSION"; 50580b64111788fd312697d4fe60017127877dadf4Mike Lockwood 51580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private TextView mLog; 52580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private EditText mEditText; 53580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private ParcelFileDescriptor mFileDescriptor; 54580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private FileInputStream mInputStream; 55580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private FileOutputStream mOutputStream; 56580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private UsbManager mUsbManager; 57580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private PendingIntent mPermissionIntent; 58580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private boolean mPermissionRequestPending; 5927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 6027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood private static final int MESSAGE_LOG = 1; 6127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 62580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 63580b64111788fd312697d4fe60017127877dadf4Mike Lockwood @Override 64580b64111788fd312697d4fe60017127877dadf4Mike Lockwood public void onReceive(Context context, Intent intent) { 65580b64111788fd312697d4fe60017127877dadf4Mike Lockwood if (ACTION_USB_PERMISSION.equals(intent.getAction())) { 66580b64111788fd312697d4fe60017127877dadf4Mike Lockwood synchronized (this) { 67c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilson UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 68580b64111788fd312697d4fe60017127877dadf4Mike Lockwood if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 69c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilson if (accessory != null) { 70c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilson openAccessory(accessory); 71c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilson } 72580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } else { 73580b64111788fd312697d4fe60017127877dadf4Mike Lockwood Log.d(TAG, "permission denied for accessory " + accessory); 74580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 75580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mPermissionRequestPending = false; 76580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 77580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 78580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 79580b64111788fd312697d4fe60017127877dadf4Mike Lockwood }; 80580b64111788fd312697d4fe60017127877dadf4Mike Lockwood 8127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood @Override 8227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void onCreate(Bundle savedInstanceState) { 8327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood super.onCreate(savedInstanceState); 8427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 85c92e6f14f9ac6c86b7784f8a21d7077ea7cae0bbSimon Wilson mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 86580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 87580b64111788fd312697d4fe60017127877dadf4Mike Lockwood IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 88580b64111788fd312697d4fe60017127877dadf4Mike Lockwood registerReceiver(mUsbReceiver, filter); 89580b64111788fd312697d4fe60017127877dadf4Mike Lockwood 9027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood setContentView(R.layout.accessory_chat); 9127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mLog = (TextView)findViewById(R.id.log); 9227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mEditText = (EditText)findViewById(R.id.message); 9327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mEditText.setOnEditorActionListener(this); 9427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 9527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 9627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood @Override 9727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void onResume() { 9827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood super.onResume(); 9927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 10027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Intent intent = getIntent(); 10127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.d(TAG, "intent: " + intent); 102580b64111788fd312697d4fe60017127877dadf4Mike Lockwood UsbAccessory[] accessories = mUsbManager.getAccessoryList(); 10327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood UsbAccessory accessory = (accessories == null ? null : accessories[0]); 10427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood if (accessory != null) { 105580b64111788fd312697d4fe60017127877dadf4Mike Lockwood if (mUsbManager.hasPermission(accessory)) { 106580b64111788fd312697d4fe60017127877dadf4Mike Lockwood openAccessory(accessory); 10727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } else { 108580b64111788fd312697d4fe60017127877dadf4Mike Lockwood synchronized (mUsbReceiver) { 109580b64111788fd312697d4fe60017127877dadf4Mike Lockwood if (!mPermissionRequestPending) { 110580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mUsbManager.requestPermission(accessory, mPermissionIntent); 111580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mPermissionRequestPending = true; 112580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 113580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 11427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 115580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } else { 11627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.d(TAG, "mAccessory is null"); 11727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 11827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 11927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 12027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood @Override 12127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void onPause() { 12227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood super.onPause(); 12327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood if (mFileDescriptor != null) { 12427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood try { 12527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mFileDescriptor.close(); 12627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } catch (IOException e) { 12727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } finally { 12827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mFileDescriptor = null; 12927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 13027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 13127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 13227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 13327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood @Override 13427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void onDestroy() { 135580b64111788fd312697d4fe60017127877dadf4Mike Lockwood unregisterReceiver(mUsbReceiver); 13627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood super.onDestroy(); 13727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 13827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 139580b64111788fd312697d4fe60017127877dadf4Mike Lockwood private void openAccessory(UsbAccessory accessory) { 140015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood Log.d(TAG, "openAccessory: " + accessory); 141015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood mFileDescriptor = mUsbManager.openAccessory(accessory); 142580b64111788fd312697d4fe60017127877dadf4Mike Lockwood if (mFileDescriptor != null) { 143580b64111788fd312697d4fe60017127877dadf4Mike Lockwood FileDescriptor fd = mFileDescriptor.getFileDescriptor(); 144580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mInputStream = new FileInputStream(fd); 145580b64111788fd312697d4fe60017127877dadf4Mike Lockwood mOutputStream = new FileOutputStream(fd); 146580b64111788fd312697d4fe60017127877dadf4Mike Lockwood Thread thread = new Thread(null, this, "AccessoryChat"); 147580b64111788fd312697d4fe60017127877dadf4Mike Lockwood thread.start(); 148580b64111788fd312697d4fe60017127877dadf4Mike Lockwood Log.d(TAG, "openAccessory succeeded"); 149580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } else { 150580b64111788fd312697d4fe60017127877dadf4Mike Lockwood Log.d(TAG, "openAccessory fail"); 151580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 152580b64111788fd312697d4fe60017127877dadf4Mike Lockwood } 153580b64111788fd312697d4fe60017127877dadf4Mike Lockwood 15427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 15527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood if (actionId == EditorInfo.IME_ACTION_DONE && mOutputStream != null) { 15627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood try { 15727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mOutputStream.write(v.getText().toString().getBytes()); 15827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } catch (IOException e) { 15927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.e(TAG, "write failed", e); 16027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 16127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood v.setText(""); 16227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood return true; 16327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 16427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.d(TAG, "onEditorAction " + actionId + " event: " + event); 16527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood return false; 16627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 16727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 16827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void run() { 16927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood int ret = 0; 17027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood byte[] buffer = new byte[16384]; 17127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood while (ret >= 0) { 17227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood try { 17327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood ret = mInputStream.read(buffer); 17427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } catch (IOException e) { 17527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood break; 17627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 17727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 17827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood if (ret > 0) { 17927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Message m = Message.obtain(mHandler, MESSAGE_LOG); 18027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood String text = new String(buffer, 0, ret); 18127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.d(TAG, "chat: " + text); 18227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood m.obj = text; 18327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mHandler.sendMessage(m); 18427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 18527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 18627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Log.d(TAG, "thread out"); 18727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 18827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 18927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood Handler mHandler = new Handler() { 19027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood @Override 19127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood public void handleMessage(Message msg) { 19227555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood switch (msg.what) { 19327555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood case MESSAGE_LOG: 19427555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood mLog.setText(mLog.getText() + "\n" + (String)msg.obj); 19527555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood break; 19627555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 19727555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood } 19827555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood }; 19927555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood} 20027555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 20127555315629ffce59a19bd03ba51a8323cc864b0Mike Lockwood 202