diff options
Diffstat (limited to 'app/src/main')
32 files changed, 933 insertions, 0 deletions
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 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
3 | package="org.pacien.tincapp"> | ||
4 | |||
5 | <uses-permission android:name="android.permission.INTERNET"/> | ||
6 | <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> | ||
7 | |||
8 | <application | ||
9 | android:allowBackup="false" | ||
10 | android:icon="@mipmap/ic_launcher" | ||
11 | android:label="@string/app_label" | ||
12 | android:supportsRtl="true" | ||
13 | android:theme="@style/AppTheme"> | ||
14 | |||
15 | <activity | ||
16 | android:name=".activities.StartActivity" | ||
17 | android:label="@string/app_label" | ||
18 | android:theme="@style/AppTheme.NoActionBar"> | ||
19 | <intent-filter> | ||
20 | <action android:name="android.intent.action.MAIN"/> | ||
21 | <category android:name="android.intent.category.LAUNCHER"/> | ||
22 | </intent-filter> | ||
23 | </activity> | ||
24 | |||
25 | <service | ||
26 | android:name="org.pacien.tincapp.service.TincVpnService" | ||
27 | android:permission="android.permission.BIND_VPN_SERVICE"> | ||
28 | <intent-filter> | ||
29 | <action android:name="android.net.VpnService"/> | ||
30 | </intent-filter> | ||
31 | </service> | ||
32 | |||
33 | </application> | ||
34 | |||
35 | </manifest> | ||
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 @@ | |||
1 | #include <jni.h> | ||
2 | #include <unistd.h> | ||
3 | #include <stdlib.h> | ||
4 | |||
5 | static inline const char **to_string_array(JNIEnv *env, jobjectArray ja) { | ||
6 | const int len = (*env)->GetArrayLength(env, ja); | ||
7 | const char **ca = calloc((size_t) len + 1, sizeof(char *)); | ||
8 | |||
9 | for (int i = 0; i < len; ++i) { | ||
10 | jstring jstr = (jstring) (*env)->GetObjectArrayElement(env, ja, i); | ||
11 | ca[i] = (*env)->GetStringUTFChars(env, jstr, NULL); | ||
12 | } | ||
13 | |||
14 | ca[len] = NULL; | ||
15 | return ca; | ||
16 | } | ||
17 | |||
18 | static inline void exec(const char **argcv) { | ||
19 | execv(argcv[0], (char *const *) argcv); | ||
20 | exit(1); | ||
21 | } | ||
22 | |||
23 | JNIEXPORT jint JNICALL | ||
24 | Java_org_pacien_tincapp_commands_Executor_forkExec(JNIEnv *env, jclass class, jobjectArray argcv) { | ||
25 | pid_t pid = fork(); | ||
26 | switch (pid) { | ||
27 | case 0: | ||
28 | exec(to_string_array(env, argcv)); | ||
29 | return 0; | ||
30 | |||
31 | default: | ||
32 | return pid; | ||
33 | } | ||
34 | } | ||
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 @@ | |||
1 | package org.pacien.tincapp.activities; | ||
2 | |||
3 | import android.content.ClipData; | ||
4 | import android.content.ClipboardManager; | ||
5 | import android.content.Context; | ||
6 | import android.content.Intent; | ||
7 | import android.net.Uri; | ||
8 | import android.os.Bundle; | ||
9 | import android.support.annotation.StringRes; | ||
10 | import android.support.design.widget.Snackbar; | ||
11 | import android.support.v7.app.AlertDialog; | ||
12 | import android.support.v7.app.AppCompatActivity; | ||
13 | import android.support.v7.widget.Toolbar; | ||
14 | import android.view.Menu; | ||
15 | import android.view.MenuItem; | ||
16 | import android.view.ViewGroup; | ||
17 | |||
18 | import org.pacien.tincapp.BuildConfig; | ||
19 | import org.pacien.tincapp.R; | ||
20 | import org.pacien.tincapp.context.AppInfo; | ||
21 | |||
22 | /** | ||
23 | * @author pacien | ||
24 | */ | ||
25 | public abstract class BaseActivity extends AppCompatActivity { | ||
26 | |||
27 | @Override | ||
28 | protected void onCreate(Bundle savedInstanceState) { | ||
29 | super.onCreate(savedInstanceState); | ||
30 | setContentView(R.layout.base); | ||
31 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | ||
32 | setSupportActionBar(toolbar); | ||
33 | } | ||
34 | |||
35 | @Override | ||
36 | public boolean onCreateOptionsMenu(Menu m) { | ||
37 | getMenuInflater().inflate(R.menu.menu_base, m); | ||
38 | return true; | ||
39 | } | ||
40 | |||
41 | public void aboutDialog(MenuItem i) { | ||
42 | new AlertDialog.Builder(this) | ||
43 | .setTitle(BuildConfig.APPLICATION_ID) | ||
44 | .setMessage(getResources().getString(R.string.app_short_desc) + "\n\n" + | ||
45 | getResources().getString(R.string.app_copyright) + " " + | ||
46 | getResources().getString(R.string.app_license) + "\n\n" + | ||
47 | AppInfo.all(getResources())) | ||
48 | .setNeutralButton(R.string.action_open_project_website, (dialog, which) -> openWebsite(R.string.app_website_url)) | ||
49 | .setPositiveButton(R.string.action_close, (dialog, which) -> { /* nop */ }) | ||
50 | .show(); | ||
51 | } | ||
52 | |||
53 | protected ViewGroup getContentView() { | ||
54 | return (ViewGroup) findViewById(R.id.main_content); | ||
55 | } | ||
56 | |||
57 | protected void openWebsite(@StringRes int url) { | ||
58 | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getResources().getString(url)))); | ||
59 | } | ||
60 | |||
61 | protected void notify(@StringRes int msg) { | ||
62 | Snackbar.make(findViewById(R.id.activity_base), msg, Snackbar.LENGTH_LONG).show(); | ||
63 | } | ||
64 | |||
65 | protected void copyIntoClipboard(String label, String str) { | ||
66 | ClipboardManager c = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); | ||
67 | c.setPrimaryClip(ClipData.newPlainText(label, str)); | ||
68 | notify(R.string.message_text_copied); | ||
69 | } | ||
70 | |||
71 | } | ||
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 @@ | |||
1 | package org.pacien.tincapp.activities; | ||
2 | |||
3 | import android.annotation.SuppressLint; | ||
4 | import android.content.Intent; | ||
5 | import android.os.Bundle; | ||
6 | import android.support.v7.app.AlertDialog; | ||
7 | import android.view.View; | ||
8 | import android.view.ViewGroup; | ||
9 | import android.widget.EditText; | ||
10 | import android.widget.FrameLayout; | ||
11 | |||
12 | import org.pacien.tincapp.R; | ||
13 | import org.pacien.tincapp.commands.PermissionFixer; | ||
14 | import org.pacien.tincapp.context.AppPaths; | ||
15 | import org.pacien.tincapp.service.TincVpnService; | ||
16 | |||
17 | /** | ||
18 | * @author pacien | ||
19 | */ | ||
20 | public class StartActivity extends BaseActivity { | ||
21 | |||
22 | @Override | ||
23 | protected void onCreate(Bundle savedInstanceState) { | ||
24 | super.onCreate(savedInstanceState); | ||
25 | getLayoutInflater().inflate(R.layout.page_start, getContentView()); | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | protected void onActivityResult(int request, int result, Intent data) { | ||
30 | notify(result == RESULT_OK ? R.string.message_vpn_permissions_granted : R.string.message_vpn_permissions_denied); | ||
31 | } | ||
32 | |||