From f4eee475a7d7301f430dc60fd8b3465485cc66f5 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:42:55 +0200 Subject: [PATCH 01/41] Create git-log.cmd --- git-log.cmd | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 git-log.cmd diff --git a/git-log.cmd b/git-log.cmd new file mode 100644 index 000000000..4b9823eb6 --- /dev/null +++ b/git-log.cmd @@ -0,0 +1,3 @@ +@echo off +git log > "X:\git.log" +start "" "X:\git.log" From fc78357dba7ba4eead1cd03ea377b4ff4c113dba Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:47:45 +0200 Subject: [PATCH 02/41] Create AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/src/gplay/AndroidManifest.xml diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml new file mode 100644 index 000000000..07787c6f5 --- /dev/null +++ b/app/src/gplay/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + From 37c5fda48418947ba45c02796b8851809d569851 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:49:54 +0200 Subject: [PATCH 03/41] Update AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml index 07787c6f5..2e6943c1b 100644 --- a/app/src/gplay/AndroidManifest.xml +++ b/app/src/gplay/AndroidManifest.xml @@ -6,4 +6,14 @@ + + + + From 4727aa752375823ff72d31b30eed79261bebcf08 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:52:11 +0200 Subject: [PATCH 04/41] Create NotificationHandler.java --- .../service/NotificationHandler.java | 412 ++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java diff --git a/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java new file mode 100644 index 000000000..236156d82 --- /dev/null +++ b/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -0,0 +1,412 @@ +package com.nutomic.syncthingandroid.service; + +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ServiceInfo; +import android.os.Build; +import androidx.annotation.StringRes; +import androidx.core.app.NotificationCompat; +import android.util.Log; + +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; +import com.nutomic.syncthingandroid.activities.DeviceActivity; +import com.nutomic.syncthingandroid.activities.FirstStartActivity; +import com.nutomic.syncthingandroid.activities.FolderActivity; +import com.nutomic.syncthingandroid.activities.LogActivity; +import com.nutomic.syncthingandroid.activities.MainActivity; +import com.nutomic.syncthingandroid.service.SyncthingService.State; + +import javax.inject.Inject; + +public class NotificationHandler { + + private static final String TAG = "NotificationHandler"; + private static final int ID_PERSISTENT = 1; + private static final int ID_PERSISTENT_WAITING = 4; + private static final int ID_RESTART = 2; + private static final int ID_STOP_BACKGROUND_WARNING = 3; + private static final int ID_CRASH = 9; + private static final int ID_MISSING_PERM = 10; + private static final String CHANNEL_PERSISTENT = "01_syncthing_persistent"; + private static final String CHANNEL_INFO = "02_syncthing_notifications"; + private static final String CHANNEL_PERSISTENT_WAITING = "03_syncthing_persistent_waiting"; + + private final Context mContext; + @Inject SharedPreferences mPreferences; + private final NotificationManager mNotificationManager; + private final NotificationChannel mPersistentChannel; + private final NotificationChannel mPersistentChannelWaiting; + private final NotificationChannel mInfoChannel; + + private String mLastNotificationText = null; + private Boolean lastStartForegroundService = false; + private Boolean appShutdownInProgress = false; + + @TargetApi(23) + private int FLAG_IMMUTABLE = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ? PendingIntent.FLAG_IMMUTABLE : 0; + + public NotificationHandler(Context context) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); + mContext = context; + mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mPersistentChannel = new NotificationChannel( + CHANNEL_PERSISTENT, mContext.getString(R.string.notifications_persistent_channel), + NotificationManager.IMPORTANCE_MIN); + mPersistentChannel.enableLights(false); + mPersistentChannel.enableVibration(false); + mPersistentChannel.setSound(null, null); + mPersistentChannel.setShowBadge(false); + mPersistentChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET); + mNotificationManager.createNotificationChannel(mPersistentChannel); + + mPersistentChannelWaiting = new NotificationChannel( + CHANNEL_PERSISTENT_WAITING, mContext.getString(R.string.notification_persistent_waiting_channel), + NotificationManager.IMPORTANCE_MIN); + mPersistentChannelWaiting.enableLights(false); + mPersistentChannelWaiting.enableVibration(false); + mPersistentChannelWaiting.setSound(null, null); + mPersistentChannelWaiting.setShowBadge(false); + mPersistentChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET); + mNotificationManager.createNotificationChannel(mPersistentChannelWaiting); + + mInfoChannel = new NotificationChannel( + CHANNEL_INFO, mContext.getString(R.string.notifications_other_channel), + NotificationManager.IMPORTANCE_LOW); + mInfoChannel.enableVibration(false); + mInfoChannel.setSound(null, null); + mInfoChannel.setShowBadge(true); + mNotificationManager.createNotificationChannel(mInfoChannel); + } else { + mPersistentChannel = null; + mPersistentChannelWaiting = null; + mInfoChannel = null; + } + } + + private NotificationCompat.Builder getNotificationBuilder(NotificationChannel channel) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return new NotificationCompat.Builder(mContext, channel.getId()); + } else { + //noinspection deprecation + return new NotificationCompat.Builder(mContext); + } + } + + /** + * Shows, updates or hides the notification. + */ + public void updatePersistentNotification(SyncthingService service) { + // Persist previous notification details. + updatePersistentNotification(service, true, 0, 0); + } + + public void updatePersistentNotification(SyncthingService service, + Boolean persistNotificationDetails, + int onlineDeviceCount, + int totalSyncCompletion) { + boolean startServiceOnBoot = mPreferences.getBoolean(Constants.PREF_START_SERVICE_ON_BOOT, false); + State currentServiceState = service.getCurrentState(); + boolean syncthingRunning = currentServiceState == SyncthingService.State.ACTIVE || + currentServiceState == SyncthingService.State.STARTING; + boolean startForegroundService = false; + if (!appShutdownInProgress) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + /** + * Android 7 and lower: + * The app may run in background and monitor run conditions even if it is not + * running as a foreground service. For that reason, we can use a normal + * notification if syncthing is DISABLED. + */ + startForegroundService = startServiceOnBoot || syncthingRunning; + } else { + /** + * Android 8+: + * Always use startForeground. + * This makes sure the app is not killed, and we don't miss run condition events. + * On Android 8+, this behaviour is mandatory to receive broadcasts. + * https://stackoverflow.com/a/44505719/1837158 + * Foreground priority requires a notification so this ensures that we either have a + * "default" or "low_priority" notification, but not "none". + */ + startForegroundService = true; + } + } + + // Check if we have to stopForeground. + if (startForegroundService != lastStartForegroundService) { + if (!startForegroundService) { + Log.v(TAG, "Stopping foreground service"); + service.stopForeground(false); + } + } + + // Prepare notification builder. + String text; + switch (currentServiceState) { + case ERROR: + case INIT: + text = mContext.getString(R.string.syncthing_terminated); + break; + case DISABLED: + text = mContext.getString(R.string.syncthing_disabled); + break; + case STARTING: + text = mContext.getString(R.string.syncthing_starting); + break; + case ACTIVE: + if (mLastNotificationText == null || !persistNotificationDetails) { + if (totalSyncCompletion == -1) { + mLastNotificationText = mContext.getString( + R.string.syncthing_active_details, + mContext.getString(R.string.no_remote_devices_connected) + ); + } else if (totalSyncCompletion == 100) { + mLastNotificationText = mContext.getString( + R.string.syncthing_active_details, + mContext.getResources().getQuantityString( + R.plurals.device_online_up_to_date, + onlineDeviceCount, + onlineDeviceCount + ) + ); + } else { + mLastNotificationText = mContext.getResources().getQuantityString( + R.plurals.syncthing_active_syncing_device_online, + onlineDeviceCount, + totalSyncCompletion, + onlineDeviceCount + ); + } + } + text = mLastNotificationText; + break; + default: + text = mContext.getString(R.string.syncthing_terminated); + break; + } + + /** + * Reason for two separate IDs: if one of the notification channels is hidden then + * the startForeground() below won't update the notification but use the old one. + */ + int idToShow = syncthingRunning ? ID_PERSISTENT : ID_PERSISTENT_WAITING; + int idToCancel = syncthingRunning ? ID_PERSISTENT_WAITING : ID_PERSISTENT; + Intent intent = new Intent(mContext, MainActivity.class); + NotificationChannel channel = syncthingRunning ? mPersistentChannel : mPersistentChannelWaiting; + NotificationCompat.Builder builder = getNotificationBuilder(channel) + .setContentTitle(text) + .setSmallIcon(R.drawable.ic_stat_notify) + .setOngoing(true) + .setOnlyAlertOnce(true) + .setPriority(NotificationCompat.PRIORITY_MIN) + .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)); + if (!appShutdownInProgress) { + if (startForegroundService) { + Log.v(TAG, "Starting foreground service or updating notification"); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + service.startForeground(idToShow, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC); + } else { + service.startForeground(idToShow, builder.build()); + } + } else { + Log.v(TAG, "Updating notification"); + mNotificationManager.notify(idToShow, builder.build()); + } + } else { + mNotificationManager.cancel(idToShow); + } + mNotificationManager.cancel(idToCancel); + + // Remember last notification visibility. + lastStartForegroundService = startForegroundService; + } + + /** + * Called by {@link SyncthingService#onStart} {@link SyncthingService#onDestroy} + * to indicate app startup and shutdown. + */ + public void setAppShutdownInProgress(Boolean newValue) { + appShutdownInProgress = newValue; + } + + public void showCrashedNotification(@StringRes int title, String extraInfo) { + Intent intent = new Intent(mContext, LogActivity.class); + Notification n = getNotificationBuilder(mInfoChannel) + .setContentTitle(mContext.getString(title, extraInfo)) + .setContentText(mContext.getString(R.string.notification_crash_text, extraInfo)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE)) + .setAutoCancel(true) + .build(); + mNotificationManager.notify(ID_CRASH, n); + } + + /** + * Calculate a deterministic ID between 1000 and 2000 to avoid duplicate + * notification ids for different device, folder consent popups triggered + * by {@link EventProcessor}. + */ + public int getNotificationIdFromText(String text) { + return 1000 + text.hashCode() % 1000; + } + + /** + * Closes a notification. Required after the user hit an action button. + */ + public void cancelConsentNotification(int notificationId) { + if (notificationId == 0) { + return; + } + Log.v(TAG, "Cancelling notification with id " + notificationId); + mNotificationManager.cancel(notificationId); + } + + /** + * Used by {@link EventProcessor} + */ + public void showConsentNotification(int notificationId, + String text, + PendingIntent piAccept, + PendingIntent piIgnore) { + /** + * As we know the id for a specific notification text, + * we'll dismiss this notification as it may be outdated. + * This is also valid if the notification does not exist. + */ + mNotificationManager.cancel(notificationId); + Notification n = getNotificationBuilder(mInfoChannel) + .setContentTitle(mContext.getString(R.string.app_name)) + .setContentText(text) + .setStyle(new NotificationCompat.BigTextStyle() + .bigText(text)) + .setContentIntent(piAccept) + .addAction(R.drawable.ic_stat_notify, mContext.getString(R.string.accept), piAccept) + .addAction(R.drawable.ic_stat_notify, mContext.getString(R.string.ignore), piIgnore) + .setSmallIcon(R.drawable.ic_stat_notify) + .setAutoCancel(true) + .build(); + mNotificationManager.notify(notificationId, n); + } + + public void showStoragePermissionRevokedNotification() { + Intent intent = new Intent(mContext, FirstStartActivity.class); + Notification n = getNotificationBuilder(mInfoChannel) + .setContentTitle(mContext.getString(R.string.syncthing_terminated)) + .setContentText(mContext.getString(R.string.toast_write_storage_permission_required)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE)) + .setAutoCancel(true) + .setOnlyAlertOnce(true) + .build(); + mNotificationManager.notify(ID_MISSING_PERM, n); + } + + public void cancelRestartNotification() { + mNotificationManager.cancel(ID_RESTART); + } + + public void showStopSyncthingWarningNotification() { + final String msg = mContext.getString(R.string.appconfig_receiver_background_enabled); + NotificationCompat.Builder nb = getNotificationBuilder(mInfoChannel) + .setContentText(msg) + .setTicker(msg) + .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) + .setContentTitle(mContext.getText(mContext.getApplicationInfo().labelRes)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setAutoCancel(true) + .setContentIntent(PendingIntent.getActivity(mContext, 0, + new Intent(mContext, MainActivity.class), + FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)); + + nb.setCategory(Notification.CATEGORY_ERROR); + mNotificationManager.notify(ID_STOP_BACKGROUND_WARNING, nb.build()); + } + + public void showDeviceConnectNotification(String deviceId, + String deviceName, + String deviceAddress) { + if (deviceId == null) { + Log.e(TAG, "showDeviceConnectNotification: deviceId == null"); + return; + } + String title = mContext.getString(R.string.device_rejected, + deviceName.isEmpty() ? deviceId.substring(0, 7) : deviceName); + int notificationId = getNotificationIdFromText(title); + + // Prepare "accept" action. + Intent intentAccept = new Intent(mContext, DeviceActivity.class) + .putExtra(DeviceActivity.EXTRA_NOTIFICATION_ID, notificationId) + .putExtra(DeviceActivity.EXTRA_IS_CREATE, true) + .putExtra(DeviceActivity.EXTRA_DEVICE_ID, deviceId) + .putExtra(DeviceActivity.EXTRA_DEVICE_NAME, deviceName); + PendingIntent piAccept = PendingIntent.getActivity(mContext, notificationId, + intentAccept, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + + // Prepare "ignore" action. + Intent intentIgnore = new Intent(mContext, SyncthingService.class) + .putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) + .putExtra(SyncthingService.EXTRA_DEVICE_ID, deviceId) + .putExtra(SyncthingService.EXTRA_DEVICE_NAME, deviceName) + .putExtra(SyncthingService.EXTRA_DEVICE_ADDRESS, deviceAddress); + intentIgnore.setAction(SyncthingService.ACTION_IGNORE_DEVICE); + PendingIntent piIgnore = PendingIntent.getService(mContext, 0, + intentIgnore, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + + // Show notification. + showConsentNotification(notificationId, title, piAccept, piIgnore); + } + + public void showFolderShareNotification(String deviceId, + String deviceName, + String folderId, + String folderLabel, + Boolean receiveEncrypted, + Boolean remoteEncrypted, + Boolean isNewFolder) { + if (deviceId == null) { + Log.e(TAG, "showFolderShareNotification: deviceId == null"); + return; + } + if (folderId == null) { + Log.e(TAG, "showFolderShareNotification: folderId == null"); + return; + } + String title = mContext.getString(R.string.folder_rejected, deviceName, + folderLabel.isEmpty() ? folderId : folderLabel + " (" + folderId + ")"); + int notificationId = getNotificationIdFromText(title); + + // Prepare "accept" action. + Intent intentAccept = new Intent(mContext, FolderActivity.class) + .putExtra(FolderActivity.EXTRA_NOTIFICATION_ID, notificationId) + .putExtra(FolderActivity.EXTRA_IS_CREATE, isNewFolder) + .putExtra(FolderActivity.EXTRA_DEVICE_ID, deviceId) + .putExtra(FolderActivity.EXTRA_FOLDER_ID, folderId) + .putExtra(FolderActivity.EXTRA_FOLDER_LABEL, folderLabel) + .putExtra(FolderActivity.EXTRA_RECEIVE_ENCRYPTED, receiveEncrypted) + .putExtra(FolderActivity.EXTRA_REMOTE_ENCRYPTED, remoteEncrypted); + PendingIntent piAccept = PendingIntent.getActivity(mContext, notificationId, + intentAccept, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + + // Prepare "ignore" action. + Intent intentIgnore = new Intent(mContext, SyncthingService.class) + .putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) + .putExtra(SyncthingService.EXTRA_DEVICE_ID, deviceId) + .putExtra(SyncthingService.EXTRA_FOLDER_ID, folderId) + .putExtra(SyncthingService.EXTRA_FOLDER_LABEL, folderLabel); + intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER); + PendingIntent piIgnore = PendingIntent.getService(mContext, 0, + intentIgnore, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + + // Show notification. + showConsentNotification(notificationId, title, piAccept, piIgnore); + } +} From af3b2112b27af8532df109a46dfc90f6edb81b9b Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:59:15 +0200 Subject: [PATCH 05/41] Update build.gradle.kts --- app/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 50295b241..0eeb5e5b8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -82,6 +82,9 @@ android { .getOrNull() .takeIf { it?.storeFile != null } } + create("gplay") { + initWith(getByName("release")) + } } compileOptions { From 69309cf4de78a1be169b7f28cae9a654c8949eec Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:59:20 +0200 Subject: [PATCH 06/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index ea18571c2..89edcc090 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -16,7 +16,7 @@ REM REM SET ANDROID_PUBLISHER_CREDENTIALS=%userprofile%\.android\play_key.json" REM SET SYNCTHING_RELEASE_STORE_FILE="%userprofile%\.android\signing_key.jks" SET SYNCTHING_RELEASE_KEY_ALIAS=Syncthing-Fork -SET BUILD_FLAVOUR_GPLAY=release +SET BUILD_FLAVOUR_GPLAY=gplay title %SYNCTHING_RELEASE_KEY_ALIAS% - Build APK REM SET GIT_INSTALL_DIR=%ProgramFiles%\Git @@ -72,6 +72,7 @@ REM REM Check if we should skip the release build and just make a debug build. IF "%SKIP_RELEASE_BUILD%" == "1" goto :absPostBuildScript REM +call :buildApk release call :buildApk %BUILD_FLAVOUR_GPLAY% REM IF "%CLEANUP_BEFORE_BUILD%" == "1" del /f "%SCRIPT_PATH%app\build\outputs\bundle\%BUILD_FLAVOUR_GPLAY%\app-%BUILD_FLAVOUR_GPLAY%.aab" 2> NUL: From a90baf85f56b065d9b540f910fbb64bc0d54fe76 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:00:07 +0200 Subject: [PATCH 07/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index 89edcc090..a07530414 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -6,7 +6,7 @@ cls REM REM Script Consts. SET CLEANUP_BEFORE_BUILD=1 -SET SKIP_RELEASE_BUILD=1 +SET SKIP_RELEASE_BUILD=0 REM REM Runtime Variables. IF EXIST "%LocalAppData%\Android\Sdk" SET "ANDROID_SDK_ROOT=%LocalAppData%\Android\Sdk" From 9e18b50e8b5b8131d4202a50268135270b6ce24e Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:13:45 +0200 Subject: [PATCH 08/41] Update strings.xml --- app/src/main/res/values-pt/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 3247272ab..5ac4bedf3 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -424,7 +424,7 @@ %1$d ficheiros copiados para a pasta \"%2$s\" - Nome do Ficheiro + Nome do Ficheiro %d Lista de Ficheiros Lista de Ficheiros @@ -517,4 +517,4 @@ Escolha um tipo de versionamento para habilitá-lo. Tipo: Simples Tipo: Lixo - \ No newline at end of file + From 70a4a05e6e39a0fbed5ee73436d01b4dd9f75309 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:14:45 +0200 Subject: [PATCH 09/41] Update strings.xml --- app/src/main/res/values-bg/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index d564ccbb6..3add23e1b 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -318,7 +318,7 @@ Премахване на неочаквани елементи Отваряне от - Синхронизиране (%1$d %, %2$s) + Синхронизиране (%1$d%%, %2$s) Изключено (%1$s на изчакване) На пауза Неизползвано @@ -357,4 +357,4 @@ Никога Запазване Запазване в Syncthing - \ No newline at end of file + From 2b69374dacfd03abf1e3b5911f28baa1d7a7ea01 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:16:06 +0200 Subject: [PATCH 10/41] Update strings.xml --- app/src/main/res/values-bg/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 3add23e1b..76bb66f5e 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -36,7 +36,7 @@ Синхронизирано - Синхронизиране (%1$d% %) + Синхронизиране (%1$d%%) Няма връзка From 99eaaf8be437ec2dd6c3aa9a741a73dc568acb7e Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:17:33 +0200 Subject: [PATCH 11/41] Update ReceiverManager.java --- .../com/nutomic/syncthingandroid/service/ReceiverManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java index 8168c29e8..9de4cd47c 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java @@ -19,7 +19,7 @@ public class ReceiverManager { public static synchronized void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter intentFilter) { mReceivers.add(receiver); - context.registerReceiver(receiver, intentFilter); + context.registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED); LogV("Registered receiver: " + receiver + " with filter: " + intentFilter); } From 455b182e775ebbed8703b64c86d451e0af8f875a Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:19:20 +0200 Subject: [PATCH 12/41] Update ReceiverManager.java --- .../nutomic/syncthingandroid/service/ReceiverManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java index 9de4cd47c..0fbcfb327 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java @@ -19,7 +19,11 @@ public class ReceiverManager { public static synchronized void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter intentFilter) { mReceivers.add(receiver); - context.registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED); + } else { + context.registerReceiver(receiver, intentFilter); + } LogV("Registered receiver: " + receiver + " with filter: " + intentFilter); } From 9a76beb1ea5eed6f1fa67fc322f67e6b1b2d803b Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:22:53 +0200 Subject: [PATCH 13/41] Update ReceiverManager.java --- .../com/nutomic/syncthingandroid/service/ReceiverManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java index 0fbcfb327..c09143cae 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java @@ -3,6 +3,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; +import android.os.Build; import android.util.Log; import java.util.ArrayList; @@ -20,8 +21,9 @@ public class ReceiverManager { public static synchronized void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter intentFilter) { mReceivers.add(receiver); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED); + context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED); } else { + @Suppress("UnspecifiedRegisterReceiverFlag" context.registerReceiver(receiver, intentFilter); } LogV("Registered receiver: " + receiver + " with filter: " + intentFilter); From 27ce95c3dcd883e6e7968ea247908c857889e8d1 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:23:08 +0200 Subject: [PATCH 14/41] Update ReceiverManager.java --- .../com/nutomic/syncthingandroid/service/ReceiverManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java index c09143cae..183983c45 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java @@ -23,7 +23,7 @@ public static synchronized void registerReceiver(Context context, BroadcastRecei if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED); } else { - @Suppress("UnspecifiedRegisterReceiverFlag" + @Suppress("UnspecifiedRegisterReceiverFlag") context.registerReceiver(receiver, intentFilter); } LogV("Registered receiver: " + receiver + " with filter: " + intentFilter); From f37c592acf609b93f2ec112d34545e15eddbd961 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:27:48 +0200 Subject: [PATCH 15/41] Update ReceiverManager.java --- .../com/nutomic/syncthingandroid/service/ReceiverManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java index 183983c45..b517dd90d 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/ReceiverManager.java @@ -18,12 +18,12 @@ public class ReceiverManager { private static List mReceivers = new ArrayList(); + @SuppressWarnings("UnspecifiedRegisterReceiverFlag") public static synchronized void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter intentFilter) { mReceivers.add(receiver); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED); } else { - @Suppress("UnspecifiedRegisterReceiverFlag") context.registerReceiver(receiver, intentFilter); } LogV("Registered receiver: " + receiver + " with filter: " + intentFilter); From 0f5129498b69e86d9e0358cdea25de2804e5c7a5 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:32:39 +0200 Subject: [PATCH 16/41] Update NotificationHandler.java --- .../nutomic/syncthingandroid/service/NotificationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java index 8743e1c71..d4dde975d 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -212,7 +212,7 @@ public void updatePersistentNotification(SyncthingService service, if (!appShutdownInProgress) { if (startForegroundService) { Log.v(TAG, "Starting foreground service or updating notification"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { service.startForeground(idToShow, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE); } else { service.startForeground(idToShow, builder.build()); From 70db25f92135d400625da47dfafb58bb67e5f28e Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:37:29 +0200 Subject: [PATCH 17/41] Update NotificationHandler.java --- .../nutomic/syncthingandroid/service/NotificationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java index 236156d82..a29343c7f 100644 --- a/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java +++ b/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -212,7 +212,7 @@ public void updatePersistentNotification(SyncthingService service, if (!appShutdownInProgress) { if (startForegroundService) { Log.v(TAG, "Starting foreground service or updating notification"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { service.startForeground(idToShow, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC); } else { service.startForeground(idToShow, builder.build()); From 89b745001cfb0f530c5c1dade345151ca4843c3c Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:44:15 +0200 Subject: [PATCH 18/41] Update AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml index 2e6943c1b..2a581bcaa 100644 --- a/app/src/gplay/AndroidManifest.xml +++ b/app/src/gplay/AndroidManifest.xml @@ -4,16 +4,13 @@ package="com.nutomic.syncthingandroid"> - + - - - + + + From 45f4a3ef18b73e789ab085d8dfc84334b04c5837 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:15:19 +0100 Subject: [PATCH 19/41] Update AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml index 2a581bcaa..98fface60 100644 --- a/app/src/gplay/AndroidManifest.xml +++ b/app/src/gplay/AndroidManifest.xml @@ -6,11 +6,11 @@ - - + + From 35c4a23c5935b75d2139dad35d3c688bda7daf2c Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:21:50 +0100 Subject: [PATCH 20/41] Update NotificationHandler.java --- .../nutomic/syncthingandroid/service/NotificationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java index d4dde975d..eb0e3d1df 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -213,7 +213,7 @@ public void updatePersistentNotification(SyncthingService service, if (startForegroundService) { Log.v(TAG, "Starting foreground service or updating notification"); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - service.startForeground(idToShow, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE); + service.startForeground(idToShow, builder.build(), FlavourConstants.FOREGROUND_SERVICE_TYPE); } else { service.startForeground(idToShow, builder.build()); } From 53a24ec00376a6d012a61c550a108380692e0002 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:21:52 +0100 Subject: [PATCH 21/41] Delete NotificationHandler.java --- .../service/NotificationHandler.java | 412 ------------------ 1 file changed, 412 deletions(-) delete mode 100644 app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java diff --git a/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java deleted file mode 100644 index a29343c7f..000000000 --- a/app/src/gplay/java/com/nutomic/syncthingandroid/service/NotificationHandler.java +++ /dev/null @@ -1,412 +0,0 @@ -package com.nutomic.syncthingandroid.service; - -import android.annotation.TargetApi; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.ServiceInfo; -import android.os.Build; -import androidx.annotation.StringRes; -import androidx.core.app.NotificationCompat; -import android.util.Log; - -import com.nutomic.syncthingandroid.R; -import com.nutomic.syncthingandroid.SyncthingApp; -import com.nutomic.syncthingandroid.activities.DeviceActivity; -import com.nutomic.syncthingandroid.activities.FirstStartActivity; -import com.nutomic.syncthingandroid.activities.FolderActivity; -import com.nutomic.syncthingandroid.activities.LogActivity; -import com.nutomic.syncthingandroid.activities.MainActivity; -import com.nutomic.syncthingandroid.service.SyncthingService.State; - -import javax.inject.Inject; - -public class NotificationHandler { - - private static final String TAG = "NotificationHandler"; - private static final int ID_PERSISTENT = 1; - private static final int ID_PERSISTENT_WAITING = 4; - private static final int ID_RESTART = 2; - private static final int ID_STOP_BACKGROUND_WARNING = 3; - private static final int ID_CRASH = 9; - private static final int ID_MISSING_PERM = 10; - private static final String CHANNEL_PERSISTENT = "01_syncthing_persistent"; - private static final String CHANNEL_INFO = "02_syncthing_notifications"; - private static final String CHANNEL_PERSISTENT_WAITING = "03_syncthing_persistent_waiting"; - - private final Context mContext; - @Inject SharedPreferences mPreferences; - private final NotificationManager mNotificationManager; - private final NotificationChannel mPersistentChannel; - private final NotificationChannel mPersistentChannelWaiting; - private final NotificationChannel mInfoChannel; - - private String mLastNotificationText = null; - private Boolean lastStartForegroundService = false; - private Boolean appShutdownInProgress = false; - - @TargetApi(23) - private int FLAG_IMMUTABLE = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ? PendingIntent.FLAG_IMMUTABLE : 0; - - public NotificationHandler(Context context) { - ((SyncthingApp) context.getApplicationContext()).component().inject(this); - mContext = context; - mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - mPersistentChannel = new NotificationChannel( - CHANNEL_PERSISTENT, mContext.getString(R.string.notifications_persistent_channel), - NotificationManager.IMPORTANCE_MIN); - mPersistentChannel.enableLights(false); - mPersistentChannel.enableVibration(false); - mPersistentChannel.setSound(null, null); - mPersistentChannel.setShowBadge(false); - mPersistentChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET); - mNotificationManager.createNotificationChannel(mPersistentChannel); - - mPersistentChannelWaiting = new NotificationChannel( - CHANNEL_PERSISTENT_WAITING, mContext.getString(R.string.notification_persistent_waiting_channel), - NotificationManager.IMPORTANCE_MIN); - mPersistentChannelWaiting.enableLights(false); - mPersistentChannelWaiting.enableVibration(false); - mPersistentChannelWaiting.setSound(null, null); - mPersistentChannelWaiting.setShowBadge(false); - mPersistentChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET); - mNotificationManager.createNotificationChannel(mPersistentChannelWaiting); - - mInfoChannel = new NotificationChannel( - CHANNEL_INFO, mContext.getString(R.string.notifications_other_channel), - NotificationManager.IMPORTANCE_LOW); - mInfoChannel.enableVibration(false); - mInfoChannel.setSound(null, null); - mInfoChannel.setShowBadge(true); - mNotificationManager.createNotificationChannel(mInfoChannel); - } else { - mPersistentChannel = null; - mPersistentChannelWaiting = null; - mInfoChannel = null; - } - } - - private NotificationCompat.Builder getNotificationBuilder(NotificationChannel channel) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - return new NotificationCompat.Builder(mContext, channel.getId()); - } else { - //noinspection deprecation - return new NotificationCompat.Builder(mContext); - } - } - - /** - * Shows, updates or hides the notification. - */ - public void updatePersistentNotification(SyncthingService service) { - // Persist previous notification details. - updatePersistentNotification(service, true, 0, 0); - } - - public void updatePersistentNotification(SyncthingService service, - Boolean persistNotificationDetails, - int onlineDeviceCount, - int totalSyncCompletion) { - boolean startServiceOnBoot = mPreferences.getBoolean(Constants.PREF_START_SERVICE_ON_BOOT, false); - State currentServiceState = service.getCurrentState(); - boolean syncthingRunning = currentServiceState == SyncthingService.State.ACTIVE || - currentServiceState == SyncthingService.State.STARTING; - boolean startForegroundService = false; - if (!appShutdownInProgress) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - /** - * Android 7 and lower: - * The app may run in background and monitor run conditions even if it is not - * running as a foreground service. For that reason, we can use a normal - * notification if syncthing is DISABLED. - */ - startForegroundService = startServiceOnBoot || syncthingRunning; - } else { - /** - * Android 8+: - * Always use startForeground. - * This makes sure the app is not killed, and we don't miss run condition events. - * On Android 8+, this behaviour is mandatory to receive broadcasts. - * https://stackoverflow.com/a/44505719/1837158 - * Foreground priority requires a notification so this ensures that we either have a - * "default" or "low_priority" notification, but not "none". - */ - startForegroundService = true; - } - } - - // Check if we have to stopForeground. - if (startForegroundService != lastStartForegroundService) { - if (!startForegroundService) { - Log.v(TAG, "Stopping foreground service"); - service.stopForeground(false); - } - } - - // Prepare notification builder. - String text; - switch (currentServiceState) { - case ERROR: - case INIT: - text = mContext.getString(R.string.syncthing_terminated); - break; - case DISABLED: - text = mContext.getString(R.string.syncthing_disabled); - break; - case STARTING: - text = mContext.getString(R.string.syncthing_starting); - break; - case ACTIVE: - if (mLastNotificationText == null || !persistNotificationDetails) { - if (totalSyncCompletion == -1) { - mLastNotificationText = mContext.getString( - R.string.syncthing_active_details, - mContext.getString(R.string.no_remote_devices_connected) - ); - } else if (totalSyncCompletion == 100) { - mLastNotificationText = mContext.getString( - R.string.syncthing_active_details, - mContext.getResources().getQuantityString( - R.plurals.device_online_up_to_date, - onlineDeviceCount, - onlineDeviceCount - ) - ); - } else { - mLastNotificationText = mContext.getResources().getQuantityString( - R.plurals.syncthing_active_syncing_device_online, - onlineDeviceCount, - totalSyncCompletion, - onlineDeviceCount - ); - } - } - text = mLastNotificationText; - break; - default: - text = mContext.getString(R.string.syncthing_terminated); - break; - } - - /** - * Reason for two separate IDs: if one of the notification channels is hidden then - * the startForeground() below won't update the notification but use the old one. - */ - int idToShow = syncthingRunning ? ID_PERSISTENT : ID_PERSISTENT_WAITING; - int idToCancel = syncthingRunning ? ID_PERSISTENT_WAITING : ID_PERSISTENT; - Intent intent = new Intent(mContext, MainActivity.class); - NotificationChannel channel = syncthingRunning ? mPersistentChannel : mPersistentChannelWaiting; - NotificationCompat.Builder builder = getNotificationBuilder(channel) - .setContentTitle(text) - .setSmallIcon(R.drawable.ic_stat_notify) - .setOngoing(true) - .setOnlyAlertOnce(true) - .setPriority(NotificationCompat.PRIORITY_MIN) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)); - if (!appShutdownInProgress) { - if (startForegroundService) { - Log.v(TAG, "Starting foreground service or updating notification"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - service.startForeground(idToShow, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC); - } else { - service.startForeground(idToShow, builder.build()); - } - } else { - Log.v(TAG, "Updating notification"); - mNotificationManager.notify(idToShow, builder.build()); - } - } else { - mNotificationManager.cancel(idToShow); - } - mNotificationManager.cancel(idToCancel); - - // Remember last notification visibility. - lastStartForegroundService = startForegroundService; - } - - /** - * Called by {@link SyncthingService#onStart} {@link SyncthingService#onDestroy} - * to indicate app startup and shutdown. - */ - public void setAppShutdownInProgress(Boolean newValue) { - appShutdownInProgress = newValue; - } - - public void showCrashedNotification(@StringRes int title, String extraInfo) { - Intent intent = new Intent(mContext, LogActivity.class); - Notification n = getNotificationBuilder(mInfoChannel) - .setContentTitle(mContext.getString(title, extraInfo)) - .setContentText(mContext.getString(R.string.notification_crash_text, extraInfo)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE)) - .setAutoCancel(true) - .build(); - mNotificationManager.notify(ID_CRASH, n); - } - - /** - * Calculate a deterministic ID between 1000 and 2000 to avoid duplicate - * notification ids for different device, folder consent popups triggered - * by {@link EventProcessor}. - */ - public int getNotificationIdFromText(String text) { - return 1000 + text.hashCode() % 1000; - } - - /** - * Closes a notification. Required after the user hit an action button. - */ - public void cancelConsentNotification(int notificationId) { - if (notificationId == 0) { - return; - } - Log.v(TAG, "Cancelling notification with id " + notificationId); - mNotificationManager.cancel(notificationId); - } - - /** - * Used by {@link EventProcessor} - */ - public void showConsentNotification(int notificationId, - String text, - PendingIntent piAccept, - PendingIntent piIgnore) { - /** - * As we know the id for a specific notification text, - * we'll dismiss this notification as it may be outdated. - * This is also valid if the notification does not exist. - */ - mNotificationManager.cancel(notificationId); - Notification n = getNotificationBuilder(mInfoChannel) - .setContentTitle(mContext.getString(R.string.app_name)) - .setContentText(text) - .setStyle(new NotificationCompat.BigTextStyle() - .bigText(text)) - .setContentIntent(piAccept) - .addAction(R.drawable.ic_stat_notify, mContext.getString(R.string.accept), piAccept) - .addAction(R.drawable.ic_stat_notify, mContext.getString(R.string.ignore), piIgnore) - .setSmallIcon(R.drawable.ic_stat_notify) - .setAutoCancel(true) - .build(); - mNotificationManager.notify(notificationId, n); - } - - public void showStoragePermissionRevokedNotification() { - Intent intent = new Intent(mContext, FirstStartActivity.class); - Notification n = getNotificationBuilder(mInfoChannel) - .setContentTitle(mContext.getString(R.string.syncthing_terminated)) - .setContentText(mContext.getString(R.string.toast_write_storage_permission_required)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, FLAG_IMMUTABLE)) - .setAutoCancel(true) - .setOnlyAlertOnce(true) - .build(); - mNotificationManager.notify(ID_MISSING_PERM, n); - } - - public void cancelRestartNotification() { - mNotificationManager.cancel(ID_RESTART); - } - - public void showStopSyncthingWarningNotification() { - final String msg = mContext.getString(R.string.appconfig_receiver_background_enabled); - NotificationCompat.Builder nb = getNotificationBuilder(mInfoChannel) - .setContentText(msg) - .setTicker(msg) - .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) - .setContentTitle(mContext.getText(mContext.getApplicationInfo().labelRes)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setAutoCancel(true) - .setContentIntent(PendingIntent.getActivity(mContext, 0, - new Intent(mContext, MainActivity.class), - FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)); - - nb.setCategory(Notification.CATEGORY_ERROR); - mNotificationManager.notify(ID_STOP_BACKGROUND_WARNING, nb.build()); - } - - public void showDeviceConnectNotification(String deviceId, - String deviceName, - String deviceAddress) { - if (deviceId == null) { - Log.e(TAG, "showDeviceConnectNotification: deviceId == null"); - return; - } - String title = mContext.getString(R.string.device_rejected, - deviceName.isEmpty() ? deviceId.substring(0, 7) : deviceName); - int notificationId = getNotificationIdFromText(title); - - // Prepare "accept" action. - Intent intentAccept = new Intent(mContext, DeviceActivity.class) - .putExtra(DeviceActivity.EXTRA_NOTIFICATION_ID, notificationId) - .putExtra(DeviceActivity.EXTRA_IS_CREATE, true) - .putExtra(DeviceActivity.EXTRA_DEVICE_ID, deviceId) - .putExtra(DeviceActivity.EXTRA_DEVICE_NAME, deviceName); - PendingIntent piAccept = PendingIntent.getActivity(mContext, notificationId, - intentAccept, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - - // Prepare "ignore" action. - Intent intentIgnore = new Intent(mContext, SyncthingService.class) - .putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) - .putExtra(SyncthingService.EXTRA_DEVICE_ID, deviceId) - .putExtra(SyncthingService.EXTRA_DEVICE_NAME, deviceName) - .putExtra(SyncthingService.EXTRA_DEVICE_ADDRESS, deviceAddress); - intentIgnore.setAction(SyncthingService.ACTION_IGNORE_DEVICE); - PendingIntent piIgnore = PendingIntent.getService(mContext, 0, - intentIgnore, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - - // Show notification. - showConsentNotification(notificationId, title, piAccept, piIgnore); - } - - public void showFolderShareNotification(String deviceId, - String deviceName, - String folderId, - String folderLabel, - Boolean receiveEncrypted, - Boolean remoteEncrypted, - Boolean isNewFolder) { - if (deviceId == null) { - Log.e(TAG, "showFolderShareNotification: deviceId == null"); - return; - } - if (folderId == null) { - Log.e(TAG, "showFolderShareNotification: folderId == null"); - return; - } - String title = mContext.getString(R.string.folder_rejected, deviceName, - folderLabel.isEmpty() ? folderId : folderLabel + " (" + folderId + ")"); - int notificationId = getNotificationIdFromText(title); - - // Prepare "accept" action. - Intent intentAccept = new Intent(mContext, FolderActivity.class) - .putExtra(FolderActivity.EXTRA_NOTIFICATION_ID, notificationId) - .putExtra(FolderActivity.EXTRA_IS_CREATE, isNewFolder) - .putExtra(FolderActivity.EXTRA_DEVICE_ID, deviceId) - .putExtra(FolderActivity.EXTRA_FOLDER_ID, folderId) - .putExtra(FolderActivity.EXTRA_FOLDER_LABEL, folderLabel) - .putExtra(FolderActivity.EXTRA_RECEIVE_ENCRYPTED, receiveEncrypted) - .putExtra(FolderActivity.EXTRA_REMOTE_ENCRYPTED, remoteEncrypted); - PendingIntent piAccept = PendingIntent.getActivity(mContext, notificationId, - intentAccept, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - - // Prepare "ignore" action. - Intent intentIgnore = new Intent(mContext, SyncthingService.class) - .putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) - .putExtra(SyncthingService.EXTRA_DEVICE_ID, deviceId) - .putExtra(SyncthingService.EXTRA_FOLDER_ID, folderId) - .putExtra(SyncthingService.EXTRA_FOLDER_LABEL, folderLabel); - intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER); - PendingIntent piIgnore = PendingIntent.getService(mContext, 0, - intentIgnore, FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - - // Show notification. - showConsentNotification(notificationId, title, piAccept, piIgnore); - } -} From d89da8164830e7e1a0cff2c9ada44c119cacbe37 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:22:02 +0100 Subject: [PATCH 22/41] Create FlavourConstants.java --- .../syncthingandroid/service/FlavourConstants.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java diff --git a/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java b/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java new file mode 100644 index 000000000..f143d5f9f --- /dev/null +++ b/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java @@ -0,0 +1,9 @@ +package com.nutomic.syncthingandroid.service; + +import android.content.pm.ServiceInfo; + +public class FlavourConstants { + + public static final Integer FOREGROUND_SERVICE_TYPE = ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC; + +} From 453113e6e43083788f19d817efba9da52a9646ab Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:22:05 +0100 Subject: [PATCH 23/41] Create FlavourConstants.java --- .../syncthingandroid/service/FlavourConstants.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java b/app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java new file mode 100644 index 000000000..2015509ca --- /dev/null +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java @@ -0,0 +1,9 @@ +package com.nutomic.syncthingandroid.service; + +import android.content.pm.ServiceInfo; + +public class FlavourConstants { + + public static final Integer FOREGROUND_SERVICE_TYPE = ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE; + +} From 098344dc118fbe5a046b2a4f264a669b1c64a127 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:35:43 +0100 Subject: [PATCH 24/41] Delete AndroidManifest.xml --- app/src/release/AndroidManifest.xml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 app/src/release/AndroidManifest.xml diff --git a/app/src/release/AndroidManifest.xml b/app/src/release/AndroidManifest.xml deleted file mode 100644 index 8a762a288..000000000 --- a/app/src/release/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - From 8d9379c8868b9582227cd7293aeb4457742dda8d Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:35:49 +0100 Subject: [PATCH 25/41] Update AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml index 98fface60..dc0d86eef 100644 --- a/app/src/gplay/AndroidManifest.xml +++ b/app/src/gplay/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="com.nutomic.syncthingandroid"> + + From 17cce8d1c5f90d741d286f51c08cee83642bfef4 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:37:03 +0100 Subject: [PATCH 26/41] 1 --- .../service/{FlavourConstants.java => FlavorConstants.java} | 2 +- .../com/nutomic/syncthingandroid/service/FlavorConstants.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/src/gplay/java/com/nutomic/syncthingandroid/service/{FlavourConstants.java => FlavorConstants.java} (86%) rename app/src/{main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java => release/java/com/nutomic/syncthingandroid/service/FlavorConstants.java} (86%) diff --git a/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java b/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavorConstants.java similarity index 86% rename from app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java rename to app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavorConstants.java index f143d5f9f..f0552e974 100644 --- a/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavourConstants.java +++ b/app/src/gplay/java/com/nutomic/syncthingandroid/service/FlavorConstants.java @@ -2,7 +2,7 @@ import android.content.pm.ServiceInfo; -public class FlavourConstants { +public class FlavorConstants { public static final Integer FOREGROUND_SERVICE_TYPE = ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC; diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java b/app/src/release/java/com/nutomic/syncthingandroid/service/FlavorConstants.java similarity index 86% rename from app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java rename to app/src/release/java/com/nutomic/syncthingandroid/service/FlavorConstants.java index 2015509ca..e2a28ab5b 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/FlavourConstants.java +++ b/app/src/release/java/com/nutomic/syncthingandroid/service/FlavorConstants.java @@ -2,7 +2,7 @@ import android.content.pm.ServiceInfo; -public class FlavourConstants { +public class FlavorConstants { public static final Integer FOREGROUND_SERVICE_TYPE = ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE; From e5db9bfe8c849c3bc98356554068dc3ae6cee928 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:37:55 +0100 Subject: [PATCH 27/41] Update NotificationHandler.java --- .../nutomic/syncthingandroid/service/NotificationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java index eb0e3d1df..a4915fca2 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -213,7 +213,7 @@ public void updatePersistentNotification(SyncthingService service, if (startForegroundService) { Log.v(TAG, "Starting foreground service or updating notification"); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - service.startForeground(idToShow, builder.build(), FlavourConstants.FOREGROUND_SERVICE_TYPE); + service.startForeground(idToShow, builder.build(), FlavorConstants.FOREGROUND_SERVICE_TYPE); } else { service.startForeground(idToShow, builder.build()); } From cf4a32a9b3a22937c6420758d9b7f69914e32fdf Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:39:34 +0100 Subject: [PATCH 28/41] Create FlavorConstants.java --- .../syncthingandroid/service/FlavorConstants.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 app/src/debug/java/com/nutomic/syncthingandroid/service/FlavorConstants.java diff --git a/app/src/debug/java/com/nutomic/syncthingandroid/service/FlavorConstants.java b/app/src/debug/java/com/nutomic/syncthingandroid/service/FlavorConstants.java new file mode 100644 index 000000000..e2a28ab5b --- /dev/null +++ b/app/src/debug/java/com/nutomic/syncthingandroid/service/FlavorConstants.java @@ -0,0 +1,9 @@ +package com.nutomic.syncthingandroid.service; + +import android.content.pm.ServiceInfo; + +public class FlavorConstants { + + public static final Integer FOREGROUND_SERVICE_TYPE = ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE; + +} From b0f1feee38329768826ee86a4f25cb38b2ea9b11 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:47:58 +0100 Subject: [PATCH 29/41] 1 --- .../nutomic/syncthingandroid/fragments/DrawerFragment.java | 2 +- .../java/com/nutomic/syncthingandroid/service/Constants.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java b/app/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java index c21180cc0..79c397dee 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java @@ -134,7 +134,7 @@ private void updateUI() { * Reason: SyncthingNative's Web UI is not approved by Google because * it is lacking full DPAD navigation support. See issue #567. */ - mDrawerActionWebGui.setVisibility((!mRunningOnTV) ? View.VISIBLE : View.GONE); + mDrawerActionWebGui.setVisibility((!mRunningOnTV || Constants.isDebuggable(getContext())) ? View.VISIBLE : View.GONE); // Enable buttons if syncthing is running. mDrawerRecentChanges.setEnabled(syncthingRunning); diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java b/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java index 943ab9ade..26a13cabc 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java @@ -1,6 +1,7 @@ package com.nutomic.syncthingandroid.service; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.os.Build; import android.text.TextUtils; @@ -276,6 +277,10 @@ public static Boolean isRunningOnEmulator() { ); } + public static Boolean isDebuggable(Context context) { + return (0 != (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); + } + /** * Decide if we should enforce HTTPS when accessing the Web UI and REST API. * Android 4.4 and earlier don't have support for TLS 1.2 requiring us to From 6a8f13e43ecae08b57efb6e9231e7d912a979178 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:55:24 +0100 Subject: [PATCH 30/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index a07530414..6fb170e57 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -47,7 +47,7 @@ IF NOT EXIST "%ANDROID_PUBLISHER_CREDENTIALS%" echo [ERROR] ANDROID_PUBLISHER_CR FOR /F "tokens=*" %%i in ('type "%ANDROID_PUBLISHER_CREDENTIALS%" 2^>NUL:') DO SET ANDROID_PUBLISHER_CREDENTIALS=%%i REM REM User has to enter the signing password if it is not filled in here. -SET SIGNING_PASSWORD= +REM SET SIGNING_PASSWORD= IF DEFINED SIGNING_PASSWORD goto :absLint :enterSigningPassword setlocal DisableDelayedExpansion From 17650c78073a68dd0957302a45e4d6f2626e33e5 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:08:10 +0100 Subject: [PATCH 31/41] Update AndroidManifest.xml --- app/src/gplay/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/gplay/AndroidManifest.xml b/app/src/gplay/AndroidManifest.xml index dc0d86eef..be1cce4fc 100644 --- a/app/src/gplay/AndroidManifest.xml +++ b/app/src/gplay/AndroidManifest.xml @@ -8,10 +8,11 @@ - + From 3ffccc0f76b20c44cee8d86defd9532e4faf0616 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:13:08 +0100 Subject: [PATCH 32/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index 6fb170e57..d70688e5f 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -6,16 +6,15 @@ cls REM REM Script Consts. SET CLEANUP_BEFORE_BUILD=1 -SET SKIP_RELEASE_BUILD=0 REM REM Runtime Variables. IF EXIST "%LocalAppData%\Android\Sdk" SET "ANDROID_SDK_ROOT=%LocalAppData%\Android\Sdk" IF NOT DEFINED ANDROID_SDK_ROOT SET "ANDROID_SDK_ROOT=%SCRIPT_PATH%..\syncthing-android-prereq" -IF NOT DEFINED ANDROID_PUBLISHER_CREDENTIALS echo [WARN] ANDROID_PUBLISHER_CREDENTIALS env var not set. We will skip the signed release build. & SET SKIP_RELEASE_BUILD=1 REM REM SET ANDROID_PUBLISHER_CREDENTIALS=%userprofile%\.android\play_key.json" REM SET SYNCTHING_RELEASE_STORE_FILE="%userprofile%\.android\signing_key.jks" SET SYNCTHING_RELEASE_KEY_ALIAS=Syncthing-Fork +SET BUILD_FLAVOUR_RELEASE=release SET BUILD_FLAVOUR_GPLAY=gplay title %SYNCTHING_RELEASE_KEY_ALIAS% - Build APK REM @@ -37,9 +36,6 @@ SET LIBCOUNT= for /f "tokens=*" %%A IN ('dir /s /a "%SCRIPT_PATH%app\src\main\jniLibs\*" 2^>NUL: ^| find /C "libsyncthingnative.so"') DO SET LIBCOUNT=%%A IF NOT "%LIBCOUNT%" == "4" echo [ERROR] SyncthingNative[s] "libsyncthingnative.so" are missing. Please run "gradlew buildNative" first. & goto :eos REM -REM Check if we should skip the release build and just make a debug build. -IF "%SKIP_RELEASE_BUILD%" == "1" goto :absLint -REM echo [INFO] Let's prepare a new "%SYNCTHING_RELEASE_KEY_ALIAS%" release. REM echo [INFO] Checking release prerequisites ... @@ -63,16 +59,16 @@ REM copy /y "%SCRIPT_PATH%app\src\main\play\release-notes\en-GB\beta.txt" "%SCRIPT_PATH%app\src\main\play\release-notes\en-GB\default.txt" REM echo [INFO] Running lint before building ... -IF "%SKIP_RELEASE_BUILD%" == "1" call gradlew --quiet lintDebug & SET RESULT=%ERRORLEVEL% -IF NOT "%SKIP_RELEASE_BUILD%" == "1" call gradlew --quiet lint & SET RESULT=%ERRORLEVEL% -IF NOT "!RESULT!" == "0" echo [ERROR] "gradlew lint" exited with code #%RESULT%. & goto :eos REM -call :buildApk debug +call gradlew --quiet lint%BUILD_FLAVOUR_RELEASE% & SET RESULT=%ERRORLEVEL% +IF NOT "!RESULT!" == "0" echo [ERROR] "gradlew lint%BUILD_FLAVOUR_RELEASE%" exited with code #%RESULT%. & goto :eos +REM +call gradlew --quiet lint%BUILD_FLAVOUR_GPLAY% & SET RESULT=%ERRORLEVEL% +IF NOT "!RESULT!" == "0" echo [ERROR] "gradlew lint%BUILD_FLAVOUR_GPLAY%" exited with code #%RESULT%. & goto :eos REM -REM Check if we should skip the release build and just make a debug build. -IF "%SKIP_RELEASE_BUILD%" == "1" goto :absPostBuildScript +echo [INFO] Building APK ... REM -call :buildApk release +call :buildApk %BUILD_FLAVOUR_RELEASE% call :buildApk %BUILD_FLAVOUR_GPLAY% REM IF "%CLEANUP_BEFORE_BUILD%" == "1" del /f "%SCRIPT_PATH%app\build\outputs\bundle\%BUILD_FLAVOUR_GPLAY%\app-%BUILD_FLAVOUR_GPLAY%.aab" 2> NUL: @@ -94,9 +90,6 @@ REM REM Copy build artifacts with correct file name to upload folder. call "%SCRIPT_PATH%postbuild_copy_apk.cmd" REM -REM Check if we should skip the release upload and finish here. -IF "%SKIP_RELEASE_BUILD%" == "1" goto :eos -REM :askUserReadyToPublish SET UI_ANSWER= SET /p UI_ANSWER=Are you ready to publish this release to GPlay? [y/n] From 5880b71326f304981e29f5bee06cc37e6cfdb465 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:15:35 +0100 Subject: [PATCH 33/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index d70688e5f..079799860 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -66,7 +66,7 @@ REM call gradlew --quiet lint%BUILD_FLAVOUR_GPLAY% & SET RESULT=%ERRORLEVEL% IF NOT "!RESULT!" == "0" echo [ERROR] "gradlew lint%BUILD_FLAVOUR_GPLAY%" exited with code #%RESULT%. & goto :eos REM -echo [INFO] Building APK ... +REM Building APK REM call :buildApk %BUILD_FLAVOUR_RELEASE% call :buildApk %BUILD_FLAVOUR_GPLAY% From 00e0270fb02b25200649a8c8f8ee6b0331bbb059 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:17:01 +0100 Subject: [PATCH 34/41] Update App_build_and_release.cmd --- App_build_and_release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App_build_and_release.cmd b/App_build_and_release.cmd index 079799860..74d5fbc33 100644 --- a/App_build_and_release.cmd +++ b/App_build_and_release.cmd @@ -138,6 +138,6 @@ echo [INFO] Building Android APK variant "%BA_BUILD_TYPE%" ... call gradlew --quiet assemble%BA_BUILD_TYPE% SET RESULT=%ERRORLEVEL% IF NOT "%RESULT%" == "0" echo [ERROR] "gradlew assemble%BA_BUILD_TYPE%" exited with code #%RESULT%. & goto :eos -type "app\build\intermediates\merged_manifests\%BA_BUILD_TYPE%\AndroidManifest.xml" | findstr /i "android:version" +type "app\build\intermediates\merged_manifests\%BA_BUILD_TYPE%\process%BA_BUILD_TYPE%Manifest\AndroidManifest.xml" | findstr /i "android:version" REM goto :eof From 5b1f456bbe6a6d156843298c29bfef9ed16a88e6 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:20:51 +0100 Subject: [PATCH 35/41] Update postbuild_copy_apk.cmd --- postbuild_copy_apk.cmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/postbuild_copy_apk.cmd b/postbuild_copy_apk.cmd index 9ea866d95..5060fc8ae 100644 --- a/postbuild_copy_apk.cmd +++ b/postbuild_copy_apk.cmd @@ -67,8 +67,8 @@ echo [INFO] VERSION_NAME=[%VERSION_NAME%], commit=[%COMMIT_SHORT_HASH%]=[%COMMIT echo [INFO] Copying APK to same directory ... REM REM Copy APK to be ready for upload to the GitHub release page. -SET APK_GITHUB_NEW_FILENAME=%APPLICATION_ID%_github_v%VERSION_NAME%_%COMMIT_SHORT_HASH%.apk -call :copyIfExist %SCRIPT_PATH%app\build\outputs\apk\debug\app-debug.apk %SCRIPT_PATH%app\build\outputs\apk\debug\%APK_GITHUB_NEW_FILENAME% +SET APK_RELEASE_NEW_FILENAME=%APPLICATION_ID%_github_v%VERSION_NAME%_%COMMIT_SHORT_HASH%.apk +call :copyIfExist %SCRIPT_PATH%app\build\outputs\apk\release\app-release.apk %SCRIPT_PATH%app\build\outputs\apk\release\%APK_RELEASE_NEW_FILENAME% REM SET APK_GPLAY_NEW_FILENAME=%APPLICATION_ID%_gplay_v%VERSION_NAME%_%COMMIT_SHORT_HASH%.apk IF NOT "%SKIP_RELEASE_BUILD%" == "1" call :copyIfExist %SCRIPT_PATH%app\build\outputs\apk\%BUILD_FLAVOUR_GPLAY%\app-%BUILD_FLAVOUR_GPLAY%.apk %SCRIPT_PATH%app\build\outputs\apk\%BUILD_FLAVOUR_GPLAY%\%APK_GPLAY_NEW_FILENAME% @@ -76,7 +76,7 @@ REM REM Copy both APK to temporary storage location if the storage is available. IF EXIST %TEMP_OUTPUT_FOLDER%\ ( echo [INFO] Copying APK to [%TEMP_OUTPUT_FOLDER%] ... - copy /y %SCRIPT_PATH%app\build\outputs\apk\debug\%APK_GITHUB_NEW_FILENAME% %TEMP_OUTPUT_FOLDER%\ 2> NUL: + copy /y %SCRIPT_PATH%app\build\outputs\apk\release\%APK_RELEASE_NEW_FILENAME% %TEMP_OUTPUT_FOLDER%\ 2> NUL: IF NOT "%SKIP_RELEASE_BUILD%" == "1" copy /y %SCRIPT_PATH%app\build\outputs\apk\%BUILD_FLAVOUR_GPLAY%\%APK_GPLAY_NEW_FILENAME% %TEMP_OUTPUT_FOLDER%\ 2> NUL: ) REM @@ -137,7 +137,7 @@ IF %FILE_SIZE% LSS 23 echo [ERROR] Download source code FAILED #3. & DEL /F %TMP REM REM Package built APKs into ZIP. echo [INFO] Adding built APKs to source code ZIP ... -%TMP_DSC_SEVENZIP_EXE% -y -bso0 a %TMP_DSC_ZIPFILE_FULLFN% %TEMP_OUTPUT_FOLDER%\%APK_GITHUB_NEW_FILENAME% +%TMP_DSC_SEVENZIP_EXE% -y -bso0 a %TMP_DSC_ZIPFILE_FULLFN% %TEMP_OUTPUT_FOLDER%\%APK_RELEASE_NEW_FILENAME% IF NOT "%SKIP_RELEASE_BUILD%" == "1" %TMP_DSC_SEVENZIP_EXE% -y -bso0 a %TMP_DSC_ZIPFILE_FULLFN% %TEMP_OUTPUT_FOLDER%\%APK_GPLAY_NEW_FILENAME% REM goto :eof From 8b6f968f184c94c1913bddcabb291e800d1596bb Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:23:40 +0100 Subject: [PATCH 36/41] Update postbuild.py --- app/postbuild.py | 51 ------------------------------------------------ 1 file changed, 51 deletions(-) diff --git a/app/postbuild.py b/app/postbuild.py index cd0112ba5..862523bd0 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -76,46 +76,6 @@ def calcAndPrintCertHash(apk_fullfn, apk_build_type): return None -def pushAPKtoDevice(apk_package_name, apk_fullfn_to_push): - if not debug_apk or not os.path.isfile(debug_apk): - print('[ERROR] pushAPKtoDevice: APK not found.'); - return None - - # Check if adb is available. - adb_bin = which("adb"); - if not adb_bin: - print('[WARNING] adb is not available on the PATH.') - # install_adb(); - # Retry: Check if adb is available. - # adb_bin = which("adb"); - if not adb_bin: - print('[ERROR] adb is not available on the PATH.') - sys.exit(0) - print('[INFO] adb_bin=\'' + adb_bin + '\'') - - print('[INFO] Connecting to attached usb device ...') - try: - subprocess.check_call([ - adb_bin, - 'devices' - ]) - except: - sys.exit(0) - - print('[INFO] Installing APK to attached usb device ...') - try: - subprocess.check_call(adb_bin + ' install -r --user 0 ' + apk_fullfn_to_push) - except: - sys.exit(0) - - print('[INFO] Starting app ...') - try: - subprocess.check_call(adb_bin + ' shell monkey -p ' + apk_package_name + ' 1') - except: - sys.exit(0) - - return None - ################# # Script Main # @@ -135,14 +95,3 @@ def pushAPKtoDevice(apk_package_name, apk_fullfn_to_push): # See the wiki for more details: wiki/Switch-between-releases_Verify-APK-is-genuine.md calcAndPrintCertHash(debug_apk, "debug"); calcAndPrintCertHash(release_apk, "release"); - -# -# Check if push to device is enabled. -# -# Purpose: Push to device eases deployment on a real Android test device for developers -# that cannot or do not wish to install the full Android Studio IDE. -if not enable_push_to_device or not os.path.isfile(enable_push_to_device): - # print('[INFO] push-to-device after build is DISABLED. To enable it, run \'echo . > ' + enable_push_to_device + '\'') - sys.exit(0) - -pushAPKtoDevice("com.github.catfriend1.syncthingandroid.debug", debug_apk) From 8acfa32cc8debaafc20a6e82843440bc26f8c58c Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:23:43 +0100 Subject: [PATCH 37/41] Update postbuild.py --- app/postbuild.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/postbuild.py b/app/postbuild.py index 862523bd0..b365b8457 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -87,7 +87,6 @@ def calcAndPrintCertHash(apk_fullfn, apk_build_type): # Build FullFNs. current_dir = os.path.dirname(os.path.realpath(__file__)) -enable_push_to_device = os.path.realpath(os.path.join(current_dir, "..", "#enable_push_to_device")) debug_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')) release_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'release', 'app-release.apk')) From 02d9949f160cc3f814b7bd9e7c319b2d369dcfcf Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:24:55 +0100 Subject: [PATCH 38/41] Update postbuild.py --- app/postbuild.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/postbuild.py b/app/postbuild.py index b365b8457..43f846046 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -88,9 +88,11 @@ def calcAndPrintCertHash(apk_fullfn, apk_build_type): # Build FullFNs. current_dir = os.path.dirname(os.path.realpath(__file__)) debug_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')) +gplay_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'gplay', 'app-gplay.apk')) release_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'release', 'app-release.apk')) # Calculate certificate hash of built APKs and output if it matches a known release channel. # See the wiki for more details: wiki/Switch-between-releases_Verify-APK-is-genuine.md calcAndPrintCertHash(debug_apk, "debug"); +calcAndPrintCertHash(debug_apk, "gplay"); calcAndPrintCertHash(release_apk, "release"); From d23a7ff5632331ad0542712db0069cae800d4f9c Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:26:03 +0100 Subject: [PATCH 39/41] Update postbuild.py --- app/postbuild.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/postbuild.py b/app/postbuild.py index 43f846046..be9b36f35 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -11,6 +11,9 @@ # - Python 2.7.15 # - Python 3.7.0 # +# Command line: +# gradlew postbuildscript +# SUPPORTED_PYTHON_PLATFORMS = ['Windows', 'Linux', 'Darwin'] From cc943d5ba611bef5d193b42cdabc0997141acd33 Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:26:15 +0100 Subject: [PATCH 40/41] Update postbuild.py --- app/postbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/postbuild.py b/app/postbuild.py index be9b36f35..c13acfe0d 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -97,5 +97,5 @@ def calcAndPrintCertHash(apk_fullfn, apk_build_type): # Calculate certificate hash of built APKs and output if it matches a known release channel. # See the wiki for more details: wiki/Switch-between-releases_Verify-APK-is-genuine.md calcAndPrintCertHash(debug_apk, "debug"); -calcAndPrintCertHash(debug_apk, "gplay"); +calcAndPrintCertHash(gplay_apk, "gplay"); calcAndPrintCertHash(release_apk, "release"); From a5050f989f9572a7f461fe6604636cf11dedf7cb Mon Sep 17 00:00:00 2001 From: Catfriend1 <16361913+Catfriend1@users.noreply.github.com> Date: Sun, 27 Oct 2024 10:26:44 +0100 Subject: [PATCH 41/41] Update postbuild.py --- app/postbuild.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/postbuild.py b/app/postbuild.py index c13acfe0d..8eb06253b 100644 --- a/app/postbuild.py +++ b/app/postbuild.py @@ -90,12 +90,12 @@ def calcAndPrintCertHash(apk_fullfn, apk_build_type): # Build FullFNs. current_dir = os.path.dirname(os.path.realpath(__file__)) -debug_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')) +# debug_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')) gplay_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'gplay', 'app-gplay.apk')) release_apk = os.path.realpath(os.path.join(current_dir, 'build', 'outputs', 'apk', 'release', 'app-release.apk')) # Calculate certificate hash of built APKs and output if it matches a known release channel. # See the wiki for more details: wiki/Switch-between-releases_Verify-APK-is-genuine.md -calcAndPrintCertHash(debug_apk, "debug"); +# calcAndPrintCertHash(debug_apk, "debug"); calcAndPrintCertHash(gplay_apk, "gplay"); calcAndPrintCertHash(release_apk, "release");