remove code only used for Orbot

This commit is contained in:
n8fr8 2017-11-16 13:41:18 -05:00
parent fce5bdede8
commit 91b73b1f6b
402 changed files with 0 additions and 36398 deletions

View File

@ -1,52 +0,0 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "org.torproject.android"
minSdkVersion 16
targetSdkVersion 25
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
flavorDimensions "free"
productFlavors {
minimalperm {
dimension "free"
minSdkVersion 16
applicationId 'org.torproject.android'
targetSdkVersion 23
maxSdkVersion 23
versionCode 15510001
versionName '15.5.1-RC-2-multi-SDK16'
}
fullperm {
dimension "free"
minSdkVersion 23
applicationId 'org.torproject.android'
targetSdkVersion 25
versionCode 15510002
versionName '15.5.1-RC-2-multi-SDK23'
}
}
}
dependencies {
compile project(':orbotservice')
compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
}

View File

@ -1,71 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/n8fr8/dev/android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-repackageclasses ''
-allowaccessmodification
-keepattributes *Annotation*
-injars src/main/libs
-outjars bin/classes-processed.jar
-dontwarn javax.naming.**
-dontwarn android.support.**
####
-keep class org.** { *; }
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

View File

@ -1,166 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.torproject.android"
android:installLocation="auto">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="25" />
<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" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:name=".OrbotApp"
android:allowBackup="false"
android:allowClearUserData="true"
android:configChanges="locale|orientation|screenSize"
android:description="@string/app_description"
android:hardwareAccelerated="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:largeHeap="false"
android:theme="@style/DefaultTheme">
<activity
android:name=".OrbotMainActivity"
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:allowTaskReparenting="true"
android:alwaysRetainTaskState="false"
android:clearTaskOnLaunch="true"
android:enabled="true"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true"
android:noHistory="true"
android:stateNotNeeded="true"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name=".vpn.VPNEnableActivity"
android:exported="false"
android:label="@string/app_name" />
<activity
android:name=".ui.PromoAppsActivity"
android:exported="false" />
<activity
android:name=".settings.SettingsPreferences"
android:label="@string/app_name" />
<activity
android:name=".ui.AppManagerActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" />
<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>
<activity
android:name=".ui.hiddenservices.HiddenServicesActivity"
android:label="@string/title_activity_hidden_services"
android:theme="@style/DefaultTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".OrbotMainActivity" />
</activity>
<provider
android:name=".ui.hiddenservices.providers.HSContentProvider"
android:authorities="org.torproject.android.ui.hiddenservices.providers"
android:exported="false" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.torproject.android.ui.hiddenservices.storage"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/hidden_services_paths" />
</provider>
<activity
android:name=".ui.hiddenservices.ClientCookiesActivity"
android:label="@string/client_cookies"
android:theme="@style/DefaultTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".OrbotMainActivity" />
</activity>
<provider
android:name=".ui.hiddenservices.providers.CookieContentProvider"
android:authorities="org.torproject.android.ui.hiddenservices.providers.cookie"
android:exported="false" />
</application>
</manifest>

View File

@ -1,158 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.torproject.android"
android:installLocation="auto">
<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" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<application
android:name=".OrbotApp"
android:allowBackup="false"
android:allowClearUserData="true"
android:configChanges="locale|orientation|screenSize"
android:description="@string/app_description"
android:hardwareAccelerated="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:largeHeap="false"
android:theme="@style/DefaultTheme">
<activity
android:name=".OrbotMainActivity"
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:allowTaskReparenting="true"
android:alwaysRetainTaskState="false"
android:clearTaskOnLaunch="true"
android:enabled="true"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true"
android:noHistory="true"
android:stateNotNeeded="true"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name=".vpn.VPNEnableActivity"
android:exported="false"
android:label="@string/app_name" />
<activity
android:name=".ui.PromoAppsActivity"
android:exported="false" />
<activity
android:name=".settings.SettingsPreferences"
android:label="@string/app_name" />
<activity
android:name=".ui.AppManagerActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" />
<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>
<activity
android:name=".ui.hiddenservices.HiddenServicesActivity"
android:label="@string/title_activity_hidden_services"
android:theme="@style/DefaultTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".OrbotMainActivity" />
</activity>
<provider
android:name=".ui.hiddenservices.providers.HSContentProvider"
android:authorities="org.torproject.android.ui.hiddenservices.providers"
android:exported="false" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.torproject.android.ui.hiddenservices.storage"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/hidden_services_paths" />
</provider>
<activity
android:name=".ui.hiddenservices.ClientCookiesActivity"
android:label="@string/client_cookies"
android:theme="@style/DefaultTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".OrbotMainActivity" />
</activity>
<provider
android:name=".ui.hiddenservices.providers.CookieContentProvider"
android:authorities="org.torproject.android.ui.hiddenservices.providers.cookie"
android:exported="false" />
</application>
</manifest>

View File

@ -1 +0,0 @@
../../../../LICENSE

View File

@ -1,506 +0,0 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.integration.android;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
/**
* <p>A utility class which helps ease integration with Barcode Scanner via {@link Intent}s. This is a simple
* way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
* project's source code.</p>
*
* <h2>Initiating a barcode scan</h2>
*
* <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
* for the result in your app.</p>
*
* <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
* {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
*
* <p>There are a few steps to using this integration. First, your {@link Activity} must implement
* the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
*
* <pre>{@code
* public void onActivityResult(int requestCode, int resultCode, Intent intent) {
* IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
* if (scanResult != null) {
* // handle scan result
* }
* // else continue with any other code you need in the method
* ...
* }
* }</pre>
*
* <p>This is where you will handle a scan result.</p>
*
* <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
*
* <pre>{@code
* IntentIntegrator integrator = new IntentIntegrator(yourActivity);
* integrator.initiateScan();
* }</pre>
*
* <p>Note that {@link #initiateScan()} returns an {@link AlertDialog} which is non-null if the
* user was prompted to download the application. This lets the calling app potentially manage the dialog.
* In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
* method.</p>
*
* <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
* {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
* yes/no button labels can be changed.</p>
*
* <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
* to invoke the scanner. This can be used to set additional options not directly exposed by this
* simplified API.</p>
*
* <p>By default, this will only allow applications that are known to respond to this intent correctly
* do so. The apps that are allowed to response can be set with {@link #setTargetApplications(List)}.
* For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
*
* <h2>Sharing text via barcode</h2>
*
* <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
*
* <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
*
* <h2>Enabling experimental barcode formats</h2>
*
* <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
* PDF417. Use {@link #initiateScan(java.util.Collection)} with
* a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
* formats.</p>
*
* @author Sean Owen
* @author Fred Lin
* @author Isaac Potoczny-Jones
* @author Brad Drehmer
* @author gcstang
*/
public class IntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
private static final String TAG = IntentIntegrator.class.getSimpleName();
public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
public static final String DEFAULT_MESSAGE =
"This application requires Barcode Scanner. Would you like to install it?";
public static final String DEFAULT_YES = "Yes";
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
public static final Collection<String> ONE_D_CODE_TYPES =
list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
"ITF", "RSS_14", "RSS_EXPANDED");
public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
public static final Collection<String> ALL_CODE_TYPES = null;
public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
public static final List<String> TARGET_ALL_KNOWN = list(
BSPLUS_PACKAGE, // Barcode Scanner+
BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
BS_PACKAGE // Barcode Scanner
// What else supports this intent?
);
private final Activity activity;
private final Fragment fragment;
private String title;
private String message;
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
/**
* @param activity {@link Activity} invoking the integration
*/
public IntentIntegrator(Activity activity) {
this.activity = activity;
this.fragment = null;
initializeConfiguration();
}
/**
* @param fragment {@link Fragment} invoking the integration.
* {@link #startActivityForResult(Intent, int)} will be called on the {@link Fragment} instead
* of an {@link Activity}
*/
public IntentIntegrator(Fragment fragment) {
this.activity = fragment.getActivity();
this.fragment = fragment;
initializeConfiguration();
}
private void initializeConfiguration() {
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleByID(int titleID) {
title = activity.getString(titleID);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageByID(int messageID) {
message = activity.getString(messageID);
}
public String getButtonYes() {
return buttonYes;
}
public void setButtonYes(String buttonYes) {
this.buttonYes = buttonYes;
}
public void setButtonYesByID(int buttonYesID) {
buttonYes = activity.getString(buttonYesID);
}
public String getButtonNo() {
return buttonNo;
}
public void setButtonNo(String buttonNo) {
this.buttonNo = buttonNo;
}
public void setButtonNoByID(int buttonNoID) {
buttonNo = activity.getString(buttonNoID);
}
public Collection<String> getTargetApplications() {
return targetApplications;
}
public final void setTargetApplications(List<String> targetApplications) {
if (targetApplications.isEmpty()) {
throw new IllegalArgumentException("No target applications");
}
this.targetApplications = targetApplications;
}
public void setSingleTargetApplication(String targetApplication) {
this.targetApplications = Collections.singletonList(targetApplication);
}
public Map<String,?> getMoreExtras() {
return moreExtras;
}
public final void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
/**
* Initiates a scan for all known barcode types with the default camera.
*
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan() {
return initiateScan(ALL_CODE_TYPES, -1);
}
/**
* Initiates a scan for all known barcode types with the specified camera.
*
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(int cameraId) {
return initiateScan(ALL_CODE_TYPES, cameraId);
}
/**
* Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
return initiateScan(desiredBarcodeFormats, -1);
}
/**
* Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
// check requested camera ID
if (cameraId >= 0) {
intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
/**
* Start an activity. This method is defined to allow different methods of activity starting for
* newer versions of Android and for compatibility library.
*
* @param intent Intent to start.
* @param code Request code for the activity
* @see android.app.Activity#startActivityForResult(Intent, int)
* @see android.app.Fragment#startActivityForResult(Intent, int)
*/
protected void startActivityForResult(Intent intent, int code) {
if (fragment == null) {
activity.startActivityForResult(intent, code);
} else {
fragment.startActivityForResult(intent, code);
}
}
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (String targetApp : targetApplications) {
if (contains(availableApps, targetApp)) {
return targetApp;
}
}
}
return null;
}
private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApp.equals(packageName)) {
return true;
}
}
return false;
}
private AlertDialog showDownloadDialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String packageName;
if (targetApplications.contains(BS_PACKAGE)) {
// Prefer to suggest download of BS if it's anywhere in the list
packageName = BS_PACKAGE;
} else {
// Otherwise, first option:
packageName = targetApplications.get(0);
}
Uri uri = Uri.parse("market://details?id=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
}
}
});
downloadDialog.setNegativeButton(buttonNo, null);
downloadDialog.setCancelable(true);
return downloadDialog.show();
}
/**
* <p>Call this from your {@link Activity}'s
* {@link Activity#onActivityResult(int, int, Intent)} method.</p>
*
* @param requestCode request code from {@code onActivityResult()}
* @param resultCode result code from {@code onActivityResult()}
* @param intent {@link Intent} from {@code onActivityResult()}
* @return null if the event handled here was not related to this class, or
* else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
*/
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
return new IntentResult(contents,
formatName,
rawBytes,
orientation,
errorCorrectionLevel);
}
return new IntentResult();
}
return null;
}
/**
* Defaults to type "TEXT_TYPE".
*
* @param text the text string to encode as a barcode
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
* @see #shareText(CharSequence, CharSequence)
*/
public final AlertDialog shareText(CharSequence text) {
return shareText(text, "TEXT_TYPE");
}
/**
* Shares the given text by encoding it as a barcode, such that another user can
* scan the text off the screen of the device.
*
* @param text the text string to encode as a barcode
* @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
return null;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.integration.android;
/**
* <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
*
* @author Sean Owen
*/
public final class IntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
IntentResult() {
this(null, null, null, null, null);
}
IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
}
/**
* @return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
*/
public String getFormatName() {
return formatName;
}
/**
* @return raw bytes of the barcode content, if applicable, or null otherwise
*/
public byte[] getRawBytes() {
return rawBytes;
}
/**
* @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
*/
public Integer getOrientation() {
return orientation;
}
/**
* @return name of the error correction level used in the barcode, if applicable
*/
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
@Override
public String toString() {
StringBuilder dialogText = new StringBuilder(100);
dialogText.append("Format: ").append(formatName).append('\n');
dialogText.append("Contents: ").append(contents).append('\n');
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
dialogText.append("Orientation: ").append(orientation).append('\n');
dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
return dialogText.toString();
}
}

