package mobi.acpm.inspeckage.ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ExpandableListView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import mobi.acpm.inspeckage.Module;
import mobi.acpm.inspeckage.R;
import mobi.acpm.inspeckage.util.Config;
import mobi.acpm.inspeckage.util.PackageDetail;
import mobi.acpm.inspeckage.util.Util;
import mobi.acpm.inspeckage.webserver.InspeckageService;
import mobi.acpm.inspeckage.webserver.WebServer;
public class MainFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private Context context;
private Activity mainActivity;
private SharedPreferences mPrefs;
private PackageDetail pd;
@SuppressLint("ValidFragment")
public MainFragment(Activity act) {
mainActivity = act;
context = mainActivity.getApplicationContext();
}
public MainFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
mPrefs = context.getSharedPreferences(Module.PREFS, context.MODE_WORLD_READABLE);
String host = null;
if(!mPrefs.getString(Config.SP_SERVER_HOST, "All interfaces").equals("All interfaces")){
host = mPrefs.getString(Config.SP_SERVER_HOST, "All interfaces");
}
startService(host,mPrefs.getInt(Config.SP_SERVER_PORT, 8008));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// / Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_main, container, false);
ExpandableListView mExpandableList = (ExpandableListView) view.findViewById(R.id.appsListView);
loadListView(view);
TextView txtModule = (TextView) view.findViewById(R.id.txtModule);
if (WebServer.isModuleEnabled()) {
txtModule.setText(R.string.module_enabled);
txtModule.setBackgroundColor(Color.TRANSPARENT);
}
TextView txtServer = (TextView) view.findViewById(R.id.txtServer);
if (Util.isMyServiceRunning(context, InspeckageService.class)) {
txtServer.setText(R.string.server_started);
txtServer.setBackgroundColor(Color.TRANSPARENT);
}
mExpandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
TextView txtPackage = (TextView) v.findViewById(R.id.txtListPkg);
TextView txtAppName = (TextView) v.findViewById(R.id.txtListItem);
loadSelectedApp(txtPackage.getText().toString());
TextView txtAppSelected = (TextView) view.findViewById(R.id.txtAppSelected);
txtAppSelected.setText(">>> " + txtPackage.getText().toString());
Toast.makeText(context, "" + txtAppName.getText().toString(), Toast.LENGTH_SHORT).show();
loadListView(view);
return true;
}
});
Switch mSwitch = (Switch) view.findViewById(R.id.only_user_app_switch);
Boolean sw = mPrefs.getBoolean(Config.SP_SWITCH_OUA, true);
mSwitch.setChecked(sw);
mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences.Editor edit = mPrefs.edit();
//Only User App
if (isChecked) {
edit.putBoolean(Config.SP_SWITCH_OUA, true);
} else {
edit.putBoolean(Config.SP_SWITCH_OUA, false);
}
edit.apply();
loadListView(view);
}
});
final Button button = (Button) view.findViewById(R.id.btnLaunchApp);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(pd==null){
pd = new PackageDetail(context, mPrefs.getString(Config.SP_PACKAGE,""));
}
Intent i = pd.getLaunchIntent();
if(i!=null) {
startActivity(i);
}else{
Toast.makeText(context, "Launch Intent not found.", Toast.LENGTH_SHORT).show();
}
}
});
loadInterfaces();
String scheme = "http://";
if(mPrefs.getBoolean(Config.SP_SWITCH_AUTH, false)) {
scheme = "https://";
}
String port = String.valueOf(mPrefs.getInt(Config.SP_SERVER_PORT, 8008));
String host = "";
if(mPrefs.getString(Config.SP_SERVER_HOST, "All interfaces").equals("All interfaces")){
String[] adds = mPrefs.getString(Config.SP_SERVER_INTERFACES, "--").split(",");
for(int i=0; i<adds.length; i++){
if(!adds[i].equals("All interfaces"))
host = host + scheme + adds[i] + ":" + port+"\n";
}
}else{
String ip = mPrefs.getString(Config.SP_SERVER_HOST, "127.0.0.1");
host = scheme + ip + ":" + port;
SharedPreferences.Editor edit = mPrefs.edit();
edit.putString(Config.SP_SERVER_IP, ip);
edit.apply();
}
TextView txtHost = (TextView) view.findViewById(R.id.txtHost);
txtHost.setText(host);
TextView txtAdb = (TextView) view.findViewById(R.id.txtAdb);
txtAdb.setText("adb forward tcp:"+port+" tcp:"+port);
TextView txtAppSelected = (TextView) view.findViewById(R.id.txtAppSelected);
txtAppSelected.setText(">>> " + mPrefs.getString(Config.SP_PACKAGE, "..."));
return view;
}
public void loadInterfaces(){
StringBuilder sb = new StringBuilder();
sb.append("All interfaces,");
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface netInterface = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = netInterface.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
String address = inetAddress.getHostAddress();
boolean isIPv4 = address.indexOf(':') < 0;
if (isIPv4) {
sb.append(address+",");
}
}
}
} catch (SocketException ex) {
Log.e("Inspeckage_Error", ex.toString());
}
SharedPreferences.Editor edit = mPrefs.edit();
edit.putString(Config.SP_SERVER_INTERFACES, sb.toString().substring(0,sb.length()-1));
edit.apply();
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
//----------------------------------------------METHODS--------------------------------------
public void startService(String host, int port) {
Intent i = new Intent(context, InspeckageService.class);
i.putExtra("port", port);
i.putExtra("host", host);
context.startService(i);
}
public void stopService() {
context.stopService(new Intent(context, InspeckageService.class));
}
private ArrayList<ExpandableListItem> getInstalledApps() {
ArrayList<ExpandableListItem> appsList = new ArrayList<>();
List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(0);
for (int i = 0; i < packs.size(); i++) {
android.content.pm.PackageInfo p = packs.get(i);
// Installed by user
if (mPrefs.getBoolean(Config.SP_SWITCH_OUA, true) ? (p.applicationInfo.flags & 129) == 0 : true) {
ExpandableListItem pInfo = new ExpandableListItem();
pInfo.setAppName(p.applicationInfo.loadLabel(context.getPackageManager()).toString());
pInfo.setPckName(p.packageName);
pInfo.setIcon(p.applicationInfo.loadIcon(context.getPackageManager()));
String pack = mPrefs.getString(Config.SP_PACKAGE, "");
if (p.packageName.trim().equals(pack.trim())) {
pInfo.setSelected(true);
}
appsList.add(pInfo);
}
}
return appsList;
}
private void loadListView(View view) {
List<String> mListDataHeader = new ArrayList<String>();
mListDataHeader.add(context.getString(R.string.fragment_config_choose));
HashMap<String, List<ExpandableListItem>> mListDataChild = new HashMap<String, List<ExpandableListItem>>();
ArrayList<ExpandableListItem> mApps = getInstalledApps();
Collections.sort(mApps, new Comparator<ExpandableListItem>() {
public int compare(ExpandableListItem o1, ExpandableListItem o2) {
return o1.getAppName().compareTo(o2.getAppName());
}
});
ExpandableListView appList = (ExpandableListView) view.findViewById(R.id.appsListView);
mListDataChild.put(mListDataHeader.get(0), mApps);
appList.setAdapter(new ExpandableListAdapter(getActivity(), mListDataHeader, mListDataChild));
}
private void loadSelectedApp(String pkg) {
SharedPreferences.Editor edit = mPrefs.edit();
//this put has to come before the PackageDetail
edit.putString(Config.SP_PACKAGE, pkg);
pd = new PackageDetail(context, pkg);
edit.putBoolean(Config.SP_HAS_W_PERMISSION, false);
if (pd.getRequestedPermissions().contains("android.permission.WRITE_EXTERNAL_STORAGE") &&
Build.VERSION.SDK_INT < 23) {
edit.putBoolean(Config.SP_HAS_W_PERMISSION, true);
}
edit.putString(Config.SP_APP_NAME, pd.getAppName());
edit.putString(Config.SP_APP_ICON_BASE64, pd.getIconBase64());
edit.putString(Config.SP_PROCESS_NAME, pd.getProcessName());
edit.putString(Config.SP_APP_VERSION, pd.getVersion());
edit.putString(Config.SP_DEBUGGABLE, pd.isDebuggable());
edit.putString(Config.SP_ALLOW_BACKUP, pd.allowBackup());
edit.putString(Config.SP_APK_DIR, pd.getApkDir());
edit.putString(Config.SP_UID, pd.getUID());
edit.putString(Config.SP_GIDS, pd.getGIDs());
edit.putString(Config.SP_DATA_DIR, pd.getDataDir());
edit.putString(Config.SP_REQ_PERMISSIONS, pd.getRequestedPermissions());
edit.putString(Config.SP_APP_PERMISSIONS, pd.getAppPermissions());
edit.putString(Config.SP_EXP_ACTIVITIES, pd.getExportedActivities());
edit.putString(Config.SP_N_EXP_ACTIVITIES, pd.getNonExportedActivities());
edit.putString(Config.SP_EXP_SERVICES, pd.getExportedServices());
edit.putString(Config.SP_N_EXP_SERVICES, pd.getNonExportedServices());
edit.putString(Config.SP_EXP_BROADCAST, pd.getExportedBroadcastReceivers());
edit.putString(Config.SP_N_EXP_BROADCAST, pd.getNonExportedBroadcastReceivers());
edit.putString(Config.SP_EXP_PROVIDER, pd.getExportedContentProvider());
edit.putString(Config.SP_N_EXP_PROVIDER, pd.getNonExportedContentProvider());
edit.putString(Config.SP_SHARED_LIB, pd.getSharedLibraries());
edit.putBoolean(Config.SP_APP_IS_RUNNING, false);
edit.putString(Config.SP_DATA_DIR_TREE, "");
//test
//edit.putString(Config.SP_REPLACE_SP, "limitEventUsage,true");
edit.apply();
//resolve this problem
if (pd.getRequestedPermissions().contains("android.permission.WRITE_EXTERNAL_STORAGE")) {
pd.extractInfoToFile();
}
}
}