client-android: store network config as app prefs
diff --git a/core/client/android/app/build.gradle b/core/client/android/app/build.gradle
index 9102497..6a8c04f 100644
--- a/core/client/android/app/build.gradle
+++ b/core/client/android/app/build.gradle
@@ -47,4 +47,5 @@
     implementation 'androidx.camera:camera-core:1.1.0-alpha11'
     implementation 'androidx.camera:camera-lifecycle:1.1.0-alpha11'
     implementation 'androidx.camera:camera-view:1.0.0-alpha31'
+    implementation "androidx.security:security-crypto:1.1.0-alpha03"
 }
\ No newline at end of file
diff --git a/core/client/android/app/src/main/AndroidManifest.xml b/core/client/android/app/src/main/AndroidManifest.xml
index a75444d..ccdff2c 100644
--- a/core/client/android/app/src/main/AndroidManifest.xml
+++ b/core/client/android/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 
     <application
         android:name=".PCloudApp"
diff --git a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudActivity.java b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudActivity.java
index 330e8cd..5e7dedd 100644
--- a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudActivity.java
+++ b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudActivity.java
@@ -81,18 +81,15 @@
         return null;
     }
 
-    public String startVpn(String ipCidr) {
+    public void startVpn() {
         Intent intent = VpnService.prepare(this);
         if (intent != null) {
-            System.out.println("#### STARTVPN");
             intent.setAction(PCloudVPNService.ACTION_CONNECT);
             startActivityForResult(intent, VPN_START_CODE);
         } else {
             intent = new Intent(this, PCloudVPNService.class);
             startService(intent);
         }
-
-        return null;
     }
 
     private native void qrcodeScanned(String contents);
diff --git a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudApp.java b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudApp.java
index 1e2b64a..b7647db 100644
--- a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudApp.java
+++ b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudApp.java
@@ -1,13 +1,66 @@
 package me.lekva.pcloud;
 
 import android.app.Application;
+import android.app.NotificationChannel;
+import android.content.SharedPreferences;
+import android.os.Build;
+
+import androidx.core.app.NotificationManagerCompat;
+import androidx.security.crypto.EncryptedSharedPreferences;
+import androidx.security.crypto.MasterKey;
 
 import org.gioui.Gio;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
 public class PCloudApp extends Application {
+    static final String STATUS_CHANNEL_ID = "pcloud-status";
+    static final int STATUS_NOTIFICATION_ID = 1;
+
+    static final String NOTIFY_CHANNEL_ID = "pcloud-notify";
+    static final int NOTIFY_NOTIFICATION_ID = 2;
+
     @Override
     public void onCreate() {
         super.onCreate();
         Gio.init(this);
+
+        createNotificationChannel(NOTIFY_CHANNEL_ID, "Notifications", NotificationManagerCompat.IMPORTANCE_DEFAULT);
+        createNotificationChannel(STATUS_CHANNEL_ID, "VPN Status", NotificationManagerCompat.IMPORTANCE_LOW);
+    }
+
+    private void createNotificationChannel(String id, String name, int importance) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            return;
+        }
+        NotificationChannel channel = new NotificationChannel(id, name, importance);
+        NotificationManagerCompat nm = NotificationManagerCompat.from(this);
+        nm.createNotificationChannel(channel);
+    }
+
+    // encryptToPref a byte array of data using the Jetpack Security
+    // library and writes it to a global encrypted preference store.
+    public void encryptToPref(String prefKey, String plaintext) throws IOException, GeneralSecurityException {
+        getEncryptedPrefs().edit().putString(prefKey, plaintext).commit();
+    }
+
+    // decryptFromPref decrypts a encrypted preference using the Jetpack Security
+    // library and returns the plaintext.
+    public String decryptFromPref(String prefKey) throws IOException, GeneralSecurityException {
+        return getEncryptedPrefs().getString(prefKey, null);
+    }
+
+    private SharedPreferences getEncryptedPrefs() throws IOException, GeneralSecurityException {
+        MasterKey key = new MasterKey.Builder(this)
+                .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
+                .build();
+        return EncryptedSharedPreferences.create(
+                this,
+                "secret_shared_prefs",
+                key,
+                EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+                EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
+        );
     }
 }
diff --git a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudVPNService.java b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudVPNService.java
index 1566ed1..91a4a38 100644
--- a/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudVPNService.java
+++ b/core/client/android/app/src/main/java/me/lekva/pcloud/PCloudVPNService.java
@@ -10,11 +10,15 @@
 import android.system.OsConstants;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.NotificationCompat;
 
 public class PCloudVPNService extends VpnService implements Handler.Callback {
     public static final String ACTION_CONNECT = "CONNECT";
     public static final String ACTION_DISCONNECT = "DISCONNECT";
 
+    private PendingIntent configureIntent;
+
     private boolean running = false;
     private Handler handler = null;
 
@@ -23,6 +27,9 @@
         if (handler == null) {
             handler = new Handler(this);
         }
+
+        configureIntent = PendingIntent.getActivity(this, 0, new Intent(this, PCloudActivity.class),
+                PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     @Override
@@ -41,8 +48,10 @@
         stopVpn();
     }
 
+    @RequiresApi(api = Build.VERSION_CODES.O)
     private void startVpn() {
         System.out.println("--- START");
+        updateForegroundNotification();
         connect();
     }
 
@@ -73,6 +82,15 @@
         return builder;
     }
 
+    private void updateForegroundNotification() {
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, PCloudApp.STATUS_CHANNEL_ID)
+                .setContentTitle("PCloud")
+                .setContentText("hiiii")
+                .setContentIntent(configureIntent)
+                .setPriority(NotificationCompat.PRIORITY_LOW);
+        startForeground(PCloudApp.STATUS_NOTIFICATION_ID, builder.build());
+    }
+
     private native void connect();
     private native void disconnect();
 }