commit 59b333984d05d3f23e8cbf34ad713d6432afd603 Author: Jordan jordannh@sent.com Date: Wed Aug 13 17:23:33 2014 -0700
Add buttons to filter application selection. --- res/layout/layout_apps.xml | 89 +++- res/values/strings.xml | 4 + .../torproject/android/settings/AppManager.java | 543 +++++++++++--------- 3 files changed, 376 insertions(+), 260 deletions(-)
diff --git a/res/layout/layout_apps.xml b/res/layout/layout_apps.xml index ddd546d..d3633a0 100644 --- a/res/layout/layout_apps.xml +++ b/res/layout/layout_apps.xml @@ -1,19 +1,74 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:duplicateParentState="false"> - -<!-- -<TextView android:text="Select apps to use with Tor:" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:textSize="16sp" - android:padding="3px" - android:layout_above="@+id/applistview" - /> - --> - -<Button android:layout_width="fill_parent" - android:layout_height="wrap_content" android:id="@+id/btnsave" - android:text="@string/button_close" android:layout_alignParentBottom="true" /> - - <ListView android:layout_above="@id/btnsave" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/applistview"></ListView> +<RelativeLayout + android:layout_width="fill_parent" + android:layout_height="fill_parent" + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:duplicateParentState="true"> + + <!-- + <TextView android:text="Select apps to use with Tor:" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textSize="16sp" + android:padding="3px" + android:layout_above="@+id/applistview" + /> + --> + + <ListView + android:id="@+id/applistview" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_above="@+id/layout_button_filters" + android:layout_alignParentTop="true" > + + </ListView> + + <Button + android:id="@+id/btnsave" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentStart="true" + android:layout_alignParentLeft="true" + android:text="@string/button_close" /> + + <RelativeLayout + android:id="@+id/layout_button_filters" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_above="@+id/btnsave" + android:orientation="horizontal" > + + <Button + android:id="@+id/button_proxy_all" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_toLeftOf="@+id/button_proxy_none" + android:layout_toStartOf="@+id/button_proxy_none" + android:text="@string/button_proxy_all" /> + + <Button + android:id="@+id/button_invert_selection" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:text="@string/button_invert_selection" /> + + <Button + android:id="@+id/button_proxy_none" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_toLeftOf="@+id/button_invert_selection" + android:layout_toStartOf="@+id/button_invert_selection" + android:text="@string/button_proxy_none" /> + + </RelativeLayout> + </RelativeLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index fa4a731..36d043e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -134,6 +134,10 @@ <string name="pref_entrance_node_summary">Fingerprints, nicks, countries and addresses for the first hop</string> <string name="pref_entrance_node_dialog">Enter Entrance Nodes</string>
+ <string name="button_proxy_all">Proxy All</string> + <string name="button_proxy_none">Proxy None</string> + <string name="button_invert_selection">Invert Selection</string> + <string name="pref_proxy_title">Outbound Network Proxy (Optional)</string>
<string name="pref_proxy_type_title">Outbound Proxy Type</string> diff --git a/src/org/torproject/android/settings/AppManager.java b/src/org/torproject/android/settings/AppManager.java index f43dd6f..88e2023 100644 --- a/src/org/torproject/android/settings/AppManager.java +++ b/src/org/torproject/android/settings/AppManager.java @@ -11,11 +11,14 @@ import java.util.Iterator; import java.util.List; import java.util.StringTokenizer;
+ + import org.torproject.android.R; import org.torproject.android.TorConstants; import org.torproject.android.service.TorService; import org.torproject.android.service.TorServiceUtils;
+//import android.R; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; @@ -26,7 +29,11 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuInflater; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; @@ -41,275 +48,325 @@ import android.widget.TextView;
public class AppManager extends Activity implements OnCheckedChangeListener, OnClickListener, TorConstants {
- private ListView listApps; - - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - this.setContentView(R.layout.layout_apps); - + private ListView listApps; + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + this.setContentView(R.layout.layout_apps); + + Button buttonSelectAll, buttonSelectNone, buttonInvert;
- } - - - @Override - protected void onResume() { - super.onResume(); - listApps = (ListView)findViewById(R.id.applistview); + buttonSelectAll = (Button) findViewById(R.id.button_proxy_all); + buttonSelectNone = (Button) findViewById(R.id.button_proxy_none); + buttonInvert = (Button) findViewById(R.id.button_invert_selection);
- Button btnSave = (Button)findViewById(R.id.btnsave); - btnSave.setOnClickListener(new OnClickListener() - { + buttonSelectAll.setOnClickListener(new Button.OnClickListener() { + @Override + public void onClick(View v) { + autoCheckApplications(v); + } + }); + buttonSelectNone.setOnClickListener(new Button.OnClickListener() { + @Override + public void onClick(View v) { + autoCheckApplications(v); + } + }); + buttonInvert.setOnClickListener(new Button.OnClickListener() { + @Override + public void onClick(View v) { + autoCheckApplications(v); + } + }); + } + + + @Override + protected void onResume() { + super.onResume(); + listApps = (ListView)findViewById(R.id.applistview);
- public void onClick(View v) { - finish(); - } - }); - - mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - loadApps(mPrefs); - } + Button btnSave = (Button)findViewById(R.id.btnsave); + btnSave.setOnClickListener(new OnClickListener() + {
- SharedPreferences mPrefs = null; - ArrayList<TorifiedApp> mApps = null; - - private void loadApps (SharedPreferences prefs) - { - - mApps = getApps(getApplicationContext(), prefs); + public void onClick(View v) { + finish(); + } + }); + + mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); + loadApps(mPrefs); + } + + SharedPreferences mPrefs = null; + ArrayList<TorifiedApp> mApps = null; + + private void loadApps (SharedPreferences prefs) + { + + mApps = getApps(getApplicationContext(), prefs);
/* Arrays.sort(apps, new Comparator<TorifiedApp>() { - public int compare(TorifiedApp o1, TorifiedApp o2) { - if (o1.isTorified() == o2.isTorified()) return o1.getName().compareTo(o2.getName()); - if (o1.isTorified()) return -1; - return 1; - } + public int compare(TorifiedApp o1, TorifiedApp o2) { + if (o1.isTorified() == o2.isTorified()) return o1.getName().compareTo(o2.getName()); + if (o1.isTorified()) return -1; + return 1; + } });*/
final LayoutInflater inflater = getLayoutInflater(); - + ListAdapter adapter = new ArrayAdapter<TorifiedApp>(this,R.layout.layout_apps_item,R.id.itemtext,mApps) { - public View getView(int position, View convertView, ViewGroup parent) { - ListEntry entry; - if (convertView == null) { - // Inflate a new view - convertView = inflater.inflate(R.layout.layout_apps_item, parent, false); - entry = new ListEntry(); - entry.icon = (ImageView) convertView.findViewById(R.id.itemicon); - entry.box = (CheckBox) convertView.findViewById(R.id.itemcheck); - entry.text = (TextView) convertView.findViewById(R.id.itemtext); - - entry.text.setOnClickListener(AppManager.this); - entry.text.setOnClickListener(AppManager.this); - - convertView.setTag(entry); - - entry.box.setOnCheckedChangeListener(AppManager.this); - } else { - // Convert an existing view - entry = (ListEntry) convertView.getTag(); - } - - - final TorifiedApp app = mApps.get(position); - - if (app.getIcon() != null) - entry.icon.setImageDrawable(app.getIcon()); - else - entry.icon.setVisibility(View.GONE); - - entry.text.setText(app.getName()); - - final CheckBox box = entry.box; - box.setTag(app); - box.setChecked(app.isTorified()); - - entry.text.setTag(box); - entry.icon.setTag(box); - - return convertView; - } + public View getView(int position, View convertView, ViewGroup parent) { + ListEntry entry; + if (convertView == null) { + // Inflate a new view + convertView = inflater.inflate(R.layout.layout_apps_item, parent, false); + entry = new ListEntry(); + entry.icon = (ImageView) convertView.findViewById(R.id.itemicon); + entry.box = (CheckBox) convertView.findViewById(R.id.itemcheck); + entry.text = (TextView) convertView.findViewById(R.id.itemtext); + + entry.text.setOnClickListener(AppManager.this); + entry.text.setOnClickListener(AppManager.this); + + convertView.setTag(entry); + + entry.box.setOnCheckedChangeListener(AppManager.this); + } else { + // Convert an existing view + entry = (ListEntry) convertView.getTag(); + } + + + final TorifiedApp app = mApps.get(position); + + if (app.getIcon() != null) + entry.icon.setImageDrawable(app.getIcon()); + else + entry.icon.setVisibility(View.GONE); + + entry.text.setText(app.getName()); + + final CheckBox box = entry.box; + box.setTag(app); + box.setChecked(app.isTorified()); + + entry.text.setTag(box); + entry.icon.setTag(box); + + return convertView; + } };
listApps.setAdapter(adapter);
- } - - private static class ListEntry { - private CheckBox box; - private TextView text; - private ImageView icon; - } - - /* (non-Javadoc) - * @see android.app.Activity#onStop() - */ - @Override - protected void onStop() { - super.onStop(); - - } + } + + private static class ListEntry { + private CheckBox box; + private TextView text; + private ImageView icon; + } + + /* (non-Javadoc) + * @see android.app.Activity#onStop() + */ + @Override + protected void onStop() { + super.onStop(); + + } + + + public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs) + { + + String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, ""); + String[] tordApps; + + StringTokenizer st = new StringTokenizer(tordAppString,"|"); + tordApps = new String[st.countTokens()]; + int tordIdx = 0; + while (st.hasMoreTokens()) + { + tordApps[tordIdx++] = st.nextToken(); + } + + Arrays.sort(tordApps); + + //else load the apps up + PackageManager pMgr = context.getPackageManager(); + + List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0); + + Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator(); + + ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>(); + + ApplicationInfo aInfo = null; + + int appIdx = 0; + TorifiedApp app = null; + + while (itAppInfo.hasNext()) + { + aInfo = itAppInfo.next(); + + app = new TorifiedApp(); + + try { + PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS); + + if (pInfo != null && pInfo.requestedPermissions != null) + { + for (String permInfo:pInfo.requestedPermissions) + { + if (permInfo.equals("android.permission.INTERNET")) + { + app.setUsesInternet(true); + + } + } + + } + + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) + { + //System app + app.setUsesInternet(true); + } + + + if (!app.usesInternet()) + continue; + else + { + apps.add(app); + } + + + app.setEnabled(aInfo.enabled); + app.setUid(aInfo.uid); + app.setUsername(pMgr.getNameForUid(app.getUid())); + app.setProcname(aInfo.processName); + + try + { + app.setName(pMgr.getApplicationLabel(aInfo).toString()); + } + catch (Exception e) + { + app.setName(aInfo.packageName); + } + + + //app.setIcon(pMgr.getApplicationIcon(aInfo)); + + // check if this application is allowed + if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { + app.setTorified(true); + } + else + { + app.setTorified(false); + } + + appIdx++; + } + + Collections.sort(apps); + + return apps; + } +
- - public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs) - { + public void saveAppSettings (Context context) + {
- String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, ""); - String[] tordApps; - - StringTokenizer st = new StringTokenizer(tordAppString,"|"); - tordApps = new String[st.countTokens()]; - int tordIdx = 0; - while (st.hasMoreTokens()) - { - tordApps[tordIdx++] = st.nextToken(); - } - - Arrays.sort(tordApps); + StringBuilder tordApps = new StringBuilder();
- //else load the apps up - PackageManager pMgr = context.getPackageManager(); - - List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0); - - Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator(); - - ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>(); - - ApplicationInfo aInfo = null; - - int appIdx = 0; - TorifiedApp app = null; - - while (itAppInfo.hasNext()) - { - aInfo = itAppInfo.next(); - - app = new TorifiedApp(); - - try { - PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS); - - if (pInfo != null && pInfo.requestedPermissions != null) - { - for (String permInfo:pInfo.requestedPermissions) - { - if (permInfo.equals("android.permission.INTERNET")) - { - app.setUsesInternet(true); - - } - } - - } - - - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) - { - //System app - app.setUsesInternet(true); - } - - - if (!app.usesInternet()) - continue; - else - { - apps.add(app); - } - - - app.setEnabled(aInfo.enabled); - app.setUid(aInfo.uid); - app.setUsername(pMgr.getNameForUid(app.getUid())); - app.setProcname(aInfo.processName); - - try - { - app.setName(pMgr.getApplicationLabel(aInfo).toString()); - } - catch (Exception e) - { - app.setName(aInfo.packageName); - } - - - //app.setIcon(pMgr.getApplicationIcon(aInfo)); - - // check if this application is allowed - if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { - app.setTorified(true); - } - else - { - app.setTorified(false); - } - - appIdx++; - } - - Collections.sort(apps); - - return apps; - } - + for (TorifiedApp tApp:mApps) + { + if (tApp.isTorified()) + { + tordApps.append(tApp.getUsername()); + tordApps.append("|"); + } + } + + Editor edit = mPrefs.edit(); + edit.putString(PREFS_KEY_TORIFIED, tordApps.toString()); + edit.commit(); + + } +
- public void saveAppSettings (Context context) - { + /** + * Called an application is check/unchecked + */ + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + final TorifiedApp app = (TorifiedApp) buttonView.getTag(); + if (app != null) { + app.setTorified(isChecked); + } + + saveAppSettings(this);
- StringBuilder tordApps = new StringBuilder(); + }
- for (TorifiedApp tApp:mApps) - { - if (tApp.isTorified()) - { - tordApps.append(tApp.getUsername()); - tordApps.append("|"); - } - } - - Editor edit = mPrefs.edit(); - edit.putString(PREFS_KEY_TORIFIED, tordApps.toString()); - edit.commit(); - - } - + public void autoCheckApplications(View button){ + ListView listView; + ListAdapter adapter; + TorifiedApp app; + float buttonId; + boolean[] isSelected; + int posI, selectedI, lvSz;
- /** - * Called an application is check/unchecked - */ - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - final TorifiedApp app = (TorifiedApp) buttonView.getTag(); - if (app != null) { - app.setTorified(isChecked); - } - - saveAppSettings(this); + buttonId = button.getId(); + listView = (ListView) findViewById(R.id.applistview); + lvSz = listView.getCount(); + isSelected = new boolean[lvSz];
- } + selectedI = -1; + + for (posI = 0; posI < lvSz; ++posI){ + app = (TorifiedApp) listView.getItemAtPosition(posI); + if (buttonId == R.id.button_proxy_all){ + app.setTorified(true); + }else if (buttonId == R.id.button_proxy_none){ + app.setTorified(false); + }else { + app.setTorified(!app.isTorified()); + } + } + }
- public void onClick(View v) { - - CheckBox cbox = (CheckBox)v.getTag(); - - final TorifiedApp app = (TorifiedApp)cbox.getTag(); - if (app != null) { - app.setTorified(!app.isTorified()); - cbox.setChecked(app.isTorified()); - } - - saveAppSettings(this); - - } + public void onClick(View v) { + + CheckBox cbox = (CheckBox)v.getTag(); + + final TorifiedApp app = (TorifiedApp)cbox.getTag(); + if (app != null) { + app.setTorified(!app.isTorified()); + cbox.setChecked(app.isTorified()); + } + + saveAppSettings(this); + + }
- + }
tor-commits@lists.torproject.org