Skip to content

Commit

Permalink
Calling configuration_switch before request USB permission:
Browse files Browse the repository at this point in the history
  • Loading branch information
trongvu committed Mar 5, 2017
1 parent e78fc2c commit ee7af53
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package com.android.trongvu.atcommander;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import android.util.Log;

public class ExecuteAsRootBase
{
public static String TAG = ExecuteAsRootBase.class.getSimpleName();
public static boolean canRunRootCommands()
{
boolean retval = false;
Process suProcess;

try
{
suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
DataInputStream osRes = new DataInputStream(suProcess.getInputStream());

if (null != os && null != osRes)
{
// Getting the id of the current user to check if this is root
os.writeBytes("id\n");
os.flush();

String currUid = osRes.readLine();
Log.d(TAG, "currUid = " + currUid);
boolean exitSu = false;
if (null == currUid)
{
retval = false;
exitSu = false;
Log.d(TAG, "Can't get root access or denied by user");
}
else if (true == currUid.contains("uid=0"))
{
retval = true;
exitSu = true;
Log.d(TAG, "Root access granted");
}
else
{
retval = false;
exitSu = true;
Log.d(TAG, "Root access rejected: " + currUid);
}

if (exitSu)
{
os.writeBytes("exit\n");
os.flush();
}
}
suProcess.waitFor();
}
catch (Exception e)
{
// Can't get root !
// Probably broken pipe exception on trying to write to output stream (os) after su failed, meaning that the device is not rooted

retval = false;
Log.d(TAG, "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage());
}

return retval;
}

public static final boolean execute()
{
boolean retval = false;

try
{
ArrayList<String> commands = getCommandsToExecute();
if (null != commands && commands.size() > 0)
{
Process suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());

// Execute commands that require root access
for (String currCommand : commands)
{
os.writeBytes(currCommand + "\n");
os.flush();
}

os.writeBytes("exit\n");
os.flush();

try
{
int suProcessRetval = suProcess.waitFor();
if (255 != suProcessRetval)
{
// Root access granted
retval = true;
}
else
{
// Root access denied
retval = false;
}
}
catch (Exception ex)
{
Log.e(TAG, "Error executing root action", ex);
}
}
}
catch (IOException ex)
{
Log.w(TAG, "Can't get root access", ex);
}
catch (SecurityException ex)
{
Log.w(TAG, "Can't get root access", ex);
}
catch (Exception ex)
{
Log.w(TAG, "Error executing internal operation", ex);
}

return retval;
}
protected static ArrayList<String> getCommandsToExecute() {
// TODO Auto-generated method stub
// by default, if there is no input value for configuration_switch,
// Apple device will use configuration #4 and Samsung device will use configuration #2
String [] commands = new String[] {"configuration_switch"};
return new ArrayList<String>(Arrays.asList(commands));
}
}
189 changes: 102 additions & 87 deletions app/src/main/java/com/android/trongvu/atcommander/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package com.android.trongvu.atcommander;

import java.util.HashMap;
import java.util.Iterator;

import com.example.androidshell.R;
import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
Expand All @@ -28,16 +21,65 @@
import android.widget.TextView;
import android.widget.Toast;

import com.example.androidshell.R;
import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;

import java.util.HashMap;
import java.util.Iterator;

