125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood/* 225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * Copyright (C) 2011 The Android Open Source Project 325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * 425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * you may not use this file except in compliance with the License. 625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * You may obtain a copy of the License at 725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * 825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * 1025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * See the License for the specific language governing permissions and 1425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood * limitations under the License. 1525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood */ 1625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 1725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodpackage com.android.serialchat; 1825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 1925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.app.Activity; 2025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.content.Context; 2125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.hardware.SerialManager; 2225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.hardware.SerialPort; 2325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.os.Bundle; 2425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.os.Handler; 2525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.os.Message; 2625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.os.ParcelFileDescriptor; 2725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.view.KeyEvent; 2825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.view.View; 2925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.view.inputmethod.EditorInfo; 3025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.util.Log; 3125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.widget.EditText; 3225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport android.widget.TextView; 3325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 3425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport java.nio.ByteBuffer; 3525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodimport java.io.IOException; 3625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 3725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwoodpublic class SerialChat extends Activity implements Runnable, TextView.OnEditorActionListener { 3825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 3925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private static final String TAG = "SerialChat"; 4025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 4125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private TextView mLog; 4225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private EditText mEditText; 4325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private ByteBuffer mInputBuffer; 4425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private ByteBuffer mOutputBuffer; 4525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private SerialManager mSerialManager; 4625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private SerialPort mSerialPort; 4725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private boolean mPermissionRequestPending; 4825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 4925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood private static final int MESSAGE_LOG = 1; 5025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 5125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood @Override 5225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void onCreate(Bundle savedInstanceState) { 5325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood super.onCreate(savedInstanceState); 5425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 5525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mSerialManager = (SerialManager)getSystemService(Context.SERIAL_SERVICE); 5625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood setContentView(R.layout.serial_chat); 5725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mLog = (TextView)findViewById(R.id.log); 5825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mEditText = (EditText)findViewById(R.id.message); 5925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mEditText.setOnEditorActionListener(this); 6025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 6125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (false) { 6225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mInputBuffer = ByteBuffer.allocateDirect(1024); 6325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mOutputBuffer = ByteBuffer.allocateDirect(1024); 6425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } else { 6525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mInputBuffer = ByteBuffer.allocate(1024); 6625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mOutputBuffer = ByteBuffer.allocate(1024); 6725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 6825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 6925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 7025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood @Override 7125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void onResume() { 7225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood super.onResume(); 7325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 7425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood String[] ports = mSerialManager.getSerialPorts(); 7525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (ports != null && ports.length > 0) { 7625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood try { 7725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mSerialPort = mSerialManager.openSerialPort(ports[0], 115200); 7825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (mSerialPort != null) { 7925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood new Thread(this).start(); 8025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 8125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } catch (IOException e) { 8225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 8325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 8425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 8525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 8625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 8725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood @Override 8825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void onPause() { 8925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood super.onPause(); 9025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 9125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 9225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 9325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood @Override 9425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void onDestroy() { 9525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (mSerialPort != null) { 9625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood try { 9725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mSerialPort.close(); 9825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } catch (IOException e) { 9925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 10025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mSerialPort = null; 10125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 10225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood super.onDestroy(); 10325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 10425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 10525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 10625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (/* actionId == EditorInfo.IME_ACTION_DONE && */ mSerialPort != null) { 10725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood try { 10825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood String text = v.getText().toString(); 10925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "write: " + text); 11025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood byte[] bytes = text.getBytes(); 11125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mOutputBuffer.clear(); 11225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mOutputBuffer.put(bytes); 11325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mSerialPort.write(mOutputBuffer, bytes.length); 11425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } catch (IOException e) { 11525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.e(TAG, "write failed", e); 11625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 11725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood v.setText(""); 11825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood return true; 11925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 12025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "onEditorAction " + actionId + " event: " + event); 12125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood return false; 12225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 12325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 12425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void run() { 12525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "run"); 12625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood int ret = 0; 12725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood byte[] buffer = new byte[1024]; 12825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood while (ret >= 0) { 12925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood try { 13025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "calling read"); 13125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mInputBuffer.clear(); 13225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood ret = mSerialPort.read(mInputBuffer); 13325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "read returned " + ret); 13425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mInputBuffer.get(buffer, 0, ret); 13525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } catch (IOException e) { 13625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.e(TAG, "read failed", e); 13725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood break; 13825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 13925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 14025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood if (ret > 0) { 14125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Message m = Message.obtain(mHandler, MESSAGE_LOG); 14225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood String text = new String(buffer, 0, ret); 14325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "chat: " + text); 14425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood m.obj = text; 14525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mHandler.sendMessage(m); 14625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 14725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 14825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Log.d(TAG, "thread out"); 14925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 15025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 15125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood Handler mHandler = new Handler() { 15225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood @Override 15325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood public void handleMessage(Message msg) { 15425d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood switch (msg.what) { 15525d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood case MESSAGE_LOG: 15625d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood mLog.setText(mLog.getText() + (String)msg.obj); 15725d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood break; 15825d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 15925d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood } 16025d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood }; 16125d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood} 16225d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 16325d1fdc35767e84ba5f9ee352ae25f52f139a791Mike Lockwood 164