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 --- .../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 ++++++++ 12 files changed, 663 insertions(+) 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 (limited to 'app/src/main/java') 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