|
@ -1,3 +1,47 @@
|
||||||
|
# auto-generated files from Android builds
|
||||||
|
build.xml
|
||||||
|
ant.properties
|
||||||
|
default.properties
|
||||||
|
proguard.cfg
|
||||||
|
proguard-project.txt
|
||||||
|
#
|
||||||
|
releases
|
||||||
|
docs
|
||||||
|
doc
|
||||||
|
.directory
|
||||||
|
|
||||||
|
#built application files
|
||||||
|
*.apk
|
||||||
|
*.ap_
|
||||||
|
|
||||||
|
# files for the dex VM
|
||||||
|
*.dex
|
||||||
|
|
||||||
|
# Java class files
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# subdirs for generated files
|
||||||
|
bin/
|
||||||
|
gen/
|
||||||
|
|
||||||
|
# Local configuration file (sdk path, etc)
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Windows thumbnail db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# OSX files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Android Studio
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
|
||||||
|
#tfx
|
||||||
|
.transifexrc
|
||||||
|
|
||||||
/external/appcompat/bin/
|
/external/appcompat/bin/
|
||||||
/external/appcompat/gen/
|
/external/appcompat/gen/
|
||||||
/external/bin/
|
/external/bin/
|
||||||
|
@ -14,17 +58,11 @@ native
|
||||||
libs/jtorctl.jar
|
libs/jtorctl.jar
|
||||||
local.properties
|
local.properties
|
||||||
builds
|
builds
|
||||||
/patches/*
|
external/patches/*
|
||||||
obj
|
obj
|
||||||
releases
|
|
||||||
.transifexrc
|
|
||||||
|
|
||||||
# native build products
|
|
||||||
*.so
|
|
||||||
pdnsd
|
|
||||||
*.mp3
|
|
||||||
|
|
||||||
# ant build products
|
app/src/main/jniLibs/
|
||||||
build.xml
|
app/src/main/libs/
|
||||||
proguard-project.txt
|
orbotservice/src/main/libs/
|
||||||
ant.properties
|
orbotservice/src/main/assets/armeabi/
|
||||||
|
|
|
@ -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"
|
package="org.torproject.android"
|
||||||
android:versionName="15.1.3-beta"
|
android:versionName="15.2.0-alpha-1"
|
||||||
android:versionCode="15130000"
|
android:versionCode="15200001"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
>
|
>
|
||||||
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23"/>
|
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23"/>
|
||||||
<!--
|
<!--
|
||||||
<permission android:name="org.torproject.android.MANAGE_TOR"
|
<permission android:name="org.torproject.android.MANAGE_TOR"
|
||||||
android:label="@string/permission_manage_tor_label"
|
android:label="@string/permission_manage_tor_label"
|
||||||
|
@ -103,7 +103,7 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name="org.torproject.android.service.OnBootReceiver"
|
<receiver android:name="org.torproject.android.OnBootReceiver"
|
||||||
android:enabled="true" android:exported="true"
|
android:enabled="true" android:exported="true"
|
||||||
|
|
||||||
>
|
>
|
||||||
|
|
34
BUILD
|
@ -47,45 +47,15 @@ that will handle basic Tor controlling features.
|
||||||
|
|
||||||
android update project --name Orbot --target android-15 --path .
|
android update project --name Orbot --target android-15 --path .
|
||||||
|
|
||||||
Now you need to split and copy the tor binary into external/bin. We split it
|
|
||||||
into < 1M chunks because some Android devices don't like resources larger than
|
|
||||||
1M.
|
|
||||||
split --bytes=1m ./external/tor/src/or/tor ./external/bin/tor
|
|
||||||
|
|
||||||
Now build the Android app
|
Now build the Android app
|
||||||
|
|
||||||
./setup-ant
|
(gradle / android studio instructions here)
|
||||||
ant release
|
|
||||||
|
|
||||||
This will produce an unsigned Tor package in ./bin/Orbot-unsigned.apk!
|
This will produce an unsigned Tor package APK.
|
||||||
|
|
||||||
To produce a usable package, you'll need to sign the .apk. The basics on
|
To produce a usable package, you'll need to sign the .apk. The basics on
|
||||||
signing can be found on the Android developer site:
|
signing can be found on the Android developer site:
|
||||||
|
|
||||||
http://developer.android.com/guide/publishing/app-signing.html
|
http://developer.android.com/guide/publishing/app-signing.html
|
||||||
|
|
||||||
The three steps are quite simple. First, you'll generate a key. Secondly,
|
|
||||||
you'll sign the application. Thirdly, you'll verify the the apk.
|
|
||||||
|
|
||||||
Generating a signing key:
|
|
||||||
|
|
||||||
keytool -genkey -v -keystore my-release-key.keystore \
|
|
||||||
-alias orbots_key -keyalg RSA -validity 10000
|
|
||||||
|
|
||||||
Sign the apk:
|
|
||||||
|
|
||||||
jarsigner -verbose -keystore my-release-key.keystore \
|
|
||||||
bin/Orbot-unsigned.apk orbots_key
|
|
||||||
|
|
||||||
Verify the signature for the apk:
|
|
||||||
|
|
||||||
jarsigner -verify bin/Orbot-unsigned.apk
|
|
||||||
mv bin/Orbot-unsigned.apk bin/Orbot-signed-alpha.apk
|
|
||||||
|
|
||||||
You can also GPG sign the apk and generate an .asc:
|
|
||||||
|
|
||||||
gpg -ab Orbot-signed-alpha.apk
|
|
||||||
|
|
||||||
Now you should have a fully signed and production ready alpha release of Orbot!
|
|
||||||
Give bin/Orbot-signed-alpha.apk an install and send us bug reports!
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.2"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "org.torproject.android"
|
||||||
|
minSdkVersion 9
|
||||||
|
targetSdkVersion 23
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(':orbotservice')
|
||||||
|
compile 'com.android.support:support-v4:23.4.0'
|
||||||
|
compile 'com.android.support:appcompat-v7:23.4.0'
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.torproject.android"
|
||||||
|
android:versionName="15.2.0-alpha-1"
|
||||||
|
android:versionCode="15200001"
|
||||||
|
android:installLocation="auto"
|
||||||
|
>
|
||||||
|
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23"/>
|
||||||
|
<!--
|
||||||
|
<permission android:name="org.torproject.android.MANAGE_TOR"
|
||||||
|
android:label="@string/permission_manage_tor_label"
|
||||||
|
android:description="@string/permission_manage_tor_description"
|
||||||
|
android:protectionLevel="signature"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="org.torproject.android.MANAGE_TOR"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
||||||
|
<application android:name="org.torproject.android.OrbotApp" android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:description="@string/app_description"
|
||||||
|
android:configChanges="locale|orientation|screenSize"
|
||||||
|
android:theme="@style/DefaultTheme"
|
||||||
|
android:allowBackup="false"
|
||||||
|
android:allowClearUserData="true"
|
||||||
|
android:persistent="true"
|
||||||
|
android:stopWithTask="false"
|
||||||
|
android:largeHeap="false"
|
||||||
|
>
|
||||||
|
|
||||||
|
<activity android:name=".OrbotMainActivity"
|
||||||
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="bridge" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<action android:name="org.torproject.android.REQUEST_HS_PORT" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<action android:name="org.torproject.android.START_TOR" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This is for ensuring the background service still runs when/if the app is swiped away
|
||||||
|
-->
|
||||||
|
<activity
|
||||||
|
android:name=".service.util.DummyActivity"
|
||||||
|
android:theme="@android:style/Theme.Translucent"
|
||||||
|
android:enabled="true"
|
||||||
|
android:allowTaskReparenting="true"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:alwaysRetainTaskState="false"
|
||||||
|
android:stateNotNeeded="true"
|
||||||
|
android:clearTaskOnLaunch="true"
|
||||||
|
android:finishOnTaskLaunch="true"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".vpn.VPNEnableActivity" android:label="@string/app_name" android:exported="false"
|
||||||
|
android:theme="@android:style/Theme.Translucent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name="org.torproject.android.ui.PromoAppsActivity" android:exported="false"/>
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name=".settings.SettingsPreferences" android:label="@string/app_name"/>
|
||||||
|
<activity android:name=".ui.AppManager" android:label="@string/app_name"/>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".service.TorService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:permission="android.permission.BIND_VPN_SERVICE"
|
||||||
|
android:stopWithTask="false" >
|
||||||
|
</service>
|
||||||
|
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".service.vpn.TorVpnService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:permission="android.permission.BIND_VPN_SERVICE" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.net.VpnService"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name=".service.StartTorReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.torproject.android.intent.action.START" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".OnBootReceiver"
|
||||||
|
android:enabled="true" android:exported="true"
|
||||||
|
|
||||||
|
>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
|
<category android:name="android.intent.category.HOME" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||||
|
<category android:name="android.intent.category.HOME" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
|
||||||
|
<category android:name="android.intent.category.HOME" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</manifest>
|
|
@ -1,26 +1,30 @@
|
||||||
package org.torproject.android.service;
|
package org.torproject.android;
|
||||||
|
|
||||||
|
|
||||||
import org.torproject.android.Prefs;
|
|
||||||
import org.torproject.android.vpn.VPNEnableActivity;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import org.torproject.android.service.util.Prefs;
|
||||||
|
import org.torproject.android.service.TorService;
|
||||||
|
import org.torproject.android.service.TorServiceConstants;
|
||||||
|
import org.torproject.android.vpn.VPNEnableActivity;
|
||||||
|
|
||||||
public class OnBootReceiver extends BroadcastReceiver {
|
public class OnBootReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
private static boolean sReceivedBoot = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Prefs.setContext(context);
|
|
||||||
if (Prefs.startOnBoot())
|
|
||||||
{
|
|
||||||
|
|
||||||
|
if (Prefs.startOnBoot() && (!sReceivedBoot))
|
||||||
|
{
|
||||||
if (Prefs.useVpn())
|
if (Prefs.useVpn())
|
||||||
startVpnService(context); //VPN will start Tor once it is done
|
startVpnService(context); //VPN will start Tor once it is done
|
||||||
else
|
else
|
||||||
startService(TorServiceConstants.ACTION_START, context);
|
startService(TorServiceConstants.ACTION_START, context);
|
||||||
|
|
||||||
|
sReceivedBoot = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,15 @@ import android.app.Activity;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.net.VpnService;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
import org.torproject.android.service.OrbotConstants;
|
||||||
|
import org.torproject.android.service.util.Prefs;
|
||||||
|
|
||||||
import info.guardianproject.util.Languages;
|
import org.torproject.android.settings.Languages;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class OrbotApp extends Application implements OrbotConstants
|
public class OrbotApp extends Application implements OrbotConstants
|
||||||
|
@ -22,18 +22,6 @@ public class OrbotApp extends Application implements OrbotConstants
|
||||||
|
|
||||||
private Locale locale;
|
private Locale locale;
|
||||||
|
|
||||||
public static File appBinHome;
|
|
||||||
public static File appCacheHome;
|
|
||||||
|
|
||||||
public static File fileTor;
|
|
||||||
public static File filePolipo;
|
|
||||||
public static File fileObfsclient;
|
|
||||||
// public static File fileMeekclient;
|
|
||||||
public static File fileXtables;
|
|
||||||
public static File fileTorRc;
|
|
||||||
public static File filePdnsd;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -42,16 +30,6 @@ public class OrbotApp extends Application implements OrbotConstants
|
||||||
Languages.setup(OrbotMainActivity.class, R.string.menu_settings);
|
Languages.setup(OrbotMainActivity.class, R.string.menu_settings);
|
||||||
Languages.setLanguage(this, Prefs.getDefaultLocale(), true);
|
Languages.setLanguage(this, Prefs.getDefaultLocale(), true);
|
||||||
|
|
||||||
appBinHome = getDir(TorServiceConstants.DIRECTORY_TOR_BINARY,Application.MODE_PRIVATE);
|
|
||||||
appCacheHome = getDir(TorServiceConstants.DIRECTORY_TOR_DATA,Application.MODE_PRIVATE);
|
|
||||||
|
|
||||||
fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
|
|
||||||
filePolipo = new File(appBinHome, TorServiceConstants.POLIPO_ASSET_KEY);
|
|
||||||
fileObfsclient = new File(appBinHome, TorServiceConstants.OBFSCLIENT_ASSET_KEY);
|
|
||||||
fileXtables = new File(appBinHome, TorServiceConstants.IPTABLES_ASSET_KEY);
|
|
||||||
fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY);
|
|
||||||
filePdnsd = new File(appBinHome, TorServiceConstants.PDNSD_ASSET_KEY);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
package org.torproject.android;
|
package org.torproject.android;
|
||||||
|
|
||||||
import static org.torproject.android.OrbotConstants.TAG;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -18,9 +16,11 @@ import java.util.Random;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
import org.torproject.android.service.OrbotConstants;
|
||||||
|
import org.torproject.android.service.util.Prefs;
|
||||||
import org.torproject.android.service.TorService;
|
import org.torproject.android.service.TorService;
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
import org.torproject.android.service.TorServiceConstants;
|
||||||
import org.torproject.android.service.TorServiceUtils;
|
import org.torproject.android.service.util.TorServiceUtils;
|
||||||
import org.torproject.android.settings.SettingsPreferences;
|
import org.torproject.android.settings.SettingsPreferences;
|
||||||
import org.torproject.android.ui.ImageProgressView;
|
import org.torproject.android.ui.ImageProgressView;
|
||||||
import org.torproject.android.ui.PromoAppsActivity;
|
import org.torproject.android.ui.PromoAppsActivity;
|
||||||
|
@ -52,6 +52,7 @@ import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
import android.support.v7.app.ActionBarDrawerToggle;
|
import android.support.v7.app.ActionBarDrawerToggle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.widget.SwitchCompat;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -70,10 +71,10 @@ import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemSelectedListener;
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.ToggleButton;
|
|
||||||
|
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
@ -89,9 +90,9 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
private TextView uploadText = null;
|
private TextView uploadText = null;
|
||||||
private TextView mTxtOrbotLog = null;
|
private TextView mTxtOrbotLog = null;
|
||||||
|
|
||||||
private Button mBtnBrowser = null;
|
// private Button mBtnBrowser = null;
|
||||||
private ToggleButton mBtnVPN = null;
|
private SwitchCompat mBtnVPN = null;
|
||||||
private ToggleButton mBtnBridges = null;
|
private SwitchCompat mBtnBridges = null;
|
||||||
|
|
||||||
private Spinner spnCountries = null;
|
private Spinner spnCountries = null;
|
||||||
|
|
||||||
|
@ -156,16 +157,20 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
new IntentFilter(TorServiceConstants.LOCAL_ACTION_LOG));
|
new IntentFilter(TorServiceConstants.LOCAL_ACTION_LOG));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendIntentToService(String action) {
|
private void sendIntentToService(final String action) {
|
||||||
Intent torService = new Intent(this, TorService.class);
|
|
||||||
|
Intent torService = new Intent(OrbotMainActivity.this, TorService.class);
|
||||||
torService.setAction(action);
|
torService.setAction(action);
|
||||||
startService(torService);
|
startService(torService);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopTor() {
|
private void stopTor() {
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.torstarting);
|
imgStatus.setImageResource(R.drawable.torstarting);
|
||||||
Intent torService = new Intent(this, TorService.class);
|
Intent torService = new Intent(OrbotMainActivity.this, TorService.class);
|
||||||
stopService(torService);
|
stopService(torService);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -253,7 +258,7 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
|
|
||||||
// Gesture detection
|
// Gesture detection
|
||||||
mGestureDetector = new GestureDetector(this, new MyGestureDetector());
|
mGestureDetector = new GestureDetector(this, new MyGestureDetector());
|
||||||
|
/**
|
||||||
mBtnBrowser = (Button)findViewById(R.id.btnBrowser);
|
mBtnBrowser = (Button)findViewById(R.id.btnBrowser);
|
||||||
mBtnBrowser.setOnClickListener(new View.OnClickListener ()
|
mBtnBrowser.setOnClickListener(new View.OnClickListener ()
|
||||||
{
|
{
|
||||||
|
@ -267,8 +272,9 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
});
|
});
|
||||||
|
|
||||||
mBtnBrowser.setEnabled(false);
|
mBtnBrowser.setEnabled(false);
|
||||||
|
*/
|
||||||
|
|
||||||
mBtnVPN = (ToggleButton)findViewById(R.id.btnVPN);
|
mBtnVPN = (SwitchCompat)findViewById(R.id.btnVPN);
|
||||||
|
|
||||||
boolean canDoVPN = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
boolean canDoVPN = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||||
|
|
||||||
|
@ -288,24 +294,26 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
startActivity(new Intent(OrbotMainActivity.this,VPNEnableActivity.class));
|
startActivity(new Intent(OrbotMainActivity.this,VPNEnableActivity.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
mBtnVPN.setOnClickListener(new View.OnClickListener ()
|
mBtnVPN.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
Prefs.putUseVpn(isChecked);
|
||||||
public void onClick(View v) {
|
|
||||||
|
|
||||||
if (mBtnVPN.isChecked())
|
if (isChecked)
|
||||||
startActivity(new Intent(OrbotMainActivity.this,VPNEnableActivity.class));
|
startActivity(new Intent(OrbotMainActivity.this,VPNEnableActivity.class));
|
||||||
else
|
else
|
||||||
stopVpnService();
|
stopVpnService();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mBtnBridges = (ToggleButton)findViewById(R.id.btnBridges);
|
mBtnBridges = (SwitchCompat)findViewById(R.id.btnBridges);
|
||||||
mBtnBridges.setChecked(Prefs.bridgesEnabled());
|
mBtnBridges.setChecked(Prefs.bridgesEnabled());
|
||||||
mBtnBridges.setOnClickListener(new View.OnClickListener ()
|
mBtnBridges.setOnClickListener(new View.OnClickListener ()
|
||||||
{
|
{
|
||||||
|
@ -319,7 +327,6 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Toast.makeText(OrbotMainActivity.this, R.string.note_only_standard_tor_bridges_work_on_intel_x86_atom_devices, Toast.LENGTH_LONG).show();
|
|
||||||
showGetBridgePrompt(""); //if other chip ar, only stock bridges are supported
|
showGetBridgePrompt(""); //if other chip ar, only stock bridges are supported
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -824,9 +831,15 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (request == REQUEST_VPN && response == RESULT_OK)
|
else if (request == REQUEST_VPN)
|
||||||
{
|
{
|
||||||
|
if (response == RESULT_OK)
|
||||||
sendIntentToService(TorServiceConstants.CMD_VPN);
|
sendIntentToService(TorServiceConstants.CMD_VPN);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Prefs.putUseVpn(false);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data);
|
IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data);
|
||||||
|
@ -1059,11 +1072,7 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
if (mPrefs != null)
|
|
||||||
{
|
|
||||||
mBtnVPN.setChecked(Prefs.useVpn());
|
|
||||||
mBtnBridges.setChecked(Prefs.bridgesEnabled());
|
mBtnBridges.setChecked(Prefs.bridgesEnabled());
|
||||||
}
|
|
||||||
|
|
||||||
requestTorStatus();
|
requestTorStatus();
|
||||||
|
|
||||||
|
@ -1120,7 +1129,7 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.toron);
|
imgStatus.setImageResource(R.drawable.toron);
|
||||||
|
|
||||||
mBtnBrowser.setEnabled(true);
|
//mBtnBrowser.setEnabled(true);
|
||||||
|
|
||||||
if (torServiceMsg != null)
|
if (torServiceMsg != null)
|
||||||
{
|
{
|
||||||
|
@ -1166,7 +1175,7 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
else
|
else
|
||||||
lblStatus.setText(getString(R.string.status_starting_up));
|
lblStatus.setText(getString(R.string.status_starting_up));
|
||||||
|
|
||||||
mBtnBrowser.setEnabled(false);
|
// mBtnBrowser.setEnabled(false);
|
||||||
|
|
||||||
} else if (torStatus == TorServiceConstants.STATUS_STOPPING) {
|
} else if (torStatus == TorServiceConstants.STATUS_STOPPING) {
|
||||||
|
|
||||||
|
@ -1175,13 +1184,13 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.torstarting);
|
imgStatus.setImageResource(R.drawable.torstarting);
|
||||||
lblStatus.setText(torServiceMsg);
|
lblStatus.setText(torServiceMsg);
|
||||||
mBtnBrowser.setEnabled(false);
|
// mBtnBrowser.setEnabled(false);
|
||||||
|
|
||||||
} else if (torStatus == TorServiceConstants.STATUS_OFF) {
|
} else if (torStatus == TorServiceConstants.STATUS_OFF) {
|
||||||
|
|
||||||
imgStatus.setImageResource(R.drawable.toroff);
|
imgStatus.setImageResource(R.drawable.toroff);
|
||||||
lblStatus.setText(getString(R.string.press_to_start));
|
lblStatus.setText(getString(R.string.press_to_start));
|
||||||
mBtnBrowser.setEnabled(false);
|
// mBtnBrowser.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torServiceMsg != null && torServiceMsg.length() > 0)
|
if (torServiceMsg != null && torServiceMsg.length() > 0)
|
||||||
|
@ -1197,6 +1206,7 @@ public class OrbotMainActivity extends AppCompatActivity
|
||||||
*/
|
*/
|
||||||
private void startTor() {
|
private void startTor() {
|
||||||
sendIntentToService(TorServiceConstants.ACTION_START);
|
sendIntentToService(TorServiceConstants.ACTION_START);
|
||||||
|
mTxtOrbotLog.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -1,7 +1,6 @@
|
||||||
package info.guardianproject.util;
|
package org.torproject.android.settings;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContextWrapper;
|
import android.content.ContextWrapper;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
|
@ -15,16 +15,11 @@ import android.preference.Preference;
|
||||||
import android.preference.Preference.OnPreferenceChangeListener;
|
import android.preference.Preference.OnPreferenceChangeListener;
|
||||||
import android.preference.Preference.OnPreferenceClickListener;
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import info.guardianproject.util.Languages;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.rootcommands.RootCommands;
|
|
||||||
import org.sufficientlysecure.rootcommands.Shell;
|
|
||||||
import org.torproject.android.OrbotApp;
|
import org.torproject.android.OrbotApp;
|
||||||
import org.torproject.android.Prefs;
|
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
import org.torproject.android.service.TorServiceUtils;
|
import org.torproject.android.ui.AppManager;
|
||||||
|
import org.torproject.android.service.util.TorServiceUtils;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -137,26 +132,9 @@ public class SettingsPreferences
|
||||||
if (prefRequestRoot.isChecked())
|
if (prefRequestRoot.isChecked())
|
||||||
{
|
{
|
||||||
|
|
||||||
boolean canRoot = RootCommands.rootAccessGiven();
|
|
||||||
prefRequestRoot.setChecked(canRoot);
|
|
||||||
|
|
||||||
if (!canRoot)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Shell shell = Shell.startRootShell();
|
|
||||||
shell.close();
|
|
||||||
|
|
||||||
prefRequestRoot.setChecked(true);
|
|
||||||
prefCBTransProxy.setEnabled(true);
|
prefCBTransProxy.setEnabled(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Toast.makeText(this, R.string.wizard_permissions_no_root_msg, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (preference == prefTransProxyApps)
|
else if (preference == prefTransProxyApps)
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
package org.torproject.android.settings;
|
package org.torproject.android.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -10,9 +10,10 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import org.torproject.android.service.OrbotConstants;
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
import org.torproject.android.OrbotConstants;
|
import org.torproject.android.service.util.TorServiceUtils;
|
||||||
import org.torproject.android.service.TorServiceUtils;
|
import org.torproject.android.service.transproxy.TorifiedApp;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -36,7 +37,6 @@ import android.widget.ImageView;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
//import android.R;
|
|
||||||
|
|
||||||
public class AppManager extends Activity implements OnCheckedChangeListener, OnClickListener, OrbotConstants {
|
public class AppManager extends Activity implements OnCheckedChangeListener, OnClickListener, OrbotConstants {
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ public class AppManager extends Activity implements OnCheckedChangeListener, OnC
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context);
|
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context);
|
||||||
ArrayList<TorifiedApp> apps = getApps(context, prefs);
|
ArrayList<TorifiedApp> apps = getApps(context, prefs);
|
||||||
parentView = (View) findViewById(R.layout.layout_apps);
|
parentView = (View) findViewById(R.id.applistview);
|
||||||
viewGroup = (ViewGroup) listView;
|
viewGroup = (ViewGroup) listView;
|
||||||
|
|
||||||
adapter = (ArrayAdapter<TorifiedApp>) listApps.getAdapter();
|
adapter = (ArrayAdapter<TorifiedApp>) listApps.getAdapter();
|
|
@ -5,12 +5,9 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.rootcommands.Shell;
|
|
||||||
import org.sufficientlysecure.rootcommands.command.SimpleCommand;
|
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
import org.torproject.android.service.TorResourceInstaller;
|
import org.torproject.android.service.util.TorResourceInstaller;
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
import org.torproject.android.service.TorServiceConstants;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -193,14 +190,12 @@ public class OrbotDiagnosticsActivity extends Activity {
|
||||||
if (!fileBin.canExecute())
|
if (!fileBin.canExecute())
|
||||||
{
|
{
|
||||||
log("(re)Setting permission on binary: " + fileBin.getAbsolutePath());
|
log("(re)Setting permission on binary: " + fileBin.getAbsolutePath());
|
||||||
Shell shell = Shell.startShell(new ArrayList<String>(), appBinHome.getAbsolutePath());
|
|
||||||
|
|
||||||
shell.add(new SimpleCommand("chmod " + TorServiceConstants.CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath())).waitForFinish();
|
Runtime.getRuntime().exec("chmod " + TorServiceConstants.CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath()).waitFor();
|
||||||
|
|
||||||
File fileTest = new File(fileBin.getAbsolutePath());
|
File fileTest = new File(fileBin.getAbsolutePath());
|
||||||
log(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute());
|
log(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute());
|
||||||
|
|
||||||
shell.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileBin.canExecute();
|
return fileBin.canExecute();
|
|
@ -14,7 +14,7 @@ import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
import org.torproject.android.OrbotConstants;
|
import org.torproject.android.service.OrbotConstants;
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
import org.torproject.android.service.TorServiceConstants;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.torproject.android.vpn;
|
package org.torproject.android.vpn;
|
||||||
|
|
||||||
import org.torproject.android.Prefs;
|
|
||||||
import org.torproject.android.R;
|
import org.torproject.android.R;
|
||||||
|
import org.torproject.android.service.util.Prefs;
|
||||||
import org.torproject.android.service.TorService;
|
import org.torproject.android.service.TorService;
|
||||||
import org.torproject.android.service.TorServiceConstants;
|
import org.torproject.android.service.TorServiceConstants;
|
||||||
|
|
||||||
|
@ -12,19 +12,16 @@ import android.app.Dialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.VpnService;
|
import android.net.VpnService;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To combat background service being stopped/swiped
|
* To combat background service being stopped/swiped
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@TargetApi(14)
|
||||||
public class VPNEnableActivity extends Activity {
|
public class VPNEnableActivity extends Activity {
|
||||||
|
|
||||||
private final static int REQUEST_VPN = 7777;
|
private final static int REQUEST_VPN = 7777;
|
||||||
|
@ -74,7 +71,6 @@ public class VPNEnableActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
Prefs.putUseVpn(true);
|
Prefs.putUseVpn(true);
|
||||||
|
|
||||||
startVpnService();
|
startVpnService();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -159,6 +155,8 @@ public class VPNEnableActivity extends Activity {
|
||||||
Intent torService = new Intent(this, TorService.class);
|
Intent torService = new Intent(this, TorService.class);
|
||||||
torService.setAction(action);
|
torService.setAction(action);
|
||||||
startService(torService);
|
startService(torService);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 802 B After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 967 B After Width: | Height: | Size: 967 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 616 B After Width: | Height: | Size: 616 B |
Before Width: | Height: | Size: 713 B After Width: | Height: | Size: 713 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 852 B After Width: | Height: | Size: 852 B |
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 990 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 294 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 319 B |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 647 B |
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 606 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 357 B |
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 607 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 458 B |
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 475 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 364 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 883 B |
Before Width: | Height: | Size: 535 B After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 618 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 747 B |
Before Width: | Height: | Size: 970 B After Width: | Height: | Size: 970 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 716 B |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |