From 2495d8032eb6839a55080b79ac818383c2f75b79 Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Fri, 5 May 2017 01:02:16 +0200 Subject: Import unversioned prototype --- app/src/main/AndroidManifest.xml | 35 +++++++++ app/src/main/c/exec.c | 34 +++++++++ .../pacien/tincapp/activities/BaseActivity.java | 71 ++++++++++++++++++ .../pacien/tincapp/activities/StartActivity.java | 82 +++++++++++++++++++++ .../java/org/pacien/tincapp/commands/Command.java | 67 +++++++++++++++++ .../java/org/pacien/tincapp/commands/Executor.java | 44 +++++++++++ .../pacien/tincapp/commands/PermissionFixer.java | 34 +++++++++ .../java/org/pacien/tincapp/commands/Tinc.java | 60 +++++++++++++++ .../java/org/pacien/tincapp/commands/Tincd.java | 28 +++++++ .../java/org/pacien/tincapp/context/AppInfo.java | 42 +++++++++++ .../java/org/pacien/tincapp/context/AppPaths.java | 75 +++++++++++++++++++ .../org/pacien/tincapp/service/TincVpnService.java | 51 +++++++++++++ .../tincapp/service/VpnInterfaceConfigurator.java | 81 ++++++++++++++++++++ .../java/org/pacien/tincapp/util/Function.java | 28 +++++++ app/src/main/res/drawable/ic_help_primary_24dp.xml | 9 +++ app/src/main/res/icon.png | Bin 0 -> 13933 bytes app/src/main/res/icon.svg | 1 + app/src/main/res/layout/base.xml | 47 ++++++++++++ app/src/main/res/layout/dialog_frame.xml | 11 +++ app/src/main/res/layout/page_start.xml | 43 +++++++++++ app/src/main/res/menu/menu_base.xml | 14 ++++ app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 1103 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 777 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1400 bytes app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 2312 bytes app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 3425 bytes app/src/main/res/values-v21/styles.xml | 8 ++ app/src/main/res/values-w820dp/dimens.xml | 3 + app/src/main/res/values/colors.xml | 7 ++ app/src/main/res/values/dimens.xml | 9 +++ app/src/main/res/values/strings.xml | 33 +++++++++ app/src/main/res/values/styles.xml | 16 ++++ 32 files changed, 933 insertions(+) create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/c/exec.c create mode 100644 app/src/main/java/org/pacien/tincapp/activities/BaseActivity.java create mode 100644 app/src/main/java/org/pacien/tincapp/activities/StartActivity.java create mode 100644 app/src/main/java/org/pacien/tincapp/commands/Command.java create mode 100644 app/src/main/java/org/pacien/tincapp/commands/Executor.java create mode 100644 app/src/main/java/org/pacien/tincapp/commands/PermissionFixer.java create mode 100644 app/src/main/java/org/pacien/tincapp/commands/Tinc.java create mode 100644 app/src/main/java/org/pacien/tincapp/commands/Tincd.java create mode 100644 app/src/main/java/org/pacien/tincapp/context/AppInfo.java create mode 100644 app/src/main/java/org/pacien/tincapp/context/AppPaths.java create mode 100644 app/src/main/java/org/pacien/tincapp/service/TincVpnService.java create mode 100644 app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfigurator.java create mode 100644 app/src/main/java/org/pacien/tincapp/util/Function.java create mode 100644 app/src/main/res/drawable/ic_help_primary_24dp.xml create mode 100644 app/src/main/res/icon.png create mode 100644 app/src/main/res/icon.svg create mode 100644 app/src/main/res/layout/base.xml create mode 100644 app/src/main/res/layout/dialog_frame.xml create mode 100644 app/src/main/res/layout/page_start.xml create mode 100644 app/src/main/res/menu/menu_base.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-v21/styles.xml create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml (limited to 'app/src/main') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2822d37 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/c/exec.c b/app/src/main/c/exec.c new file mode 100644 index 0000000..fdaec0f --- /dev/null +++ b/app/src/main/c/exec.c @@ -0,0 +1,34 @@ +#include +#include +#include + +static inline const char **to_string_array(JNIEnv *env, jobjectArray ja) { + const int len = (*env)->GetArrayLength(env, ja); + const char **ca = calloc((size_t) len + 1, sizeof(char *)); + + for (int i = 0; i < len; ++i) { + jstring jstr = (jstring) (*env)->GetObjectArrayElement(env, ja, i); + ca[i] = (*env)->GetStringUTFChars(env, jstr, NULL); + } + + ca[len] = NULL; + return ca; +} + +static inline void exec(const char **argcv) { + execv(argcv[0], (char *const *) argcv); + exit(1); +} + +JNIEXPORT jint JNICALL +Java_org_pacien_tincapp_commands_Executor_forkExec(JNIEnv *env, jclass class, jobjectArray argcv) { + pid_t pid = fork(); + switch (pid) { + case 0: + exec(to_string_array(env, argcv)); + return 0; + + default: + return pid; + } +} diff --git a/app/src/main/java/org/pacien/tincapp/activities/BaseActivity.java b/app/src/main/java/org/pacien/tincapp/activities/BaseActivity.java new file mode 100644 index 0000000..0e6cb95 --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/activities/BaseActivity.java @@ -0,0 +1,71 @@ +package org.pacien.tincapp.activities; + +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.StringRes; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.ViewGroup; + +import org.pacien.tincapp.BuildConfig; +import org.pacien.tincapp.R; +import org.pacien.tincapp.context.AppInfo; + +/** + * @author pacien + */ +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.base); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + } + + @Override + public boolean onCreateOptionsMenu(Menu m) { + getMenuInflater().inflate(R.menu.menu_base, m); + return true; + } + + public void aboutDialog(MenuItem i) { + new AlertDialog.Builder(this) + .setTitle(BuildConfig.APPLICATION_ID) + .setMessage(getResources().getString(R.string.app_short_desc) + "\n\n" + + getResources().getString(R.string.app_copyright) + " " + + getResources().getString(R.string.app_license) + "\n\n" + + AppInfo.all(getResources())) + .setNeutralButton(R.string.action_open_project_website, (dialog, which) -> openWebsite(R.string.app_website_url)) + .setPositiveButton(R.string.action_close, (dialog, which) -> { /* nop */ }) + .show(); + } + + protected ViewGroup getContentView() { + return (ViewGroup) findViewById(R.id.main_content); + } + + protected void openWebsite(@StringRes int url) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getResources().getString(url)))); + } + + protected void notify(@StringRes int msg) { + Snackbar.make(findViewById(R.id.activity_base), msg, Snackbar.LENGTH_LONG).show(); + } + + protected void copyIntoClipboard(String label, String str) { + ClipboardManager c = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + c.setPrimaryClip(ClipData.newPlainText(label, str)); + notify(R.string.message_text_copied); + } + +} diff --git a/app/src/main/java/org/pacien/tincapp/activities/StartActivity.java b/app/src/main/java/org/pacien/tincapp/activities/StartActivity.java new file mode 100644 index 0000000..e469fa0 --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/activities/StartActivity.java @@ -0,0 +1,82 @@ +package org.pacien.tincapp.activities; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.FrameLayout; + +import org.pacien.tincapp.R; +import org.pacien.tincapp.commands.PermissionFixer; +import org.pacien.tincapp.context.AppPaths; +import org.pacien.tincapp.service.TincVpnService; + +/** + * @author pacien + */ +public class StartActivity extends BaseActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLayoutInflater().inflate(R.layout.page_start, getContentView()); + } + + @Override + protected void onActivityResult(int request, int result, Intent data) { + notify(result == RESULT_OK ? R.string.message_vpn_permissions_granted : R.string.message_vpn_permissions_denied); + } + + public void requestVpnPermission(View v) { + Intent askPermIntent = TincVpnService.prepare(this); + + if (askPermIntent != null) + startActivityForResult(askPermIntent, 0); + else + onActivityResult(0, RESULT_OK, null); + } + + public void startVpnDialog(View v) { + final EditText i = new EditText(this); + i.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); + i.setHint(R.string.field_net_name); + + @SuppressLint("InflateParams") + ViewGroup vg = (ViewGroup) getLayoutInflater().inflate(R.layout.dialog_frame, null); + vg.addView(i); + + new AlertDialog.Builder(this) + .setTitle(R.string.title_connect_to_network) + .setView(vg) + .setPositiveButton(R.string.action_connect, (dialog, which) -> startVpn(i.getText().toString())) + .setNegativeButton(R.string.action_close, (dialog, which) -> { /* nop */ }) + .show(); + } + + public void confDirDialog(View v) { + String confDir = AppPaths.confDir(this).getPath(); + + new AlertDialog.Builder(this) + .setTitle(R.string.title_tinc_config_dir) + .setMessage(confDir) + .setNeutralButton(R.string.action_fix_perms, (dialog, which) -> fixPerms()) + .setNegativeButton(R.string.action_copy, + (dialog, which) -> copyIntoClipboard(getResources().getString(R.string.title_tinc_config_dir), confDir)) + .setPositiveButton(R.string.action_close, (dialog, which) -> { /* nop */ }) + .show(); + } + + private void startVpn(String netName) { + startService(new Intent(this, TincVpnService.class) + .putExtra(TincVpnService.INTENT_EXTRA_NET_NAME, netName)); + } + + private void fixPerms() { + boolean ok = PermissionFixer.makePrivateDirsPublic(getApplicationContext()); + notify(ok ? R.string.message_perms_fixed : R.string.message_perms_fix_failure); + } + +} diff --git a/app/src/main/java/org/pacien/tincapp/commands/Command.java b/app/src/main/java/org/pacien/tincapp/commands/Command.java new file mode 100644 index 0000000..28ff226 --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/commands/Command.java @@ -0,0 +1,67 @@ +package org.pacien.tincapp.commands; + +import com.annimon.stream.Collectors; +import com.annimon.stream.Optional; +import com.annimon.stream.Stream; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * @author pacien + */ +class Command { + + static private class Option { + final String key; + final Optional val; + + Option(String key, String val) { + this.key = key; + this.val = Optional.ofNullable(val); + } + + @Override + public String toString() { + return val.isPresent() ? "--" + key + "=" + val.get() : "--" + key; + } + } + + final private String cmd; + final private List