Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for the Android VPN client #1

Open
wants to merge 25 commits into
base: feature/android-port
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
deea38a
Move the code from the pr447 branch
Senyoret1 Nov 5, 2020
a99c7ce
Initial steps for adding the UI to the Android client
Senyoret1 Nov 8, 2020
408c822
More basic UI elements for the Android app
Senyoret1 Nov 10, 2020
d98eb00
Improvements for the Android VPN server list
Senyoret1 Jan 17, 2021
b688f69
Improvements for the Android app lists
Senyoret1 Jan 19, 2021
0af9b7c
Local server management code for the Android VPN client
Senyoret1 Jan 20, 2021
16a6d03
Several improvements for the Android client
Senyoret1 Jan 22, 2021
4d3d719
Basic navigation for the Android server list
Senyoret1 Jan 23, 2021
8503efe
Basis for the Android modal windows
Senyoret1 Jan 25, 2021
5beb308
Basic options for servers in the Android app
Senyoret1 Jan 28, 2021
6dd2ef8
Additional options for servers in the Android app
Senyoret1 Jan 31, 2021
206d6b8
New navigation mode for the Android app
Senyoret1 Feb 3, 2021
d942667
Show the VPN status in the android app
Senyoret1 Feb 7, 2021
b4f9ac3
Merge branch 'pr588_' into pr588
Senyoret1 Feb 7, 2021
c8dd555
Several improvements for the Android client
Senyoret1 Feb 11, 2021
0e69f24
Add the data starts to the Android app
Senyoret1 Feb 15, 2021
9a8d9a5
Improved list management for the Android app
Senyoret1 Feb 21, 2021
8f439a3
General improvements for the Android client
Senyoret1 Feb 23, 2021
d92cb55
More improvements for the Android client
Senyoret1 Feb 25, 2021
6b74ec6
Initial tablet code for the Android client
Senyoret1 Feb 28, 2021
ce7203b
Additional tablet code for the Android client
Senyoret1 Mar 3, 2021
f4d770e
More tablet code for the Android client
Senyoret1 Mar 8, 2021
49dad1b
Remaining tablet code for the Android client
Senyoret1 Mar 9, 2021
b662f69
Additional improvements for the Android client
Senyoret1 Mar 10, 2021
0853486
Improvements for the Android client
Senyoret1 Mar 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ cmd/skywirevisormobile/android/app/skywire-sources.jar
cmd/skywirevisormobile/android/app/.idea
cmd/skywirevisormobile/android/app/build
cmd/skywirevisormobile/android/.gradle
cmd/skywirevisormobile/android/local.properties
30 changes: 26 additions & 4 deletions cmd/skywirevisormobile/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ repositories {
flatDir {
dirs '.'
}
maven { url 'https://jitpack.io' }
}

android {
compileSdkVersion 27
compileSdkVersion 29

defaultConfig {
applicationId "com.skywire.skycoin.vpn"
minSdkVersion 26
targetSdkVersion 27
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
Expand All @@ -34,6 +35,27 @@ android {


dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
// Appcompat.
implementation "androidx.appcompat:appcompat:1.2.0"
implementation 'com.google.android.material:material:1.2.1'
implementation "androidx.preference:preference:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager2:viewpager2:1.0.0"

// Skywire lib.
implementation(name:'skywire', ext:'aar')

// RxJava.
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'

// Retrofit.
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'

// MPAndroidChart.
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}
38 changes: 30 additions & 8 deletions cmd/skywirevisormobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2015 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skywire.skycoin.vpn" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
android:name=".App"
android:allowBackup="true"
android:label="SkywireVPN">
<service android:name=".SkywireVPNService"
android:label="@string/general_app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme"
>

<receiver
android:directBootAware="true"
android:name=".Receiver"
android:enabled="true">
<intent-filter android:priority="2000000000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

<service android:name=".vpn.SkywireVPNService"
android:description="@string/general_service_description"
android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
</service>

<activity
android:name=".MainActivity"
android:label="SkywireVPN" >
android:name=".activities.index.IndexActivity"
android:configChanges="keyboardHidden"
android:launchMode="singleTask"
android:label="@string/general_app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".activities.apps.AppsActivity"
android:configChanges="keyboardHidden"
android:label="@string/tmp_select_apps_title" >
</activity>

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package com.skywire.skycoin.vpn;

import android.app.Activity;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.skywire.skycoin.vpn.helpers.HelperFunctions;
import com.skywire.skycoin.vpn.helpers.Notifications;
import com.skywire.skycoin.vpn.vpn.VPNCoordinator;

import io.reactivex.rxjava3.plugins.RxJavaPlugins;

/**
* Class for the main app instance.
*/
public class App extends Application {
/**
* Class used internally to know when there are activities being displayed.
*/
private static class ActivityLifecycleCallback implements Application.ActivityLifecycleCallbacks {

// How many activities are being shown.
private static int foregroundActivities = 0;

// Functions for knowing when activities start and stop being shown.
@Override
public void onActivityResumed(@NonNull final Activity activity) { foregroundActivities++; }
@Override
public void onActivityStopped(@NonNull final Activity activity) { foregroundActivities--; }

/**
* Returns if there is at least one activity being displayed.
*/
public static boolean isApplicationInForeground() { return foregroundActivities > 0; }

// Other functions needed by the interface.
@Override
public void onActivityPaused(@NonNull Activity activity) { }
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { }
@Override
public void onActivityDestroyed(@NonNull Activity activity) { }
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { }
@Override
public void onActivityStarted(@NonNull Activity activity) { }
}

/**
* Reference to the current app instance.
*/
private static Context appContext;

@Override
public void onCreate() {
super.onCreate();
// Save the current app instance.
appContext = this;

// Ensure the singleton is initialized early.
VPNCoordinator.getInstance();

// Create the notification channels, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Channel for the VPN service state updates.
NotificationChannel stateChannel = new NotificationChannel(
Notifications.NOTIFICATION_CHANNEL_ID,
getString(R.string.general_app_name),
NotificationManager.IMPORTANCE_DEFAULT
);
stateChannel.setDescription(getString(R.string.general_notification_channel_description));
stateChannel.setSound(null,null);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(stateChannel);

// Channel for alerts.
NotificationChannel alertsChannel = new NotificationChannel(
Notifications.ALERT_NOTIFICATION_CHANNEL_ID,
getString(R.string.general_alert_notification_name),
NotificationManager.IMPORTANCE_HIGH
);
alertsChannel.setDescription(getString(R.string.general_alert_notification_channel_description));
notificationManager.createNotificationChannel(alertsChannel);
}

// Code for precessing errors which were not caught by the normal error management
// procedures RxJava has. This prevents the app to be closed by unexpected errors, mainly
// code trying to report events in closed observables.
RxJavaPlugins.setErrorHandler(throwable -> {
HelperFunctions.logError("ERROR INSIDE RX: ", throwable);
});

// Detect when activities are started and stopped.
registerActivityLifecycleCallbacks(new ActivityLifecycleCallback());
}

/**
* Gets the current app context.
*/
public static Context getContext(){
return appContext;
}

/**
* Gets if the UI is being displayed.
*/
public static boolean displayingUI(){
return ActivityLifecycleCallback.isApplicationInForeground();
}
}

This file was deleted.

Loading