summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2020-12-28 00:47:19 +0100
committercyBerta <cyberta@riseup.net>2020-12-28 00:47:19 +0100
commitc008a935f92b79cb7b6f649fc876d398e20ebb22 (patch)
tree6aed01587d06016eaeaf023952580e37b6516e4f
parent8efd199a90e6d9388400b19e9fc6b68c81284f11 (diff)
download apk, request permission and install app update
-rw-r--r--app/src/fatweb/AndroidManifest.xml7
-rw-r--r--app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadBroadcastReceiver.java32
-rw-r--r--app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadConnector.java8
-rw-r--r--app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadNotificationManager.java86
-rw-r--r--app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/InstallActivity.java94
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java9
-rw-r--r--app/src/main/res/values/strings.xml3
9 files changed, 195 insertions, 59 deletions
diff --git a/app/src/fatweb/AndroidManifest.xml b/app/src/fatweb/AndroidManifest.xml
index 5188b05b..28246e5f 100644
--- a/app/src/fatweb/AndroidManifest.xml
+++ b/app/src/fatweb/AndroidManifest.xml
@@ -39,10 +39,6 @@
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.PACKAGE_INSTALL"/>
- <data android:scheme="package"/>
- </intent-filter>
</receiver>
<provider android:name="androidx.core.content.FileProvider"
@@ -53,6 +49,9 @@
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" />
</provider>
+ <activity
+ android:name=".appUpdate.InstallActivity"
+ android:theme="@style/invisibleTheme" />
</application>
diff --git a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadBroadcastReceiver.java b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadBroadcastReceiver.java
index 6613d394..f410b9ff 100644
--- a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadBroadcastReceiver.java
+++ b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadBroadcastReceiver.java
@@ -19,7 +19,6 @@ package se.leap.bitmaskclient.appUpdate;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
@@ -27,12 +26,12 @@ import android.widget.Toast;
import java.io.File;
import se.leap.bitmaskclient.Constants;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.utils.ConfigHelper;
import static android.app.Activity.RESULT_CANCELED;
import static se.leap.bitmaskclient.Constants.BROADCAST_DOWNLOAD_SERVICE_EVENT;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
-import static se.leap.bitmaskclient.appUpdate.DownloadConnector.APP_TYPE;
-import static se.leap.bitmaskclient.appUpdate.DownloadService.DOWNLOAD_FAILED;
import static se.leap.bitmaskclient.appUpdate.DownloadService.DOWNLOAD_PROGRESS;
import static se.leap.bitmaskclient.appUpdate.DownloadService.NO_NEW_VERISON;
import static se.leap.bitmaskclient.appUpdate.DownloadService.PROGRESS_VALUE;
@@ -40,8 +39,9 @@ import static se.leap.bitmaskclient.appUpdate.DownloadService.UPDATE_DOWNLOADED;
import static se.leap.bitmaskclient.appUpdate.DownloadService.UPDATE_DOWNLOAD_FAILED;
import static se.leap.bitmaskclient.appUpdate.DownloadService.UPDATE_FOUND;
import static se.leap.bitmaskclient.appUpdate.DownloadService.UPDATE_NOT_FOUND;
+import static se.leap.bitmaskclient.appUpdate.DownloadService.VERIFICATION_ERROR;
import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.DOWNLOAD_UPDATE;
-import static se.leap.bitmaskclient.appUpdate.FileProviderUtil.getUriFor;
+import static se.leap.bitmaskclient.appUpdate.UpdateDownloadManager.getUpdateFile;
public class DownloadBroadcastReceiver extends BroadcastReceiver {
@@ -75,25 +75,21 @@ public class DownloadBroadcastReceiver extends BroadcastReceiver {
case UPDATE_NOT_FOUND:
if (resultData.getBoolean(NO_NEW_VERISON, false)) {
//TODO: Save in preferences date, retry in a week
- } else if (resultData.getBoolean(DOWNLOAD_FAILED, false)) {
- Toast.makeText(context.getApplicationContext(), "Update check failed.", Toast.LENGTH_LONG).show();
}
break;
case UPDATE_DOWNLOADED:
- notificationManager.cancelNotifications();
- Intent installIntent = new Intent(Intent.ACTION_VIEW);
- File update = UpdateDownloadManager.getUpdateFile(context);
- if (update.exists()) {
- installIntent.setDataAndType(getUriFor(context, update), APP_TYPE);
- }
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- context.startActivity(installIntent);
+ notificationManager.buildDownloadSuccessfulNotification();
break;
case UPDATE_DOWNLOAD_FAILED:
- notificationManager.cancelNotifications();
- Toast.makeText(context.getApplicationContext(), "Update download failed.", Toast.LENGTH_LONG).show();
+ if (resultData.getBoolean(VERIFICATION_ERROR, false)) {
+ Toast.makeText(context.getApplicationContext(), context.getString(R.string.version_update_error_pgp_verification), Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(context.getApplicationContext(), context.getString(R.string.version_update_error), Toast.LENGTH_LONG).show();
+ }
+ File file = getUpdateFile(context);
+ if (file.exists()) {
+ file.delete();
+ }
break;
case DOWNLOAD_PROGRESS:
int progress = resultData.getInt(PROGRESS_VALUE, 0);
diff --git a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadConnector.java b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadConnector.java
index 9427083d..d4c5de7f 100644
--- a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadConnector.java
+++ b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadConnector.java
@@ -45,8 +45,8 @@ import okio.Okio;
public class DownloadConnector {
private static final String TAG = DownloadConnector.class.getSimpleName();
- final static String APP_TYPE = "application/vnd.android.package-archive";
- final static String TEXT_FILE_TYPE = "application/text";
+ public final static String APP_TYPE = "application/vnd.android.package-archive";
+ public final static String TEXT_FILE_TYPE = "application/text";
public interface DownloadProgress {
void onUpdate(int progress);
@@ -78,8 +78,8 @@ public class DownloadConnector {
}
static File requestFileFromServer(@NonNull String url, @NonNull OkHttpClient okHttpClient, File destFile, DownloadProgress callback) {
- BufferedSink sink = null;
- BufferedSource source = null;
+ BufferedSink sink;
+ BufferedSource source;
try {
Request.Builder requestBuilder = new Request.Builder()
.url(url)
diff --git a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadNotificationManager.java b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadNotificationManager.java
index 4f7f2883..aaf487aa 100644
--- a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadNotificationManager.java
+++ b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/DownloadNotificationManager.java
@@ -42,18 +42,14 @@ public class DownloadNotificationManager {
}
public void buildDownloadFoundNotification() {
- NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ NotificationManager notificationManager = initNotificationManager();
if (notificationManager == null) {
return;
}
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- createNotificationChannel(notificationManager);
- }
- NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this.context, DownloadService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
- notificationBuilder.setAutoCancel(true)
- .setDefaults(Notification.DEFAULT_ALL)
+ NotificationCompat.Builder notificationBuilder = initNotificationBuilderDefaults();
+ notificationBuilder
+ .setSmallIcon(R.drawable.ic_about_36)
.setWhen(System.currentTimeMillis())
- .setSmallIcon(R.mipmap.ic_launcher)
.setTicker(context.getString(R.string.version_update_title, context.getString(R.string.app_name)))
.setContentTitle(context.getString(R.string.version_update_title, context.getString(R.string.app_name)))
.setContentText(context.getString(R.string.version_update_found))
@@ -61,6 +57,51 @@ public class DownloadNotificationManager {
notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
}
+ public void buildDownloadSuccessfulNotification() {
+ NotificationManager notificationManager = initNotificationManager();
+ if (notificationManager == null) {
+ return;
+ }
+ NotificationCompat.Builder notificationBuilder = initNotificationBuilderDefaults();
+ notificationBuilder
+ .setSmallIcon(android.R.drawable.stat_sys_download_done)
+ .setWhen(System.currentTimeMillis())
+ .setTicker(context.getString(R.string.version_update_title, context.getString(R.string.app_name)))
+ .setContentTitle(context.getString(R.string.version_update_download_title, context.getString(R.string.app_name)))
+ .setContentText(context.getString(R.string.version_update_download_description))
+ .setContentIntent(getInstallIntent());
+ notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
+ }
+
+ public void buildDownloadUpdateProgress(int progress) {
+ NotificationManager notificationManager = initNotificationManager();
+ if (notificationManager == null) {
+ return;
+ }
+
+ NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this.context, DownloadService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
+ notificationBuilder
+ .setDefaults(Notification.DEFAULT_ALL)
+ .setAutoCancel(false)
+ .setOngoing(true)
+ .setSmallIcon(android.R.drawable.stat_sys_download)
+ .setContentTitle(context.getString(R.string.version_update_apk_description, context.getString(R.string.app_name)))
+ .setProgress(100, progress, false)
+ .setContentIntent(getDownloadIntent());
+ notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
+ }
+
+ private NotificationManager initNotificationManager() {
+ NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager == null) {
+ return null;
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ createNotificationChannel(notificationManager);
+ }
+ return notificationManager;
+ }
+
@TargetApi(26)
private void createNotificationChannel(NotificationManager notificationManager) {
CharSequence name = "Bitmask Updates";
@@ -75,7 +116,13 @@ public class DownloadNotificationManager {
notificationManager.createNotificationChannel(channel);
}
-
+ private NotificationCompat.Builder initNotificationBuilderDefaults() {
+ NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this.context, DownloadService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
+ notificationBuilder.
+ setDefaults(Notification.DEFAULT_ALL).
+ setAutoCancel(true);
+ return notificationBuilder;
+ }
private PendingIntent getDownloadIntent() {
Intent downloadIntent = new Intent(context, DownloadBroadcastReceiver.class);
@@ -83,24 +130,9 @@ public class DownloadNotificationManager {
return PendingIntent.getBroadcast(context, 0, downloadIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
- public void buildDownloadUpdateProgress(int progress) {
- NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- if (notificationManager == null) {
- return;
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- createNotificationChannel(notificationManager);
- }
- NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this.context, DownloadService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
- notificationBuilder.setAutoCancel(true)
- .setDefaults(Notification.DEFAULT_ALL)
- .setAutoCancel(false)
- .setOngoing(true)
- .setSmallIcon(R.mipmap.ic_launcher)
- .setContentTitle(context.getString(R.string.version_update_apk_description, context.getString(R.string.app_name)))
- .setProgress(100, progress, false)
- .setContentIntent(getDownloadIntent());
- notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
+ private PendingIntent getInstallIntent() {
+ Intent installIntent = new Intent(context, InstallActivity.class);
+ return PendingIntent.getActivity(context, 0, installIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
public void cancelNotifications() {
diff --git a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/InstallActivity.java b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/InstallActivity.java
index e373a888..f2f82238 100644
--- a/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/InstallActivity.java
+++ b/app/src/fatweb/java/se.leap.bitmaskclient/appUpdate/InstallActivity.java
@@ -1,4 +1,96 @@
+/**
+ * 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.appUpdate;
-public class InstallActivity {
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+
+import java.io.File;
+
+import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.utils.PreferenceHelper;
+
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_INSTALL_UPDATE;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_REQUEST_UPDATE;
+import static se.leap.bitmaskclient.appUpdate.DownloadConnector.APP_TYPE;
+import static se.leap.bitmaskclient.appUpdate.FileProviderUtil.getUriFor;
+
+public class InstallActivity extends Activity {
+
+ private static final String TAG = InstallActivity.class.getSimpleName();
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestPermissionAndInstall();
+ }
+
+
+ private void requestPermissionAndInstall() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !this.getPackageManager().canRequestPackageInstalls()) {
+ startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:"+getPackageName())),
+ REQUEST_CODE_REQUEST_UPDATE);
+ } else {
+ installUpdate();
+ }
+ }
+
+ protected void installUpdate() {
+ PreferenceHelper.restartOnUpdate(this.getApplicationContext(), true);
+
+ Intent installIntent = new Intent(Intent.ACTION_VIEW);
+ File update = UpdateDownloadManager.getUpdateFile(this.getApplicationContext());
+ if (update.exists()) {
+ installIntent.setDataAndType(getUriFor(this.getApplicationContext(), update), APP_TYPE);
+ installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ this.startActivityForResult(installIntent, REQUEST_CODE_INSTALL_UPDATE);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_REQUEST_UPDATE) {
+ if (resultCode == RESULT_OK) {
+ installUpdate();
+ } else {
+ Toast.makeText(this, getString(R.string.version_update_error_permissions), Toast.LENGTH_LONG).show();
+ finish();
+ }
+ } else if (requestCode == REQUEST_CODE_INSTALL_UPDATE) {
+ switch (resultCode) {
+ case RESULT_OK:
+ Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show();
+ break;
+ case RESULT_CANCELED:
+ case RESULT_FIRST_USER:
+ Toast.makeText(this, getString(R.string.version_update_error), Toast.LENGTH_LONG).show();
+ break;
+ }
+ finish();
+ }
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java
index dfd94759..f62af638 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java
@@ -36,9 +36,7 @@ public interface Constants {
String ALLOW_TETHERING_USB = "tethering_usb";
String SHOW_EXPERIMENTAL = "show_experimental";
String USE_IPv6_FIREWALL = "use_ipv6_firewall";
- String APK_DOWNLOAD_ID = "apk_download_id";
- String VERSION_FILE_DOWNLOAD_ID = "version_file_downlaod_id";
- String SIGNATURE_DOWNLOAD_ID = "signature_file_download_id";
+ String RESTART_ON_UPDATE = "restart_on_update";
//////////////////////////////////////////////
@@ -50,6 +48,8 @@ public interface Constants {
int REQUEST_CODE_SWITCH_PROVIDER = 1;
int REQUEST_CODE_LOG_IN = 2;
int REQUEST_CODE_ADD_PROVIDER = 3;
+ int REQUEST_CODE_INSTALL_UPDATE = 4;
+ int REQUEST_CODE_REQUEST_UPDATE = 5;
//////////////////////////////////////////////
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index 9937eeeb..9d49d5da 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -183,9 +183,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/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
index cb2aeb26..5ca2ec75 100644
--- a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java
@@ -27,6 +27,7 @@ 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 +122,14 @@ public class PreferenceHelper {
apply();
}
+ 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);
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5ba51afe..d047da21 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -149,4 +149,7 @@
<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>