View File

@ -1,49 +0,0 @@
package org.torproject.android;
import android.content.BroadcastReceiver;
import android.content.Context;
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 {
private static boolean sReceivedBoot = false;
@Override
public void onReceive(Context context, Intent intent) {
if (Prefs.startOnBoot() && (!sReceivedBoot))
{
if (Prefs.useVpn())
startVpnService(context); //VPN will start Tor once it is done
else
startService(TorServiceConstants.ACTION_START, context);
sReceivedBoot = true;
}
}
public void startVpnService (final Context context)
{
Intent intent = new Intent(context,VPNEnableActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
private void startService (String action, Context context)
{
Intent torService = new Intent(context, TorService.class);
torService.setAction(action);
context.startService(torService);
}
}

View File

@ -1,111 +0,0 @@
package org.torproject.android;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.VpnService;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;
import org.torproject.android.service.OrbotConstants;
import org.torproject.android.service.TorEventHandler;
import org.torproject.android.service.TorService;
import org.torproject.android.service.util.Prefs;
import org.torproject.android.settings.Languages;
import java.util.Locale;
import java.util.Set;
public class OrbotApp extends Application implements OrbotConstants
{
private Locale locale;
@Override
public void onCreate() {
super.onCreate();
Prefs.setContext(this);
Languages.setup(OrbotMainActivity.class, R.string.menu_settings);
Languages.setLanguage(this, Prefs.getDefaultLocale(), true);
checkTransparentProxyingLegacy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "onConfigurationChanged " + newConfig.locale.getLanguage());
Languages.setLanguage(this, Prefs.getDefaultLocale(), true);
}
public static void forceChangeLanguage(Activity activity) {
Intent intent = activity.getIntent();
if (intent == null) // when launched as LAUNCHER
intent = new Intent(activity, OrbotMainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.finish();
activity.overridePendingTransition(0, 0);
activity.startActivity(intent);
activity.overridePendingTransition(0, 0);
}
public static Languages getLanguages(Activity activity) {
return Languages.get(activity);
}
private void checkTransparentProxyingLegacy ()
{
if (Prefs.useTransparentProxying())
{
showToolbarNotification(getString(R.string.no_transproxy_warning_short),getString(R.string.no_transproxy_warning), 9999, org.torproject.android.service.R.drawable.ic_stat_notifyerr);
}
}
@SuppressLint("NewApi")
protected void showToolbarNotification (String shortMsg, String notifyMsg, int notifyId, int icon)
{
NotificationCompat.Builder notifyBuilder;
//Reusable code.
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(getPackageName());
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(org.torproject.android.service.R.string.app_name));
notifyBuilder.setContentIntent(pendIntent);
notifyBuilder.setContentText(shortMsg);
notifyBuilder.setSmallIcon(icon);
notifyBuilder.setTicker(notifyMsg);
notifyBuilder.setOngoing(false);
notifyBuilder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notifyMsg).setBigContentTitle(getString(org.torproject.android.service.R.string.app_name)));
Notification notification = notifyBuilder.build();
notificationManager.notify(notifyId, notification);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,232 +0,0 @@
package org.torproject.android.settings;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Languages {
public static final String TAG = "Languages";
public static final Locale defaultLocale;
public static final Locale TIBETAN = new Locale("bo");
static final Locale localesToTest[] = {
Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN,
Locale.ITALIAN, Locale.JAPANESE, Locale.KOREAN,
Locale.TRADITIONAL_CHINESE, Locale.SIMPLIFIED_CHINESE,
TIBETAN, new Locale("af"), new Locale("am"),
new Locale("ar"), new Locale("az"), new Locale("bg"),
new Locale("bn"), new Locale("ca"), new Locale("cs"),
new Locale("da"), new Locale("el"), new Locale("es"),
new Locale("et"), new Locale("eu"), new Locale("fa"),
new Locale("fi"), new Locale("gl"), new Locale("hi"),
new Locale("hr"), new Locale("hu"), new Locale("hy"),
new Locale("in"), new Locale("hy"), new Locale("in"),
new Locale("is"), new Locale("it"), new Locale("iw"),
new Locale("ka"), new Locale("kk"), new Locale("km"),
new Locale("kn"), new Locale("ky"), new Locale("lo"),
new Locale("lt"), new Locale("lv"), new Locale("mk"),
new Locale("ml"), new Locale("mn"), new Locale("mr"),
new Locale("ms"), new Locale("my"), new Locale("nb"),
new Locale("ne"), new Locale("nl"), new Locale("pl"),
new Locale("pt"), new Locale("rm"), new Locale("ro"),
new Locale("ru"), new Locale("si"), new Locale("sk"),
new Locale("sl"), new Locale("sn"), new Locale("sr"),
new Locale("sv"), new Locale("sw"), new Locale("ta"),
new Locale("te"), new Locale("th"), new Locale("tl"),
new Locale("tr"), new Locale("uk"), new Locale("ur"),
new Locale("uz"), new Locale("vi"), new Locale("zu"),
};
private static final String USE_SYSTEM_DEFAULT = "";
private static final String defaultString = "Use System Default";
private static Locale locale;
private static Languages singleton;
private static Class<?> clazz;
private static int resId;
private static Map<String, String> tmpMap = new TreeMap<String, String>();
private static Map<String, String> nameMap;
static {
defaultLocale = Locale.getDefault();
}
private Languages(Activity activity) {
AssetManager assets = activity.getAssets();
Configuration config = activity.getResources().getConfiguration();
// Resources() requires DisplayMetrics, but they are only needed for drawables
DisplayMetrics ignored = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(ignored);
Resources resources;
Set<Locale> localeSet = new LinkedHashSet<Locale>();
for (Locale locale : localesToTest) {
config.locale = locale;
resources = new Resources(assets, ignored, config);
if (!TextUtils.equals(defaultString, resources.getString(resId))
|| locale.equals(Locale.ENGLISH))
localeSet.add(locale);
}
for (Locale locale : localeSet) {
if (locale.equals(TIBETAN)) {
// include English name for devices without Tibetan font support
tmpMap.put(TIBETAN.getLanguage(), "Tibetan བོད་སྐད།"); // Tibetan
} else if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
tmpMap.put(Locale.SIMPLIFIED_CHINESE.toString(), "中文 (中国)"); // Chinese (China)
} else if (locale.equals(Locale.TRADITIONAL_CHINESE)) {
tmpMap.put(Locale.TRADITIONAL_CHINESE.toString(), "中文 (台灣)"); // Chinese (Taiwan)
} else {
tmpMap.put(locale.getLanguage(), locale.getDisplayLanguage(locale));
}
}
/* USE_SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
localeSet.add(null);
tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(resId));
nameMap = Collections.unmodifiableMap(tmpMap);
}
/**
* Get the instance of {@link Languages} to work with, providing the
* {@link Activity} that is will be working as part of, as well as the
* {@code resId} that has the exact string "Use System Default",
* i.e. {@code R.string.use_system_default}.
* <p/>
* That string resource {@code resId} is also used to find the supported
* translations: if an included translation has a translated string that
* matches that {@code resId}, then that language will be included as a
* supported language.
*
* @param clazz the {@link Class} of the default {@code Activity},
* usually the main {@code Activity} from where the
* Settings is launched from.
* @param resId the string resource ID to for the string "Use System Default",
* e.g. {@code R.string.use_system_default}
* @return
*/
public static void setup(Class<?> clazz, int resId) {
if (Languages.clazz == null) {
Languages.clazz = clazz;
Languages.resId = resId;
} else {
throw new RuntimeException("Languages singleton was already initialized, duplicate call to Languages.setup()!");
}
}
/**
* Get the singleton to work with.
*
* @param activity the {@link Activity} this is working as part of
* @return
*/
public static Languages get(Activity activity) {
if (singleton == null) {
singleton = new Languages(activity);
}
return singleton;
}
//@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("NewApi")
public static void setLanguage(final ContextWrapper contextWrapper, String language, boolean refresh) {
if (locale != null && TextUtils.equals(locale.getLanguage(), language) && (!refresh)) {
return; // already configured
} else if (language == null || language == USE_SYSTEM_DEFAULT) {
locale = defaultLocale;
} else {
/* handle locales with the country in it, i.e. zh_CN, zh_TW, etc */
String localeSplit[] = language.split("_");
if (localeSplit.length > 1) {
locale = new Locale(localeSplit[0], localeSplit[1]);
} else {
locale = new Locale(language);
}
}
final Resources resources = contextWrapper.getBaseContext().getResources();
Configuration config = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
} else {
config.locale = locale;
}
resources.updateConfiguration(config, resources.getDisplayMetrics());
Locale.setDefault(locale);
}
/**
* Force reload the {@link Activity to make language changes take effect.}
*
* @param activity the {@code Activity} to force reload
*/
public static void forceChangeLanguage(Activity activity) {
Intent intent = activity.getIntent();
if (intent == null) // when launched as LAUNCHER
return;
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.finish();
activity.overridePendingTransition(0, 0);
activity.startActivity(intent);
activity.overridePendingTransition(0, 0);
}
/**
* Return the name of the language based on the locale.
*
* @param locale
* @return
*/
public String getName(String locale) {
String ret = nameMap.get(locale);
// if no match, try to return a more general name (i.e. English for
// en_IN)
if (ret == null && locale.contains("_"))
ret = nameMap.get(locale.split("_")[0]);
return ret;
}
/**
* Return an array of the names of all the supported languages, sorted to
* match what is returned by {@link Languages#getSupportedLocales()}.
*
* @return
*/
public String[] getAllNames() {
return nameMap.values().toArray(new String[nameMap.size()]);
}
public int getPosition(Locale locale) {
String localeName = locale.getLanguage();
int i = 0;
for (String key : nameMap.keySet())
if (TextUtils.equals(key, localeName))
return i;
else
i++;
return -1;
}
/**
* Get sorted list of supported locales.
*
* @return
*/
public String[] getSupportedLocales() {
Set<String> keys = nameMap.keySet();
return keys.toArray(new String[keys.size()]);
}
}

