/*******************************************************************************
* Copyright 2010 Alexandros Schillings
*
* 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 aws.apps.underthehood.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import aws.apps.underthehood.R;
public class ExecuteThread extends Thread {
public final static String MSG_IPCONFIG = "msg_ipconfig";
public final static String MSG_IP_ROUTE = "msg_ip_route";
public final static String MSG_PROC = "msg_proc";
public final static String MSG_OTHER = "msg_other";
public final static String MSG_PS = "msg_ps";
public final static String MSG_NETSTAT = "msg_netstat";
public final static String MSG_SYSPROP = "msg_sysprop";
public final static int STATE_DONE = 0;
public final static int STATE_RUNNING = 1;
public final static int WORK_COMPLETED = 50;
public final static int WORK_INTERUPTED = 51;
private final String TAG = this.getClass().getName();
private Handler mHandler;
private Context c;
private int mState;
private boolean isRooted;
private Hashtable<CharSequence, Boolean> actions;
@SuppressWarnings("unchecked")
public ExecuteThread(Handler h, Context ctx, Bundle b) {//Hashtable<CharSequence, Boolean> action_list) {
//super();
this.mHandler = h;
this.c = ctx;
this.actions = (Hashtable<CharSequence, Boolean>) b.get("actions");
this.isRooted = checkIfSu();
}
public void run() {
mState = STATE_RUNNING;
Bundle b = new Bundle();
Message msg = new Message();
Log.d(TAG, "^ ExecuteThread: Thread Started");
while (mState == STATE_RUNNING) {
try {
Thread.sleep(100);
b.clear();
b.putStringArrayList(MSG_IPCONFIG, executeIpconfig(actions));
b.putStringArrayList(MSG_IP_ROUTE, executeIpRoute(actions));
b.putStringArrayList(MSG_PROC, executeProc(actions));
b.putStringArrayList(MSG_OTHER, executeOther(actions));
b.putStringArrayList(MSG_PS, executePs(actions));
b.putStringArrayList(MSG_NETSTAT, executeNetstat(actions));
b.putStringArrayList(MSG_SYSPROP, executeGetProp(actions));
msg = new Message();
msg.what = WORK_COMPLETED;
msg.setData(b);
mHandler.sendMessage(msg);
this.setState(STATE_DONE);
} catch (InterruptedException e) {
Log.e(TAG, "^ ExecuteThread: Thread Interrupted");
b.clear();
int what = WORK_INTERUPTED;
msg.what = what;
msg.setData(b);
mHandler.sendMessage(msg);
this.setState(STATE_DONE);
} catch (Exception e){
Log.e(TAG, "^ ExecuteThread: exception " + e.getMessage());
msg = new Message();
b.clear();
int what = WORK_INTERUPTED;
msg.what = what;
msg.setData(b);
mHandler.sendMessage(msg);
this.setState(STATE_DONE);
}
}
Log.d(TAG, "^ ProgressThread: Thread Exited");
}
/*
* sets the current state for the thread, used to stop the thread
*/
public void setState(int state) {
mState = state;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
/** It will execute a command without SU privileges */
private String executeCommandAsUser(String cmd){
String res = "";
ExecTerminal et = new ExecTerminal();
res = et.exec(cmd);
if (res.trim().equals("")){
res = "result was blank";
}
return res;
}
/** It will execute a command as a normal user */
private String executeCommandAsSu(String cmd){
String res = "";
ExecTerminal et = new ExecTerminal();
res = et.execSu(cmd);
if (res.trim().equals("")){
res = "result was blank";
}
return res;
}
private ArrayList<String> executeIpconfig(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_netcfg));
l.add(execute(R.string.shell_netcfg, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ifconfig_dash_a));
l.add(execute(R.string.shell_ifconfig_dash_a, action_list, isRooted));
return l;
}
private ArrayList<String> executeIpRoute(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(c.getString(R.string.seperator_identifier) + "IPv4");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ip_addr));
l.add(execute(R.string.shell_ip_addr, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ip_route_show));
l.add(execute(R.string.shell_ip_route_show, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_route_n));
l.add(execute(R.string.shell_route_n, action_list, isRooted));
l.add(c.getString(R.string.seperator_identifier) + "IPv6");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ip_inet6_addr));
l.add(execute(R.string.shell_ip_inet6_addr, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ip_inet6_route_show));
l.add(execute(R.string.shell_ip_inet6_route_show, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_route_inet6));
l.add(execute(R.string.shell_route_inet6, action_list, isRooted));
return l;
}
private ArrayList<String> executeProc(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(c.getString(R.string.seperator_identifier) + "General Info");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_version));
l.add(execute(R.string.shell_cat_proc_version, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_meminfo));
l.add(execute(R.string.shell_cat_proc_meminfo, action_list, isRooted));
l.add(c.getString(R.string.seperator_identifier) + "Hardware Info");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_devices));
l.add(execute(R.string.shell_cat_proc_devices, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_mounts));
l.add(execute(R.string.shell_cat_proc_mounts, action_list, isRooted));
l.add(c.getString(R.string.seperator_identifier) + "Network Info");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_net_arp));
l.add(execute(R.string.shell_cat_proc_net_arp, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_net_route));
l.add(execute(R.string.shell_cat_proc_net_route, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_net_wireless));
l.add(execute(R.string.shell_cat_proc_net_wireless, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_net_if_inet6));
l.add(execute(R.string.shell_cat_proc_net_if_inet6, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_cat_proc_net_ipv6_route));
l.add(execute(R.string.shell_cat_proc_net_ipv6_route, action_list, isRooted));
return l;
}
private ArrayList<String> executeGetProp(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
File file = new File("/system/build.prop");
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner;
try {
scanner = new Scanner(file);
} catch (FileNotFoundException e) {
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_product_version));
l.add(execute(R.string.shell_getprop_product_version, action_list, false));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_build_fingerprint));
l.add(execute(R.string.shell_getprop_build_fingerprint, action_list, false));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_gsm_baseband));
l.add(execute(R.string.shell_getprop_gsm_baseband, action_list, false));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_vm_execution_mode));
l.add(execute(R.string.shell_getprop_vm_execution_mode, action_list, false));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_vm_heapsize));
l.add(execute(R.string.shell_getprop_vm_heapsize, action_list, false));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_getprop_lcd_density));
l.add(execute(R.string.shell_getprop_lcd_density, action_list, false));
return l;
}
try {
String line;
String lineArray[];
String tmp;
while(scanner.hasNextLine()) {
line = scanner.nextLine();
if(!line.startsWith("#")){
lineArray = line.split("=");
if(lineArray.length >= 2){
tmp = "";
l.add("> " + lineArray[0]);
for(int i = 1; i < lineArray.length; i ++){
if(tmp.length()>0){
tmp += "=" + lineArray[i];
}else{
tmp = lineArray[i];
}
l.add(tmp.trim());
}
}
}
}
} finally {
scanner.close();
}
return l;
}
private ArrayList<String> executeOther(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(c.getString(R.string.seperator_identifier) + "System info" +
"");
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_df_ah));
l.add(execute(R.string.shell_df_ah, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_uname_a));
l.add(execute(R.string.shell_uname_a, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_lsmod));
l.add(execute(R.string.shell_lsmod, action_list, isRooted));
//l.add(c.getString(R.string.seperator_identifier) + "build.prop");
return l;
}
private ArrayList<String> executePs(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_ps));
l.add(execute(R.string.shell_ps, action_list, isRooted));
return l;
}
private ArrayList<String> executeNetstat(Hashtable<CharSequence, Boolean> action_list){
ArrayList<String> l = new ArrayList<String>();
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_netstat_r));
l.add(execute(R.string.shell_netstat_r, action_list, isRooted));
l.add(getPromptSymbol(isRooted) + c.getString(R.string.shell_netstat_a));
l.add(execute(R.string.shell_netstat_a, action_list, isRooted));
return l;
}
private String execute(int commandString, Hashtable<CharSequence, Boolean> action_list, boolean isRooted){
String result = "";
String cmd = c.getString(commandString);
if(action_list.get(cmd)){
if(isRooted){
result = executeCommandAsSu(cmd);
} else {
result = executeCommandAsUser(cmd);
}
} else {
result = c.getString(R.string.text_execution_skipped_by_user);
}
return result.trim();
}
private boolean checkIfSu(){
String res = "";
ExecTerminal et = new ExecTerminal();
res = et.execSu("su && echo 1");
if (res.trim().equals("1")){
Log.d(TAG, "^ Device can do SU");
return true;
}
Log.d(TAG, "^ Device can't do SU");
return false;
}
private String getPromptSymbol(boolean root){
if(root){
return "#";
}else{
return "$";
}
}
}