package dev.ukanth.ufirewall.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ScaleDrawable;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import dev.ukanth.ufirewall.Api;
import dev.ukanth.ufirewall.Api.PackageInfoData;
import dev.ukanth.ufirewall.MainActivity;
import dev.ukanth.ufirewall.R;
import dev.ukanth.ufirewall.activity.AppDetailActivity;
import dev.ukanth.ufirewall.log.Log;
public class AppListArrayAdapter extends ArrayAdapter<PackageInfoData> implements OnCheckedChangeListener {
public static final String TAG = "AFWall";
private final Context context;
private final List<PackageInfoData> listApps;
private Activity activity;
final int color = G.sysColor();
final int defaultColor = Color.WHITE;
public AppListArrayAdapter(MainActivity activity, Context context, List<PackageInfoData> apps) {
super(context, R.layout.main_list, apps);
this.activity = activity;
this.context = context;
this.listApps = apps;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
// Inflate a new view
convertView = inflater.inflate(R.layout.main_list, parent, false);
holder = new ViewHolder();
holder.box_wifi = (CheckBox) convertView.findViewById(R.id.itemcheck_wifi);
holder.box_wifi.setOnCheckedChangeListener(this);
if (Api.isMobileNetworkSupported(context)) {
holder.box_3g = addSupport(convertView, true, R.id.itemcheck_3g);
} else {
removeSupport(convertView, R.id.itemcheck_3g);
}
if (G.enableRoam()) {
holder.box_roam = addSupport(convertView, true, R.id.itemcheck_roam);
}
if (G.enableVPN()) {
holder.box_vpn = addSupport(convertView, true, R.id.itemcheck_vpn);
}
if (G.enableLAN()) {
holder.box_lan = addSupport(convertView, true, R.id.itemcheck_lan);
}
holder.text = (TextView) convertView.findViewById(R.id.itemtext);
holder.icon = (ImageView) convertView.findViewById(R.id.itemicon);
if (G.disableIcons()) {
holder.icon.setVisibility(View.GONE);
activity.findViewById(R.id.imageHolder).setVisibility(View.GONE);
}
convertView.setTag(holder);
} else {
// Convert an existing view
holder = (ViewHolder) convertView.getTag();
holder.box_wifi = (CheckBox) convertView.findViewById(R.id.itemcheck_wifi);
if (Api.isMobileNetworkSupported(context)) {
holder.box_3g = addSupport(convertView, true, R.id.itemcheck_3g);
} else {
removeSupport(convertView, R.id.itemcheck_3g);
}
if (G.enableRoam()) {
addSupport(convertView, false, R.id.itemcheck_roam);
}
if (G.enableVPN()) {
addSupport(convertView, false, R.id.itemcheck_vpn);
}
if (G.enableLAN()) {
addSupport(convertView, false, R.id.itemcheck_lan);
}
holder.text = (TextView) convertView.findViewById(R.id.itemtext);
holder.icon = (ImageView) convertView.findViewById(R.id.itemicon);
if (G.disableIcons()) {
holder.icon.setVisibility(View.GONE);
activity.findViewById(R.id.imageHolder).setVisibility(View.GONE);
}
}
holder.app = listApps.get(position);
if (G.showUid()) {
holder.text.setText(holder.app.toStringWithUID());
} else {
holder.text.setText(holder.app.toString());
}
final int id = holder.app.uid;
if (id > 0) {
holder.text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, AppDetailActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("appid", id);
context.startActivity(intent);
}
});
}
ApplicationInfo info = holder.app.appinfo;
if (info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
holder.text.setTextColor(defaultColor);
} else {
holder.text.setTextColor(color);
}
if (!G.disableIcons()) {
holder.icon.setImageDrawable(holder.app.cached_icon);
if (!holder.app.icon_loaded && info != null) {
// this icon has not been loaded yet - load it on a
// separated thread
try {
new LoadIconTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, holder.app,
context.getPackageManager(), convertView);
} catch (Exception r) {
}
}
} else {
holder.icon.setVisibility(View.GONE);
activity.findViewById(R.id.imageHolder).setVisibility(View.GONE);
}
holder.box_wifi.setTag(holder.app);
holder.box_wifi.setChecked(holder.app.selected_wifi);
if (Api.isMobileNetworkSupported(context)) {
holder.box_3g.setTag(holder.app);
holder.box_3g.setChecked(holder.app.selected_3g);
}
if (G.enableRoam()) {
holder.box_roam = addSupport(holder.box_roam, holder.app, 0);
}
if (G.enableVPN()) {
holder.box_vpn = addSupport(holder.box_vpn, holder.app, 1);
}
if (G.enableLAN()) {
holder.box_lan = addSupport(holder.box_lan, holder.app, 2);
}
return convertView;
}
private CheckBox addSupport(CheckBox check, PackageInfoData app, int flag) {
if (check != null) {
check.setTag(app);
switch (flag) {
case 0:
check.setChecked(app.selected_roam);
break;
case 1:
check.setChecked(app.selected_vpn);
break;
case 2:
check.setChecked(app.selected_lan);
break;
}
}
return check;
}
private CheckBox addSupport(View convertView, boolean action, int id) {
CheckBox check = (CheckBox) convertView.findViewById(id);
check.setVisibility(View.VISIBLE);
if (action) {
check.setOnCheckedChangeListener(this);
}
return check;
}
private CheckBox removeSupport(View convertView, int id) {
CheckBox check = (CheckBox) convertView.findViewById(id);
check.setVisibility(View.GONE);
return check;
}
static class ViewHolder {
private CheckBox box_lan;
private CheckBox box_wifi;
private CheckBox box_3g;
private CheckBox box_roam;
private CheckBox box_vpn;
private TextView text;
private ImageView icon;
private PackageInfoData app;
}
/**
* Asynchronous task used to load icons in a background thread.
*/
private static class LoadIconTask extends AsyncTask<Object, Void, View> {
@Override
protected View doInBackground(Object... params) {
try {
final PackageInfoData app = (PackageInfoData) params[0];
final PackageManager pkgMgr = (PackageManager) params[1];
final View viewToUpdate = (View) params[2];
if (!app.icon_loaded) {
Drawable d = new ScaleDrawable(pkgMgr.getApplicationIcon(app.appinfo), 0, 32, 32).getDrawable();
d.setBounds(0, 0, 32, 32);
app.cached_icon = d;
app.icon_loaded = true;
}
// Return the view to update at "onPostExecute"
// Note that we cannot be sure that this view still references
// "app"
return viewToUpdate;
} catch (Exception e) {
Log.e(TAG, "Error loading icon", e);
return null;
}
}
protected void onPostExecute(View viewToUpdate) {
try {
// This is executed in the UI thread, so it is safe to use
// viewToUpdate.getTag()
// and modify the UI
final ViewHolder entryToUpdate = (ViewHolder) viewToUpdate.getTag();
entryToUpdate.icon.setImageDrawable(entryToUpdate.app.cached_icon);
} catch (Exception e) {
Log.e(TAG, "Error showing icon", e);
}
}
;
}
/**
* Called an application is check/unchecked
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final PackageInfoData app = (PackageInfoData) buttonView.getTag();
if (app != null) {
switch (buttonView.getId()) {
case R.id.itemcheck_wifi:
if (app.selected_wifi != isChecked) {
app.selected_wifi = isChecked;
MainActivity.dirty = true;
notifyDataSetChanged();
}
break;
case R.id.itemcheck_3g:
if (app.selected_3g != isChecked) {
app.selected_3g = isChecked;
MainActivity.dirty = true;
notifyDataSetChanged();
}
break;
case R.id.itemcheck_roam:
if (app.selected_roam != isChecked) {
app.selected_roam = isChecked;
MainActivity.dirty = true;
notifyDataSetChanged();
}
break;
case R.id.itemcheck_vpn:
if (app.selected_vpn != isChecked) {
app.selected_vpn = isChecked;
MainActivity.dirty = true;
notifyDataSetChanged();
}
break;
case R.id.itemcheck_lan:
if (app.selected_lan != isChecked) {
app.selected_lan = isChecked;
MainActivity.dirty = true;
notifyDataSetChanged();
}
break;
}
}
}
}