View File

@ -1,74 +0,0 @@
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android.settings;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import org.torproject.android.OrbotApp;
import org.torproject.android.R;
import org.torproject.android.service.util.TorServiceUtils;
import java.util.Locale;
public class SettingsPreferences
extends PreferenceActivity implements OnPreferenceClickListener {
private static final String TAG = "SettingsPreferences";
private ListPreference prefLocale = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
prefLocale = (ListPreference) findPreference("pref_default_locale");
prefLocale.setOnPreferenceClickListener(this);
Languages languages = Languages.get(this);
prefLocale.setEntries(languages.getAllNames());
prefLocale.setEntryValues(languages.getSupportedLocales());
prefLocale.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String language = (String) newValue;
if (preference == prefLocale) {
SharedPreferences settings = TorServiceUtils
.getSharedPrefs(getApplicationContext());
String lang = settings.getString("pref_default_locale",
Locale.getDefault().getLanguage());
OrbotApp app = (OrbotApp) getApplication();
Languages.setLanguage(app, language, true);
lang = settings.getString("pref_default_locale",
Locale.getDefault().getLanguage());
OrbotApp.forceChangeLanguage(SettingsPreferences.this);
}
return false;
}
});
}
public boolean onPreferenceClick(Preference preference) {
setResult(RESULT_OK);
return true;
}
}

View File

@ -1,361 +0,0 @@
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android.ui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.torproject.android.service.OrbotConstants;
import org.torproject.android.R;
import org.torproject.android.service.util.TorServiceUtils;
import org.torproject.android.service.vpn.TorifiedApp;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
public class AppManagerActivity extends AppCompatActivity implements OnClickListener, OrbotConstants {
private GridView listApps;
private ListAdapter adapterApps;
private final static String TAG = "Orbot";
PackageManager pMgr = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pMgr = getPackageManager();
this.setContentView(R.layout.layout_apps);
setTitle(R.string.apps_mode);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home)
{
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
listApps = (GridView) findViewById(R.id.applistview);
mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
new AsyncTask<Void, Void, Void>() {
private ProgressDialog dialog;
protected void onPreExecute() {
// Pre Code
dialog = new ProgressDialog(AppManagerActivity.this, android.support.v4.app.DialogFragment.STYLE_NO_TITLE);
dialog.show();
}
protected Void doInBackground(Void... unused) {
loadApps(mPrefs);
return null;
}
protected void onPostExecute(Void unused) {
listApps.setAdapter(adapterApps);
dialog.cancel();
}
}.execute();
}
SharedPreferences mPrefs = null;
ArrayList<TorifiedApp> mApps = null;
private void loadApps (SharedPreferences prefs)
{
mApps = getApps(getApplicationContext(), prefs);
Collections.sort(mApps,new Comparator<TorifiedApp>() {
public int compare(TorifiedApp o1, TorifiedApp o2) {
if (o1.isTorified() == o2.isTorified()) return o1.getName().compareTo(o2.getName());
if (o1.isTorified()) return -1;
return 1;
}
});
final LayoutInflater inflater = getLayoutInflater();
adapterApps = new ArrayAdapter<TorifiedApp>(this, R.layout.layout_apps_item, R.id.itemtext,mApps) {
public View getView(int position, View convertView, ViewGroup parent) {
ListEntry entry = null;
if (convertView == null)
convertView = inflater.inflate(R.layout.layout_apps_item, parent, false);
else
entry = (ListEntry) convertView.getTag();
if (entry == null) {
// Inflate a new view
entry = new ListEntry();
entry.icon = (ImageView) convertView.findViewById(R.id.itemicon);
entry.box = (CheckBox) convertView.findViewById(R.id.itemcheck);
entry.text = (TextView) convertView.findViewById(R.id.itemtext);
convertView.setTag(entry);
}
final TorifiedApp app = mApps.get(position);
if (entry.icon != null) {
try {
entry.icon.setImageDrawable(pMgr.getApplicationIcon(app.getPackageName()));
entry.icon.setOnClickListener(AppManagerActivity.this);
entry.icon.setTag(entry.box);
}
catch (Exception e)
{
e.printStackTrace();
}
}
if (entry.text != null) {
entry.text.setText(app.getName());
entry.text.setOnClickListener(AppManagerActivity.this);
entry.text.setTag(entry.box);
}
if (entry.box != null) {
entry.box.setOnClickListener(AppManagerActivity.this);
entry.box.setChecked(app.isTorified());
entry.box.setTag(app);
}
return convertView;
}
};
}
private static class ListEntry {
private CheckBox box;
private TextView text;
private ImageView icon;
}
/* (non-Javadoc)
* @see android.app.Activity#onStop()
*/
@Override
protected void onStop() {
super.onStop();
}
public ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs)
{
String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
String[] tordApps;
StringTokenizer st = new StringTokenizer(tordAppString,"|");
tordApps = new String[st.countTokens()];
int tordIdx = 0;
while (st.hasMoreTokens())
{
tordApps[tordIdx++] = st.nextToken();
}
Arrays.sort(tordApps);
//else load the apps up
List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0);
Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator();
ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>();
ApplicationInfo aInfo = null;
int appIdx = 0;
TorifiedApp app = null;
while (itAppInfo.hasNext())
{
aInfo = itAppInfo.next();
app = new TorifiedApp();
try {
PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
if (pInfo != null && pInfo.requestedPermissions != null)
{
for (String permInfo:pInfo.requestedPermissions)
{
if (permInfo.equals("android.permission.INTERNET"))
{
app.setUsesInternet(true);
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**
if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1)
{
//System app
app.setUsesInternet(true);
}**/
try
{
app.setName(pMgr.getApplicationLabel(aInfo).toString());
}
catch (Exception e)
{
// no name
continue; //we only show apps with names
}
if (!app.usesInternet())
continue;
else
{
apps.add(app);
}
app.setEnabled(aInfo.enabled);
app.setUid(aInfo.uid);
app.setUsername(pMgr.getNameForUid(app.getUid()));
app.setProcname(aInfo.processName);
app.setPackageName(aInfo.packageName);
// check if this application is allowed
if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
app.setTorified(true);
}
else
{
app.setTorified(false);
}
appIdx++;
}
Collections.sort(apps);
return apps;
}
public void saveAppSettings (Context context)
{
StringBuilder tordApps = new StringBuilder();
Intent response = new Intent();
for (TorifiedApp tApp:mApps)
{
if (tApp.isTorified())
{
tordApps.append(tApp.getUsername());
tordApps.append("|");
response.putExtra(tApp.getUsername(),true);
}
}
Editor edit = mPrefs.edit();
edit.putString(PREFS_KEY_TORIFIED, tordApps.toString());
edit.commit();
setResult(RESULT_OK,response);
}
/**
* Called an application is check/unchecked
*/
/**
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final TorifiedApp app = (TorifiedApp) buttonView.getTag();
if (app != null) {
app.setTorified(isChecked);
}
saveAppSettings(this);
}**/
public void onClick(View v) {
CheckBox cbox = null;
if (v instanceof CheckBox)
cbox = (CheckBox)v;
else if (v.getTag() instanceof CheckBox)
cbox = (CheckBox)v.getTag();
if (cbox != null) {
final TorifiedApp app = (TorifiedApp) cbox.getTag();
if (app != null) {
app.setTorified(!app.isTorified());
cbox.setChecked(app.isTorified());
}
saveAppSettings(this);
}
}
}

View File

@ -1,5 +0,0 @@
package org.torproject.android.ui;
public class BridgeSetupActivity {
}

View File

@ -1,78 +0,0 @@
package org.torproject.android.ui;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class ImageProgressView extends ImageView
{
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float progress = 0f; // 0 to 1
private RectF circle;
public ImageProgressView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public ImageProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageProgressView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
paint.setAntiAlias(true);
paint.setStrokeWidth(20);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (circle == null)
{
circle = new RectF(getWidth()/2,getHeight()/2+getHeight()/8, getWidth()/3,getHeight()/3);
}
float sweepAngle = 360f * progress;
canvas.drawArc(circle, 0, sweepAngle, true, paint);
}
}

View File

