Merge branch 'master' of git://git.torproject.org/n8fr8/orbot
Conflicts: AUTHORS AndroidManifest.xml
This commit is contained in:
commit
34ce45398f
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.torproject.android" android:versionName="0.2.2.25-orbot-alpha-1.0.5.2" android:versionCode="14">
|
package="org.torproject.android" android:versionName="0.2.3.1-orbot-alpha-1.0.5.3" android:versionCode="16">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
|
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
|
<application android:theme="@style/DefaultTheme" android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
|
||||||
|
|
||||||
<activity android:name=".Orbot"
|
<activity android:name=".Orbot"
|
||||||
android:theme="@android:style/Theme.NoTitleBar">
|
android:theme="@android:style/Theme.NoTitleBar">
|
||||||
|
@ -29,6 +29,10 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".LotsaText"/>
|
||||||
|
<activity android:name=".Permissions"/>
|
||||||
|
<activity android:name=".TipsAndTricks"/>
|
||||||
|
<activity android:name=".ConfigureTransProxy"/>
|
||||||
<activity android:name=".SettingsPreferences" android:label="@string/app_name"/>
|
<activity android:name=".SettingsPreferences" android:label="@string/app_name"/>
|
||||||
<activity android:name=".AppManager" android:label="@string/app_name"/>
|
<activity android:name=".AppManager" android:label="@string/app_name"/>
|
||||||
<activity android:name=".WizardActivity" android:label="@string/app_name"/>
|
<activity android:name=".WizardActivity" android:label="@string/app_name"/>
|
||||||
|
|
8
BUILD
8
BUILD
|
@ -124,7 +124,13 @@ Finally, we'll make a proper Android package with ant and the Android App SDK:
|
||||||
export APP_SDK=~/Documents/projects/android/android-sdk-linux_x86-1.5_r3/tools
|
export APP_SDK=~/Documents/projects/android/android-sdk-linux_x86-1.5_r3/tools
|
||||||
cd ../Orbot/
|
cd ../Orbot/
|
||||||
cp $DROID_ROOT/external/privoxy/privoxy-3.0.12-stable/privoxy assets/privoxy
|
cp $DROID_ROOT/external/privoxy/privoxy-3.0.12-stable/privoxy assets/privoxy
|
||||||
cp $DROID_ROOT/external/tor/tor/src/or/tor assets/tor
|
|
||||||
|
Now you need to split and copy the tor binary into res/raw. We split it into < 1M chunks
|
||||||
|
because some Android devices don't like resources larger than 1M.
|
||||||
|
|
||||||
|
split --bytes=1m $DROID_ROOT/external/tor/tor/src/or/tor res/raw/tor
|
||||||
|
|
||||||
|
Now build the Android app
|
||||||
$APP_SDK/android update project --name Orbot --target 3 --path .
|
$APP_SDK/android update project --name Orbot --target 3 --path .
|
||||||
ant release
|
ant release
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
NOTE: Specific #s below correspond to Trac tickets logged and maintained at https://trac.torproject.org/projects/tor/
|
NOTE: Specific #s below correspond to Trac tickets logged and maintained at https://trac.torproject.org/projects/tor/
|
||||||
|
|
||||||
|
1.0.5.3
|
||||||
|
- added auto-tor of wireless and usb tethering
|
||||||
|
- integrated new setup wizard
|
||||||
|
- moved large tor binary into split multiple 1M segments to fix for devices with 1M resource limit
|
||||||
|
|
||||||
|
1.0.5.1/.2
|
||||||
|
- small updates to layout of main screen to fit smaller screens
|
||||||
|
- fixed preference setting of EntryNode torrc value
|
||||||
|
|
||||||
1.0.5
|
1.0.5
|
||||||
- added exit node and "StrictExitNode" preference
|
- added exit node and "StrictExitNode" preference
|
||||||
- fixed tor binary installation issue related to max resource size and compression
|
- fixed tor binary installation issue related to max resource size and compression
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
.
|
||||||
|
└── org
|
||||||
|
└── torproject
|
||||||
|
└── android
|
||||||
|
├── AppManager.java
|
||||||
|
//this is what helps us track the app-by-app torification
|
||||||
|
//and gets the app name, icon, etc for display - we have some problems here
|
||||||
|
//in normalizing the icon on the list label
|
||||||
|
//some of this code came originally from DroidWall project (yay open source)
|
||||||
|
|
||||||
|
├── boot
|
||||||
|
│ └── OnbootBroadcastReceiver.java
|
||||||
|
//i think this is a dup now and should be removed
|
||||||
|
|
||||||
|
├── HiddenServiceManager.java
|
||||||
|
//empty! but at some point i thought it would be good to aggregate HS functions here
|
||||||
|
|
||||||
|
├── OnBootReceiver.java
|
||||||
|
//this is the class registered in AndroidManifest.xml to handle Onboot events
|
||||||
|
//to start Orbot/Tor when the device boots if the user has elected to do so - what kind of permissions does this require?
|
||||||
|
// <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
|
// BTW, this shows up as a fairly unintrusive type perm request now in Android / in older versions (1.6 and earlier)
|
||||||
|
// it was reported "as read / monitor phone state" and paranoid Tor-types didn't like the idea of it
|
||||||
|
// in 1.6+ it has a much better UX in terms of having a more granular permisions around boot since it is a very
|
||||||
|
// common request - ah , that's awesome, i think i remember seeing sth of this sorts when i was going through the guardianproject mailing list. iirc this is something ioerror wanted
|
||||||
|
|
||||||
|
|
||||||
|
├── Orbot.java
|
||||||
|
//our wonderful main activity!
|
||||||
|
|
||||||
|
├── ProcessSettingsAsyncTask.java
|
||||||
|
//this was just added in 1.0.5.x, but it was meant to help stop the UI blocking while processing settings and prefs
|
||||||
|
//it uses the AsyncTask feature of Android, which seems to work pretty well
|
||||||
|
//for this type of non-time critical function you just want to happen in the background at some point soon-ish
|
||||||
|
|
||||||
|
├── SettingsPreferences.java
|
||||||
|
// Settings activity that loads the res/xml/preferences.xml resource up
|
||||||
|
// has some custom event handlng, onActivityResult callback result code's as well
|
||||||
|
// basically meant to tell Orbot activity if critical settings have been modified and whether
|
||||||
|
// those new settings should be applied (like iptables/transproxy changes)
|
||||||
|
|
||||||
|
├── TorConstants.java
|
||||||
|
// globals! well, constants! but yeah, just a place to put values we use a lot
|
||||||
|
|
||||||
|
├── TorifiedApp.java
|
||||||
|
// object to store a single app's metadata for display in UI and for transproxy process
|
||||||
|
|
||||||
|
├── Utils.java
|
||||||
|
// random methods that can be useful, a.k.a. another place to put stuff
|
||||||
|
|
||||||
|
├── WizardActivity.java
|
||||||
|
// our original attempt at wizard activity that didn't get far
|
||||||
|
|
||||||
|
└── WizardHelper.java
|
||||||
|
// the helper class that manages the dialog based wizard
|
||||||
|
|
||||||
|
├── service //okay the Service subpackage!
|
||||||
|
|
||||||
|
│ ├── Api.java
|
||||||
|
//this is more code taken from DroidWall, that needs to be cleaned up and paired down to just what we need it for
|
||||||
|
//this is related to 1.0.5.x changes with how we bundle and install our C binaries (tor, privoxy and iptables)
|
||||||
|
|
||||||
|
│ ├── ITorService.aidl
|
||||||
|
// the android remote interface definition file;
|
||||||
|
// this is the remote interface which the Orbot activity gets a reference to
|
||||||
|
// and that in the TorService is instantiated as the "binder"
|
||||||
|
|
||||||
|
│ ├── ITorServiceCallback.aidl
|
||||||
|
// this is the callback interface that the Orbot activity instantiates, and passes
|
||||||
|
// to the ITorService; reverse of ITorService in a sense
|
||||||
|
|
||||||
|
│ ├── TorBinaryInstaller.java
|
||||||
|
// this handles installation of binaries; uses Api.java; // tied into Wizard as well
|
||||||
|
|
||||||
|
│ ├── TorServiceConstants.java
|
||||||
|
// reusable constants for just the Service package
|
||||||
|
|
||||||
|
│ ├── TorService.java
|
||||||
|
// the main might powerful service class; Orbot and TorService are the front and backends of this whole app
|
||||||
|
// should run as a remote service, but the manifest doesn't seem to indicate that at the moment
|
||||||
|
|
||||||
|
│ ├── TorServiceUtils.java
|
||||||
|
//utility methods for the service; specificaly check for root and tools for finding processID of background binaries
|
||||||
|
|
||||||
|
│ └── TorTransProxy.java
|
||||||
|
// all the code for iptables transproxying management
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -5,12 +5,13 @@
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:stretchColumns="1">
|
android:stretchColumns="1">
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<ImageView android:id="@+id/itemicon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="3dip"></ImageView>
|
<ImageView android:id="@+id/itemicon" android:layout_width="50dip" android:layout_height="50dip" android:padding="3dip"></ImageView>
|
||||||
|
|
||||||
<TextView android:layout_height="wrap_content" android:id="@+id/itemtext" android:text="uid:packages" android:textSize="18sp" android:padding="3dip"></TextView>
|
<TextView android:layout_height="wrap_content" android:id="@+id/itemtext" android:text="uid:packages" android:textSize="18sp" android:padding="3dip"></TextView>
|
||||||
|
|
||||||
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/itemcheck" ></CheckBox>
|
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/itemcheck" ></CheckBox>
|
||||||
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,17 @@
|
||||||
android:layout_toLeftOf="@+id/radioModeImage"
|
android:layout_toLeftOf="@+id/radioModeImage"
|
||||||
android:textColor="#cccccc" />
|
android:textColor="#cccccc" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
<RelativeLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
|
||||||
|
>
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imgStatus"
|
android:id="@+id/imgStatus"
|
||||||
android:layout_margin="5dip"
|
android:layout_margin="15dip"
|
||||||
android:layout_width="320dip"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="320dip"
|
android:layout_height="320dip"
|
||||||
android:src="@drawable/toroff"
|
android:src="@drawable/toroff"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
@ -45,14 +51,14 @@
|
||||||
|
|
||||||
<TextView android:id="@+id/lblStatus"
|
<TextView android:id="@+id/lblStatus"
|
||||||
android:text="@string/press_to_start"
|
android:text="@string/press_to_start"
|
||||||
android:layout_gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="30dip"
|
android:layout_height="60dip"
|
||||||
android:textColor="#ffffff"
|
android:textColor="#ffffff"
|
||||||
|
android:layout_below="@id/imgStatus"
|
||||||
/>
|
/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/relativeLayout1"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#000000">
|
||||||
|
|
||||||
|
<TextView android:textSize="10pt"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/WizardTextTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:fadingEdge="vertical"
|
||||||
|
android:text="TITLE"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:padding="20px" android:layout_centerInParent="true">
|
||||||
|
</TextView>
|
||||||
|
</RelativeLayout>
|
||||||
|
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<ScrollView android:id="@+id/helpscrollview"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_span="3"
|
||||||
|
>
|
||||||
|
<LinearLayout android:background="#575757" android:layout_width="wrap_content" android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:orientation="vertical">
|
||||||
|
<TextView android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:padding="20dip"></TextView>
|
||||||
|
<Button android:layout_width="wrap_content" android:visibility="gone" android:layout_height="wrap_content" android:gravity="center" android:text="Grant Permission" android:id="@+id/grantPermissions" android:layout_gravity="center"></Button>
|
||||||
|
<TextView android:layout_width="wrap_content" android:visibility="gone" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody2" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:padding="20dip"></TextView>
|
||||||
|
<CheckBox android:id="@+id/checkBox" android:layout_gravity="center" android:text="@string/wizard_permissions_consent" android:layout_height="wrap_content" android:layout_width="wrap_content" android:gravity="center" android:visibility="visible"></CheckBox>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
|
||||||
|
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,69 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/relativeLayout1"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#000000">
|
||||||
|
<TextView android:textSize="10pt"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/WizardTextTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:fadingEdge="vertical"
|
||||||
|
android:text="TITLE"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:padding="20px" android:layout_centerInParent="true">
|
||||||
|
</TextView>
|
||||||
|
</RelativeLayout>
|
||||||
|
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
|
||||||
<ScrollView android:id="@+id/helpscrollview"
|
<ScrollView android:id="@+id/helpscrollview"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_span="3">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:background="#575757"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:padding="3px">
|
android:padding="3px">
|
||||||
<TextView android:text="@string/wizard_configure_msg" android:textColor="#ffffff" android:id="@+id/WizardRootTextView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
|
<TextView android:text="@string/wizard_transproxy_msg" android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:padding="20dip"></TextView>
|
||||||
|
<RadioGroup android:id="@+id/radioGroup" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingLeft="15dip">
|
||||||
|
<RadioButton android:text="@string/wizard_configure_all" android:id="@+id/radio0" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
|
||||||
<CheckBox android:layout_marginTop="20px" android:text="@string/wizard_configure_all" android:id="@+id/WizardRootCheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
|
<TextView android:layout_height="wrap_content"
|
||||||
<TextView android:text=" or " android:textColor="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
|
android:text="@string/wizard_transproxy_hint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
<Button android:text="@string/wizard_configure_select_apps" android:id="@+id/WizardRootButton01" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
android:textSize="15sp"
|
||||||
|
android:paddingBottom="10dip" android:paddingRight="20dip">
|
||||||
|
</TextView>
|
||||||
|
<RadioButton android:text="@string/wizard_configure_select_apps" android:id="@+id/radio1" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
|
||||||
|
<RadioButton android:text="@string/wizard_transproxy_none" android:id="@+id/radio2" android:layout_height="wrap_content" android:layout_width="wrap_content"></RadioButton>
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
|
||||||
|
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,63 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/relativeLayout1"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#000000">
|
||||||
|
<TextView android:textSize="10pt"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/WizardTextTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:fadingEdge="vertical"
|
||||||
|
android:text="TITLE"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:padding="20px" android:layout_centerInParent="true">
|
||||||
|
</TextView>
|
||||||
|
</RelativeLayout>
|
||||||
|
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<TableRow android:layout_margin="10dip" android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
|
||||||
<ScrollView android:id="@+id/helpscrollview"
|
<ScrollView android:id="@+id/helpscrollview"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_span="3">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:background="#575757"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:padding="3px">
|
android:paddingRight="20dip"
|
||||||
|
>
|
||||||
|
|
||||||
<TextView android:text="@string/wizard_tips_msg" android:layout_gravity="left" android:textColor="#ffffff" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
|
<TextView android:text="@string/wizard_tips_msg" android:layout_width="wrap_content" android:textColor="#ffffff" android:layout_height="wrap_content" android:textSize="8pt" android:id="@+id/WizardTextBody1" android:padding="20dip"></TextView>
|
||||||
|
<Button android:text="@string/wizard_tips_gibberbot" android:layout_gravity="left" android:drawableLeft="@drawable/ic_launcher_gibberbot" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallGibberbot" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<Button android:text="@string/wizard_tips_otrchat" android:layout_gravity="left" android:drawableLeft="@drawable/ic_launcher_gibberbot" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallOtrchat" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
<Button android:text="@string/wizard_tips_firefox" android:layout_gravity="left" android:drawableLeft="@drawable/icon_firefox" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallFirefox" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<Button android:text="@string/wizard_tips_orweb" android:drawableLeft="@drawable/icon_orweb" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonInstallOrweb" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
<Button android:text="@string/wizard_tips_proxymob" android:layout_marginTop="10px" android:drawableLeft="@drawable/proxymob" android:id="@+id/WizardRootButtonInstallProxyMob" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<Button android:text="@string/wizard_tips_proxy" android:layout_marginTop="10px" android:id="@+id/WizardRootButtonProxyHelp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
<TableRow android:background="#000000" android:layout_marginTop="10dip" android:paddingTop="10dip" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px">
|
||||||
|
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/relativeLayout1"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#000000"
|
||||||
|
>
|
||||||
|
<ImageView
|
||||||
|
android:src="@drawable/warning"
|
||||||
|
android:id="@+id/orbot_image"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:paddingLeft="20px" android:layout_marginLeft="10dip" android:layout_marginTop="8dip">
|
||||||
|
</ImageView>
|
||||||
|
<TextView
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="10pt"
|
||||||
|
android:layout_toRightOf="@id/orbot_image"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/WizardTextTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:fadingEdge="vertical"
|
||||||
|
android:text="TITLE"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:paddingLeft="5px"
|
||||||
|
android:padding="20px"
|
||||||
|
>
|
||||||
|
</TextView>
|
||||||
|
</RelativeLayout>
|
||||||
|
<TableLayout android:id="@+id/TableLayout01" android:stretchColumns="*" android:layout_height="fill_parent" android:layout_width="wrap_content" >
|
||||||
|
|
||||||
|
<TableRow android:id="@+id/TableRow01" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="10dip">
|
||||||
|
|
||||||
|
|
||||||
|
<ScrollView android:id="@+id/helpscrollview"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_span="3">
|
||||||
|
|
||||||
|
<TextView android:background="#575757" android:text="this is sample text this is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample textthis is sample text" android:textColor="#ffffff" android:id="@+id/WizardTextBody" android:textSize="8pt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dip"></TextView>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
<TableRow android:background="#000000" android:id="@+id/TableRow01" android:textColor="#00ff00" android:layout_width="fill_parent" android:layout_height="30px" android:layout_marginTop="10dip" android:paddingTop="10dip">
|
||||||
|
<Button android:text="Back" android:id="@+id/btnWizard1" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
<Button android:text="Next" android:id="@+id/btnWizard2" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
BIN
res/raw/tor
BIN
res/raw/tor
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,5 +7,8 @@ RelayBandwidthRate 20 KBytes
|
||||||
RelayBandwidthBurst 20 KBytes
|
RelayBandwidthBurst 20 KBytes
|
||||||
UseBridges 0
|
UseBridges 0
|
||||||
AutomapHostsOnResolve 1
|
AutomapHostsOnResolve 1
|
||||||
|
TransListenAddress 0.0.0.0
|
||||||
TransPort 9040
|
TransPort 9040
|
||||||
|
DNSListenAddress 0.0.0.0
|
||||||
DNSPort 5400
|
DNSPort 5400
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">اوربوت (Orbot)</string>
|
<string name="app_name">اوربوت (Orbot)</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">اوربات</string>
|
<string name="app_name">اوربات</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Орбот</string>
|
<string name="app_name">Орбот</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
<string name="secure_default_web_url">https://check.torproject.org</string>
|
<string name="secure_default_web_url">https://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Orbot</string>
|
<string name="app_name">Orbot</string>
|
||||||
<string name="app_version">1.0.5</string>
|
|
||||||
|
|
||||||
<string name="internal_web_url">http://orbot/</string>
|
<string name="internal_web_url">http://orbot/</string>
|
||||||
<string name="default_web_url">http://check.torproject.org</string>
|
<string name="default_web_url">http://check.torproject.org</string>
|
||||||
|
@ -130,5 +129,42 @@
|
||||||
<string name="pref_general_group">General</string>
|
<string name="pref_general_group">General</string>
|
||||||
<string name="pref_start_boot_title">Start Orbot on Boot</string>
|
<string name="pref_start_boot_title">Start Orbot on Boot</string>
|
||||||
<string name="pref_start_boot_summary">Automatically start Orbot and connect Tor when your Android device boots</string>
|
<string name="pref_start_boot_summary">Automatically start Orbot and connect Tor when your Android device boots</string>
|
||||||
|
<!-- New Wizard Strings -->
|
||||||
|
<!-- Title Screen -->
|
||||||
|
<string name="wizard_title_msg">Orbot brings Tor to Android \n\nTor helps you defend against a form of network surveillance that threatens privacy, confidential business activity and relationships, and state security known as traffic analysis</string>
|
||||||
|
<!-- Warning screen -->
|
||||||
|
<string name="wizard_warning_title">Warning</string>
|
||||||
|
<string name="wizard_warning_msg">Simply installing Orbot will not automatically anonymize your mobile traffic.\n\nPlease follow the following steps to get started</string>
|
||||||
|
<!-- Permissions screen -->
|
||||||
|
<string name="wizard_permissions_title">Permissions</string>
|
||||||
|
<string name="wizard_permissions_root_msg1">Orbot has detected that you have root permissions enabled. To enable \'Transparent Proxying\', please grant superuser privileges to Orbot</string>
|
||||||
|
<string name="wizard_permissions_root_msg2">If you choose to continue without providing superuser privileges, make sure to use apps made to work with orbot</string>
|
||||||
|
<string name="wizard_permissions_msg">Orbot has detected that you do not have root permissions.\nTransparent Proxying is not possible without superuser privileges.\nMake sure to use apps that have been configured to work with Orbot</string>
|
||||||
|
<!-- TipsAndTricks screen -->
|
||||||
|
<string name="wizard_tips_title">Orbot configured Apps</string>
|
||||||
|
<string name="wizard_tips_gibberbot">Gibberbot - Secure instant messaging client for Android</string>
|
||||||
|
<string name="wizard_tips_firefox">Firefox - Android browser - To be used along with ProxyMob Add-on </string>
|
||||||
|
<string name="wizard_tips_proxymob">ProxyMob - Simple Firefox Add-on for setting HTTP, SOCKS and SSL proxy settings</string>
|
||||||
|
<string name="gibberbot_apk_url">https://market.android.com/details?id=info.guardianproject.otr.app.im</string>
|
||||||
|
<string name="firefox_apk_url">https://market.android.com/details?id=org.mozilla.firefox</string>
|
||||||
|
<string name="proxymob_url">https://addons.mozilla.org/mobile/downloads/latest/251558/type:attachment/addon-251558-latest.xpi?src=addon-detail</string>
|
||||||
|
<!-- Transparent Proxy screen -->
|
||||||
|
<string name="wizard_transproxy_title">Transparent Proxy</string>
|
||||||
|
<string name="wizard_transproxy_msg">Transparent Proxying allows you to redirect client requests without any special configuration or knowledge at the client.</string>
|
||||||
|
<string name="wizard_transproxy_hint">(Check this box if you have no idea what we are talking about)</string>
|
||||||
|
<string name="wizard_transproxy_none">None</string>
|
||||||
|
|
||||||
|
<string name="pref_transparent_tethering_title">Tor Tethering</string>
|
||||||
|
<string name="pref_transparent_tethering_summary">Enable Tor Transparent Proxying for Wifi and USB Tethered Devices</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="pref_select_apps">Select Apps</string>
|
||||||
|
<string name="pref_select_apps_summary">Choose Apps to Route Through Tor</string>
|
||||||
|
|
||||||
|
<string name="pref_node_configuration">Node Configuration</string>
|
||||||
|
<string name="pref_node_configuration_summary">These are advanced settings that can reduce your anonymity</string>
|
||||||
|
|
||||||
|
<string name="pref_entrance_node">Entrance Nodes</string>
|
||||||
|
<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>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<color name="custom_theme_color">#333</color>
|
||||||
|
<style name="DefaultTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">@drawable/bgtitanium</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
|
@ -35,18 +35,27 @@ android:title="@string/pref_transparent_all_title"/>
|
||||||
<Preference
|
<Preference
|
||||||
android:defaultValue=""
|
android:defaultValue=""
|
||||||
android:key="pref_transparent_app_list"
|
android:key="pref_transparent_app_list"
|
||||||
android:title="Select Apps"
|
android:title="@string/pref_select_apps"
|
||||||
android:summary="Choose Apps to Route Through Tor"
|
android:summary="@string/pref_select_apps_summary"
|
||||||
android:enabled="true"/>
|
android:enabled="true"/>
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="pref_transparent_tethering"
|
||||||
|
android:summary="@string/pref_transparent_tethering_summary"
|
||||||
|
android:enabled="true"
|
||||||
|
android:title="@string/pref_transparent_tethering_title"/>
|
||||||
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="Node Configuration" android:summary="These are advanced settings that can reduce your anonymity">
|
<PreferenceCategory android:title="@string/pref_node_configuration"
|
||||||
|
android:summary="@string/pref_node_configuration_summary">
|
||||||
|
|
||||||
<EditTextPreference android:key="pref_entrance_nodes"
|
<EditTextPreference android:key="pref_entrance_nodes"
|
||||||
android:title="Entrance Nodes"
|
android:title="@string/pref_entrance_node"
|
||||||
android:summary="Fingerprints, nicks, countries and addresses for the first hop"
|
android:summary="@string/pref_entrance_node_summary"
|
||||||
android:dialogTitle="Enter Entrance Nodes"
|
android:dialogTitle="@string/pref_entrance_node_dialog"
|
||||||
/>
|
/>
|
||||||
<EditTextPreference android:key="pref_exit_nodes"
|
<EditTextPreference android:key="pref_exit_nodes"
|
||||||
android:title="Exit Nodes"
|
android:title="Exit Nodes"
|
||||||
|
@ -70,11 +79,6 @@ android:summary="Use *only* these specified nodes"/>
|
||||||
android:title="Use Bridges" android:key="pref_bridges_enabled"
|
android:title="Use Bridges" android:key="pref_bridges_enabled"
|
||||||
android:summary="Enable alternate entrance nodes into the Tor Network"></CheckBoxPreference>
|
android:summary="Enable alternate entrance nodes into the Tor Network"></CheckBoxPreference>
|
||||||
|
|
||||||
<!-- 5/8/2010 NF: Arma says this doesn't actually work, so commenting out for now
|
|
||||||
<CheckBoxPreference android:defaultValue="false"
|
|
||||||
android:title="Update from Authority" android:key="pref_bridges_update"
|
|
||||||
android:summary="Modify bridge list automatically"></CheckBoxPreference>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<EditTextPreference android:key="pref_bridges_list"
|
<EditTextPreference android:key="pref_bridges_list"
|
||||||
android:title="Bridges"
|
android:title="Bridges"
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
package org.torproject.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.RadioGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
public class ConfigureTransProxy extends Activity implements TorConstants {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
private int flag = 0;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
context = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
|
||||||
|
super.onStart();
|
||||||
|
setContentView(R.layout.layout_wizard_root);
|
||||||
|
|
||||||
|
stepSix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void stepSix(){
|
||||||
|
|
||||||
|
String title = context.getString(R.string.wizard_transproxy_title);
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
Button back = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button next = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
next.setEnabled(false);
|
||||||
|
|
||||||
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
//Dirty flag variable - improve logic
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if( flag == 1 )
|
||||||
|
context.startActivity(new Intent(context, AppManager.class));
|
||||||
|
|
||||||
|
else
|
||||||
|
showWizardFinal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
RadioGroup mRadioGroup = (RadioGroup)findViewById(R.id.radioGroup);
|
||||||
|
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener (){
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(RadioGroup group, int checkedId){
|
||||||
|
Button next = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
next.setEnabled(true);
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
showWizardFinal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
RadioButton rb0 = (RadioButton)findViewById(R.id.radio0);
|
||||||
|
RadioButton rb1 = (RadioButton)findViewById(R.id.radio1);
|
||||||
|
RadioButton rb2 = (RadioButton)findViewById(R.id.radio2);
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT, rb0.isChecked());
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT_ALL, rb0.isChecked());
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
if(rb0.isChecked())
|
||||||
|
{
|
||||||
|
pEdit.putString("radiobutton","rb0");
|
||||||
|
pEdit.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(rb1.isChecked())
|
||||||
|
{
|
||||||
|
flag = 1;
|
||||||
|
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT, true);
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT_ALL, false);
|
||||||
|
pEdit.putString("radiobutton","rb1");
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
context.startActivity(new Intent(context, AppManager.class));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(rb2.isChecked())
|
||||||
|
{
|
||||||
|
pEdit.putString("radiobutton", "rb2");
|
||||||
|
pEdit.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showWizardFinal ()
|
||||||
|
{
|
||||||
|
String title = null;
|
||||||
|
String msg = null;
|
||||||
|
|
||||||
|
|
||||||
|
title = context.getString(R.string.wizard_final);
|
||||||
|
msg = context.getString(R.string.wizard_final_msg);
|
||||||
|
|
||||||
|
DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
context.startActivity(new Intent(context, Orbot.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setIcon(R.drawable.icon)
|
||||||
|
.setTitle(title)
|
||||||
|
.setPositiveButton(R.string.button_close, ocListener)
|
||||||
|
.setMessage(msg)
|
||||||
|
.show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
package org.torproject.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class LotsaText extends Activity implements TorConstants{
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
context = this;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
|
||||||
|
super.onStart();
|
||||||
|
setContentView(R.layout.scrollingtext_buttons_view);
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
boolean wizardScreen1 = prefs.getBoolean("wizardscreen1",true);
|
||||||
|
if(wizardScreen1)
|
||||||
|
stepOne();
|
||||||
|
else
|
||||||
|
stepTwo();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void stepOne() {
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
pEdit.putBoolean("wizardscreen1",true);
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
String title = context.getString(R.string.wizard_title);
|
||||||
|
String msg = context.getString(R.string.wizard_title_msg);
|
||||||
|
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
|
||||||
|
txtBody.setText(msg);
|
||||||
|
|
||||||
|
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
ImageView img = (ImageView) findViewById(R.id.orbot_image);
|
||||||
|
|
||||||
|
btn1.setVisibility(Button.INVISIBLE);
|
||||||
|
img.setImageResource(R.drawable.tor);
|
||||||
|
|
||||||
|
btn2.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
stepTwo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stepTwo() {
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
pEdit.putBoolean("wizardscreen1",false);
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
setContentView(R.layout.scrollingtext_buttons_view);
|
||||||
|
String title = context.getString(R.string.wizard_warning_title);
|
||||||
|
String msg = context.getString(R.string.wizard_warning_msg);
|
||||||
|
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
|
||||||
|
txtBody.setText(msg);
|
||||||
|
|
||||||
|
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
ImageView img = (ImageView) findViewById(R.id.orbot_image);
|
||||||
|
|
||||||
|
btn1.setVisibility(Button.VISIBLE);
|
||||||
|
img.setImageResource(R.drawable.warning);
|
||||||
|
|
||||||
|
btn1.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
stepOne();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btn2.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
package org.torproject.android;
|
package org.torproject.android;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -24,6 +26,7 @@ import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -47,35 +50,48 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Useful UI bits */
|
/* Useful UI bits */
|
||||||
|
// so this is probably pretty obvious, here, but also an area
|
||||||
|
// which we might see quite a bit of change+complexity was the main screen
|
||||||
|
// UI gets new features
|
||||||
private TextView lblStatus = null; //the main text display widget
|
private TextView lblStatus = null; //the main text display widget
|
||||||
private ImageView imgStatus = null; //the main touchable image for activating Orbot
|
private ImageView imgStatus = null; //the main touchable image for activating Orbot
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog; //the spinning progress dialog that shows up now and then
|
||||||
private MenuItem mItemOnOff = null;
|
private MenuItem mItemOnOff = null; //the menu item which we toggle based on Orbot state
|
||||||
|
|
||||||
/* Some tracking bits */
|
/* Some tracking bits */
|
||||||
private int torStatus = STATUS_READY; //latest status reported from the tor service
|
private int torStatus = STATUS_READY; //latest status reported from the tor service
|
||||||
|
// this is a value we get passed back from the TorService
|
||||||
|
|
||||||
/* Tor Service interaction */
|
/* Tor Service interaction */
|
||||||
/* The primary interface we will be calling on the service. */
|
/* The primary interface we will be calling on the service. */
|
||||||
ITorService mService = null;
|
ITorService mService = null; //interface to remote TorService
|
||||||
private boolean autoStartOnBind = false;
|
private boolean autoStartOnBind = false; //controls whether service starts when class binds to it
|
||||||
|
|
||||||
SharedPreferences prefs;
|
SharedPreferences prefs; //what the user really wants!
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/**
|
||||||
|
* When the Orbot activity is created, we call startService
|
||||||
|
* to ensure the Tor remote service is running. However, it may
|
||||||
|
* already be running, and this should not create more than one instnace
|
||||||
|
*/
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
//if Tor binary is not running, then start the service up
|
//if Tor binary is not running, then start the service up
|
||||||
|
//might want to look at whether we need to call this every time
|
||||||
|
//or whether binding to the service is enough
|
||||||
startService(new Intent(INTENT_TOR_SERVICE));
|
startService(new Intent(INTENT_TOR_SERVICE));
|
||||||
|
|
||||||
|
//something to play with on the UI branch
|
||||||
setTheme(android.R.style.Theme_Black_NoTitleBar);
|
setTheme(android.R.style.Theme_Black_NoTitleBar);
|
||||||
|
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
//same here - layout_main has been cleaned up since 1.0.5.2 a bit (removed table as you recmnd)
|
||||||
|
//but ther eis more to be done
|
||||||
setContentView(R.layout.layout_main);
|
setContentView(R.layout.layout_main);
|
||||||
|
|
||||||
|
//obvious? -yep got everything so far
|
||||||
lblStatus = (TextView)findViewById(R.id.lblStatus);
|
lblStatus = (TextView)findViewById(R.id.lblStatus);
|
||||||
lblStatus.setOnLongClickListener(this);
|
lblStatus.setOnLongClickListener(this);
|
||||||
imgStatus = (ImageView)findViewById(R.id.imgStatus);
|
imgStatus = (ImageView)findViewById(R.id.imgStatus);
|
||||||
|
@ -124,8 +140,16 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
LayoutInflater li = LayoutInflater.from(this);
|
LayoutInflater li = LayoutInflater.from(this);
|
||||||
View view = li.inflate(R.layout.layout_about, null);
|
View view = li.inflate(R.layout.layout_about, null);
|
||||||
|
|
||||||
|
String version = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
version = "Version Not Found";
|
||||||
|
}
|
||||||
|
|
||||||
TextView versionName = (TextView)view.findViewById(R.id.versionName);
|
TextView versionName = (TextView)view.findViewById(R.id.versionName);
|
||||||
versionName.setText(R.string.app_version);
|
versionName.setText(version);
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(getString(R.string.button_about))
|
.setTitle(getString(R.string.button_about))
|
||||||
|
@ -201,14 +225,25 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is our attempt to REALLY exit Orbot, and stop the background service
|
||||||
|
* However, Android doesn't like people "quitting" apps, and/or our code may not
|
||||||
|
* be quite right b/c no matter what we do, it seems like the TorService still exists
|
||||||
|
**/
|
||||||
private void doExit ()
|
private void doExit ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
//one of the confusing things about all of this code is the multiple
|
||||||
|
//places where things like "stopTor" are called, both in the Activity and the Service
|
||||||
|
//not something to tackle in your first iteration, but i thin we can talk about fixing
|
||||||
|
//terminology but also making sure there are clear distinctions in control
|
||||||
stopTor();
|
stopTor();
|
||||||
|
|
||||||
|
//perhaps this should be referenced as INTENT_TOR_SERVICE as in startService
|
||||||
stopService(new Intent(ITorService.class.getName()));
|
stopService(new Intent(ITorService.class.getName()));
|
||||||
|
|
||||||
|
//clears all notifications from the status bar
|
||||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mNotificationManager.cancelAll();
|
mNotificationManager.cancelAll();
|
||||||
|
|
||||||
|
@ -228,6 +263,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
/*
|
/*
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event){
|
public boolean onKeyDown(int keyCode, KeyEvent event){
|
||||||
|
|
||||||
|
//yeah this should probably go away now :) - or not
|
||||||
if(keyCode==KeyEvent.KEYCODE_BACK){
|
if(keyCode==KeyEvent.KEYCODE_BACK){
|
||||||
|
|
||||||
if(currentView != R.layout.layout_main){
|
if(currentView != R.layout.layout_main){
|
||||||
|
@ -408,7 +444,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
|
|
||||||
pEdit.commit();
|
pEdit.commit();
|
||||||
|
|
||||||
new WizardHelper(this).showWizard();
|
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +490,12 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
private void showHelp ()
|
private void showHelp ()
|
||||||
{
|
{
|
||||||
|
|
||||||
new WizardHelper(this).showWizard();
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
pEdit.putBoolean("wizardscreen1",true);
|
||||||
|
pEdit.commit();
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,6 +513,9 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
//if we get a response from an activity we launched (like from line 527 where we launch the Settings/Prefs screen)
|
||||||
|
//and the resultCode matches our arbitrary 1010 value, AND Tor is running
|
||||||
|
//then update the preferences in an async background task
|
||||||
if (requestCode == 1 && resultCode == 1010 && mService != null)
|
if (requestCode == 1 && resultCode == 1010 && mService != null)
|
||||||
{
|
{
|
||||||
new ProcessSettingsAsyncTask().execute(mService);
|
new ProcessSettingsAsyncTask().execute(mService);
|
||||||
|
@ -480,6 +524,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
|
|
||||||
AlertDialog aDialog = null;
|
AlertDialog aDialog = null;
|
||||||
|
|
||||||
|
//general alert dialog for mostly Tor warning messages
|
||||||
|
//sometimes this can go haywire or crazy with too many error
|
||||||
|
//messages from Tor, and the user cannot stop or exit Orbot
|
||||||
|
//so need to ensure repeated error messages are not spamming this method
|
||||||
private void showAlert(String title, String msg, boolean button)
|
private void showAlert(String title, String msg, boolean button)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -511,15 +559,17 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Set the state of the running/not running graphic and label
|
* Set the state of the running/not running graphic and label
|
||||||
|
* this all needs to be looked at w/ the shift to progressDialog
|
||||||
*/
|
*/
|
||||||
public void updateStatus (String torServiceMsg)
|
public void updateStatus (String torServiceMsg)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//if the serivce is bound, query it for the curren status value (int)
|
||||||
if (mService != null)
|
if (mService != null)
|
||||||
torStatus = mService.getStatus();
|
torStatus = mService.getStatus();
|
||||||
|
|
||||||
|
//now update the layout_main UI based on the status
|
||||||
if (imgStatus != null)
|
if (imgStatus != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -605,16 +655,25 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// guess what? this start's Tor! actually no it just requests via the local ITorService to the remote TorService instance
|
||||||
|
// to start Tor
|
||||||
private void startTor () throws RemoteException
|
private void startTor () throws RemoteException
|
||||||
{
|
{
|
||||||
|
// here we bind AGAIN - at some point i think we had to bind multiple times just in case
|
||||||
|
// but i would love to clarify, clean this up
|
||||||
bindService();
|
bindService();
|
||||||
|
|
||||||
|
// this is a bit of a strange/old/borrowed code/design i used to change the service state
|
||||||
|
// not sure it really makes sense when what we want to say is just "startTor"
|
||||||
mService.setProfile(TorServiceConstants.PROFILE_ON); //this means turn on
|
mService.setProfile(TorServiceConstants.PROFILE_ON); //this means turn on
|
||||||
|
|
||||||
|
//here we update the UI which is a bit sloppy and mixed up code wise
|
||||||
|
//might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense
|
||||||
imgStatus.setImageResource(R.drawable.torstarting);
|
imgStatus.setImageResource(R.drawable.torstarting);
|
||||||
lblStatus.setText(getString(R.string.status_starting_up));
|
lblStatus.setText(getString(R.string.status_starting_up));
|
||||||
|
|
||||||
|
|
||||||
|
//we send a message here to the progressDialog i believe, but we can clarify that shortly
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
|
Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
|
|
||||||
|
@ -622,11 +681,15 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//now we stop Tor! amazing!
|
||||||
private void stopTor () throws RemoteException
|
private void stopTor () throws RemoteException
|
||||||
{
|
{
|
||||||
|
//if the service is bound, then turn it off, using the same "PROFILE_" technique
|
||||||
if (mService != null)
|
if (mService != null)
|
||||||
{
|
{
|
||||||
mService.setProfile(TorServiceConstants.PROFILE_OFF);
|
mService.setProfile(TorServiceConstants.PROFILE_OFF);
|
||||||
|
|
||||||
|
//again this is related to the progress dialog or some other threaded UI object
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
|
Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
@ -675,6 +738,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
/**
|
/**
|
||||||
* This implementation is used to receive callbacks from the remote
|
* This implementation is used to receive callbacks from the remote
|
||||||
* service.
|
* service.
|
||||||
|
*
|
||||||
|
* If we have this setup probably, we shouldn't have to poll or query status
|
||||||
|
* to the service, as it should send it as it changes or when we bind/unbind to it
|
||||||
|
* from this activity
|
||||||
*/
|
*/
|
||||||
private ITorServiceCallback mCallback = new ITorServiceCallback.Stub() {
|
private ITorServiceCallback mCallback = new ITorServiceCallback.Stub() {
|
||||||
/**
|
/**
|
||||||
|
@ -684,14 +751,17 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
* NOT be running in our main thread like most other things -- so,
|
* NOT be running in our main thread like most other things -- so,
|
||||||
* to update the UI, we need to use a Handler to hop over there.
|
* to update the UI, we need to use a Handler to hop over there.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//receive a new string vaule end-user displayable message from the ITorService
|
||||||
public void statusChanged(String value) {
|
public void statusChanged(String value) {
|
||||||
|
|
||||||
|
//pass it off to the progressDialog
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG);
|
Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG);
|
||||||
msg.getData().putString(HANDLER_TOR_MSG, value);
|
msg.getData().putString(HANDLER_TOR_MSG, value);
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override //this was when we displayed the log in the main Activity; can prob take this out now
|
||||||
public void logMessage(String value) throws RemoteException {
|
public void logMessage(String value) throws RemoteException {
|
||||||
|
|
||||||
Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
|
Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
|
||||||
|
@ -702,6 +772,8 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// this is what takes messages or values from the callback threads or other non-mainUI threads
|
||||||
|
//and passes them back into the main UI thread for display to the user
|
||||||
private Handler mHandler = new Handler() {
|
private Handler mHandler = new Handler() {
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
|
@ -741,6 +813,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
/**
|
/**
|
||||||
* Class for interacting with the main interface of the service.
|
* Class for interacting with the main interface of the service.
|
||||||
*/
|
*/
|
||||||
|
// this is the connection that gets called back when a successfull bind occurs
|
||||||
|
// we should use this to activity monitor unbind so that we don't have to call
|
||||||
|
// bindService() a million times
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
private ServiceConnection mConnection = new ServiceConnection() {
|
||||||
public void onServiceConnected(ComponentName className,
|
public void onServiceConnected(ComponentName className,
|
||||||
IBinder service) {
|
IBinder service) {
|
||||||
|
@ -756,6 +832,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
try {
|
try {
|
||||||
mService.registerCallback(mCallback);
|
mService.registerCallback(mCallback);
|
||||||
|
|
||||||
|
//again with the update status?!? :P
|
||||||
updateStatus("");
|
updateStatus("");
|
||||||
|
|
||||||
if (autoStartOnBind)
|
if (autoStartOnBind)
|
||||||
|
@ -789,10 +866,15 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//should move this up with all the other class variables
|
||||||
boolean mIsBound = false;
|
boolean mIsBound = false;
|
||||||
|
|
||||||
|
//this is where we bind!
|
||||||
private void bindService ()
|
private void bindService ()
|
||||||
{
|
{
|
||||||
|
//since its auto create, we prob don't ever need to call startService
|
||||||
|
//also we should again be consistent with using either iTorService.class.getName()
|
||||||
|
//or the variable constant
|
||||||
bindService(new Intent(ITorService.class.getName()),
|
bindService(new Intent(ITorService.class.getName()),
|
||||||
mConnection, Context.BIND_AUTO_CREATE);
|
mConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
|
@ -800,6 +882,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//unbind removes the callback, and unbinds the service
|
||||||
private void unbindService ()
|
private void unbindService ()
|
||||||
{
|
{
|
||||||
if (mIsBound) {
|
if (mIsBound) {
|
||||||
|
@ -815,6 +898,9 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//maybe needs this?
|
||||||
|
mService = null;
|
||||||
|
|
||||||
// Detach our existing connection.
|
// Detach our existing connection.
|
||||||
unbindService(mConnection);
|
unbindService(mConnection);
|
||||||
mIsBound = false;
|
mIsBound = false;
|
||||||
|
|
|
@ -0,0 +1,229 @@
|
||||||
|
package org.torproject.android;
|
||||||
|
|
||||||
|
import org.torproject.android.service.TorService;
|
||||||
|
import org.torproject.android.service.TorServiceUtils;
|
||||||
|
import org.torproject.android.service.TorTransProxy;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
public class Permissions extends Activity implements TorConstants {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
context = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
|
||||||
|
super.onStart();
|
||||||
|
setContentView(R.layout.layout_wizard_permissions);
|
||||||
|
|
||||||
|
stepThree();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stepThree(){
|
||||||
|
|
||||||
|
boolean hasRoot = TorServiceUtils.checkRootAccess();
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
pEdit.putBoolean("has_root",hasRoot);
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
if (hasRoot)
|
||||||
|
{
|
||||||
|
stepFourRoot();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stepFour();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stepFourRoot(){
|
||||||
|
|
||||||
|
String title = context.getString(R.string.wizard_permissions_title);
|
||||||
|
String msg1 = context.getString(R.string.wizard_permissions_root_msg1);
|
||||||
|
String msg2 = context.getString(R.string.wizard_permissions_root_msg2);
|
||||||
|
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
TextView txtBody1 = ((TextView)findViewById(R.id.WizardTextBody1));
|
||||||
|
txtBody1.setText(msg1);
|
||||||
|
|
||||||
|
|
||||||
|
TextView txtBody2 = ((TextView)findViewById(R.id.WizardTextBody2));
|
||||||
|
txtBody2.setText(msg2);
|
||||||
|
txtBody2.setVisibility(TextView.VISIBLE);
|
||||||
|
|
||||||
|
Button grantPermissions = ((Button)findViewById(R.id.grantPermissions));
|
||||||
|
grantPermissions.setVisibility(Button.VISIBLE);
|
||||||
|
|
||||||
|
Button back = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button next = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
next.setEnabled(false);
|
||||||
|
|
||||||
|
CheckBox consent = (CheckBox)findViewById(R.id.checkBox);
|
||||||
|
consent.setVisibility(CheckBox.VISIBLE);
|
||||||
|
|
||||||
|
consent.setOnCheckedChangeListener(new OnCheckedChangeListener (){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
|
boolean isChecked) {
|
||||||
|
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
Editor pEdit = prefs.edit();
|
||||||
|
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT, !isChecked);
|
||||||
|
pEdit.putBoolean(PREF_TRANSPARENT_ALL, !isChecked);
|
||||||
|
|
||||||
|
pEdit.commit();
|
||||||
|
|
||||||
|
Button next = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
if(isChecked)
|
||||||
|
next.setEnabled(true);
|
||||||
|
else
|
||||||
|
next.setEnabled(false);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
grantPermissions.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//Check and Install iptables - TorTransProxy.testOwnerModule(this)
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
boolean hasRoot = prefs.getBoolean("has_root",false);
|
||||||
|
|
||||||
|
if (hasRoot)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
int resp = TorTransProxy.testOwnerModule(context);
|
||||||
|
|
||||||
|
if (resp < 0)
|
||||||
|
{
|
||||||
|
hasRoot = false;
|
||||||
|
Toast.makeText(context, "ERROR: IPTables OWNER module not available", Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
Log.i(TorService.TAG,"ERROR: IPTables OWNER module not available");
|
||||||
|
stepFour();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
hasRoot = false;
|
||||||
|
Log.d(TorService.TAG,"ERROR: IPTables OWNER module not available",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), ConfigureTransProxy.class), 1);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), TipsAndTricks.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stepFour(){
|
||||||
|
|
||||||
|
Toast.makeText(context, "NON ROOT FUNC", Toast.LENGTH_SHORT).show();
|
||||||
|
String title = context.getString(R.string.wizard_permissions_title);
|
||||||
|
String msg = context.getString(R.string.wizard_permissions_msg);
|
||||||
|
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody1));
|
||||||
|
txtBody.setText(msg);
|
||||||
|
|
||||||
|
Button btn1 = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button btn2 = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
btn2.setEnabled(true);
|
||||||
|
|
||||||
|
|
||||||
|
TextView txtBody2 = ((TextView)findViewById(R.id.WizardTextBody2));
|
||||||
|
txtBody2.setVisibility(TextView.GONE);
|
||||||
|
|
||||||
|
Button grantPermissions = ((Button)findViewById(R.id.grantPermissions));
|
||||||
|
grantPermissions.setVisibility(Button.GONE);
|
||||||
|
|
||||||
|
|
||||||
|
CheckBox consent = (CheckBox)findViewById(R.id.checkBox);
|
||||||
|
consent.setVisibility(CheckBox.GONE);
|
||||||
|
|
||||||
|
btn1.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), LotsaText.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btn2.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), TipsAndTricks.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,9 @@ public class SettingsPreferences
|
||||||
|
|
||||||
private boolean hasRoot = false;
|
private boolean hasRoot = false;
|
||||||
|
|
||||||
|
|
||||||
|
private final static int HIDDEN_SERVICE_PREF_IDX = 6;
|
||||||
|
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -77,12 +80,11 @@ public class SettingsPreferences
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hiddenGroupIdx = 6;
|
|
||||||
|
|
||||||
prefHiddenServices = ((CheckBoxPreference)((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(0));
|
prefHiddenServices = ((CheckBoxPreference)((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(0));
|
||||||
prefHiddenServices.setOnPreferenceClickListener(this);
|
prefHiddenServices.setOnPreferenceClickListener(this);
|
||||||
((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
|
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
|
||||||
((PreferenceCategory)this.getPreferenceScreen().getPreference(hiddenGroupIdx)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
|
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -113,8 +115,8 @@ public class SettingsPreferences
|
||||||
else if (preference == prefHiddenServices)
|
else if (preference == prefHiddenServices)
|
||||||
{
|
{
|
||||||
|
|
||||||
((PreferenceCategory)this.getPreferenceScreen().getPreference(5)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
|
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(1).setEnabled(prefHiddenServices.isChecked());
|
||||||
((PreferenceCategory)this.getPreferenceScreen().getPreference(5)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
|
((PreferenceCategory)this.getPreferenceScreen().getPreference(HIDDEN_SERVICE_PREF_IDX)).getPreference(2).setEnabled(prefHiddenServices.isChecked());
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package org.torproject.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class TipsAndTricks extends Activity implements TorConstants {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
context = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
|
||||||
|
super.onStart();
|
||||||
|
setContentView(R.layout.layout_wizard_tips);
|
||||||
|
|
||||||
|
stepFive();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void stepFive(){
|
||||||
|
|
||||||
|
String title = context.getString(R.string.wizard_tips_title);
|
||||||
|
TextView txtTitle = ((TextView)findViewById(R.id.WizardTextTitle));
|
||||||
|
txtTitle.setText(title);
|
||||||
|
|
||||||
|
Button btn1 = (Button)findViewById(R.id.WizardRootButtonInstallGibberbot);
|
||||||
|
|
||||||
|
btn1.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
String url = context.getString(R.string.gibberbot_apk_url);
|
||||||
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button btn2 = (Button)findViewById(R.id.WizardRootButtonInstallFirefox);
|
||||||
|
|
||||||
|
btn2.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
String url = context.getString(R.string.firefox_apk_url);
|
||||||
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button btn3 = (Button)findViewById(R.id.WizardRootButtonInstallProxyMob);
|
||||||
|
|
||||||
|
btn3.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
String url = context.getString(R.string.proxymob_url);
|
||||||
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button back = ((Button)findViewById(R.id.btnWizard1));
|
||||||
|
Button next = ((Button)findViewById(R.id.btnWizard2));
|
||||||
|
|
||||||
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
startActivityForResult(new Intent(getBaseContext(), Permissions.class), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
next.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
showWizardFinal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showWizardFinal ()
|
||||||
|
{
|
||||||
|
String title = null;
|
||||||
|
String msg = null;
|
||||||
|
|
||||||
|
|
||||||
|
title = context.getString(R.string.wizard_final);
|
||||||
|
msg = context.getString(R.string.wizard_final_msg);
|
||||||
|
|
||||||
|
DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
context.startActivity(new Intent(context, Orbot.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setIcon(R.drawable.icon)
|
||||||
|
.setTitle(title)
|
||||||
|
.setPositiveButton(R.string.button_close, ocListener)
|
||||||
|
.setMessage(msg)
|
||||||
|
.show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,71 +0,0 @@
|
||||||
package org.torproject.android;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
public class WizardActivity extends Activity implements OnClickListener
|
|
||||||
{
|
|
||||||
|
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
|
|
||||||
this.setContentView(R.layout.layout_help);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
showStep1();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void showStep1()
|
|
||||||
{
|
|
||||||
showDialog("Test","","foo","bar",this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showDialog (String title, String msg, String button1, String button2, OnClickListener ocListener)
|
|
||||||
{
|
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.setInverseBackgroundForced(true)
|
|
||||||
.setTitle(title)
|
|
||||||
.setMessage(msg)
|
|
||||||
.setNeutralButton(button1, ocListener)
|
|
||||||
.setNegativeButton(button2, ocListener)
|
|
||||||
.show();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface arg0, int arg1) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -215,7 +215,7 @@ public class WizardHelper implements TorConstants {
|
||||||
LayoutInflater li = LayoutInflater.from(context);
|
LayoutInflater li = LayoutInflater.from(context);
|
||||||
View view = li.inflate(R.layout.layout_wizard_tips, null);
|
View view = li.inflate(R.layout.layout_wizard_tips, null);
|
||||||
|
|
||||||
Button btn1 = (Button)view.findViewById(R.id.WizardRootButtonInstallOtrchat);
|
Button btn1 = (Button)view.findViewById(R.id.WizardRootButtonInstallGibberbot);
|
||||||
|
|
||||||
btn1.setOnClickListener(new OnClickListener() {
|
btn1.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ public class WizardHelper implements TorConstants {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Button btn2 = (Button)view.findViewById(R.id.WizardRootButtonInstallOrweb);
|
Button btn2 = (Button)view.findViewById(R.id.WizardRootButtonInstallFirefox);
|
||||||
|
|
||||||
btn2.setOnClickListener(new OnClickListener() {
|
btn2.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ public class WizardHelper implements TorConstants {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Button btn3 = (Button)view.findViewById(R.id.WizardRootButtonProxyHelp);
|
Button btn3 = (Button)view.findViewById(R.id.WizardRootButtonInstallProxyMob);
|
||||||
|
|
||||||
btn3.setOnClickListener(new OnClickListener() {
|
btn3.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ public class WizardHelper implements TorConstants {
|
||||||
|
|
||||||
public void showWizardRootConfigureTorification()
|
public void showWizardRootConfigureTorification()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
LayoutInflater li = LayoutInflater.from(context);
|
LayoutInflater li = LayoutInflater.from(context);
|
||||||
View view = li.inflate(R.layout.layout_wizard_root, null);
|
View view = li.inflate(R.layout.layout_wizard_root, null);
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ public class WizardHelper implements TorConstants {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package org.torproject.android.boot;
|
|
||||||
|
|
||||||
import org.torproject.android.service.ITorService;
|
|
||||||
import org.torproject.android.service.TorService;
|
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class OnbootBroadcastReceiver extends BroadcastReceiver implements TorServiceConstants {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
|
|
||||||
Log.d(TAG, "received on boot notification");
|
|
||||||
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
|
|
||||||
boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
|
|
||||||
|
|
||||||
Log.d(TAG, "startOnBoot:" + startOnBoot);
|
|
||||||
|
|
||||||
if (startOnBoot)
|
|
||||||
{
|
|
||||||
Intent serviceIntent = new Intent(context,TorService.class);
|
|
||||||
serviceIntent.setAction("onboot");
|
|
||||||
context.startService(serviceIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//bindService(new Intent(ITorService.class.getName()),
|
|
||||||
// mConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -55,7 +55,7 @@ import android.widget.Toast;
|
||||||
* Contains shared programming interfaces.
|
* Contains shared programming interfaces.
|
||||||
* All iptables "communication" is handled by this class.
|
* All iptables "communication" is handled by this class.
|
||||||
*/
|
*/
|
||||||
public final class Api {
|
public final class IptablesManager {
|
||||||
/** application version string */
|
/** application version string */
|
||||||
public static final String VERSION = "1.5.1-dev";
|
public static final String VERSION = "1.5.1-dev";
|
||||||
/** special application UID used to indicate "any application" */
|
/** special application UID used to indicate "any application" */
|
||||||
|
@ -861,8 +861,8 @@ public final class Api {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* notify */
|
/* notify */
|
||||||
final Intent message = new Intent(Api.STATUS_CHANGED_MSG);
|
final Intent message = new Intent(IptablesManager.STATUS_CHANGED_MSG);
|
||||||
message.putExtra(Api.STATUS_EXTRA, enabled);
|
message.putExtra(IptablesManager.STATUS_EXTRA, enabled);
|
||||||
ctx.sendBroadcast(message);
|
ctx.sendBroadcast(message);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
|
@ -20,138 +20,75 @@ import android.util.Log;
|
||||||
public class TorBinaryInstaller implements TorServiceConstants {
|
public class TorBinaryInstaller implements TorServiceConstants {
|
||||||
|
|
||||||
|
|
||||||
String installPath;
|
File installFolder;
|
||||||
String apkPath;
|
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
public TorBinaryInstaller (Context context, String installPath, String apkPath)
|
public TorBinaryInstaller (Context context, File installFolder)
|
||||||
{
|
{
|
||||||
this.installPath = installPath;
|
this.installFolder = installFolder;
|
||||||
this.apkPath = apkPath;
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the binary installation if the file doesn't exist or is forced
|
|
||||||
*/
|
|
||||||
public void start (boolean force)
|
|
||||||
{
|
|
||||||
|
|
||||||
boolean torBinaryExists = new File(installPath + TOR_BINARY_ASSET_KEY).exists();
|
|
||||||
Log.d(TAG,"Tor binary exists=" + torBinaryExists);
|
|
||||||
|
|
||||||
boolean privoxyBinaryExists = new File(installPath + PRIVOXY_ASSET_KEY).exists();
|
|
||||||
Log.d(TAG,"Privoxy binary exists=" + privoxyBinaryExists);
|
|
||||||
|
|
||||||
if (!(torBinaryExists && privoxyBinaryExists) || force)
|
|
||||||
installFromRaw ();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
/*
|
/*
|
||||||
* Extract the Tor binary from the APK file using ZIP
|
* Extract the Tor binary from the APK file using ZIP
|
||||||
*/
|
*/
|
||||||
private void installFromRaw ()
|
public boolean installFromRaw ()
|
||||||
{
|
{
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
|
||||||
InputStream is = context.getResources().openRawResource(R.raw.tor);
|
|
||||||
streamToFile(is,installPath + TOR_BINARY_ASSET_KEY);
|
|
||||||
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.torrc);
|
|
||||||
streamToFile(is,installPath + TORRC_ASSET_KEY);
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.privoxy);
|
|
||||||
streamToFile(is,installPath + PRIVOXY_ASSET_KEY);
|
|
||||||
|
|
||||||
is = context.getResources().openRawResource(R.raw.privoxy_config);
|
|
||||||
streamToFile(is,installPath + PRIVOXYCONFIG_ASSET_KEY);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Log.d(TAG,"SUCCESS: installed tor, privoxy binaries from raw");
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Extract the Tor binary from the APK file using ZIP
|
|
||||||
*/
|
|
||||||
private void installFromZip ()
|
|
||||||
{
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
InputStream is;
|
||||||
|
|
||||||
ZipFile zip = new ZipFile(apkPath);
|
is = context.getResources().openRawResource(R.raw.toraa);
|
||||||
|
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, false);
|
||||||
|
|
||||||
ZipEntry zipen = zip.getEntry(ASSETS_BASE + TOR_BINARY_ASSET_KEY);
|
is = context.getResources().openRawResource(R.raw.torab);
|
||||||
streamToFile(zip.getInputStream(zipen),installPath + TOR_BINARY_ASSET_KEY);
|
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
|
||||||
|
|
||||||
zipen = zip.getEntry(ASSETS_BASE + TORRC_ASSET_KEY);
|
is = context.getResources().openRawResource(R.raw.torac);
|
||||||
streamToFile(zip.getInputStream(zipen),installPath + TORRC_ASSET_KEY);
|
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
|
||||||
|
|
||||||
zipen = zip.getEntry(ASSETS_BASE + PRIVOXY_ASSET_KEY);
|
is = context.getResources().openRawResource(R.raw.torad);
|
||||||
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXY_ASSET_KEY);
|
streamToFile(is,installFolder, TOR_BINARY_ASSET_KEY, true);
|
||||||
|
|
||||||
zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
|
is = context.getResources().openRawResource(R.raw.torrc);
|
||||||
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
|
streamToFile(is,installFolder, TORRC_ASSET_KEY, false);
|
||||||
|
|
||||||
zipen = zip.getEntry(ASSETS_BASE + PRIVOXYCONFIG_ASSET_KEY);
|
is = context.getResources().openRawResource(R.raw.privoxy);
|
||||||
streamToFile(zip.getInputStream(zipen),installPath + PRIVOXYCONFIG_ASSET_KEY);
|
streamToFile(is,installFolder, PRIVOXY_ASSET_KEY, false);
|
||||||
|
|
||||||
|
is = context.getResources().openRawResource(R.raw.privoxy_config);
|
||||||
zip.close();
|
streamToFile(is,installFolder, PRIVOXYCONFIG_ASSET_KEY, false);
|
||||||
|
|
||||||
Log.d(TAG,"SUCCESS: unzipped tor, privoxy, iptables binaries from apk");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe)
|
||||||
{
|
{
|
||||||
Log.d(TAG,"FAIL: unable to unzip binaries from apk",ioe);
|
Log.e(TAG, "unable to install tor binaries from raw", ioe);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the inputstream contents to the file
|
* Write the inputstream contents to the file
|
||||||
*/
|
*/
|
||||||
private static void streamToFile(InputStream stm, String targetFilename)
|
private static boolean streamToFile(InputStream stm, File folder, String targetFilename, boolean append) throws IOException
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
FileOutputStream stmOut = null;
|
|
||||||
|
|
||||||
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
|
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
|
||||||
|
|
||||||
int bytecount;
|
int bytecount;
|
||||||
|
|
||||||
|
File outFile = new File(folder, targetFilename);
|
||||||
|
|
||||||
File outFile = new File(targetFilename);
|
FileOutputStream stmOut = new FileOutputStream(outFile, append);
|
||||||
|
|
||||||
try {
|
|
||||||
outFile.createNewFile();
|
|
||||||
|
|
||||||
stmOut = new FileOutputStream(outFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (java.io.IOException e)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
Log.d(TAG,"Error opening output file " + targetFilename,e);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
while ((bytecount = stm.read(buffer)) > 0)
|
while ((bytecount = stm.read(buffer)) > 0)
|
||||||
|
|
||||||
|
@ -163,17 +100,8 @@ public class TorBinaryInstaller implements TorServiceConstants {
|
||||||
|
|
||||||
stmOut.close();
|
stmOut.close();
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (java.io.IOException e)
|
return true;
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
Log.d(TAG,"Error writing output file '" + targetFilename + "': " + e.toString());
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
/* Copyright (c) 2009-2011, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
package org.torproject.android.service;
|
package org.torproject.android.service;
|
||||||
|
|
||||||
|
@ -60,16 +60,13 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
private ArrayList<String> resetBuffer = null;
|
private ArrayList<String> resetBuffer = null;
|
||||||
|
|
||||||
|
|
||||||
private String appHome;
|
// private String appHome;
|
||||||
private String appBinHome;
|
private File appBinHome;
|
||||||
private String appDataHome;
|
private File appDataHome;
|
||||||
|
|
||||||
private String torBinaryPath;
|
private String torBinaryPath;
|
||||||
private String privoxyPath;
|
private String privoxyPath;
|
||||||
|
|
||||||
|
|
||||||
private boolean hasRoot = false;
|
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -416,43 +413,37 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
private boolean checkTorBinaries () throws Exception
|
private boolean checkTorBinaries () throws Exception
|
||||||
{
|
{
|
||||||
//android.os.Debug.waitForDebugger();
|
|
||||||
|
|
||||||
//check and install iptables
|
//check and install iptables
|
||||||
Api.assertBinaries(this, true);
|
IptablesManager.assertBinaries(this, true);
|
||||||
|
|
||||||
File fileInstall = getDir("",0);
|
|
||||||
String subBinPath = "bin/";
|
|
||||||
|
|
||||||
appHome = fileInstall.getAbsolutePath();
|
appBinHome = getDir("bin",0);
|
||||||
appBinHome = appHome + subBinPath;
|
appDataHome = getCacheDir();
|
||||||
appDataHome = getCacheDir().getAbsolutePath() + '/';
|
|
||||||
logNotice( "appHome=" + appHome);
|
// logNotice( "appHome=" + appHome);
|
||||||
|
|
||||||
|
File fileTor = new File(appBinHome, TOR_BINARY_ASSET_KEY);
|
||||||
|
File filePrivoxy = new File(appBinHome, PRIVOXY_ASSET_KEY);
|
||||||
|
|
||||||
torBinaryPath = appBinHome + TOR_BINARY_ASSET_KEY;
|
|
||||||
privoxyPath = appBinHome + PRIVOXY_ASSET_KEY;
|
|
||||||
|
|
||||||
logNotice( "checking Tor binaries");
|
logNotice( "checking Tor binaries");
|
||||||
|
|
||||||
boolean torBinaryExists = new File(torBinaryPath).exists();
|
if (!(fileTor.exists() && filePrivoxy.exists()))
|
||||||
boolean privoxyBinaryExists = new File(privoxyPath).exists();
|
|
||||||
|
|
||||||
if (!(torBinaryExists && privoxyBinaryExists))
|
|
||||||
{
|
{
|
||||||
killTorProcess ();
|
killTorProcess ();
|
||||||
|
|
||||||
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome, appBinHome);
|
TorBinaryInstaller installer = new TorBinaryInstaller(this, appBinHome);
|
||||||
installer.start(true);
|
boolean success = installer.installFromRaw();
|
||||||
|
|
||||||
torBinaryExists = new File(torBinaryPath).exists();
|
if (success)
|
||||||
privoxyBinaryExists = new File(privoxyPath).exists();
|
|
||||||
|
|
||||||
if (torBinaryExists && privoxyBinaryExists)
|
|
||||||
{
|
{
|
||||||
logNotice(getString(R.string.status_install_success));
|
logNotice(getString(R.string.status_install_success));
|
||||||
|
|
||||||
showToolbarNotification(getString(R.string.status_install_success), NOTIFY_ID, R.drawable.tornotification);
|
showToolbarNotification(getString(R.string.status_install_success), NOTIFY_ID, R.drawable.tornotification);
|
||||||
|
|
||||||
|
|
||||||
|
torBinaryPath = fileTor.getAbsolutePath();
|
||||||
|
privoxyPath = filePrivoxy.getAbsolutePath();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -470,6 +461,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
logNotice("Found Tor binary: " + torBinaryPath);
|
logNotice("Found Tor binary: " + torBinaryPath);
|
||||||
logNotice("Found Privoxy binary: " + privoxyPath);
|
logNotice("Found Privoxy binary: " + privoxyPath);
|
||||||
|
|
||||||
|
|
||||||
|
torBinaryPath = fileTor.getAbsolutePath();
|
||||||
|
privoxyPath = filePrivoxy.getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder log = new StringBuilder ();
|
StringBuilder log = new StringBuilder ();
|
||||||
|
@ -545,6 +539,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
|
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
|
||||||
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
|
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
|
||||||
boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
|
boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
|
||||||
|
boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false);
|
||||||
|
|
||||||
TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
|
TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
|
||||||
|
|
||||||
|
@ -581,6 +576,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
showAlert("Status", "Setting up app-based transparent proxying...");
|
showAlert("Status", "Setting up app-based transparent proxying...");
|
||||||
code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this));
|
code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TorService.logMessage ("TorTransProxy resp code: " + code);
|
TorService.logMessage ("TorTransProxy resp code: " + code);
|
||||||
|
@ -588,12 +584,23 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
if (code == 0)
|
if (code == 0)
|
||||||
{
|
{
|
||||||
showAlert("Status", "Transparent proxying ENABLED");
|
showAlert("Status", "Transparent proxying ENABLED");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (transProxyTethering)
|
||||||
|
{
|
||||||
|
showAlert("Status", "TransProxy enabled for Tethering!");
|
||||||
|
|
||||||
|
TorTransProxy.enableTetheringRules(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
showAlert("Status", "WARNING: error starting transparent proxying!");
|
showAlert("Status", "WARNING: error starting transparent proxying!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -618,9 +625,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
StringBuilder log = new StringBuilder();
|
StringBuilder log = new StringBuilder();
|
||||||
|
|
||||||
String torrcPath = appBinHome + TORRC_ASSET_KEY;
|
String torrcPath = new File(appBinHome, TORRC_ASSET_KEY).getAbsolutePath();
|
||||||
|
|
||||||
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome + " -f " + torrcPath + " || exit\n"};
|
String[] torCmd = {torBinaryPath + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + torrcPath + " || exit\n"};
|
||||||
|
|
||||||
boolean runAsRootFalse = false;
|
boolean runAsRootFalse = false;
|
||||||
boolean waitForProcess = false;
|
boolean waitForProcess = false;
|
||||||
|
@ -688,7 +695,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
{
|
{
|
||||||
log = new StringBuilder();
|
log = new StringBuilder();
|
||||||
|
|
||||||
String privoxyConfigPath = appBinHome + PRIVOXYCONFIG_ASSET_KEY;
|
String privoxyConfigPath = new File(appBinHome, PRIVOXYCONFIG_ASSET_KEY).getAbsolutePath();
|
||||||
|
|
||||||
String[] cmds =
|
String[] cmds =
|
||||||
{ privoxyPath + " " + privoxyConfigPath + " &" };
|
{ privoxyPath + " " + privoxyConfigPath + " &" };
|
||||||
|
@ -753,7 +760,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
logNotice( "SUCCESS connected to control port");
|
logNotice( "SUCCESS connected to control port");
|
||||||
|
|
||||||
String torAuthCookie = appDataHome + TOR_CONTROL_COOKIE;
|
String torAuthCookie = new File(appDataHome, TOR_CONTROL_COOKIE).getAbsolutePath();
|
||||||
|
|
||||||
File fileCookie = new File(torAuthCookie);
|
File fileCookie = new File(torAuthCookie);
|
||||||
|
|
||||||
|
@ -1137,18 +1144,12 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
if (value == null || value.length() == 0)
|
if (value == null || value.length() == 0)
|
||||||
{
|
{
|
||||||
resetBuffer.add(name);
|
resetBuffer.add(name);
|
||||||
/*
|
|
||||||
if (conn != null)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
conn.resetConf(Arrays.asList(new String[]{name}));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(TAG, "Unable to reset conf",e);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
configBuffer.add(name + ' ' + value);
|
configBuffer.add(name + ' ' + value);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1290,12 +1291,9 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
boolean enableHiddenServices = prefs.getBoolean("pref_hs_enable", false);
|
||||||
|
|
||||||
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false);
|
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false);
|
||||||
String entranceNodes = prefs.getString("pref_entrance_nodes", "");
|
String entranceNodes = prefs.getString("pref_entrance_nodes", null);
|
||||||
String exitNodes = prefs.getString("pref_exit_nodes", "");
|
String exitNodes = prefs.getString("pref_exit_nodes", null);
|
||||||
String excludeNodes = prefs.getString("pref_exclude_nodes", "");
|
String excludeNodes = prefs.getString("pref_exclude_nodes", null);
|
||||||
|
|
||||||
|
|
||||||
//boolean enableTransparentProxy = prefs.getBoolean(TorConstants.PREF_TRANSPARENT, false);
|
|
||||||
|
|
||||||
if (currentStatus == STATUS_ON)
|
if (currentStatus == STATUS_ON)
|
||||||
{
|
{
|
||||||
|
@ -1311,10 +1309,10 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinder.updateConfiguration("EntranceNodes", entranceNodes, false);
|
mBinder.updateConfiguration("EntryNodes", entranceNodes, false);
|
||||||
mBinder.updateConfiguration("ExitNodes", exitNodes, false);
|
mBinder.updateConfiguration("ExitNodes", exitNodes, false);
|
||||||
mBinder.updateConfiguration("ExcludeNodes", excludeNodes, false);
|
mBinder.updateConfiguration("ExcludeNodes", excludeNodes, false);
|
||||||
mBinder.updateConfiguration("StrictExitNodes", enableStrictNodes ? "1" : "0", false);
|
mBinder.updateConfiguration("StrictNodes", enableStrictNodes ? "1" : "0", false);
|
||||||
|
|
||||||
if (useBridges)
|
if (useBridges)
|
||||||
{
|
{
|
||||||
|
@ -1407,7 +1405,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
|
||||||
|
|
||||||
if (enableHiddenServices)
|
if (enableHiddenServices)
|
||||||
{
|
{
|
||||||
mBinder.updateConfiguration("HiddenServiceDir",appDataHome, false);
|
mBinder.updateConfiguration("HiddenServiceDir",appDataHome.getAbsolutePath(), false);
|
||||||
|
|
||||||
String hsPorts = prefs.getString("pref_hs_ports","");
|
String hsPorts = prefs.getString("pref_hs_ports","");
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,11 @@ public class TorServiceUtils implements TorServiceConstants {
|
||||||
* Check if we have root access
|
* Check if we have root access
|
||||||
* @return boolean true if we have root
|
* @return boolean true if we have root
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
public static boolean checkRootAccess() {
|
public static boolean checkRootAccess() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StringBuilder log = new StringBuilder();
|
StringBuilder log = new StringBuilder();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -45,7 +47,40 @@ public class TorServiceUtils implements TorServiceConstants {
|
||||||
TorService.logMessage("Could not acquire root permissions");
|
TorService.logMessage("Could not acquire root permissions");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static boolean checkRootAccess(){
|
||||||
|
|
||||||
|
StringBuilder log = new StringBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Check if Superuser.apk exists
|
||||||
|
File file = new File("/system/app/Superuser.apk");
|
||||||
|
|
||||||
|
//Check for 'su' binary
|
||||||
|
String[] cmd = {"which su"};
|
||||||
|
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
|
||||||
|
|
||||||
|
if (file.exists() && exitCode == 0) {
|
||||||
|
TorService.logMessage("Can acquire root permissions");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
//this means that there is no root to be had (normally) so we won't log anything
|
||||||
|
TorService.logException("Error checking for root access",e);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
TorService.logException("Error checking for root access",e);
|
||||||
|
//this means that there is no root to be had (normally)
|
||||||
|
}
|
||||||
|
|
||||||
|
TorService.logMessage("Could not acquire root permissions");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int findProcessId(String command)
|
public static int findProcessId(String command)
|
||||||
|
|
|
@ -313,14 +313,12 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int enableWifiHotspotRules (Context context) throws Exception
|
public static int enableTetheringRules (Context context) throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
boolean runRoot = true;
|
boolean runRoot = true;
|
||||||
boolean waitFor = true;
|
boolean waitFor = true;
|
||||||
|
|
||||||
//redirectDNSResolvConf(); //not working yet
|
|
||||||
|
|
||||||
String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
|
String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
|
||||||
|
|
||||||
StringBuilder script = new StringBuilder();
|
StringBuilder script = new StringBuilder();
|
||||||
|
@ -328,25 +326,24 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
int code = -1;
|
int code = -1;
|
||||||
|
|
||||||
|
String[] hwinterfaces = {"usb0","wl0.1"};
|
||||||
|
|
||||||
|
for (int i = 0; i < hwinterfaces.length; i++)
|
||||||
|
{
|
||||||
script.append(ipTablesPath);
|
script.append(ipTablesPath);
|
||||||
script.append(" -I FORWARD");
|
script.append(" -t nat -A PREROUTING -i ");
|
||||||
script.append(" -m state --state ESTABLISHED,RELATED -j ACCEPT");
|
script.append(hwinterfaces[i]);
|
||||||
|
script.append(" -p udp --dport 53 -j REDIRECT --to-ports ");
|
||||||
|
script.append(TOR_DNS_PORT);
|
||||||
script.append(" || exit\n");
|
script.append(" || exit\n");
|
||||||
|
|
||||||
script.append(ipTablesPath);
|
script.append(ipTablesPath);
|
||||||
script.append(" -I FORWARD");
|
script.append(" -t nat -A PREROUTING -i ");
|
||||||
script.append(" -j ACCEPT");
|
script.append(hwinterfaces[i]);
|
||||||
script.append(" || exit\n");
|
script.append(" -p tcp -j REDIRECT --to-ports ");
|
||||||
|
script.append(TOR_TRANSPROXY_PORT);
|
||||||
/*
|
|
||||||
script.append(ipTablesPath);
|
|
||||||
script.append(" -P FORWARD DROP");
|
|
||||||
script.append(" || exit\n");
|
|
||||||
*/
|
|
||||||
|
|
||||||
script.append(ipTablesPath);
|
|
||||||
script.append(" -t nat -I POSTROUTING -j MASQUERADE");
|
|
||||||
script.append(" || exit\n");
|
script.append(" || exit\n");
|
||||||
|
}
|
||||||
|
|
||||||
String[] cmdAdd = {script.toString()};
|
String[] cmdAdd = {script.toString()};
|
||||||
|
|
||||||
|
@ -374,8 +371,6 @@ public class TorTransProxy implements TorServiceConstants {
|
||||||
|
|
||||||
purgeIptables(context);
|
purgeIptables(context);
|
||||||
|
|
||||||
enableWifiHotspotRules(context);
|
|
||||||
|
|
||||||
int torUid = context.getApplicationInfo().uid;
|
int torUid = context.getApplicationInfo().uid;
|
||||||
|
|
||||||
// Set up port redirection
|
// Set up port redirection
|
||||||
|
|
Loading…
Reference in New Issue