summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java38
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java16
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java20
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java28
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java50
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java28
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/FileHelper.java24
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java28
-rw-r--r--app/src/main/res/values/strings.xml10
-rw-r--r--app/src/main/res/values/themes.xml2
-rw-r--r--app/src/main/res/xml/file_provider_paths.xml12
15 files changed, 248 insertions, 26 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java b/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
index bde5114b..437998e0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
+++ b/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
@@ -1,16 +1,42 @@
+/**
+ * Copyright (c) 2020 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
package se.leap.bitmaskclient;
import android.content.Context;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
-import androidx.multidex.MultiDexApplication;
+
import androidx.appcompat.app.AppCompatDelegate;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.multidex.MultiDexApplication;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
+import se.leap.bitmaskclient.appUpdate.DownloadBroadcastReceiver;
import se.leap.bitmaskclient.tethering.TetheringStateManager;
+import static android.content.Intent.CATEGORY_DEFAULT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_DOWNLOAD_SERVICE_EVENT;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.appUpdate.DownloadBroadcastReceiver.ACTION_DOWNLOAD;
+import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE;
+import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.DOWNLOAD_UPDATE;
import static se.leap.bitmaskclient.utils.PreferenceHelper.getSavedProviderFromSharedPreferences;
/**
@@ -22,6 +48,7 @@ public class BitmaskApp extends MultiDexApplication {
private final static String TAG = BitmaskApp.class.getSimpleName();
private RefWatcher refWatcher;
private ProviderObservable providerObservable;
+ private DownloadBroadcastReceiver downloadBroadcastReceiver;
@Override
@@ -41,6 +68,15 @@ public class BitmaskApp extends MultiDexApplication {
EipSetupObserver.init(this, preferences);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
TetheringStateManager.getInstance().init(this);
+ if (BuildConfig.FLAVOR.contains("Fatweb")) {
+ downloadBroadcastReceiver = new DownloadBroadcastReceiver();
+ IntentFilter intentFilter = new IntentFilter(BROADCAST_DOWNLOAD_SERVICE_EVENT);
+ intentFilter.addAction(ACTION_DOWNLOAD);
+ intentFilter.addAction(CHECK_VERSION_FILE);
+ intentFilter.addAction(DOWNLOAD_UPDATE);
+ intentFilter.addCategory(CATEGORY_DEFAULT);
+ LocalBroadcastManager.getInstance(this.getApplicationContext()).registerReceiver(downloadBroadcastReceiver, intentFilter);
+ }
}
/**
diff --git a/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java b/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java
index 0ef77e2b..4f27f88a 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ButterKnifeActivity.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (c) 2020 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package se.leap.bitmaskclient;
import androidx.appcompat.app.AppCompatActivity;
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java
index 6462b663..1d364074 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (c) 2020 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package se.leap.bitmaskclient;
import android.text.TextUtils;
@@ -20,6 +36,8 @@ public interface Constants {
String ALLOW_TETHERING_USB = "tethering_usb";
String SHOW_EXPERIMENTAL = "show_experimental";
String USE_IPv6_FIREWALL = "use_ipv6_firewall";
+ String RESTART_ON_UPDATE = "restart_on_update";
+ String LAST_UPDATE_CHECK = "last_update_check";
//////////////////////////////////////////////
@@ -31,6 +49,7 @@ public interface Constants {
int REQUEST_CODE_SWITCH_PROVIDER = 1;
int REQUEST_CODE_LOG_IN = 2;
int REQUEST_CODE_ADD_PROVIDER = 3;
+ int REQUEST_CODE_REQUEST_UPDATE = 4;
//////////////////////////////////////////////
@@ -105,6 +124,7 @@ public interface Constants {
String BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT = "BROADCAST.GATEWAY_SETUP_WATCHER_EVENT";
String BROADCAST_RESULT_CODE = "BROADCAST.RESULT_CODE";
String BROADCAST_RESULT_KEY = "BROADCAST.RESULT_KEY";
+ String BROADCAST_DOWNLOAD_SERVICE_EVENT = "BROADCAST.DOWNLOAD_SERVICE_EVENT";
//////////////////////////////////////////////
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
index 7504e0c0..e365c857 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
@@ -1,3 +1,20 @@
+/**
+ * Copyright (c) 2020 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
package se.leap.bitmaskclient;
import android.content.BroadcastReceiver;
@@ -21,6 +38,7 @@ import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConnectionStatus;
import de.blinkt.openvpn.core.LogItem;
import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.appUpdate.DownloadServiceCommand;
import se.leap.bitmaskclient.eip.EIP;
import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.eip.EipStatus;
@@ -48,6 +66,7 @@ import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON;
+import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE;
/**
* Created by cyberta on 05.12.18.
@@ -58,6 +77,7 @@ class EipSetupObserver extends BroadcastReceiver implements VpnStatus.StateListe
//The real timout is 4*2s + 1*4s + 1*8s + 1*16s + 1*32s + 1*64s = 132 s;
private static final String TIMEOUT = "4";
+ private static final int UPDATE_CHECK_TIMEOUT = 1000*60*60*24*7;
private Context context;
private VpnProfile setupVpnProfile;
private String observedProfileFromVpnStatus;
@@ -292,12 +312,20 @@ class EipSetupObserver extends BroadcastReceiver implements VpnStatus.StateListe
//setupNClostestGateway > 0: at least one failed gateway -> did the provider change it's gateways?
ProviderAPICommand.execute(context, ProviderAPI.DOWNLOAD_SERVICE_JSON, provider);
}
+
+ if (shouldCheckAppUpdate()) {
+ DownloadServiceCommand.execute(context, CHECK_VERSION_FILE);
+ }
finishGatewaySetup(false);
} else if ("TCP_CONNECT".equals(state)) {
changingGateway.set(false);
}
}
+ private boolean shouldCheckAppUpdate() {
+ return System.currentTimeMillis() - PreferenceHelper.getLastAppUpdateCheck(context) >= UPDATE_CHECK_TIMEOUT;
+ }
+
private void selectNextGateway() {
changingGateway.set(true);
reconnectTry.set(0);
diff --git a/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java b/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java
index 3b67d96b..519e4fc2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java
+++ b/app/src/main/java/se/leap/bitmaskclient/FeatureVersionCode.java
@@ -1,7 +1,6 @@
package se.leap.bitmaskclient;
public interface FeatureVersionCode {
- int MULTIPLE_PROFILES = 132;
int RENAMED_EIP_IN_PREFERENCES = 132;
int GEOIP_SERVICE = 148;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
index 7b9874e0..576e76e0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
@@ -62,7 +62,7 @@ public class OkHttpClientGenerator {
Resources resources;
- public OkHttpClientGenerator(SharedPreferences preferences, Resources resources) {
+ public OkHttpClientGenerator(/*SharedPreferences preferences,*/ Resources resources) {
this.resources = resources;
}
@@ -74,22 +74,21 @@ public class OkHttpClientGenerator {
return initHttpClient(initError, caCert);
}
+ public OkHttpClient init() {
+ try {
+ return createClient(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
private OkHttpClient initHttpClient(JSONObject initError, String certificate) {
+ if (resources == null) {
+ return null;
+ }
try {
- TLSCompatSocketFactory sslCompatFactory;
- ConnectionSpec spec = getConnectionSpec();
- OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
-
- if (!isEmpty(certificate)) {
- sslCompatFactory = new TLSCompatSocketFactory(certificate);
- } else {
- sslCompatFactory = new TLSCompatSocketFactory();
- }
- sslCompatFactory.initSSLSocketFactory(clientBuilder);
- clientBuilder.cookieJar(getCookieJar())
- .connectionSpecs(Collections.singletonList(spec));
- clientBuilder.dns(new DnsResolver());
- return clientBuilder.build();
+ return createClient(certificate);
} catch (IllegalArgumentException e) {
e.printStackTrace();
// TODO ca cert is invalid - show better error ?!
@@ -110,10 +109,31 @@ public class OkHttpClientGenerator {
} catch (IOException e) {
e.printStackTrace();
addErrorMessageToJson(initError, resources.getString(error_io_exception_user_message));
+ } catch (Exception e) {
+ e.printStackTrace();
+ // unexpected exception, should never happen
+ // only to shorten the method signature createClient(String certificate)
}
return null;
}
+ private OkHttpClient createClient(String certificate) throws Exception {
+ TLSCompatSocketFactory sslCompatFactory;
+ ConnectionSpec spec = getConnectionSpec();
+ OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
+
+ if (!isEmpty(certificate)) {
+ sslCompatFactory = new TLSCompatSocketFactory(certificate);
+ } else {
+ sslCompatFactory = new TLSCompatSocketFactory();
+ }
+ sslCompatFactory.initSSLSocketFactory(clientBuilder);
+ clientBuilder.cookieJar(getCookieJar())
+ .connectionSpecs(Collections.singletonList(spec));
+ clientBuilder.dns(new DnsResolver());
+ return clientBuilder.build();
+ }
+
@NonNull
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
index 4058b824..bec16139 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -120,7 +120,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB
private ProviderApiManager initApiManager() {
SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
- OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(preferences, getResources());
+ OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(getResources());
return new ProviderApiManager(preferences, getResources(), clientGenerator, this);
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index 9937eeeb..1a679b1c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -133,9 +133,6 @@ public class StartActivity extends Activity{
* execute necessary upgrades for version change
*/
private void executeUpgrade() {
- if (hasNewFeature(FeatureVersionCode.MULTIPLE_PROFILES)) {
- // TODO prepare usage of multiple profiles
- }
if (hasNewFeature(FeatureVersionCode.RENAMED_EIP_IN_PREFERENCES)) {
String eipJson = preferences.getString(PROVIDER_KEY, null);
if (eipJson != null) {
@@ -183,9 +180,14 @@ public class StartActivity extends Activity{
if (getIntent() != null && getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false)) {
EipCommand.startVPN(this.getApplicationContext(), true);
finish();
- return;
+ } else if (PreferenceHelper.getRestartOnUpdate(this.getApplicationContext())) {
+ PreferenceHelper.restartOnUpdate(this.getApplicationContext(), false);
+ EipCommand.startVPN(this.getApplicationContext(), false);
+ showMainActivity();
+ finish();
+ } else {
+ showMainActivity();
}
- showMainActivity();
}
} else {
configureLeapProvider();
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
index 1ee32654..25450f56 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
@@ -4,9 +4,9 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.ResultReceiver;
+
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import androidx.core.content.ContextCompat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +38,6 @@ public class EipCommand {
* @param resultReceiver The resultreceiver to reply to
*/
private static void execute(@NotNull Context context, @NotNull String action, @Nullable ResultReceiver resultReceiver, @Nullable Intent vpnIntent) {
- // TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
if (vpnIntent == null) {
vpnIntent = new Intent();
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
index 2748c944..5a142d90 100644
--- a/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/utils/ConfigHelper.java
@@ -53,6 +53,7 @@ import static se.leap.bitmaskclient.Constants.DEFAULT_BITMASK;
/**
* Stores constants, and implements auxiliary methods used across all Bitmask Android classes.
+ * Wraps BuildConfigFields for to support easier unit testing
*
* @author parmegv
* @author MeanderingCode
@@ -120,7 +121,7 @@ public class ConfigHelper {
try {
KeyFactory kf;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
- kf = KeyFactory.getInstance("RSA", "BC");
+ kf = KeyFactory.getInstance("RSA", "BC");
} else {
kf = KeyFactory.getInstance("RSA");
}
@@ -201,4 +202,29 @@ public class ConfigHelper {
return (string1 == null && string2 == null) ||
(string1 != null && string1.equals(string2));
}
+
+ public static String getApkFileName() {
+ try {
+ return BuildConfig.update_apk_url.substring(BuildConfig.update_apk_url.lastIndexOf("/"));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static String getVersionFileName() {
+ try {
+ return BuildConfig.version_file_url.substring(BuildConfig.version_file_url.lastIndexOf("/"));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static String getSignatureFileName() {
+ try {
+ return BuildConfig.signature_url.substring(BuildConfig.signature_url.lastIndexOf("/"));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/FileHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/FileHelper.java
index 1c3e1ebb..ebcc32ba 100644
--- a/app/src/main/java/se/leap/bitmaskclient/utils/FileHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/utils/FileHelper.java
@@ -1,8 +1,13 @@
package se.leap.bitmaskclient.utils;
+import android.content.Context;
+
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
/**
* Created by cyberta on 18.03.18.
@@ -19,4 +24,23 @@ public class FileHelper {
writer.close();
}
+ public static String readPublicKey(Context context) {
+ {
+ InputStream inputStream;
+ try {
+ inputStream = context.getAssets().open("public.pgp");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ reader.close();
+ return sb.toString();
+ } catch (IOException errabi) {
+ return null;
+ }
+ }
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
index cb2aeb26..5b62d0ff 100644
--- a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
@@ -22,11 +22,13 @@ import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_WIFI;
import static se.leap.bitmaskclient.Constants.ALWAYS_ON_SHOW_DIALOG;
import static se.leap.bitmaskclient.Constants.DEFAULT_SHARED_PREFS_BATTERY_SAVER;
import static se.leap.bitmaskclient.Constants.EXCLUDED_APPS;
+import static se.leap.bitmaskclient.Constants.LAST_UPDATE_CHECK;
import static se.leap.bitmaskclient.Constants.LAST_USED_PROFILE;
import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
import static se.leap.bitmaskclient.Constants.PROVIDER_EIP_DEFINITION;
import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.Constants.RESTART_ON_UPDATE;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.Constants.SHOW_EXPERIMENTAL;
import static se.leap.bitmaskclient.Constants.USE_IPv6_FIREWALL;
@@ -121,6 +123,22 @@ public class PreferenceHelper {
apply();
}
+ public static void setLastAppUpdateCheck(Context context) {
+ putLong(context, LAST_UPDATE_CHECK, System.currentTimeMillis());
+ }
+
+ public static long getLastAppUpdateCheck(Context context) {
+ return getLong(context, LAST_UPDATE_CHECK, 0);
+ }
+
+ public static void restartOnUpdate(Context context, boolean isEnabled) {
+ putBoolean(context, RESTART_ON_UPDATE, isEnabled);
+ }
+
+ public static boolean getRestartOnUpdate(Context context) {
+ return getBoolean(context, RESTART_ON_UPDATE, false);
+ }
+
public static boolean getUsePluggableTransports(Context context) {
return getBoolean(context, USE_PLUGGABLE_TRANSPORTS, false);
}
@@ -214,6 +232,16 @@ public class PreferenceHelper {
return preferences.getStringSet(EXCLUDED_APPS, new HashSet<>());
}
+ public static long getLong(Context context, String key, long defValue) {
+ SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ return preferences.getLong(key, defValue);
+ }
+
+ public static void putLong(Context context, String key, long value) {
+ SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences.edit().putLong(key, value).apply();
+ }
+
public static String getString(Context context, String key, String defValue) {
SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
return preferences.getString(key, defValue);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6d4c62e1..d047da21 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -142,4 +142,14 @@
<string name="root_permission_error">%s cannot execute features like VPN Hotspot or IPv6 firewall without root permissions.</string>
<string name="qs_enable_vpn">Start %s</string>
+ <string name="version_update_found">Tap here to start the download.</string>
+ <string name="version_update_title">A new %s version has been found.</string>
+ <string name="version_update_apk_description">Downloading a new %s version</string>
+ <string name="version_update_storage_access_required">Storage access is required to web update.</string>
+ <string name="version_update_storage_permission_denied">Storage permission request was denied.</string>
+ <string name="version_update_download_title">A new %s version has been downloaded.</string>
+ <string name="version_update_download_description">Tap here to install the update.</string>
+ <string name="version_update_error_pgp_verification">PGP verification error. Ignoring download.</string>
+ <string name="version_update_error">Update failed.</string>
+ <string name="version_update_error_permissions">No permissions to install app.</string>
</resources>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 7e98ccf4..ab489fc6 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -22,6 +22,8 @@
<style name="invisibleTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
<item name="android:windowAnimationStyle">@null</item>
+ <item name="android:windowDisablePreview">true</item>
+ <item name="android:windowFullscreen">true</item>
</style>
</resources>
diff --git a/app/src/main/res/xml/file_provider_paths.xml b/app/src/main/res/xml/file_provider_paths.xml
new file mode 100644
index 00000000..5b9dd9fb
--- /dev/null
+++ b/app/src/main/res/xml/file_provider_paths.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths>
+ <external-path
+ name="external"
+ path="." />
+ <external-files-path
+ name="external_files"
+ path="." />
+ <files-path
+ name="files"
+ path="." />
+</paths> \ No newline at end of file