@ -1,328 +0,0 @@
package org.torproject.android.ui;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.torproject.android.R;
import org.torproject.android.service.util.TorResourceInstaller;
import org.torproject.android.service.TorServiceConstants;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;
import android.text.format.Formatter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class OrbotDiagnosticsActivity extends Activity {
private TextView mTextView = null;
private final static String TAG = "OrbotDiag";
private StringBuffer log = new StringBuffer();
Process mProcess;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_diag);
mTextView = (TextView)findViewById(R.id.diaglog);
}
private String getFreeStorage ()
{
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return Formatter.formatFileSize(this, availableBlocks * blockSize);
}
@Override
protected void onPause() {
super.onPause();
stopTor();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void stopTor ()
{
File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
if (mProcess != null)
mProcess.destroy();
}
@Override
protected void onResume() {
super.onResume();
log("Hello, Orbot!");
try
{
log(android.os.Build.DEVICE);
log(android.os.Build.HARDWARE);
log(android.os.Build.MANUFACTURER);
log(android.os.Build.MODEL);
log(android.os.Build.VERSION.CODENAME);
log(android.os.Build.VERSION.RELEASE);
}
catch (Exception e)
{
log("error getting device info");
}
showFileTree ();
runTorTest();
}
private void runTorTest ()
{
try
{
File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
File appDataHome = this.getDir("data", Context.MODE_PRIVATE);
File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
enableBinExec (fileTor, appBinHome);
InputStream is = getResources().openRawResource(R.raw.torrc);
File fileTorrc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY + "diag");
TorResourceInstaller.streamToFile(is,fileTorrc, false, false);
/**
ArrayList<String> alEnv = new ArrayList<String>();
alEnv.add("HOME=" + appBinHome.getAbsolutePath());
Shell shell = Shell.startShell(alEnv,appBinHome.getAbsolutePath());
SimpleCommand cmdTor = new SimpleCommand(fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath());
shell.add(cmdTor);
**/
String cmd = fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath();
log ("Executing command> " + cmd);
mProcess = Runtime.getRuntime().exec(cmd);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
StreamGobbler sg = new StreamGobbler();
sg.reader = bufferedReader;
sg.process = mProcess;
new Thread(sg).start();
if (mProcess.getErrorStream() != null)
{
bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getErrorStream()));
sg = new StreamGobbler();
sg.reader = bufferedReader;
sg.process = mProcess;
new Thread(sg).start();
}
}
catch (Exception e)
{
Log.d(TAG,"runTorTest exception",e);
}
}
class StreamGobbler implements Runnable
{
BufferedReader reader;
Process process;
public void run ()
{
String line = null;
try {
while ( (line = reader.readLine()) != null)
{
Message msg = mHandler.obtainMessage(0);
msg.getData().putString("log", line);
mHandler.sendMessage(msg);
}
} catch (IOException e) {
Log.d(TAG, "error reading line",e);
}
//log("Tor exit code=" + process.exitValue() + ";");
}
}
private boolean enableBinExec (File fileBin, File appBinHome) throws Exception
{
log(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute());
if (!fileBin.canExecute())
{
log("(re)Setting permission on binary: " + fileBin.getAbsolutePath());
Runtime.getRuntime().exec("chmod " + TorServiceConstants.CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath()).waitFor();
File fileTest = new File(fileBin.getAbsolutePath());
log(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute());
}
return fileBin.canExecute();
}
private void showFileTree ()
{
File fileDir = this.getDir("bin", Context.MODE_PRIVATE);
if (fileDir.exists())
{
log("checking file tree: " + fileDir.getAbsolutePath());
printDir (fileDir.getName(), fileDir);
}
else
{
log("app_bin does not exist");
}
fileDir = this.getDir("data", Context.MODE_PRIVATE);
if (fileDir.exists())
{
log("checking file tree: " + fileDir.getAbsolutePath());
printDir (fileDir.getName(), fileDir);
}
else
{
log ("app_data does not exist");
}
}
private void printDir (String path, File fileDir)
{
File[] files = fileDir.listFiles();
if (files != null && files.length > 0)
{
for (File file : files)
{
try
{
if (file.isDirectory())
{
printDir(path + '/' + file.getName(), file);
}
else
{
log(path + '/' + file.getName() + " len:" + file.length() + " exec:" + file.canExecute());
}
}
catch (Exception e)
{
log("problem printing out file information");
}
}
}
}
Handler mHandler = new Handler ()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String logMsg = msg.getData().getString("log");
log(logMsg);
}
};
private void log (String msg)
{
Log.d(TAG, msg);
mTextView.append(msg + '\n');
log.append(msg + '\n');
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate menu resource file.
getMenuInflater().inflate(R.menu.share_menu, menu);
// Locate MenuItem with ShareActionProvider
MenuItem item = menu.findItem(R.id.menu_item_share);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_share:
sendLog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void sendLog ()
{
int maxLength = 5000;
String logShare = null;
if (log.length() > maxLength)
logShare = log.substring(0, maxLength);
else
logShare = log.toString();
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, logShare);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
}

View File

@ -1,216 +0,0 @@
package org.torproject.android.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import org.torproject.android.service.OrbotConstants;
import org.torproject.android.R;
import org.torproject.android.service.TorServiceConstants;
import java.util.List;
public class PromoAppsActivity extends Activity implements OrbotConstants {
final static String MARKET_URI = "market://details?id=";
final static String FDROID_APP_URI = "https://f-droid.org/repository/browse/?fdid=";
final static String PLAY_APP_URI = "https://play.google.com/store/apps/details?id=";
final static String FDROID_URI = "https://f-droid.org/repository/browse/?fdfilter=info.guardianproject";
final static String PLAY_URI = "https://play.google.com/store/apps/developer?id=The+Guardian+Project";
private final static String FDROID_PACKAGE_NAME = "org.fdroid.fdroid";
private final static String PLAY_PACKAGE_NAME = "com.android.vending";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
protected void onStart() {
super.onStart();
setContentView(R.layout.layout_promo_apps);
stepFive();
}
@Override
protected void onResume() {
super.onResume();
}
void stepFive(){
String title = getString(R.string.wizard_tips_title);
setTitle(title);
Button btnLink = (Button)findViewById(R.id.WizardRootButtonInstallGibberbot);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
finish();
startActivity(getInstallIntent("info.guardianproject.otr.app.im",PromoAppsActivity.this));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonInstallOrweb);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
finish();
startActivity(getInstallIntent(TorServiceConstants.BROWSER_APP_USERNAME,PromoAppsActivity.this));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonInstallDuckgo);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
finish();
startActivity(getInstallIntent("com.duckduckgo.mobile.android",PromoAppsActivity.this));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonInstallTwitter);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String url = getString(R.string.twitter_setup_url);
finish();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonInstallStoryMaker);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
finish();
startActivity(getInstallIntent("info.guardianproject.mrapp",PromoAppsActivity.this));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonInstallMartus);
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
finish();
startActivity(getInstallIntent("org.martus.android",PromoAppsActivity.this));
}
});
btnLink = (Button)findViewById(R.id.WizardRootButtonGooglePlay);
PackageManager pm = getPackageManager();
final Intent intent = new Intent(Intent.ACTION_VIEW);
// change text and icon based on which app store is installed (or not)
try {
if (isAppInstalled(pm, FDROID_PACKAGE_NAME)) {
Drawable icon = pm.getApplicationIcon(FDROID_PACKAGE_NAME);
btnLink.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
btnLink.setText(R.string.wizard_tips_fdroid);
intent.setPackage(FDROID_PACKAGE_NAME);
intent.setData(Uri.parse(FDROID_URI));
} else if (isAppInstalled(pm, PLAY_PACKAGE_NAME)) {
Drawable icon = pm.getApplicationIcon(PLAY_PACKAGE_NAME);
btnLink.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
btnLink.setText(R.string.wizard_tips_play);
intent.setPackage(PLAY_PACKAGE_NAME);
intent.setData(Uri.parse(PLAY_URI));
}
} catch (NameNotFoundException e) {
e.printStackTrace();
btnLink.setText(R.string.wizard_tips_fdroid_org);
intent.setData(Uri.parse(FDROID_URI));
}
btnLink.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
startActivity(intent);
}
});
Button next = ((Button)findViewById(R.id.btnWizard2));
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
public static boolean isAppInstalled(PackageManager pm, String packageName) {
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
public static Intent getInstallIntent(String packageName, Context context) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(MARKET_URI + packageName));
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resInfos = pm.queryIntentActivities(intent, 0);
String foundPackageName = null;
for (ResolveInfo r : resInfos) {
Log.i(TAG, "market: " + r.activityInfo.packageName);
if (TextUtils.equals(r.activityInfo.packageName, FDROID_PACKAGE_NAME)
|| TextUtils.equals(r.activityInfo.packageName, PLAY_PACKAGE_NAME)) {
foundPackageName = r.activityInfo.packageName;
break;
}
}
if (foundPackageName == null) {
intent.setData(Uri.parse(FDROID_APP_URI + packageName));
} else {
intent.setPackage(foundPackageName);
}
return intent;
}
}

View File

@ -1,76 +0,0 @@
package org.torproject.android.ui;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
/**
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
*/
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}

View File

@ -1,5 +0,0 @@
package org.torproject.android.ui;
public class VPNSetupActivity {
}

View File

@ -1,199 +0,0 @@
package org.torproject.android.ui.hiddenservices;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import org.json.JSONException;
import org.json.JSONObject;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.adapters.ClientCookiesAdapter;
import org.torproject.android.ui.hiddenservices.dialogs.AddCookieDialog;
import org.torproject.android.ui.hiddenservices.dialogs.CookieActionsDialog;
import org.torproject.android.ui.hiddenservices.dialogs.SelectCookieBackupDialog;
import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
public class ClientCookiesActivity extends AppCompatActivity {
public final int WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR = 3;
private ContentResolver mResolver;
private ClientCookiesAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_client_cookies);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mResolver = getContentResolver();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AddCookieDialog dialog = new AddCookieDialog();
dialog.show(getSupportFragmentManager(), "AddCookieDialog");
}
});
mAdapter = new ClientCookiesAdapter(
this,
mResolver.query(CookieContentProvider.CONTENT_URI, CookieContentProvider.PROJECTION, null, null, null)
, 0);
mResolver.registerContentObserver(
CookieContentProvider.CONTENT_URI, true, new HSObserver(new Handler())
);
ListView cookies = (ListView) findViewById(R.id.clien_cookies_list);
cookies.setAdapter(mAdapter);
cookies.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor item = (Cursor) parent.getItemAtPosition(position);
Bundle arguments = new Bundle();
arguments.putInt(
"_id", item.getInt(item.getColumnIndex(CookieContentProvider.ClientCookie._ID))
);
arguments.putString(
"domain", item.getString(item.getColumnIndex(CookieContentProvider.ClientCookie.DOMAIN))
);
arguments.putString(
"auth_cookie_value", item.getString(item.getColumnIndex(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE))
);
arguments.putInt(
"enabled", item.getInt(item.getColumnIndex(CookieContentProvider.ClientCookie.ENABLED))
);
CookieActionsDialog dialog = new CookieActionsDialog();
dialog.setArguments(arguments);
dialog.show(getSupportFragmentManager(), "CookieActionsDialog");
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.cookie_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.cookie_restore_backup) {
if (PermissionManager.isLollipopOrHigher()
&& !PermissionManager.hasExternalWritePermission(this)) {
PermissionManager.requestExternalWritePermissions(this, WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR);
return true;
}
SelectCookieBackupDialog dialog = new SelectCookieBackupDialog();
dialog.show(getSupportFragmentManager(), "SelectCookieBackupDialog");
} else if (id == R.id.cookie_from_qr) {
IntentIntegrator integrator = new IntentIntegrator(ClientCookiesActivity.this);
integrator.initiateScan();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (grantResults.length < 1
|| grantResults[0] != PackageManager.PERMISSION_GRANTED) {
return;
}
switch (requestCode) {
case WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR: {
SelectCookieBackupDialog dialog = new SelectCookieBackupDialog();
dialog.show(getSupportFragmentManager(), "SelectCookieBackupDialog");
break;
}
case CookieActionsDialog.WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTION_DIALOG: {
Toast.makeText(this, R.string.click_again_for_backup, Toast.LENGTH_LONG).show();
break;
}
}
}
@Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data);
if (scanResult == null) return;
String results = scanResult.getContents();
if (results == null || results.length() < 1) return;
try {
JSONObject savedValues = new JSONObject(results);
ContentValues fields = new ContentValues();
fields.put(
CookieContentProvider.ClientCookie.DOMAIN,
savedValues.getString(CookieContentProvider.ClientCookie.DOMAIN)
);
fields.put(
CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE,
savedValues.getString(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE)
);
mResolver.insert(CookieContentProvider.CONTENT_URI, fields);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, R.string.error, Toast.LENGTH_LONG).show();
}
}
class HSObserver extends ContentObserver {
HSObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
mAdapter.changeCursor(mResolver.query(
CookieContentProvider.CONTENT_URI, CookieContentProvider.PROJECTION, null, null, null
));
}
}
}

