tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2017
- 20 participants
- 1183 discussions
commit 53e53d6fffb23716f1584e49ea8785033addad7a
Author: arrase <arrase(a)gmail.com>
Date: Tue Nov 22 23:19:48 2016 +0100
clean
---
.../src/main/java/org/torproject/android/service/TorService.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index 09a75ca..dfd0195 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -67,7 +67,6 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.Normalizer;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
1
0
commit 7600b4c58cead4021ad7b427b3634f54e06709d3
Author: arrase <arrase(a)gmail.com>
Date: Tue Nov 22 01:24:23 2016 +0100
menu entry for restore backup
---
.../android/ui/hs/HiddenServicesActivity.java | 20 ++++++++++++++++++++
app/src/main/res/menu/hs_menu.xml | 6 ++++++
app/src/main/res/values/strings.xml | 1 +
3 files changed, 27 insertions(+)
diff --git a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
index 24bbd70..a10c3e2 100644
--- a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
@@ -8,6 +8,8 @@ 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;
@@ -87,6 +89,24 @@ public class HiddenServicesActivity extends AppCompatActivity {
});
}
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.hs_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.menu_restore_backup) {
+ // TODO: Restore backup
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
class HSObserver extends ContentObserver {
HSObserver(Handler handler) {
super(handler);
diff --git a/app/src/main/res/menu/hs_menu.xml b/app/src/main/res/menu/hs_menu.xml
new file mode 100644
index 0000000..cfe580d
--- /dev/null
+++ b/app/src/main/res/menu/hs_menu.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/menu_restore_backup"
+ android:title="@string/restore_backup" />
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 05408dc..adeba6f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -346,4 +346,5 @@
<string name="please_grant_permissions_for_external_storage">Please grant permissions for external storage</string>
<string name="permission_granted">Permission granted</string>
<string name="permission_denied">Permission denied</string>
+ <string name="restore_backup">Restore Backup</string>
</resources>
1
0
commit f030963c9e9b8e349db5ba959dddb7e0089be7f7
Author: arrase <arrase(a)gmail.com>
Date: Tue Nov 22 22:37:34 2016 +0100
refactor
---
.../org/torproject/android/OrbotMainActivity.java | 4 +-
.../org/torproject/android/backup/BackupUtils.java | 45 ++++++++++
.../java/org/torproject/android/backup/ZipIt.java | 98 ++++++++++++++++++++++
.../android/hsutils/HiddenServiceUtils.java | 46 ----------
.../android/ui/hs/HiddenServicesActivity.java | 4 +-
.../android/ui/hs/dialogs/HSActionsDialog.java | 4 +-
.../java/org/torproject/android/zip/ZipIt.java | 98 ----------------------
7 files changed, 148 insertions(+), 151 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 6d58d0e..e0fdbb0 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -29,7 +29,7 @@ import org.torproject.android.ui.PromoAppsActivity;
import org.torproject.android.ui.Rotate3dAnimation;
import org.torproject.android.ui.hs.providers.HSContentProvider;
import org.torproject.android.vpn.VPNEnableActivity;
-import org.torproject.android.hsutils.HiddenServiceUtils;
+import org.torproject.android.backup.BackupUtils;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -646,7 +646,7 @@ public class OrbotMainActivity extends AppCompatActivity
Cursor onion = getContentResolver().query(HSContentProvider.CONTENT_URI, mProjection, "port=" + hsPort, null, null);
if(onion != null) {
hostname = onion.getString(onion.getColumnIndex(HSContentProvider.HiddenService.NAME));
- HiddenServiceUtils hsutils = new HiddenServiceUtils(getApplicationContext());
+ BackupUtils hsutils = new BackupUtils(getApplicationContext());
if(keyZipPath != null && keyZipPath.length() > 0)
{
hsutils.restoreOnionBackup(hsPort, keyZipPath);
diff --git a/app/src/main/java/org/torproject/android/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/backup/BackupUtils.java
new file mode 100644
index 0000000..42c98f8
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/backup/BackupUtils.java
@@ -0,0 +1,45 @@
+package org.torproject.android.backup;
+
+import android.app.Application;
+import android.content.Context;
+
+import org.torproject.android.service.TorServiceConstants;
+import org.torproject.android.storage.ExternalStorage;
+
+import java.io.File;
+
+public class BackupUtils {
+ private static File appCacheHome;
+
+ public BackupUtils(Context context) {
+ appCacheHome = context.getDir(TorServiceConstants.DIRECTORY_TOR_DATA, Application.MODE_PRIVATE);
+ }
+
+ public String createOnionBackup(Integer port) {
+
+ ExternalStorage storage = new ExternalStorage();
+ String storage_path = storage.createBackupDir();
+ if (storage_path == null) {
+ return null;
+ }
+
+ String zip_path = storage_path + "/hs" + port + ".zip";
+ String files[] = {
+ appCacheHome + "/hs" + port + "/hostname",
+ appCacheHome + "/hs" + port + "/private_key"
+ };
+
+ ZipIt zip = new ZipIt(files, zip_path);
+
+ if (!zip.zip()) {
+ return null;
+ }
+
+ return zip_path;
+ }
+
+ public void restoreOnionBackup(Integer port, String path) {
+ ZipIt zip = new ZipIt(null, path);
+ zip.unzip(appCacheHome + "/hs" + port);
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/backup/ZipIt.java b/app/src/main/java/org/torproject/android/backup/ZipIt.java
new file mode 100644
index 0000000..bde29f0
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/backup/ZipIt.java
@@ -0,0 +1,98 @@
+package org.torproject.android.backup;
+
+
+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(String[] files, String zipFile) {
+ _files = files;
+ _zipFile = zipFile;
+ }
+
+ public boolean zip() {
+ try {
+ BufferedInputStream origin = null;
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/torproject/android/hsutils/HiddenServiceUtils.java b/app/src/main/java/org/torproject/android/hsutils/HiddenServiceUtils.java
deleted file mode 100644
index 0cf359b..0000000
--- a/app/src/main/java/org/torproject/android/hsutils/HiddenServiceUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.torproject.android.hsutils;
-
-import android.app.Application;
-import android.content.Context;
-
-import org.torproject.android.service.TorServiceConstants;
-import org.torproject.android.storage.ExternalStorage;
-import org.torproject.android.zip.ZipIt;
-
-import java.io.File;
-
-public class HiddenServiceUtils {
- private static File appCacheHome;
-
- public HiddenServiceUtils(Context context) {
- appCacheHome = context.getDir(TorServiceConstants.DIRECTORY_TOR_DATA, Application.MODE_PRIVATE);
- }
-
- public String createOnionBackup(Integer port) {
-
- ExternalStorage storage = new ExternalStorage();
- String storage_path = storage.createBackupDir();
- if (storage_path == null) {
- return null;
- }
-
- String zip_path = storage_path + "/hs" + port + ".zip";
- String files[] = {
- appCacheHome + "/hs" + port + "/hostname",
- appCacheHome + "/hs" + port + "/private_key"
- };
-
- ZipIt zip = new ZipIt(files, zip_path);
-
- if (!zip.zip()) {
- return null;
- }
-
- return zip_path;
- }
-
- public void restoreOnionBackup(Integer port, String path) {
- ZipIt zip = new ZipIt(null, path);
- zip.unzip(appCacheHome + "/hs" + port);
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
index a10c3e2..52103dc 100644
--- a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
@@ -58,9 +58,7 @@ public class HiddenServicesActivity extends AppCompatActivity {
mAdapter = new OnionListAdapter(
this,
- mCR.query(
- HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null
- ),
+ mCR.query(HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null),
0
);
diff --git a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java
index 52ea6c5..f432a01 100644
--- a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java
@@ -22,7 +22,7 @@ import android.widget.Button;
import android.widget.Toast;
import org.torproject.android.R;
-import org.torproject.android.hsutils.HiddenServiceUtils;
+import org.torproject.android.backup.BackupUtils;
import org.torproject.android.ui.hs.providers.HSContentProvider;
public class HSActionsDialog extends DialogFragment {
@@ -49,7 +49,7 @@ public class HSActionsDialog extends DialogFragment {
return;
}
- HiddenServiceUtils hsutils = new HiddenServiceUtils(mContext);
+ BackupUtils hsutils = new BackupUtils(mContext);
String backupPath = hsutils.createOnionBackup(Integer.parseInt(arguments.getString("port")));
if (backupPath == null || backupPath.length() < 1) {
diff --git a/app/src/main/java/org/torproject/android/zip/ZipIt.java b/app/src/main/java/org/torproject/android/zip/ZipIt.java
deleted file mode 100644
index 84a0b7a..0000000
--- a/app/src/main/java/org/torproject/android/zip/ZipIt.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.torproject.android.zip;
-
-
-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(String[] files, String zipFile) {
- _files = files;
- _zipFile = zipFile;
- }
-
- public boolean zip() {
- try {
- BufferedInputStream origin = null;
- 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;
- }
-}
\ No newline at end of file
1
0
commit 5f02561f9d00b238c880d0a77bcd63f41c556bc3
Author: arrase <arrase(a)gmail.com>
Date: Sun Nov 27 18:50:20 2016 +0100
backup restore
---
.../org/torproject/android/OrbotMainActivity.java | 3 +-
.../ui/hiddenservices/backup/BackupUtils.java | 77 +++++++++++++++++++---
.../android/ui/hiddenservices/backup/ZipIt.java | 11 ++--
.../ui/hiddenservices/dialogs/HSDataDialog.java | 8 +--
.../hiddenservices/dialogs/SelectBackupDialog.java | 5 +-
.../providers/HSContentProvider.java | 8 +--
app/src/main/res/values/strings.xml | 1 +
7 files changed, 88 insertions(+), 25 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 9a5bfb5..e08ddfa 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -649,7 +649,8 @@ public class OrbotMainActivity extends AppCompatActivity
BackupUtils hsutils = new BackupUtils(getApplicationContext());
if(keyZipPath != null && keyZipPath.length() > 0)
{
- hsutils.restoreZipBackup(hsPort, keyZipPath);
+ // TODO
+ // hsutils.restoreZipBackup(hsPort, keyZipPath);
requestTorRereadConfig();
}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java
index 07a9600..d446190 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java
@@ -1,26 +1,31 @@
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.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
-import org.torproject.android.service.R;
+import org.torproject.android.R;
import org.torproject.android.service.TorServiceConstants;
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.FileWriter;
import java.io.IOException;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
public class BackupUtils {
+ private final String configFileName = "config.json";
private File mHSBasePath;
private Context mContext;
private ContentResolver mResolver;
- private final String configFileName = "config.json";
public BackupUtils(Context context) {
mContext = context;
@@ -112,18 +117,70 @@ public class BackupUtils {
return zip_path;
}
- public void restoreZipBackup(Integer port, String path) {
+ public void restoreZipBackup(File backup) {
+ 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 = null;
+
try {
- File hsPath = new File(mHSBasePath.getCanonicalPath(), "/hs" + port);
- if (hsPath.mkdirs()) {
- ZipIt zip = new ZipIt(null, path);
- zip.unzip(hsPath.getCanonicalPath());
- return;
- }
+ 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();
}
- Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
+ 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.PORT,
+ savedValues.getInt(HSContentProvider.HiddenService.PORT)
+ );
+
+ 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.CREATED_BY_USER,
+ savedValues.getInt(HSContentProvider.HiddenService.CREATED_BY_USER)
+ );
+
+ mResolver.insert(HSContentProvider.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();
}
}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
index 42e0bf9..130b56b 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
@@ -1,6 +1,9 @@
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;
@@ -18,14 +21,14 @@ public class ZipIt {
private String[] _files;
private String _zipFile;
- public ZipIt(String[] files, String zipFile) {
+ public ZipIt(@Nullable String[] files, @NonNull String zipFile) {
_files = files;
_zipFile = zipFile;
}
public boolean zip() {
try {
- BufferedInputStream origin = null;
+ BufferedInputStream origin;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
@@ -71,12 +74,12 @@ public class ZipIt {
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
- File fmd = new File(output_path + filename);
+ File fmd = new File(output_path + "/" + filename);
fmd.mkdirs();
continue;
}
- FileOutputStream fout = new FileOutputStream(output_path + filename);
+ FileOutputStream fout = new FileOutputStream(output_path + "/" + filename);
// cteni zipu a zapis
while ((count = zis.read(buffer)) != -1) {
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
index f8ce1fd..329d6a8 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
@@ -82,10 +82,10 @@ public class HSDataDialog extends DialogFragment {
private void saveData(String name, Integer local, Integer remote) {
ContentValues fields = new ContentValues();
- fields.put("name", name);
- fields.put("port", local);
- fields.put("onion_port", remote);
- fields.put("created_by_user", 1);
+ fields.put(HSContentProvider.HiddenService.NAME, name);
+ fields.put(HSContentProvider.HiddenService.PORT, local);
+ fields.put(HSContentProvider.HiddenService.ONION_PORT, remote);
+ fields.put(HSContentProvider.HiddenService.CREATED_BY_USER, 1);
ContentResolver cr = getContext().getContentResolver();
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
index 5ca4158..0c0d943 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
@@ -12,6 +12,7 @@ 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;
@@ -72,7 +73,9 @@ public class SelectBackupDialog extends DialogFragment {
backups.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- // TODO
+ BackupUtils backupUtils = new BackupUtils(view.getContext().getApplicationContext());
+ File p = (File) parent.getItemAtPosition(position);
+ backupUtils.restoreZipBackup(p);
}
});
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
index 2270f5d..fe6dbf1 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
@@ -16,10 +16,6 @@ import org.torproject.android.ui.hiddenservices.database.HSDatabase;
public class HSContentProvider extends ContentProvider {
- private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers";
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTH + "/hs");
-
public static final String[] PROJECTION = new String[]{
HiddenService._ID,
HiddenService.NAME,
@@ -28,7 +24,9 @@ public class HSContentProvider extends ContentProvider {
HiddenService.ONION_PORT,
HiddenService.CREATED_BY_USER
};
-
+ 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;
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d2057ff..656a3dd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -343,6 +343,7 @@
<string name="backup_service">Backup Service</string>
<string name="delete_service">Delete Service</string>
<string name="backup_saved_at_external_storage">Backup saved at external storage</string>
+ <string name="backup_restored">Backup restored</string>
<string name="filemanager_not_available">Filemanager not available</string>
<string name="please_grant_permissions_for_external_storage">Please grant permissions for external storage</string>
<string name="permission_granted">Permission granted</string>
1
0
commit b04d0eb17aa6b804c5f99b9fbca3ced63375580a
Author: arrase <arrase(a)gmail.com>
Date: Thu Nov 24 22:22:04 2016 +0100
actionbar permission request flow
---
.../ui/hiddenservices/HiddenServicesActivity.java | 28 +++++++++++++++++++---
.../ui/hiddenservices/dialogs/HSActionsDialog.java | 9 ++++---
.../hiddenservices/dialogs/SelectBackupDialog.java | 2 +-
.../hiddenservices/storage/PermissionManager.java | 8 +++----
app/src/main/res/values/strings.xml | 2 +-
5 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
index 119b13a..dc233bb 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
@@ -2,6 +2,7 @@ package org.torproject.android.ui.hiddenservices;
import android.content.ContentResolver;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
@@ -16,18 +17,18 @@ import android.widget.ListView;
import android.widget.TextView;
import org.torproject.android.R;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
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.SelectBackupDialog;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
+import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
public class HiddenServicesActivity extends AppCompatActivity {
+ public final int WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR = 1;
private ContentResolver mCR;
private OnionListAdapter mAdapter;
private Toolbar toolbar;
-
private String[] mProjection = new String[]{
HSContentProvider.HiddenService._ID,
HSContentProvider.HiddenService.NAME,
@@ -102,7 +103,7 @@ public class HiddenServicesActivity extends AppCompatActivity {
if (id == R.id.menu_restore_backup) {
if (PermissionManager.usesRuntimePermissions()
&& !PermissionManager.hasExternalWritePermission(this)) {
- PermissionManager.requestPermissions(this);
+ PermissionManager.requestPermissions(this, WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR);
return true;
}
@@ -114,6 +115,27 @@ public class HiddenServicesActivity extends AppCompatActivity {
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: {
+ SelectBackupDialog dialog = new SelectBackupDialog();
+ dialog.show(getSupportFragmentManager(), "SelectBackupDialog");
+ break;
+ }
+ case HSActionsDialog.WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG: {
+ // TODO
+ break;
+ }
+ }
+ }
+
class HSObserver extends ContentObserver {
HSObserver(Handler handler) {
super(handler);
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
index 103f87b..7d79fb2 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
@@ -17,11 +17,11 @@ import android.widget.Toast;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
+import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
public class HSActionsDialog extends DialogFragment {
- public final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
+ public static final int WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG = 2;
@NonNull
@Override
@@ -41,7 +41,10 @@ public class HSActionsDialog extends DialogFragment {
if (PermissionManager.usesRuntimePermissions()
&& !PermissionManager.hasExternalWritePermission(mContext)) {
- PermissionManager.requestPermissions(getActivity());
+
+ PermissionManager.requestPermissions(
+ getActivity(), WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG);
+
return;
}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
index ce2c717..5ca4158 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
@@ -11,8 +11,8 @@ import android.widget.AdapterView;
import android.widget.ListView;
import org.torproject.android.R;
-import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
import org.torproject.android.ui.hiddenservices.adapters.BackupAdapter;
+import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
import java.io.File;
import java.io.FilenameFilter;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
index 80706c5..3a3cf09 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
@@ -14,7 +14,6 @@ import android.view.View;
import org.torproject.android.R;
public class PermissionManager {
- private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
public static boolean usesRuntimePermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
@@ -25,7 +24,8 @@ public class PermissionManager {
return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
- public static void requestPermissions(FragmentActivity activity) {
+ public static void requestPermissions(FragmentActivity activity, int action) {
+ final int mAction = action;
final FragmentActivity mActivity = activity;
if (ActivityCompat.shouldShowRequestPermissionRationale
@@ -38,13 +38,13 @@ public class PermissionManager {
public void onClick(View v) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
+ mAction);
}
}).show();
} else {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
+ mAction);
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 97f2798..d2057ff 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -349,5 +349,5 @@
<string name="permission_denied">Permission denied</string>
<string name="restore_backup">Restore Backup</string>
<string name="create_a_backup_first">Create a backup first</string>
- <string name="name_can_t_be_empty">Name can't be empty</string>
+ <string name="name_can_t_be_empty">Name can\'t be empty</string>
</resources>
1
0
commit 22c573f70aee830ed92f308c5fad3cbb73148ee3
Author: arrase <arrase(a)gmail.com>
Date: Wed Nov 23 01:37:06 2016 +0100
adds AppDataProvider
---
app/build.gradle | 7 ++++
app/src/main/AndroidManifest.xml | 10 ++++++
.../android/storage/AppDataProvider.java | 39 ++++++++++++++++++++++
app/src/main/res/xml/hidden_services_paths.xml | 5 +++
4 files changed, 61 insertions(+)
diff --git a/app/build.gradle b/app/build.gradle
index cc364c7..7debed3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -26,9 +26,16 @@ android {
}
}
+repositories {
+ maven {
+ url "https://s3.amazonaws.com/repo.commonsware.com"
+ }
+}
+
dependencies {
compile project(':orbotservice')
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
+ compile 'com.commonsware.cwac:provider:0.4.4'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 24d989a..2df7eab 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -149,6 +149,16 @@
android:name=".ui.hs.providers.HSContentProvider"
android:exported="false"
android:authorities="org.torproject.android.ui.hs.providers" />
+
+ <provider
+ android:name="com.commonsware.cwac.provider.StreamProvider"
+ android:authorities="org.torproject.android.backup"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="com.commonsware.cwac.provider.STREAM_PROVIDER_PATHS"
+ android:resource="@xml/hidden_services_paths"/>
+ </provider>
</application>
</manifest>
\ No newline at end of file
diff --git a/app/src/main/java/org/torproject/android/storage/AppDataProvider.java b/app/src/main/java/org/torproject/android/storage/AppDataProvider.java
new file mode 100644
index 0000000..c04a293
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/storage/AppDataProvider.java
@@ -0,0 +1,39 @@
+package org.torproject.android.storage;
+
+
+import android.app.Application;
+import android.content.Context;
+
+import com.commonsware.cwac.provider.LocalPathStrategy;
+import com.commonsware.cwac.provider.StreamProvider;
+import com.commonsware.cwac.provider.StreamStrategy;
+
+import org.torproject.android.service.TorServiceConstants;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+public class AppDataProvider extends StreamProvider {
+ private static final String TAG = "app-data-path";
+
+ @Override
+ protected StreamStrategy buildStrategy(Context context,
+ String tag, String name,
+ String path,
+ HashMap<String, String> attrs)
+ throws IOException {
+
+ if (TAG.equals(tag)) {
+ return (new LocalPathStrategy(
+ name,
+ context.getDir(
+ TorServiceConstants.DIRECTORY_TOR_DATA,
+ Application.MODE_PRIVATE
+ )
+ )
+ );
+ }
+
+ return (super.buildStrategy(context, tag, name, path, attrs));
+ }
+}
diff --git a/app/src/main/res/xml/hidden_services_paths.xml b/app/src/main/res/xml/hidden_services_paths.xml
new file mode 100644
index 0000000..943fd09
--- /dev/null
+++ b/app/src/main/res/xml/hidden_services_paths.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+ <app-data-path name="hidden-services" path="hidden_services/"/>
+
+</paths>
\ No newline at end of file
1
0
commit d28db417827c601eddaf6be9f01326c68b9c3e03
Author: arrase <arrase(a)gmail.com>
Date: Thu Nov 24 02:56:11 2016 +0100
big refactor
---
app/src/main/AndroidManifest.xml | 10 +-
.../org/torproject/android/OrbotMainActivity.java | 6 +-
.../org/torproject/android/backup/BackupUtils.java | 65 ----------
.../java/org/torproject/android/backup/ZipIt.java | 98 ---------------
.../android/storage/AppDataProvider.java | 39 ------
.../android/storage/ExternalStorage.java | 34 ------
.../android/storage/PermissionManager.java | 50 --------
.../ui/hiddenservices/HiddenServicesActivity.java | 129 ++++++++++++++++++++
.../ui/hiddenservices/adapters/BackupAdapter.java | 50 ++++++++
.../hiddenservices/adapters/OnionListAdapter.java | 38 ++++++
.../ui/hiddenservices/backup/BackupUtils.java | 65 ++++++++++
.../android/ui/hiddenservices/backup/ZipIt.java | 98 +++++++++++++++
.../ui/hiddenservices/database/HSDatabase.java | 35 ++++++
.../ui/hiddenservices/dialogs/HSActionsDialog.java | 103 ++++++++++++++++
.../ui/hiddenservices/dialogs/HSDataDialog.java | 89 ++++++++++++++
.../hiddenservices/dialogs/SelectBackupDialog.java | 81 +++++++++++++
.../providers/HSContentProvider.java | 133 +++++++++++++++++++++
.../ui/hiddenservices/storage/AppDataProvider.java | 39 ++++++
.../ui/hiddenservices/storage/ExternalStorage.java | 34 ++++++
.../hiddenservices/storage/PermissionManager.java | 50 ++++++++
.../android/ui/hs/HiddenServicesActivity.java | 129 --------------------
.../android/ui/hs/adapters/BackupAdapter.java | 50 --------
.../android/ui/hs/adapters/OnionListAdapter.java | 38 ------
.../android/ui/hs/database/HSDatabase.java | 35 ------
.../android/ui/hs/dialogs/HSActionsDialog.java | 109 -----------------
.../android/ui/hs/dialogs/HSDataDialog.java | 89 --------------
.../android/ui/hs/dialogs/SelectBackupDialog.java | 81 -------------
.../android/ui/hs/providers/HSContentProvider.java | 133 ---------------------
app/src/main/res/layout/layout_hs_list_view.xml | 2 +-
.../main/res/layout/layout_hs_list_view_main.xml | 2 +-
.../org/torproject/android/service/TorService.java | 2 +-
31 files changed, 955 insertions(+), 961 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c099076..b7a5e87 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -137,7 +137,7 @@
</receiver>
<activity
- android:name=".ui.hs.HiddenServicesActivity"
+ android:name=".ui.hiddenservices.HiddenServicesActivity"
android:label="@string/title_activity_hidden_services"
android:theme="@style/DefaultTheme" >
<meta-data
@@ -146,13 +146,13 @@
</activity>
<provider
- android:name=".ui.hs.providers.HSContentProvider"
+ android:name=".ui.hiddenservices.providers.HSContentProvider"
android:exported="false"
- android:authorities="org.torproject.android.ui.hs.providers" />
+ android:authorities="org.torproject.android.ui.hiddenservices.providers" />
<provider
- android:name="org.torproject.android.storage.AppDataProvider"
- android:authorities="org.torproject.android.storage"
+ android:name=".ui.hiddenservices.storage.AppDataProvider"
+ android:authorities="org.torproject.android.ui.hiddenservices.storage"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 1ea9b6e..9a5bfb5 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -23,13 +23,13 @@ import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.service.util.TorServiceUtils;
import org.torproject.android.settings.SettingsPreferences;
import org.torproject.android.ui.AppManager;
-import org.torproject.android.ui.hs.HiddenServicesActivity;
+import org.torproject.android.ui.hiddenservices.HiddenServicesActivity;
import org.torproject.android.ui.ImageProgressView;
import org.torproject.android.ui.PromoAppsActivity;
import org.torproject.android.ui.Rotate3dAnimation;
-import org.torproject.android.ui.hs.providers.HSContentProvider;
+import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
import org.torproject.android.vpn.VPNEnableActivity;
-import org.torproject.android.backup.BackupUtils;
+import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
diff --git a/app/src/main/java/org/torproject/android/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/backup/BackupUtils.java
deleted file mode 100644
index 57d8c8d..0000000
--- a/app/src/main/java/org/torproject/android/backup/BackupUtils.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.torproject.android.backup;
-
-import android.app.Application;
-import android.content.Context;
-import android.widget.Toast;
-
-import org.torproject.android.service.R;
-import org.torproject.android.service.TorServiceConstants;
-import org.torproject.android.storage.ExternalStorage;
-
-import java.io.File;
-import java.io.IOException;
-
-public class BackupUtils {
- private File mHSBasePath;
- private Context mContext;
-
- public BackupUtils(Context context) {
- mContext = context;
- mHSBasePath = mContext.getDir(
- TorServiceConstants.DIRECTORY_TOR_DATA,
- Application.MODE_PRIVATE
- );
- }
-
- public String createZipBackup(Integer port) {
-
- File storage_path = ExternalStorage.getOrCreateBackupDir();
-
- if (storage_path == null)
- return null;
-
- String zip_path = storage_path.getAbsolutePath() + "/hs" + port + ".zip";
- String files[] = {
- mHSBasePath + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR + "/hs" + port + "/hostname",
- mHSBasePath + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR + "/hs" + port + "/private_key"
- };
-
- ZipIt zip = new ZipIt(files, zip_path);
-
- if (!zip.zip()) {
- return null;
- }
-
- return zip_path;
- }
-
- public void restoreZipBackup(Integer port, String path) {
- String hsBasePath;
-
- try {
- hsBasePath = mHSBasePath.getCanonicalPath() + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR;
- File hsPath = new File(hsBasePath, "/hs" + port);
- if (hsPath.mkdirs()) {
- ZipIt zip = new ZipIt(null, path);
- zip.unzip(hsPath.getCanonicalPath());
- return;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
- }
-}
diff --git a/app/src/main/java/org/torproject/android/backup/ZipIt.java b/app/src/main/java/org/torproject/android/backup/ZipIt.java
deleted file mode 100644
index bde29f0..0000000
--- a/app/src/main/java/org/torproject/android/backup/ZipIt.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.torproject.android.backup;
-
-
-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(String[] files, String zipFile) {
- _files = files;
- _zipFile = zipFile;
- }
-
- public boolean zip() {
- try {
- BufferedInputStream origin = null;
- 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;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/torproject/android/storage/AppDataProvider.java b/app/src/main/java/org/torproject/android/storage/AppDataProvider.java
deleted file mode 100644
index c04a293..0000000
--- a/app/src/main/java/org/torproject/android/storage/AppDataProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.torproject.android.storage;
-
-
-import android.app.Application;
-import android.content.Context;
-
-import com.commonsware.cwac.provider.LocalPathStrategy;
-import com.commonsware.cwac.provider.StreamProvider;
-import com.commonsware.cwac.provider.StreamStrategy;
-
-import org.torproject.android.service.TorServiceConstants;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-public class AppDataProvider extends StreamProvider {
- private static final String TAG = "app-data-path";
-
- @Override
- protected StreamStrategy buildStrategy(Context context,
- String tag, String name,
- String path,
- HashMap<String, String> attrs)
- throws IOException {
-
- if (TAG.equals(tag)) {
- return (new LocalPathStrategy(
- name,
- context.getDir(
- TorServiceConstants.DIRECTORY_TOR_DATA,
- Application.MODE_PRIVATE
- )
- )
- );
- }
-
- return (super.buildStrategy(context, tag, name, path, attrs));
- }
-}
diff --git a/app/src/main/java/org/torproject/android/storage/ExternalStorage.java b/app/src/main/java/org/torproject/android/storage/ExternalStorage.java
deleted file mode 100644
index bea196e..0000000
--- a/app/src/main/java/org/torproject/android/storage/ExternalStorage.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.torproject.android.storage;
-
-import android.os.Environment;
-
-import java.io.File;
-
-public class ExternalStorage {
- private static final String BACKUPS_DIR = "Orbot-HiddenServices";
-
- public static File getOrCreateBackupDir() {
- if (!isExternalStorageWritable())
- return null;
-
- File dir = new File(Environment.getExternalStorageDirectory(), 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);
- }
-}
diff --git a/app/src/main/java/org/torproject/android/storage/PermissionManager.java b/app/src/main/java/org/torproject/android/storage/PermissionManager.java
deleted file mode 100644
index 128db8e..0000000
--- a/app/src/main/java/org/torproject/android/storage/PermissionManager.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.torproject.android.storage;
-
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-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 {
- private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
-
- public static boolean usesRuntimePermissions() {
- return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
- }
-
- @SuppressLint("NewApi")
- public static boolean hasExternalWritePermission(Context context) {
- return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
- }
-
- public static void requestPermissions(FragmentActivity activity) {
- 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("ENABLE",
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ActivityCompat.requestPermissions(mActivity,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
- }
- }).show();
- } else {
- ActivityCompat.requestPermissions(mActivity,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
- }
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
new file mode 100644
index 0000000..119b13a
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
@@ -0,0 +1,129 @@
+package org.torproject.android.ui.hiddenservices;
+
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+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.TextView;
+
+import org.torproject.android.R;
+import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
+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.SelectBackupDialog;
+import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
+
+public class HiddenServicesActivity extends AppCompatActivity {
+ private ContentResolver mCR;
+ private OnionListAdapter mAdapter;
+ private Toolbar toolbar;
+
+ private String[] mProjection = new String[]{
+ HSContentProvider.HiddenService._ID,
+ HSContentProvider.HiddenService.NAME,
+ HSContentProvider.HiddenService.PORT,
+ HSContentProvider.HiddenService.DOMAIN,
+ HSContentProvider.HiddenService.CREATED_BY_USER
+ };
+
+ 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) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ mCR = getContentResolver();
+
+ FloatingActionButton 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,
+ mCR.query(HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null),
+ 0
+ );
+
+ mCR.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) {
+ TextView port = (TextView) view.findViewById(R.id.hs_port);
+ TextView onion = (TextView) view.findViewById(R.id.hs_onion);
+
+ Bundle arguments = new Bundle();
+ arguments.putString("port", port.getText().toString());
+ arguments.putString("onion", onion.getText().toString());
+
+ HSActionsDialog dialog = new HSActionsDialog();
+ dialog.setArguments(arguments);
+ dialog.show(getSupportFragmentManager(), "HSActionsDialog");
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.hs_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.menu_restore_backup) {
+ if (PermissionManager.usesRuntimePermissions()
+ && !PermissionManager.hasExternalWritePermission(this)) {
+ PermissionManager.requestPermissions(this);
+ return true;
+ }
+
+ SelectBackupDialog dialog = new SelectBackupDialog();
+ dialog.show(getSupportFragmentManager(), "SelectBackupDialog");
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ class HSObserver extends ContentObserver {
+ HSObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ mAdapter.changeCursor(mCR.query(
+ HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null
+ ));
+ }
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/BackupAdapter.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/BackupAdapter.java
new file mode 100644
index 0000000..196023b
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/BackupAdapter.java
@@ -0,0 +1,50 @@
+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;
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java
new file mode 100644
index 0000000..1edbef2
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java
@@ -0,0 +1,38 @@
+package org.torproject.android.ui.hiddenservices.adapters;
+
+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.TextView;
+
+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) {
+ 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)));
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ return cursorInflater.inflate(R.layout.layout_hs_list_item, parent, false);
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java
new file mode 100644
index 0000000..c60beb9
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java
@@ -0,0 +1,65 @@
+package org.torproject.android.ui.hiddenservices.backup;
+
+import android.app.Application;
+import android.content.Context;
+import android.widget.Toast;
+
+import org.torproject.android.service.R;
+import org.torproject.android.service.TorServiceConstants;
+import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
+
+import java.io.File;
+import java.io.IOException;
+
+public class BackupUtils {
+ private File mHSBasePath;
+ private Context mContext;
+
+ public BackupUtils(Context context) {
+ mContext = context;
+ mHSBasePath = mContext.getDir(
+ TorServiceConstants.DIRECTORY_TOR_DATA,
+ Application.MODE_PRIVATE
+ );
+ }
+
+ public String createZipBackup(Integer port) {
+
+ File storage_path = ExternalStorage.getOrCreateBackupDir();
+
+ if (storage_path == null)
+ return null;
+
+ String zip_path = storage_path.getAbsolutePath() + "/hs" + port + ".zip";
+ String files[] = {
+ mHSBasePath + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR + "/hs" + port + "/hostname",
+ mHSBasePath + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR + "/hs" + port + "/private_key"
+ };
+
+ ZipIt zip = new ZipIt(files, zip_path);
+
+ if (!zip.zip()) {
+ return null;
+ }
+
+ return zip_path;
+ }
+
+ public void restoreZipBackup(Integer port, String path) {
+ String hsBasePath;
+
+ try {
+ hsBasePath = mHSBasePath.getCanonicalPath() + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR;
+ File hsPath = new File(hsBasePath, "/hs" + port);
+ if (hsPath.mkdirs()) {
+ ZipIt zip = new ZipIt(null, path);
+ zip.unzip(hsPath.getCanonicalPath());
+ return;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
new file mode 100644
index 0000000..42e0bf9
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
@@ -0,0 +1,98 @@
+package org.torproject.android.ui.hiddenservices.backup;
+
+
+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(String[] files, String zipFile) {
+ _files = files;
+ _zipFile = zipFile;
+ }
+
+ public boolean zip() {
+ try {
+ BufferedInputStream origin = null;
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java
new file mode 100644
index 0000000..8f1123f
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java
@@ -0,0 +1,35 @@
+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";
+ 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, " +
+ "created_by_user INTEGER DEFAULT 0, " +
+ "port INTEGER);";
+
+ public HSDatabase(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(HS_DATA_TABLE_CREATE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ }
+}
+
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
new file mode 100644
index 0000000..103f87b
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
@@ -0,0 +1,103 @@
+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.storage.PermissionManager;
+import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
+
+public class HSActionsDialog extends DialogFragment {
+ public final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
+
+ @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.usesRuntimePermissions()
+ && !PermissionManager.hasExternalWritePermission(mContext)) {
+ PermissionManager.requestPermissions(getActivity());
+ 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 delete = (Button) dialog_view.findViewById(R.id.btn_hs_delete);
+ delete.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ v.getContext().getContentResolver().delete(
+ HSContentProvider.CONTENT_URI, "port=" + arguments.getString("port"), null
+ );
+ 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;
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
new file mode 100644
index 0000000..0b04135
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
@@ -0,0 +1,89 @@
+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.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()
+ );
+
+ if (checkInput(localPort, onionPort)) {
+ saveData(serverName, localPort, onionPort);
+ 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(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 (!is_ok) {
+ Toast.makeText(getContext(), error_msg, Toast.LENGTH_SHORT).show();
+ }
+
+ return is_ok;
+ }
+
+ private void saveData(String name, Integer local, Integer remote) {
+ ContentValues fields = new ContentValues();
+ fields.put("name", name);
+ fields.put("port", local);
+ fields.put("onion_port", remote);
+ fields.put("created_by_user", 1);
+
+ ContentResolver cr = getContext().getContentResolver();
+
+ cr.insert(HSContentProvider.CONTENT_URI, fields);
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
new file mode 100644
index 0000000..ce2c717
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectBackupDialog.java
@@ -0,0 +1,81 @@
+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.storage.ExternalStorage;
+import org.torproject.android.ui.hiddenservices.adapters.BackupAdapter;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class SelectBackupDialog 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) {
+ // TODO
+ }
+ });
+
+ return backupsDialog.create();
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
new file mode 100644
index 0000000..856c685
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
@@ -0,0 +1,133 @@
+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 {
+ 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;
+
+ //Inicializamos el UriMatcher
+ static {
+ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI(AUTH, "hs", ONIONS);
+ uriMatcher.addURI(AUTH, "hs/#", ONION_ID);
+ }
+
+ private HSDatabase mServerDB;
+ private Context mContext;
+
+ @Override
+ public boolean onCreate() {
+ mContext = getContext();
+ mServerDB = new HSDatabase(mContext);
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ //Si es una consulta a un ID concreto construimos el WHERE
+ String where = selection;
+ if (uriMatcher.match(uri) == ONION_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServerDB.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 = mServerDB.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) {
+
+ //Si es una consulta a un ID concreto construimos el WHERE
+ String where = selection;
+ if (uriMatcher.match(uri) == ONION_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServerDB.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 = mServerDB.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 CREATED_BY_USER = "created_by_user";
+
+ private HiddenService() {
+ }
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/AppDataProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/AppDataProvider.java
new file mode 100644
index 0000000..6e55569
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/AppDataProvider.java
@@ -0,0 +1,39 @@
+package org.torproject.android.ui.hiddenservices.storage;
+
+
+import android.app.Application;
+import android.content.Context;
+
+import com.commonsware.cwac.provider.LocalPathStrategy;
+import com.commonsware.cwac.provider.StreamProvider;
+import com.commonsware.cwac.provider.StreamStrategy;
+
+import org.torproject.android.service.TorServiceConstants;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+public class AppDataProvider extends StreamProvider {
+ private static final String TAG = "app-data-path";
+
+ @Override
+ protected StreamStrategy buildStrategy(Context context,
+ String tag, String name,
+ String path,
+ HashMap<String, String> attrs)
+ throws IOException {
+
+ if (TAG.equals(tag)) {
+ return (new LocalPathStrategy(
+ name,
+ context.getDir(
+ TorServiceConstants.DIRECTORY_TOR_DATA,
+ Application.MODE_PRIVATE
+ )
+ )
+ );
+ }
+
+ return (super.buildStrategy(context, tag, name, path, attrs));
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/ExternalStorage.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/ExternalStorage.java
new file mode 100644
index 0000000..cda3f8c
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/ExternalStorage.java
@@ -0,0 +1,34 @@
+package org.torproject.android.ui.hiddenservices.storage;
+
+import android.os.Environment;
+
+import java.io.File;
+
+public class ExternalStorage {
+ private static final String BACKUPS_DIR = "Orbot-HiddenServices";
+
+ public static File getOrCreateBackupDir() {
+ if (!isExternalStorageWritable())
+ return null;
+
+ File dir = new File(Environment.getExternalStorageDirectory(), 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);
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
new file mode 100644
index 0000000..80706c5
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
@@ -0,0 +1,50 @@
+package org.torproject.android.ui.hiddenservices.storage;
+
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+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 {
+ private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
+
+ public static boolean usesRuntimePermissions() {
+ return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
+ }
+
+ @SuppressLint("NewApi")
+ public static boolean hasExternalWritePermission(Context context) {
+ return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
+ }
+
+ public static void requestPermissions(FragmentActivity activity) {
+ 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("ENABLE",
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ActivityCompat.requestPermissions(mActivity,
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
+ }
+ }).show();
+ } else {
+ ActivityCompat.requestPermissions(mActivity,
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
+ }
+ }
+}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
deleted file mode 100644
index 4474668..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/HiddenServicesActivity.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.torproject.android.ui.hs;
-
-
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-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.TextView;
-
-import org.torproject.android.R;
-import org.torproject.android.storage.PermissionManager;
-import org.torproject.android.ui.hs.adapters.OnionListAdapter;
-import org.torproject.android.ui.hs.dialogs.HSActionsDialog;
-import org.torproject.android.ui.hs.dialogs.HSDataDialog;
-import org.torproject.android.ui.hs.dialogs.SelectBackupDialog;
-import org.torproject.android.ui.hs.providers.HSContentProvider;
-
-public class HiddenServicesActivity extends AppCompatActivity {
- private ContentResolver mCR;
- private OnionListAdapter mAdapter;
- private Toolbar toolbar;
-
- private String[] mProjection = new String[]{
- HSContentProvider.HiddenService._ID,
- HSContentProvider.HiddenService.NAME,
- HSContentProvider.HiddenService.PORT,
- HSContentProvider.HiddenService.DOMAIN,
- HSContentProvider.HiddenService.CREATED_BY_USER
- };
-
- 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) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- mCR = getContentResolver();
-
- FloatingActionButton 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,
- mCR.query(HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null),
- 0
- );
-
- mCR.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) {
- TextView port = (TextView) view.findViewById(R.id.hs_port);
- TextView onion = (TextView) view.findViewById(R.id.hs_onion);
-
- Bundle arguments = new Bundle();
- arguments.putString("port", port.getText().toString());
- arguments.putString("onion", onion.getText().toString());
-
- HSActionsDialog dialog = new HSActionsDialog();
- dialog.setArguments(arguments);
- dialog.show(getSupportFragmentManager(), "HSActionsDialog");
- }
- });
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.hs_menu, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
-
- if (id == R.id.menu_restore_backup) {
- if (PermissionManager.usesRuntimePermissions()
- && !PermissionManager.hasExternalWritePermission(this)) {
- PermissionManager.requestPermissions(this);
- return true;
- }
-
- SelectBackupDialog dialog = new SelectBackupDialog();
- dialog.show(getSupportFragmentManager(), "SelectBackupDialog");
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- class HSObserver extends ContentObserver {
- HSObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- mAdapter.changeCursor(mCR.query(
- HSContentProvider.CONTENT_URI, mProjection, mWhere, null, null
- ));
- }
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/adapters/BackupAdapter.java b/app/src/main/java/org/torproject/android/ui/hs/adapters/BackupAdapter.java
deleted file mode 100644
index bcc7a5a..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/adapters/BackupAdapter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.torproject.android.ui.hs.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;
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/adapters/OnionListAdapter.java b/app/src/main/java/org/torproject/android/ui/hs/adapters/OnionListAdapter.java
deleted file mode 100644
index 0ae10cb..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/adapters/OnionListAdapter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.torproject.android.ui.hs.adapters;
-
-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.TextView;
-
-import org.torproject.android.R;
-import org.torproject.android.ui.hs.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) {
- 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)));
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return cursorInflater.inflate(R.layout.layout_hs_list_item, parent, false);
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/database/HSDatabase.java b/app/src/main/java/org/torproject/android/ui/hs/database/HSDatabase.java
deleted file mode 100644
index 07e2ca2..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/database/HSDatabase.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.torproject.android.ui.hs.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";
- 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, " +
- "created_by_user INTEGER DEFAULT 0, " +
- "port INTEGER);";
-
- public HSDatabase(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(HS_DATA_TABLE_CREATE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
-}
-
diff --git a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java
deleted file mode 100644
index d5603b7..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSActionsDialog.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.torproject.android.ui.hs.dialogs;
-
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.app.Dialog;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-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.backup.BackupUtils;
-import org.torproject.android.storage.PermissionManager;
-import org.torproject.android.ui.hs.providers.HSContentProvider;
-
-public class HSActionsDialog extends DialogFragment {
- public final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
-
- @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.usesRuntimePermissions()
- && !PermissionManager.hasExternalWritePermission(mContext)) {
- PermissionManager.requestPermissions(getActivity());
- 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 delete = (Button) dialog_view.findViewById(R.id.btn_hs_delete);
- delete.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- v.getContext().getContentResolver().delete(
- HSContentProvider.CONTENT_URI, "port=" + arguments.getString("port"), null
- );
- 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;
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSDataDialog.java b/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSDataDialog.java
deleted file mode 100644
index 922b7f0..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/dialogs/HSDataDialog.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.torproject.android.ui.hs.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.hs.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()
- );
-
- if (checkInput(localPort, onionPort)) {
- saveData(serverName, localPort, onionPort);
- 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(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 (!is_ok) {
- Toast.makeText(getContext(), error_msg, Toast.LENGTH_SHORT).show();
- }
-
- return is_ok;
- }
-
- private void saveData(String name, Integer local, Integer remote) {
- ContentValues fields = new ContentValues();
- fields.put("name", name);
- fields.put("port", local);
- fields.put("onion_port", remote);
- fields.put("created_by_user", 1);
-
- ContentResolver cr = getContext().getContentResolver();
-
- cr.insert(HSContentProvider.CONTENT_URI, fields);
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/dialogs/SelectBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hs/dialogs/SelectBackupDialog.java
deleted file mode 100644
index 37c722b..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/dialogs/SelectBackupDialog.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.torproject.android.ui.hs.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.storage.ExternalStorage;
-import org.torproject.android.ui.hs.adapters.BackupAdapter;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class SelectBackupDialog 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) {
- // TODO
- }
- });
-
- return backupsDialog.create();
- }
-}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java
deleted file mode 100644
index f222b85..0000000
--- a/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.torproject.android.ui.hs.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.hs.database.HSDatabase;
-
-
-public class HSContentProvider extends ContentProvider {
- private static final String AUTH = "org.torproject.android.ui.hs.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;
-
- //Inicializamos el UriMatcher
- static {
- uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- uriMatcher.addURI(AUTH, "hs", ONIONS);
- uriMatcher.addURI(AUTH, "hs/#", ONION_ID);
- }
-
- private HSDatabase mServerDB;
- private Context mContext;
-
- @Override
- public boolean onCreate() {
- mContext = getContext();
- mServerDB = new HSDatabase(mContext);
- return true;
- }
-
- @Nullable
- @Override
- public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- //Si es una consulta a un ID concreto construimos el WHERE
- String where = selection;
- if (uriMatcher.match(uri) == ONION_ID) {
- where = "_id=" + uri.getLastPathSegment();
- }
-
- SQLiteDatabase db = mServerDB.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 = mServerDB.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) {
-
- //Si es una consulta a un ID concreto construimos el WHERE
- String where = selection;
- if (uriMatcher.match(uri) == ONION_ID) {
- where = "_id=" + uri.getLastPathSegment();
- }
-
- SQLiteDatabase db = mServerDB.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 = mServerDB.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 CREATED_BY_USER = "created_by_user";
-
- private HiddenService() {
- }
- }
-}
diff --git a/app/src/main/res/layout/layout_hs_list_view.xml b/app/src/main/res/layout/layout_hs_list_view.xml
index c47a392..3e7b32f 100644
--- a/app/src/main/res/layout/layout_hs_list_view.xml
+++ b/app/src/main/res/layout/layout_hs_list_view.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
- tools:context="org.torproject.android.ui.hs.HiddenServicesActivity">
+ tools:context="org.torproject.android.ui.hiddenservices.HiddenServicesActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/layout_hs_list_view_main.xml b/app/src/main/res/layout/layout_hs_list_view_main.xml
index bb1c94c..284a01c 100644
--- a/app/src/main/res/layout/layout_hs_list_view_main.xml
+++ b/app/src/main/res/layout/layout_hs_list_view_main.xml
@@ -10,7 +10,7 @@
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- tools:context="org.torproject.android.ui.hs.HiddenServicesActivity"
+ tools:context="org.torproject.android.ui.hiddenservices.HiddenServicesActivity"
tools:showIn="@layout/layout_hs_list_view">
<ListView
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index f8ed3b3..6d12424 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -132,7 +132,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
private Shell mShellPolipo;
- private static final Uri CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hs.providers/hs");
+ private static final Uri CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers/hs");
public static final class HiddenService implements BaseColumns {
public static final String NAME = "name";
1
0
commit da601d86ef9725d05e3aa684fe8c6b10e2f010d4
Author: arrase <arrase(a)gmail.com>
Date: Thu Nov 24 02:35:00 2016 +0100
layout fix
---
app/src/main/res/layout/layout_hs_backups_list.xml | 6 +++---
app/src/main/res/layout/layout_hs_backups_list_item.xml | 3 ++-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/app/src/main/res/layout/layout_hs_backups_list.xml b/app/src/main/res/layout/layout_hs_backups_list.xml
index d1db786..521f381 100644
--- a/app/src/main/res/layout/layout_hs_backups_list.xml
+++ b/app/src/main/res/layout/layout_hs_backups_list.xml
@@ -2,11 +2,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="15dp">
+ android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:id="@+id/listview_hs_backups" />
+ android:id="@+id/listview_hs_backups"
+ android:layout_marginTop="15dp" />
</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_hs_backups_list_item.xml b/app/src/main/res/layout/layout_hs_backups_list_item.xml
index 40a9ede..eb32ec2 100644
--- a/app/src/main/res/layout/layout_hs_backups_list_item.xml
+++ b/app/src/main/res/layout/layout_hs_backups_list_item.xml
@@ -19,6 +19,7 @@
android:id="@+id/backup_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textSize="30sp" />
+ android:textSize="30sp"
+ android:layout_marginBottom="5dp" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
1
0

02 Mar '17
commit 0818b0c96313d47493b5d34afd95ada4b19adc3c
Author: arrase <arrase(a)gmail.com>
Date: Wed Nov 23 00:12:06 2016 +0100
isolate hidden services configuration dirs
---
.../java/org/torproject/android/backup/BackupUtils.java | 13 ++++++++-----
.../android/ui/hs/providers/HSContentProvider.java | 1 -
.../java/org/torproject/android/service/TorService.java | 17 +++++++++++------
.../torproject/android/service/TorServiceConstants.java | 2 ++
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/backup/BackupUtils.java
index 42c98f8..5d77d17 100644
--- a/app/src/main/java/org/torproject/android/backup/BackupUtils.java
+++ b/app/src/main/java/org/torproject/android/backup/BackupUtils.java
@@ -9,10 +9,13 @@ import org.torproject.android.storage.ExternalStorage;
import java.io.File;
public class BackupUtils {
- private static File appCacheHome;
+ private static File mHSBasePath;
public BackupUtils(Context context) {
- appCacheHome = context.getDir(TorServiceConstants.DIRECTORY_TOR_DATA, Application.MODE_PRIVATE);
+ mHSBasePath = context.getDir(
+ TorServiceConstants.DIRECTORY_TOR_DATA + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR,
+ Application.MODE_PRIVATE
+ );
}
public String createOnionBackup(Integer port) {
@@ -25,8 +28,8 @@ public class BackupUtils {
String zip_path = storage_path + "/hs" + port + ".zip";
String files[] = {
- appCacheHome + "/hs" + port + "/hostname",
- appCacheHome + "/hs" + port + "/private_key"
+ mHSBasePath + "/hs" + port + "/hostname",
+ mHSBasePath + "/hs" + port + "/private_key"
};
ZipIt zip = new ZipIt(files, zip_path);
@@ -40,6 +43,6 @@ public class BackupUtils {
public void restoreOnionBackup(Integer port, String path) {
ZipIt zip = new ZipIt(null, path);
- zip.unzip(appCacheHome + "/hs" + port);
+ zip.unzip(mHSBasePath + "/hs" + port);
}
}
diff --git a/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java
index 2c031d8..f222b85 100644
--- a/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java
+++ b/app/src/main/java/org/torproject/android/ui/hs/providers/HSContentProvider.java
@@ -121,7 +121,6 @@ public class HSContentProvider extends ContentProvider {
}
public static final class HiddenService implements BaseColumns {
- //Nombres de columnas
public static final String NAME = "name";
public static final String PORT = "port";
public static final String ONION_PORT = "onion_port";
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index dfd0195..f8ed3b3 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -23,14 +23,12 @@ import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.BaseColumns;
@@ -128,18 +126,20 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
public static File fileObfsclient;
public static File fileXtables;
public static File fileTorRc;
+ private File mHSBasePath;
private Shell mShell;
private Shell mShellPolipo;
+
private static final Uri CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hs.providers/hs");
public static final class HiddenService implements BaseColumns {
- //Nombres de columnas
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 CREATED_BY_USER = "created_by_user";
private HiddenService() {
}
@@ -147,7 +147,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
private String[] mProjection = new String[]{
HiddenService._ID,
- HiddenService.NAME,
HiddenService.DOMAIN,
HiddenService.PORT,
HiddenService.ONION_PORT};
@@ -532,6 +531,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
fileXtables = new File(appBinHome, TorServiceConstants.IPTABLES_ASSET_KEY);
fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY);
+ mHSBasePath = new File(appCacheHome , TorServiceConstants.HIDDEN_SERVICES_DIR);
+
+ if (!mHSBasePath.isDirectory()) {
+ mHSBasePath.mkdirs();
+ }
+
mEventHandler = new TorEventHandler(this);
if (mNotificationManager == null)
@@ -773,7 +778,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
// Update only new domains
if(HSDomain == null || HSDomain.length() < 1) {
- String hsDirPath = new File(appCacheHome,"hs" + HSLocalPort).getCanonicalPath();
+ String hsDirPath = new File(mHSBasePath.getAbsolutePath(),"hs" + HSLocalPort).getCanonicalPath();
File file = new File(hsDirPath, "hostname");
if (file.exists())
@@ -1782,7 +1787,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
while (hidden_services.moveToNext()) {
Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.PORT));
Integer HSOnionPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.ONION_PORT));
- String hsDirPath = new File(appCacheHome,"hs" + HSLocalPort).getCanonicalPath();
+ String hsDirPath = new File(mHSBasePath.getAbsolutePath(),"hs" + HSLocalPort).getCanonicalPath();
debug("Adding hidden service on port: " + HSLocalPort);
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
index 00ade29..9bc5a03 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
@@ -159,4 +159,6 @@ public interface TorServiceConstants {
"meek_lite 0.0.2.0:3 url=https://az668014.vo.msecnd.net/ front=ajax.aspnetcdn.com"
};
+ public static final String HIDDEN_SERVICES_DIR = "hidden_services";
+
}
1
0
commit 85de87f0a0326878f4fb439b8156fe6f6d2c769a
Author: arrase <arrase(a)gmail.com>
Date: Thu Nov 24 02:30:19 2016 +0100
layout fix
---
app/src/main/res/layout/layout_hs_backups_list.xml | 4 +++-
app/src/main/res/layout/layout_hs_backups_list_item.xml | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/src/main/res/layout/layout_hs_backups_list.xml b/app/src/main/res/layout/layout_hs_backups_list.xml
index 6c123ff..d1db786 100644
--- a/app/src/main/res/layout/layout_hs_backups_list.xml
+++ b/app/src/main/res/layout/layout_hs_backups_list.xml
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layout_marginTop="15dp">
<ListView
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/layout_hs_backups_list_item.xml b/app/src/main/res/layout/layout_hs_backups_list_item.xml
index fe76d47..40a9ede 100644
--- a/app/src/main/res/layout/layout_hs_backups_list_item.xml
+++ b/app/src/main/res/layout/layout_hs_backups_list_item.xml
@@ -19,6 +19,6 @@
android:id="@+id/backup_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textSize="35sp" />
+ android:textSize="30sp" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
1
0