diff options
Diffstat (limited to 'app/src/main')
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 |