View File

@ -1,214 +0,0 @@
package org.torproject.android.ui.hiddenservices;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.adapters.OnionListAdapter;
import org.torproject.android.ui.hiddenservices.dialogs.HSActionsDialog;
import org.torproject.android.ui.hiddenservices.dialogs.HSDataDialog;
import org.torproject.android.ui.hiddenservices.dialogs.SelectHSBackupDialog;
import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
public class HiddenServicesActivity extends AppCompatActivity {
public final int WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR = 1;
private ContentResolver mResolver;
private OnionListAdapter mAdapter;
private FloatingActionButton fab;
private String mWhere = HSContentProvider.HiddenService.CREATED_BY_USER + "=1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_hs_list_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mResolver = getContentResolver();
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
HSDataDialog dialog = new HSDataDialog();
dialog.show(getSupportFragmentManager(), "HSDataDialog");
}
});
mAdapter = new OnionListAdapter(
this,
mResolver.query(
HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null
),
0
);
mResolver.registerContentObserver(
HSContentProvider.CONTENT_URI, true, new HSObserver(new Handler())
);
ListView onion_list = (ListView) findViewById(R.id.onion_list);
onion_list.setAdapter(mAdapter);
onion_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor item = (Cursor) parent.getItemAtPosition(position);
Bundle arguments = new Bundle();
arguments.putInt(
"_id", item.getInt(item.getColumnIndex(HSContentProvider.HiddenService._ID))
);
arguments.putString(
"port", item.getString(item.getColumnIndex(HSContentProvider.HiddenService.PORT))
);
arguments.putString(
"onion", item.getString(item.getColumnIndex(HSContentProvider.HiddenService.DOMAIN))
);
arguments.putInt(
"auth_cookie", item.getInt(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE))
);
arguments.putString(
"auth_cookie_value", item.getString(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE))
);
HSActionsDialog dialog = new HSActionsDialog();
dialog.setArguments(arguments);
dialog.show(getSupportFragmentManager(), "HSActionsDialog");
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.hs_menu, menu);
MenuItem item = menu.findItem(R.id.hs_type);
Spinner spinner = (Spinner) MenuItemCompat.getActionView(item);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.array_hs_types, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View v, int pos, long id) {
if (pos == 0) {
mWhere = HSContentProvider.HiddenService.CREATED_BY_USER + "=1";
fab.show();
} else {
mWhere = HSContentProvider.HiddenService.CREATED_BY_USER + "=0";
fab.hide();
}
mAdapter.changeCursor(mResolver.query(
HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null
));
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_restore_backup) {
if (PermissionManager.isLollipopOrHigher()
&& !PermissionManager.hasExternalWritePermission(this)) {
PermissionManager.requestExternalWritePermissions(this, WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR);
return true;
}
SelectHSBackupDialog dialog = new SelectHSBackupDialog();
dialog.show(getSupportFragmentManager(), "SelectHSBackupDialog");
}
return super.onOptionsItemSelected(item);
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (grantResults.length < 1
|| grantResults[0] != PackageManager.PERMISSION_GRANTED) {
return;
}
switch (requestCode) {
case WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR: {
SelectHSBackupDialog dialog = new SelectHSBackupDialog();
dialog.show(getSupportFragmentManager(), "SelectHSBackupDialog");
break;
}
case HSActionsDialog.WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG: {
Toast.makeText(this, R.string.click_again_for_backup, Toast.LENGTH_LONG).show();
break;
}
}
}
class HSObserver extends ContentObserver {
HSObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
mAdapter.changeCursor(mResolver.query(
HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null
));
if (PermissionManager.isLollipopOrHigher()) {
Cursor active = mResolver.query(
HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, HSContentProvider.HiddenService.ENABLED + "=1", null, null
);
if (active == null) return;
if (active.getCount() > 0) // Call only if there running services
PermissionManager.requestBatteryPermmssions(HiddenServicesActivity.this, getApplicationContext());
else // Drop whe not needed
PermissionManager.requestDropBatteryPermmssions(HiddenServicesActivity.this, getApplicationContext());
active.close();
}
}
}
}

View File

@ -1,50 +0,0 @@
package org.torproject.android.ui.hiddenservices.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.torproject.android.R;
import java.io.File;
import java.util.List;
public class BackupAdapter extends ArrayAdapter<File> {
private int mResource;
public BackupAdapter(Context context, int resource) {
super(context, resource);
mResource = resource;
}
public BackupAdapter(Context context, int resource, List<File> zips) {
super(context, resource, zips);
mResource = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(mResource, null);
}
File p = getItem(position);
if (p != null) {
TextView name = (TextView) v.findViewById(R.id.backup_name);
if (name != null)
name.setText(p.getName());
}
return v;
}
}

View File

@ -1,64 +0,0 @@
package org.torproject.android.ui.hiddenservices.adapters;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
public class ClientCookiesAdapter extends CursorAdapter {
private LayoutInflater cursorInflater;
public ClientCookiesAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
cursorInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final Context mContext = context;
int id = cursor.getInt(cursor.getColumnIndex(CookieContentProvider.ClientCookie._ID));
final String where = CookieContentProvider.ClientCookie._ID + "=" + id;
TextView domain = (TextView) view.findViewById(R.id.cookie_onion);
domain.setText(cursor.getString(cursor.getColumnIndex(CookieContentProvider.ClientCookie.DOMAIN)));
Switch enabled = (Switch) view.findViewById(R.id.cookie_switch);
enabled.setChecked(
cursor.getInt(cursor.getColumnIndex(CookieContentProvider.ClientCookie.ENABLED)) == 1
);
enabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ContentResolver resolver = mContext.getContentResolver();
ContentValues fields = new ContentValues();
fields.put(CookieContentProvider.ClientCookie.ENABLED, isChecked);
resolver.update(
CookieContentProvider.CONTENT_URI, fields, where, null
);
Toast.makeText(
mContext, R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG
).show();
}
});
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return cursorInflater.inflate(R.layout.layout_client_cookie_list_item, parent, false);
}
}

View File

@ -1,68 +0,0 @@
package org.torproject.android.ui.hiddenservices.adapters;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
public class OnionListAdapter extends CursorAdapter {
private LayoutInflater cursorInflater;
public OnionListAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
cursorInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final Context mContext = context;
int id = cursor.getInt(cursor.getColumnIndex(HSContentProvider.HiddenService._ID));
final String where = HSContentProvider.HiddenService._ID + "=" + id;
TextView port = (TextView) view.findViewById(R.id.hs_port);
port.setText(cursor.getString(cursor.getColumnIndex(HSContentProvider.HiddenService.PORT)));
TextView name = (TextView) view.findViewById(R.id.hs_name);
name.setText(cursor.getString(cursor.getColumnIndex(HSContentProvider.HiddenService.NAME)));
TextView domain = (TextView) view.findViewById(R.id.hs_onion);
domain.setText(cursor.getString(cursor.getColumnIndex(HSContentProvider.HiddenService.DOMAIN)));
Switch enabled = (Switch) view.findViewById(R.id.hs_switch);
enabled.setChecked(
cursor.getInt(cursor.getColumnIndex(HSContentProvider.HiddenService.ENABLED)) == 1
);
enabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ContentResolver resolver = mContext.getContentResolver();
ContentValues fields = new ContentValues();
fields.put(HSContentProvider.HiddenService.ENABLED, isChecked);
resolver.update(
HSContentProvider.CONTENT_URI, fields, where, null
);
Toast.makeText(
mContext, R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG
).show();
}
});
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return cursorInflater.inflate(R.layout.layout_hs_list_item, parent, false);
}
}

View File