public class MainActivity extends Activity {

public static final String ACTION_USB_PERMISSION = "com.android.trongvu.atcommander.USB_PERMISSION";
public static final String LOG_TAG = "ATCommander";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
UsbDevice dev = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
connectUSBDevice(dev);
} else {
Log.d(LOG_TAG, "permission denied for accessory " + dev);
}
}
}
};
EditText input;
Button btn;
TextView out;
ScrollView mScrollView;
String command;
UsbDevice dev = null;
UsbDeviceConnection mUsbDeviceConnection = null;
UsbManager mUsbManager = null;
Handler mHandler = new Handler();
UsbSerialDevice serialPort = null;
private PendingIntent mPermissionIntent;
public static final String ACTION_USB_PERMISSION = "com.android.trongvu.atcommander.USB_PERMISSION";
public static final String LOG_TAG = "ATCommander";
private boolean isConnected = false;
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
@Override
public void onReceivedData(final byte[] arg0) {
mHandler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
out.append(new String(arg0) + "\n");
}
});
// we could not scroll till the end right after set text
// so we wait for 100ms before scrolling
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
}, 100);
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -56,7 +98,7 @@ public void onClick(View arg0) {
input.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE){
if (actionId == EditorInfo.IME_ACTION_DONE) {
onExecute(btn);
return true;
}
Expand All @@ -65,57 +107,38 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
});
}

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice dev = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (dev != null) {
Log.i(LOG_TAG, "open device");
mUsbDeviceConnection = mUsbManager.openDevice(dev);
serialPort = UsbSerialDevice.createUsbSerialDevice(dev, mUsbDeviceConnection);
if (serialPort == null) {
Log.i(LOG_TAG, "open Serial port == null");
mUsbDeviceConnection.close();
return;
}
Log.i(LOG_TAG, "open Serial port != null");
if (!serialPort.open()) {
Log.i(LOG_TAG, "open Serial port open failed");
mUsbDeviceConnection.close();
return;
}
// Devices are opened with default values, Usually
// 9600,8,1,None,OFF
// CDC driver default values 115200,8,1,None,OFF
Log.i(LOG_TAG, "open Serial port opened");
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
Toast.makeText(getApplicationContext(), "AT ready", Toast.LENGTH_SHORT).show();
isConnected = true;
}
} else {
Log.d(LOG_TAG, "permission denied for accessory " + dev);
}
private void connectUSBDevice(UsbDevice dev) {
synchronized (this) {
if (dev != null) {
Log.i(LOG_TAG, "open device");
mUsbDeviceConnection = mUsbManager.openDevice(dev);
serialPort = UsbSerialDevice.createUsbSerialDevice(dev, mUsbDeviceConnection);
if (serialPort == null) {
Log.i(LOG_TAG, "open Serial port == null");
mUsbDeviceConnection.close();
return;
}
Log.i(LOG_TAG, "open Serial port != null");
if (!serialPort.open()) {
Log.i(LOG_TAG, "open Serial port open failed");
mUsbDeviceConnection.close();
return;
}
// Devices are opened with default values, Usually
// 9600,8,1,None,OFF
// CDC driver default values 115200,8,1,None,OFF
Log.i(LOG_TAG, "open Serial port opened");
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
Toast.makeText(getApplicationContext(), "AT ready", Toast.LENGTH_SHORT).show();
isConnected = true;
}
}
};

UsbDevice dev = null;
UsbDeviceConnection mUsbDeviceConnection = null;
UsbManager mUsbManager = null;
Handler mHandler = new Handler();
UsbSerialDevice serialPort = null;
private boolean isConnected = false;
}

private void onExecute(View arg0) {
// send AT command
Expand All @@ -137,7 +160,7 @@ private void onExecute(View arg0) {
input.setText("");
}
}

@Override
protected void onResume() {
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
Expand All @@ -148,15 +171,15 @@ protected void onResume() {
mUsbManager.getDeviceList();
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

//dev block, check if is there any CDC devices
while (deviceIterator.hasNext()) {
UsbDevice tmp = deviceIterator.next();
out.append("vid = " + Integer.toHexString(tmp.getVendorId()) + ":" +
" pid = " + Integer.toHexString(tmp.getProductId()) +
" isCdcDevice = " + UsbSerialDevice.isCdcDevice(tmp) + "\n");
out.append("vid = " + Integer.toHexString(tmp.getVendorId()) + ":" +
" pid = " + Integer.toHexString(tmp.getProductId()) +
" isCdcDevice = " + UsbSerialDevice.isCdcDevice(tmp) + "\n");
}

//reset to 1st position
deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
Expand All @@ -169,35 +192,27 @@ protected void onResume() {
Log.i(LOG_TAG, "dev != null, switch mode");
//new ExecuteAsRootBase().execute();
// we should request permision here
mUsbManager.requestPermission(dev, mPermissionIntent);
if(!mUsbManager.hasPermission(dev)) {
if(ExecuteAsRootBase.canRunRootCommands()){
//we can run root command, so change configuration before request permission
ExecuteAsRootBase.execute();
}
mUsbManager.requestPermission(dev, mPermissionIntent);
}else{
connectUSBDevice(dev);
}
}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(mUsbReceiver);
}

private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
@Override
public void onReceivedData(final byte[] arg0) {
mHandler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
out.append(new String(arg0) + "\n");
}
});
// we could not scroll till the end right after set text
// so we wait for 100ms before scrolling
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
}, 100);
if(serialPort != null){
serialPort.close();
}
};
if(mUsbDeviceConnection != null){
mUsbDeviceConnection.close();
}
}
}

0 comments on commit ee7af53

Please sign in to comment.