@ -1,336 +0,0 @@
package org.torproject.android.ui.hiddenservices.backup;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import org.torproject.android.R;
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
public class BackupUtils {
private final String configFileName = "config.json";
private Context mContext;
private ContentResolver mResolver;
public BackupUtils(Context context) {
mContext = context;
mResolver = mContext.getContentResolver();
}
public String createZipBackup(Integer port) {
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
String configFilePath = mHSBasePath + "/hs" + port + "/" + configFileName;
String hostnameFilePath = mHSBasePath + "/hs" + port + "/hostname";
String keyFilePath = mHSBasePath + "/hs" + port + "/private_key";
File storage_path = ExternalStorage.getOrCreateBackupDir();
if (storage_path == null)
return null;
Cursor portData = mResolver.query(
HSContentProvider.CONTENT_URI,
HSContentProvider.PROJECTION,
HSContentProvider.HiddenService.PORT + "=" + port,
null,
null
);
JSONObject config = new JSONObject();
try {
if (portData == null || portData.getCount() != 1)
return null;
portData.moveToNext();
config.put(
HSContentProvider.HiddenService.NAME,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.NAME))
);
config.put(
HSContentProvider.HiddenService.PORT,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.PORT))
);
config.put(
HSContentProvider.HiddenService.ONION_PORT,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.ONION_PORT))
);
config.put(
HSContentProvider.HiddenService.DOMAIN,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.DOMAIN))
);
config.put(
HSContentProvider.HiddenService.AUTH_COOKIE,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE))
);
config.put(
HSContentProvider.HiddenService.AUTH_COOKIE_VALUE,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE))
);
config.put(
HSContentProvider.HiddenService.CREATED_BY_USER,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.CREATED_BY_USER))
);
config.put(
HSContentProvider.HiddenService.ENABLED,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.ENABLED))
);
} catch (JSONException e) {
e.printStackTrace();
return null;
} catch (NullPointerException e) {
e.printStackTrace();
return null;
}
portData.close();
try {
FileWriter file = new FileWriter(configFilePath);
file.write(config.toString());
file.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
String zip_path = storage_path.getAbsolutePath() + "/hs" + port + ".zip";
String files[] = {hostnameFilePath, keyFilePath, configFilePath};
ZipIt zip = new ZipIt(files, zip_path);
if (!zip.zip())
return null;
return zip_path;
}
public void restoreZipBackup(File backup) {
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
int port;
Cursor service;
String backupName = backup.getName();
String hsDir = backupName.substring(0, backupName.lastIndexOf('.'));
String configFilePath = mHSBasePath + "/" + hsDir + "/" + configFileName;
String jString = null;
File hsPath = new File(mHSBasePath.getAbsolutePath(), hsDir);
if (!hsPath.isDirectory())
hsPath.mkdirs();
ZipIt zip = new ZipIt(null, backup.getAbsolutePath());
zip.unzip(hsPath.getAbsolutePath());
File config = new File(configFilePath);
FileInputStream stream;
try {
stream = new FileInputStream(config);
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
jString = Charset.defaultCharset().decode(bb).toString();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (jString == null)
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
try {
JSONObject savedValues = new JSONObject(jString);
ContentValues fields = new ContentValues();
fields.put(
HSContentProvider.HiddenService.NAME,
savedValues.getString(HSContentProvider.HiddenService.NAME)
);
fields.put(
HSContentProvider.HiddenService.ONION_PORT,
savedValues.getInt(HSContentProvider.HiddenService.ONION_PORT)
);
fields.put(
HSContentProvider.HiddenService.DOMAIN,
savedValues.getString(HSContentProvider.HiddenService.DOMAIN)
);
fields.put(
HSContentProvider.HiddenService.AUTH_COOKIE,
savedValues.getInt(HSContentProvider.HiddenService.AUTH_COOKIE)
);
fields.put(
HSContentProvider.HiddenService.CREATED_BY_USER,
savedValues.getInt(HSContentProvider.HiddenService.CREATED_BY_USER)
);
fields.put(
HSContentProvider.HiddenService.ENABLED,
savedValues.getInt(HSContentProvider.HiddenService.ENABLED)
);
port = savedValues.getInt(HSContentProvider.HiddenService.PORT);
fields.put(HSContentProvider.HiddenService.PORT, port);
service = mResolver.query(
HSContentProvider.CONTENT_URI,
HSContentProvider.PROJECTION,
HSContentProvider.HiddenService.PORT + "=" + port,
null,
null
);
if (service == null || service.getCount() == 0) {
mResolver.insert(HSContentProvider.CONTENT_URI, fields);
} else {
mResolver.update(
HSContentProvider.CONTENT_URI,
fields,
HSContentProvider.HiddenService.PORT + "=" + port,
null
);
service.close();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
}
Toast.makeText(mContext, R.string.backup_restored, Toast.LENGTH_LONG).show();
}
public void restoreKeyBackup(int hsPort, Uri hsKeyPath) {
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
File serviceDir = new File(mHSBasePath, "hs" + hsPort);
if (!serviceDir.isDirectory())
serviceDir.mkdirs();
try {
ParcelFileDescriptor mInputPFD = mContext.getContentResolver().openFileDescriptor(hsKeyPath, "r");
InputStream fileStream = new FileInputStream(mInputPFD.getFileDescriptor());
OutputStream file = new FileOutputStream(serviceDir.getAbsolutePath() + "/private_key");
byte[] buffer = new byte[1024];
int length;
while ((length = fileStream.read(buffer)) > 0) {
file.write(buffer, 0, length);
}
file.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
public void restoreCookieBackup(File p) {
File config = new File(p.getAbsolutePath());
FileInputStream stream;
String jString = null;
try {
stream = new FileInputStream(config);
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
jString = Charset.defaultCharset().decode(bb).toString();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (jString == null)
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
try {
JSONObject savedValues = new JSONObject(jString);
ContentValues fields = new ContentValues();
fields.put(
CookieContentProvider.ClientCookie.DOMAIN,
savedValues.getString(CookieContentProvider.ClientCookie.DOMAIN)
);
fields.put(
CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE,
savedValues.getString(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE)
);
fields.put(
CookieContentProvider.ClientCookie.ENABLED,
savedValues.getInt(CookieContentProvider.ClientCookie.ENABLED)
);
mResolver.insert(CookieContentProvider.CONTENT_URI, fields);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
}
Toast.makeText(mContext, R.string.backup_restored, Toast.LENGTH_LONG).show();
}
public String createCookieBackup(String domain, String cookie, Integer enabled) {
File storage_path = ExternalStorage.getOrCreateBackupDir();
String backupFile = storage_path.getAbsolutePath() + '/' + domain.replace(".onion", ".json");
JSONObject backup = new JSONObject();
try {
backup.put(CookieContentProvider.ClientCookie.DOMAIN, domain);
backup.put(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE, cookie);
backup.put(CookieContentProvider.ClientCookie.ENABLED, enabled);
FileWriter file = new FileWriter(backupFile);
file.write(backup.toString());
file.close();
} catch (JSONException | IOException e) {
e.printStackTrace();
return null;
}
return backupFile;
}
}

View File

@ -1,101 +0,0 @@
package org.torproject.android.ui.hiddenservices.backup;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipIt {
private static final int BUFFER = 2048;
private String[] _files;
private String _zipFile;
public ZipIt(@Nullable String[] files, @NonNull String zipFile) {
_files = files;
_zipFile = zipFile;
}
public boolean zip() {
try {
BufferedInputStream origin;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for (String _file : _files) {
FileInputStream fi = new FileInputStream(_file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_file.substring(_file.lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
return false;
}
return true;
}
public boolean unzip(String output_path) {
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(_zipFile);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
// zapis do souboru
filename = ze.getName();
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(output_path + "/" + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(output_path + "/" + filename);
// cteni zipu a zapis
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}

View File

@ -1,47 +0,0 @@
package org.torproject.android.ui.hiddenservices.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class HSDatabase extends SQLiteOpenHelper {
public static final String HS_DATA_TABLE_NAME = "hs_data";
public static final String HS_CLIENT_COOKIE_TABLE_NAME = "hs_client_cookie";
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "hidden_services";
private static final String HS_DATA_TABLE_CREATE =
"CREATE TABLE " + HS_DATA_TABLE_NAME + " (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"domain TEXT, " +
"onion_port INTEGER, " +
"auth_cookie INTEGER DEFAULT 0, " +
"auth_cookie_value TEXT, " +
"created_by_user INTEGER DEFAULT 0, " +
"enabled INTEGER DEFAULT 1, " +
"port INTEGER);";
private static final String HS_CLIENT_COOKIE_TABLE_CREATE =
"CREATE TABLE " + HS_CLIENT_COOKIE_TABLE_NAME + " (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"domain TEXT, " +
"auth_cookie_value TEXT, " +
"enabled INTEGER DEFAULT 1);";
public HSDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(HS_DATA_TABLE_CREATE);
db.execSQL(HS_CLIENT_COOKIE_TABLE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

View File

@ -1,84 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
public class AddCookieDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_add_client_cookie_dialog, null);
final AlertDialog addCookieDialog = new AlertDialog.Builder(getActivity())
.setView(dialog_view)
.setTitle(R.string.client_cookies)
.create();
Button save = (Button) dialog_view.findViewById(R.id.cookie_dialog_save);
save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String onion = ((EditText) dialog_view.findViewById(R.id.cookie_onion)).getText().toString();
String cookie = ((EditText) dialog_view.findViewById(R.id.cookie_value)).getText().toString();
if (checkInput(onion, cookie)) {
saveData(onion, cookie);
Toast.makeText(
v.getContext(), R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG
).show();
addCookieDialog.dismiss();
}
}
});
Button cancel = (Button) dialog_view.findViewById(R.id.cookie_dialog_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
addCookieDialog.cancel();
}
});
return addCookieDialog;
}
private boolean checkInput(String onion, String cookie) {
boolean is_set = ((onion != null && onion.length() > 0) && (cookie != null && cookie.length() > 0));
if (!is_set) {
Toast.makeText(getContext(), R.string.fields_can_t_be_empty, Toast.LENGTH_SHORT).show();
return false;
}
if (!onion.matches("([a-z0-9]{16})\\.onion")) {
Toast.makeText(getContext(), R.string.invalid_onion_address, Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
private void saveData(String domain, String cookie) {
ContentValues fields = new ContentValues();
fields.put(CookieContentProvider.ClientCookie.DOMAIN, domain);
fields.put(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE, cookie);
ContentResolver cr = getContext().getContentResolver();
cr.insert(CookieContentProvider.CONTENT_URI, fields);
}
}

View File

@ -1,95 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
public class CookieActionsDialog extends DialogFragment {
public static final int WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTION_DIALOG = 4;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle arguments = getArguments();
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_cookie_actions, null);
final AlertDialog actionDialog = new AlertDialog.Builder(getActivity())
.setView(dialog_view)
.setTitle(R.string.client_cookies)
.create();
Button backup = (Button) dialog_view.findViewById(R.id.btn_cookie_backup);
backup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context mContext = v.getContext();
if (PermissionManager.isLollipopOrHigher()
&& !PermissionManager.hasExternalWritePermission(mContext)) {
PermissionManager.requestExternalWritePermissions(
getActivity(), WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTION_DIALOG);
return;
}
BackupUtils backup_utils = new BackupUtils(mContext);
String backupPath = backup_utils.createCookieBackup(
arguments.getString("domain"),
arguments.getString("auth_cookie_value"),
arguments.getInt("enabled")
);
if (backupPath == null || backupPath.length() < 1) {
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
actionDialog.dismiss();
return;
}
Toast.makeText(mContext, R.string.backup_saved_at_external_storage, Toast.LENGTH_LONG).show();
Uri selectedUri = Uri.parse(backupPath.substring(0, backupPath.lastIndexOf("/")));
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "resource/folder");
if (intent.resolveActivityInfo(mContext.getPackageManager(), 0) != null) {
startActivity(intent);
} else {
Toast.makeText(mContext, R.string.filemanager_not_available, Toast.LENGTH_LONG).show();
}
actionDialog.dismiss();
}
});
Button delete = (Button) dialog_view.findViewById(R.id.btn_cookie_delete);
delete.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CookieDeleteDialog dialog = new CookieDeleteDialog();
dialog.setArguments(arguments);
dialog.show(getFragmentManager(), "CookieDeleteDialog");
actionDialog.dismiss();
}
});
Button cancel = (Button) dialog_view.findViewById(R.id.btn_cookie_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
actionDialog.dismiss();
}
});
return actionDialog;
}
}

View File

@ -1,50 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
public class CookieDeleteDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle arguments = getArguments();
final Context context = getContext();
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
// Delete from db
context.getContentResolver().delete(
CookieContentProvider.CONTENT_URI,
CookieContentProvider.ClientCookie._ID + "=" + arguments.getInt("_id"),
null
);
break;
case DialogInterface.BUTTON_NEGATIVE:
// Do nothing
break;
}
}
};
return new AlertDialog.Builder(context)
.setMessage(R.string.confirm_cookie_deletion)
.setPositiveButton(R.string.btn_okay, dialogClickListener)
.setNegativeButton(R.string.btn_cancel, dialogClickListener)
.create();
}
}

View File

@ -1,130 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
public class HSActionsDialog extends DialogFragment {
public static final int WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG = 2;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle arguments = getArguments();
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_hs_actions, null);
final AlertDialog actionDialog = new AlertDialog.Builder(getActivity())
.setView(dialog_view)
.setTitle(R.string.hidden_services)
.create();
Button backup = (Button) dialog_view.findViewById(R.id.btn_hs_backup);
backup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context mContext = v.getContext();
if (PermissionManager.isLollipopOrHigher()
&& !PermissionManager.hasExternalWritePermission(mContext)) {
PermissionManager.requestExternalWritePermissions(
getActivity(), WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG);
return;
}
BackupUtils hsutils = new BackupUtils(mContext);
String backupPath = hsutils.createZipBackup(Integer.parseInt(arguments.getString("port")));
if (backupPath == null || backupPath.length() < 1) {
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
actionDialog.dismiss();
return;
}
Toast.makeText(mContext, R.string.backup_saved_at_external_storage, Toast.LENGTH_LONG).show();
Uri selectedUri = Uri.parse(backupPath.substring(0, backupPath.lastIndexOf("/")));
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "resource/folder");
if (intent.resolveActivityInfo(mContext.getPackageManager(), 0) != null) {
startActivity(intent);
} else {
Toast.makeText(mContext, R.string.filemanager_not_available, Toast.LENGTH_LONG).show();
}
actionDialog.dismiss();
}
});
Button copy = (Button) dialog_view.findViewById(R.id.btn_hs_clipboard);
copy.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context mContext = v.getContext();
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("onion", arguments.getString("onion"));
clipboard.setPrimaryClip(clip);
Toast.makeText(mContext, R.string.done, Toast.LENGTH_LONG).show();
actionDialog.dismiss();
}
});
Button showAuth = (Button) dialog_view.findViewById(R.id.bt_hs_show_auth);
showAuth.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String auth_cookie_value = arguments.getString("auth_cookie_value");
if (arguments.getInt("auth_cookie") == 1) {
if (auth_cookie_value == null || auth_cookie_value.length() < 1) {
Toast.makeText(
v.getContext(), R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG
).show();
} else {
HSCookieDialog dialog = new HSCookieDialog();
dialog.setArguments(arguments);
dialog.show(getFragmentManager(), "HSCookieDialog");
}
} else {
Toast.makeText(
v.getContext(), R.string.auth_cookie_was_not_configured, Toast.LENGTH_LONG
).show();
}
actionDialog.dismiss();
}
});
Button delete = (Button) dialog_view.findViewById(R.id.btn_hs_delete);
delete.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
HSDeleteDialog dialog = new HSDeleteDialog();
dialog.setArguments(arguments);
dialog.show(getFragmentManager(), "HSDeleteDialog");
actionDialog.dismiss();
}
});
Button cancel = (Button) dialog_view.findViewById(R.id.btn_hs_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
actionDialog.dismiss();
}
});
return actionDialog;
}
}

View File

@ -1,81 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import org.json.JSONException;
import org.json.JSONObject;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
public class HSCookieDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_hs_cookie, null);
final Bundle arguments = getArguments();
final String auth_cookie_value = arguments.getString("auth_cookie_value");
final AlertDialog cookieDialog = new AlertDialog.Builder(getActivity())
.setView(dialog_view)
.create();
TextView cookie = (TextView) dialog_view.findViewById(R.id.hs_cookie);
cookie.setText(auth_cookie_value);
Button clipboard = (Button) dialog_view.findViewById(R.id.hs_cookie_to_clipboard);
clipboard.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context mContext = v.getContext();
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("cookie", auth_cookie_value);
clipboard.setPrimaryClip(clip);
Toast.makeText(mContext, R.string.done, Toast.LENGTH_LONG).show();
cookieDialog.dismiss();
}
});
Button shareQR = (Button) dialog_view.findViewById(R.id.hs_cookie_to_qr);
shareQR.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
JSONObject backup = new JSONObject();
backup.put(CookieContentProvider.ClientCookie.DOMAIN, arguments.getString("onion"));
backup.put(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE, arguments.getString("auth_cookie_value"));
IntentIntegrator integrator = new IntentIntegrator(getActivity());
integrator.shareText(backup.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cookieDialog.dismiss();
}
});
Button cancel = (Button) dialog_view.findViewById(R.id.hs_cookie_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cookieDialog.dismiss();
}
});
return cookieDialog;
}
}

View File

@ -1,102 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
public class HSDataDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the layout
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_hs_data_dialog, null);
// Use the Builder class for convenient dialog construction
final AlertDialog serviceDataDialog = new AlertDialog.Builder(getActivity())
.setView(dialog_view)
.setTitle(R.string.hidden_services)
.create();
// Buttons action
Button save = (Button) dialog_view.findViewById(R.id.HSDialogSave);
save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String serverName = ((EditText) dialog_view.findViewById(R.id.hsName)).getText().toString();
Integer localPort = Integer.parseInt(
((EditText) dialog_view.findViewById(R.id.hsLocalPort)).getText().toString()
);
Integer onionPort = Integer.parseInt(
((EditText) dialog_view.findViewById(R.id.hsOnionPort)).getText().toString()
);
Boolean authCookie = ((CheckBox) dialog_view.findViewById(R.id.hsAuth)).isChecked();
if (checkInput(serverName, localPort, onionPort)) {
saveData(serverName, localPort, onionPort, authCookie);
Toast.makeText(
v.getContext(), R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG
).show();
serviceDataDialog.dismiss();
}
}
});
Button cancel = (Button) dialog_view.findViewById(R.id.HSDialogCancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
serviceDataDialog.cancel();
}
});
return serviceDataDialog;
}
private boolean checkInput(String serverName, Integer local, Integer remote) {
boolean is_ok = true;
Integer error_msg = 0;
if ((local < 1 || local > 65535) || (remote < 1 || remote > 65535)) {
error_msg = R.string.invalid_port;
is_ok = false;
}
if (serverName == null || serverName.length() < 1) {
error_msg = R.string.name_can_t_be_empty;
is_ok = false;
}
if (!is_ok) {
Toast.makeText(getContext(), error_msg, Toast.LENGTH_SHORT).show();
}
return is_ok;
}
private void saveData(String name, Integer local, Integer remote, Boolean authCookie) {
ContentValues fields = new ContentValues();
fields.put(HSContentProvider.HiddenService.NAME, name);
fields.put(HSContentProvider.HiddenService.PORT, local);
fields.put(HSContentProvider.HiddenService.ONION_PORT, remote);
fields.put(HSContentProvider.HiddenService.AUTH_COOKIE, authCookie);
fields.put(HSContentProvider.HiddenService.CREATED_BY_USER, 1);
ContentResolver cr = getContext().getContentResolver();
cr.insert(HSContentProvider.CONTENT_URI, fields);
}
}

View File

@ -1,65 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import org.torproject.android.R;
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
import java.io.File;
public class HSDeleteDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle arguments = getArguments();
final Context context = getContext();
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
// Delete from db
context.getContentResolver().delete(
HSContentProvider.CONTENT_URI,
HSContentProvider.HiddenService._ID + "=" + arguments.getInt("_id"),
null
);
// Delete from interal storage
String base = context.getFilesDir().getAbsolutePath() + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR;
File dir = new File(base, "hs" + arguments.getString("port"));
if (dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
new File(dir, aChildren).delete();
}
dir.delete();
}
break;
case DialogInterface.BUTTON_NEGATIVE:
// Do nothing
break;
}
}
};
return new AlertDialog.Builder(context)
.setMessage(R.string.confirm_service_deletion)
.setPositiveButton(R.string.btn_okay, dialogClickListener)
.setNegativeButton(R.string.btn_cancel, dialogClickListener)
.create();
}
}

View File

@ -1,84 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.adapters.BackupAdapter;
import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SelectCookieBackupDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder cookieBackupDialog = new AlertDialog.Builder(getActivity());
cookieBackupDialog.setTitle(R.string.restore_backup);
File backupDir = ExternalStorage.getOrCreateBackupDir();
File[] files = null;
try {
files = backupDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".json");
}
});
} catch (NullPointerException e) {
// Silent block
}
if (files == null || files.length < 1) {
cookieBackupDialog.setMessage(R.string.create_a_backup_first);
cookieBackupDialog.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return cookieBackupDialog.create();
}
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_hs_backups_list, null);
cookieBackupDialog.setView(dialog_view);
cookieBackupDialog.setPositiveButton(R.string.btn_okay, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
ListView backups = (ListView) dialog_view.findViewById(R.id.listview_hs_backups);
List<File> json_backups = new ArrayList<>();
Collections.addAll(json_backups, files);
backups.setAdapter(new BackupAdapter(getContext(), R.layout.layout_hs_backups_list_item, json_backups));
backups.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BackupUtils backupUtils = new BackupUtils(view.getContext().getApplicationContext());
File p = (File) parent.getItemAtPosition(position);
backupUtils.restoreCookieBackup(p);
}
});
return cookieBackupDialog.create();
}
}

View File

@ -1,84 +0,0 @@
package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.adapters.BackupAdapter;
import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SelectHSBackupDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder backupsDialog = new AlertDialog.Builder(getActivity());
backupsDialog.setTitle(R.string.restore_backup);
File backupDir = ExternalStorage.getOrCreateBackupDir();
File[] files = null;
try {
files = backupDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".zip");
}
});
} catch (NullPointerException e) {
// Silent block
}
if (files == null || files.length < 1) {
backupsDialog.setMessage(R.string.create_a_backup_first);
backupsDialog.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return backupsDialog.create();
}
final View dialog_view = getActivity().getLayoutInflater().inflate(R.layout.layout_hs_backups_list, null);
backupsDialog.setView(dialog_view);
backupsDialog.setPositiveButton(R.string.btn_okay, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
ListView backups = (ListView) dialog_view.findViewById(R.id.listview_hs_backups);
List<File> zips = new ArrayList<>();
Collections.addAll(zips, files);
backups.setAdapter(new BackupAdapter(getContext(), R.layout.layout_hs_backups_list_item, zips));
backups.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BackupUtils backupUtils = new BackupUtils(view.getContext().getApplicationContext());
File p = (File) parent.getItemAtPosition(position);
backupUtils.restoreZipBackup(p);
}
});
return backupsDialog.create();
}
}

View File

@ -1,103 +0,0 @@
package org.torproject.android.ui.hiddenservices.permissions;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import org.torproject.android.R;
public class PermissionManager {
public static int VERY_LONG_LENGTH = 6000;
public static boolean isLollipopOrHigher() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
}
@SuppressLint("NewApi")
public static boolean hasExternalWritePermission(Context context) {
return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
public static void requestExternalWritePermissions(FragmentActivity activity, int action) {
final int mAction = action;
final FragmentActivity mActivity = activity;
if (ActivityCompat.shouldShowRequestPermissionRationale
(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Snackbar.make(mActivity.findViewById(android.R.id.content),
R.string.please_grant_permissions_for_external_storage,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.activate,
new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
mAction);
}
}).show();
} else {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
mAction);
}
}
@TargetApi(Build.VERSION_CODES.M)
public static void requestBatteryPermmssions(FragmentActivity activity, Context context) {
final Context mContext = context;
final String packageName = mContext.getPackageName();
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName))
return;
Snackbar.make(activity.findViewById(android.R.id.content),
R.string.consider_disable_battery_optimizations,
VERY_LONG_LENGTH).setAction(R.string.disable,
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
mContext.startActivity(intent);
}
}).show();
}
@TargetApi(Build.VERSION_CODES.M)
public static void requestDropBatteryPermmssions(FragmentActivity activity, Context context) {
final Context mContext = context;
final String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName))
return;
Snackbar.make(activity.findViewById(android.R.id.content),
R.string.consider_enable_battery_optimizations,
VERY_LONG_LENGTH).setAction(R.string.enable,
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
mContext.startActivity(intent);
}
}).show();
}
}

View File

@ -1,134 +0,0 @@
package org.torproject.android.ui.hiddenservices.providers;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.torproject.android.ui.hiddenservices.database.HSDatabase;
public class CookieContentProvider extends ContentProvider {
public static final String[] PROJECTION = new String[]{
ClientCookie._ID,
ClientCookie.DOMAIN,
ClientCookie.AUTH_COOKIE_VALUE,
ClientCookie.ENABLED
};
private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers.cookie";
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTH + "/cookie");
//UriMatcher
private static final int COOKIES = 1;
private static final int COOKIE_ID = 2;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTH, "hs", COOKIES);
uriMatcher.addURI(AUTH, "hs/#", COOKIE_ID);
}
private HSDatabase mServervices;
private Context mContext;
@Override
public boolean onCreate() {
mContext = getContext();
mServervices = new HSDatabase(mContext);
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String where = selection;
if (uriMatcher.match(uri) == COOKIE_ID) {
where = "_id=" + uri.getLastPathSegment();
}
SQLiteDatabase db = mServervices.getReadableDatabase();
return db.query(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, projection, where,
selectionArgs, null, null, sortOrder);
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
int match = uriMatcher.match(uri);
switch (match) {
case COOKIES:
return "vnd.android.cursor.dir/vnd.torproject.cookies";
case COOKIE_ID:
return "vnd.android.cursor.item/vnd.torproject.cookie";
default:
return null;
}
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, ContentValues values) {
long regId;
SQLiteDatabase db = mServervices.getWritableDatabase();
regId = db.insert(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, null, values);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return ContentUris.withAppendedId(CONTENT_URI, regId);
}
@Override
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
String where = selection;
if (uriMatcher.match(uri) == COOKIE_ID) {
where = "_id=" + uri.getLastPathSegment();
}
SQLiteDatabase db = mServervices.getWritableDatabase();
Integer rows = db.delete(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, where, selectionArgs);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return rows;
}
@Override
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = mServervices.getWritableDatabase();
String where = selection;
if (uriMatcher.match(uri) == COOKIE_ID) {
where = "_id=" + uri.getLastPathSegment();
}
Integer rows = db.update(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, values, where, null);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return rows;
}
public static final class ClientCookie implements BaseColumns {
public static final String DOMAIN = "domain";
public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
public static final String ENABLED = "enabled";
private ClientCookie() {
}
}
}

View File

@ -1,144 +0,0 @@
package org.torproject.android.ui.hiddenservices.providers;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.torproject.android.ui.hiddenservices.database.HSDatabase;
public class HSContentProvider extends ContentProvider {
public static final String[] PROJECTION = new String[]{
HiddenService._ID,
HiddenService.NAME,
HiddenService.PORT,
HiddenService.DOMAIN,
HiddenService.ONION_PORT,
HiddenService.AUTH_COOKIE,
HiddenService.AUTH_COOKIE_VALUE,
HiddenService.CREATED_BY_USER,
HiddenService.ENABLED
};
private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers";
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTH + "/hs");
//UriMatcher
private static final int ONIONS = 1;
private static final int ONION_ID = 2;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTH, "hs", ONIONS);
uriMatcher.addURI(AUTH, "hs/#", ONION_ID);
}
private HSDatabase mServervices;
private Context mContext;
@Override
public boolean onCreate() {
mContext = getContext();
mServervices = new HSDatabase(mContext);
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String where = selection;
if (uriMatcher.match(uri) == ONION_ID) {
where = "_id=" + uri.getLastPathSegment();
}
SQLiteDatabase db = mServervices.getReadableDatabase();
return db.query(HSDatabase.HS_DATA_TABLE_NAME, projection, where,
selectionArgs, null, null, sortOrder);
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
int match = uriMatcher.match(uri);
switch (match) {
case ONIONS:
return "vnd.android.cursor.dir/vnd.torproject.onions";
case ONION_ID:
return "vnd.android.cursor.item/vnd.torproject.onion";
default:
return null;
}
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, ContentValues values) {
long regId;
SQLiteDatabase db = mServervices.getWritableDatabase();
regId = db.insert(HSDatabase.HS_DATA_TABLE_NAME, null, values);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return ContentUris.withAppendedId(CONTENT_URI, regId);
}
@Override
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
String where = selection;
if (uriMatcher.match(uri) == ONION_ID) {
where = "_id=" + uri.getLastPathSegment();
}
SQLiteDatabase db = mServervices.getWritableDatabase();
Integer rows = db.delete(HSDatabase.HS_DATA_TABLE_NAME, where, selectionArgs);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return rows;
}
@Override
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = mServervices.getWritableDatabase();
String where = selection;
if (uriMatcher.match(uri) == ONION_ID) {
where = "_id=" + uri.getLastPathSegment();
}
Integer rows = db.update(HSDatabase.HS_DATA_TABLE_NAME, values, where, null);
mContext.getContentResolver().notifyChange(CONTENT_URI, null);
return rows;
}
public static final class HiddenService implements BaseColumns {
public static final String NAME = "name";
public static final String PORT = "port";
public static final String ONION_PORT = "onion_port";
public static final String DOMAIN = "domain";
public static final String AUTH_COOKIE = "auth_cookie";
public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
public static final String CREATED_BY_USER = "created_by_user";
public static final String ENABLED = "enabled";
private HiddenService() {
}
}
}

View File

@ -1,34 +0,0 @@
package org.torproject.android.ui.hiddenservices.storage;
import android.os.Environment;
import java.io.File;
public class ExternalStorage {
private static final String ORBOT_BACKUPS_DIR = "Orbot";
public static File getOrCreateBackupDir() {
if (!isExternalStorageWritable())
return null;
File dir = new File(Environment.getExternalStorageDirectory(), ORBOT_BACKUPS_DIR);
if (!dir.isDirectory() && !dir.mkdirs())
return null;
return dir;
}
/* Checks if external storage is available for read and write */
public static boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
/* Checks if external storage is available to at least read */
public static boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
}

View File

@ -1,163 +0,0 @@
package org.torproject.android.vpn;
import org.torproject.android.R;
import org.torproject.android.service.util.Prefs;
import org.torproject.android.service.TorService;
import org.torproject.android.service.TorServiceConstants;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.VpnService;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Window;
/*
* To combat background service being stopped/swiped
*/
@TargetApi(14)
public class VPNEnableActivity extends AppCompatActivity {
private final static int REQUEST_VPN = 7777;
private Intent intent = null;
private boolean checkVpn = true;
private Handler h = new Handler();
@Override
public void onCreate( Bundle icicle ) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate( icicle );
Log.d("VPNEnableActivity","prompting user to start Orbot VPN");
}
public void onResume ()
{
super.onResume();
if (checkVpn)
{
intent = VpnService.prepare(this);
if (intent != null)
promptStartVpnService();
else
startVpnService ();
checkVpn = false;
}
}
public void promptStartVpnService ()
{
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(getString(R.string.app_name) + ' ' + getString(R.string.apps_mode))
.setMessage(getString(R.string.you_can_enable_all_apps_on_your_device_to_run_through_the_tor_network_using_the_vpn_feature_of_android_))
.setPositiveButton(R.string.activate, new Dialog.OnClickListener ()
{
@Override
public void onClick(DialogInterface dialog, int which) {
Prefs.putUseVpn(true);
startVpnService();
}
})
.setNegativeButton(R.string.btn_cancel, new Dialog.OnClickListener ()
{
@Override
public void onClick(DialogInterface dialog, int which) {
h.postDelayed(new Runnable () {
public void run ()
{
VPNEnableActivity.this.finish();
}
}, 100);
}
}).create();
dialog.show();
}
private void startVpnService ()
{
if (intent == null)
{
Log.d("VPNEnableActivity","VPN enabled, starting Tor...");
sendIntentToService(TorServiceConstants.CMD_VPN);
Handler h = new Handler();
h.postDelayed(new Runnable () {
public void run ()
{
sendIntentToService(TorServiceConstants.ACTION_START);
finish();
}
}, 100);
}
else
{
Log.w("VPNEnableActivity","prompt for VPN");
startActivityForResult(intent,REQUEST_VPN);
}
}
@Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == REQUEST_VPN && response == RESULT_OK)
{
sendIntentToService(TorServiceConstants.CMD_VPN);
h.postDelayed(new Runnable () {
public void run ()
{
sendIntentToService(TorServiceConstants.ACTION_START);
finish();
}
}, 1000);
}
}
private void sendIntentToService(String action) {
Intent torService = new Intent(this, TorService.class);
torService.setAction(action);
startService(torService);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More