diff --git a/app/src/main/java/com/nutomic/syncthingandroid/model/Config.java b/app/src/main/java/com/nutomic/syncthingandroid/model/Config.java index fb6581fa..183f3f8d 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/model/Config.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/model/Config.java @@ -8,7 +8,6 @@ public class Config { public List folders; public Gui gui; public Options options; - public List pendingDevices; public List remoteIgnoredDevices; public class Gui { diff --git a/app/src/main/java/com/nutomic/syncthingandroid/model/Device.java b/app/src/main/java/com/nutomic/syncthingandroid/model/Device.java index 29a307fd..71dbe507 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/model/Device.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/model/Device.java @@ -12,7 +12,6 @@ public class Device { public String certName; public boolean introducer; public boolean paused; - public List pendingFolders; public List ignoredFolders; /** diff --git a/app/src/main/java/com/nutomic/syncthingandroid/model/PendingDevice.java b/app/src/main/java/com/nutomic/syncthingandroid/model/PendingDevice.java deleted file mode 100644 index 303c8e75..00000000 --- a/app/src/main/java/com/nutomic/syncthingandroid/model/PendingDevice.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.nutomic.syncthingandroid.model; - -import android.text.TextUtils; - -public class PendingDevice { - public String time = ""; - public String deviceID = ""; - public String name = ""; - public String address = ""; - - /** - * Returns the device name, or the first characters of the ID if the name is empty. - */ - public String getDisplayName() { - return (TextUtils.isEmpty(name)) - ? deviceID.substring(0, 7) - : name; - } -} diff --git a/app/src/main/java/com/nutomic/syncthingandroid/model/PendingFolder.java b/app/src/main/java/com/nutomic/syncthingandroid/model/PendingFolder.java deleted file mode 100644 index b179dbb0..00000000 --- a/app/src/main/java/com/nutomic/syncthingandroid/model/PendingFolder.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.nutomic.syncthingandroid.model; - -import android.text.TextUtils; - -public class PendingFolder { - public String time = ""; - public String id = ""; - public String label = ""; - - /** - * Returns the folder label, or the first characters of the ID if the label is empty. - */ - public String getDisplayLabel() { - return (TextUtils.isEmpty(label)) - ? id.substring(0, 7) - : label; - } -} diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java b/app/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java index 0eb3eefc..ff50612b 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java @@ -12,6 +12,8 @@ import android.os.Looper; import android.provider.MediaStore; import android.util.Log; +import androidx.core.util.Consumer; + import com.annimon.stream.Stream; import com.nutomic.syncthingandroid.BuildConfig; import com.nutomic.syncthingandroid.R; @@ -24,6 +26,8 @@ import com.nutomic.syncthingandroid.model.Event; import com.nutomic.syncthingandroid.model.Folder; import java.io.File; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import javax.inject.Inject; @@ -101,11 +105,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener mApi.reloadConfig(); } break; - case "DeviceRejected": - onDeviceRejected( - (String) event.data.get("device"), // deviceId - (String) event.data.get("name") // deviceName - ); + case "PendingDevicesChanged": + mapNullable((List>) event.data.get("added"), this::onPendingDevicesChanged); break; case "FolderCompletion": CompletionInfo completionInfo = new CompletionInfo(); @@ -116,12 +117,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener completionInfo ); break; - case "FolderRejected": - onFolderRejected( - (String) event.data.get("device"), // deviceId - (String) event.data.get("folder"), // folderId - (String) event.data.get("folderLabel") // folderLabel - ); + case "PendingFoldersChanged": + mapNullable((List>) event.data.get("added"), this::onPendingFoldersChanged); break; case "ItemFinished": String folder = (String) event.data.get("folder"); @@ -209,7 +206,10 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener } } - private void onDeviceRejected(String deviceId, String deviceName) { + private void onPendingDevicesChanged(Map added) { + String deviceId = added.get("deviceID"); + String deviceName = added.get("name"); + String deviceAddress = added.get("address"); if (deviceId == null) { return; } @@ -231,7 +231,9 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener // 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_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, PendingIntent.FLAG_UPDATE_CURRENT); @@ -240,8 +242,10 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore); } - private void onFolderRejected(String deviceId, String folderId, - String folderLabel) { + private void onPendingFoldersChanged(Map added) { + String deviceId = added.get("deviceID"); + String folderId = added.get("folderID"); + String folderLabel = added.get("folderLabel"); if (deviceId == null || folderId == null) { return; } @@ -276,7 +280,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener 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_ID, folderId) + .putExtra(SyncthingService.EXTRA_FOLDER_LABEL, folderLabel); intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER); PendingIntent piIgnore = PendingIntent.getService(mContext, 0, intentIgnore, PendingIntent.FLAG_UPDATE_CURRENT); @@ -284,4 +289,13 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener // Show notification. mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore); } + + private void mapNullable(List l, Consumer c) { + if (l != null) { + for (T m : l) { + c.accept(m); + } + } + } + } diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java b/app/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java index 65dba0dd..497c2edf 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java @@ -1,6 +1,5 @@ package com.nutomic.syncthingandroid.service; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.preference.PreferenceManager; @@ -32,24 +31,22 @@ import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.model.FolderStatus; import com.nutomic.syncthingandroid.model.IgnoredFolder; import com.nutomic.syncthingandroid.model.Options; -import com.nutomic.syncthingandroid.model.PendingDevice; -import com.nutomic.syncthingandroid.model.PendingFolder; import com.nutomic.syncthingandroid.model.RemoteIgnoredDevice; import com.nutomic.syncthingandroid.model.SystemInfo; import com.nutomic.syncthingandroid.model.SystemVersion; -import com.nutomic.syncthingandroid.service.Constants; import java.lang.reflect.Type; import java.net.URL; +import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; @@ -218,7 +215,6 @@ public class RestApi { } Log.v(TAG, "onReloadConfigComplete: Successfully parsed configuration."); if (BuildConfig.DEBUG) { - Log.v(TAG, "mConfig.pendingDevices = " + new Gson().toJson(mConfig.pendingDevices)); Log.v(TAG, "mConfig.remoteIgnoredDevices = " + new Gson().toJson(mConfig.remoteIgnoredDevices)); } @@ -265,7 +261,7 @@ public class RestApi { * Ignored devices will not trigger the "DeviceRejected" event * in {@link EventProcessor#onEvent}. */ - public void ignoreDevice(String deviceId) { + public void ignoreDevice(String deviceId, String deviceName, String deviceAddress) { synchronized (mConfigLock) { // Check if the device has already been ignored. for (RemoteIgnoredDevice remoteIgnoredDevice : mConfig.remoteIgnoredDevices) { @@ -276,24 +272,11 @@ public class RestApi { } } - /** - * Ignore device by moving its corresponding "pendingDevice" entry to - * a newly created "remotePendingDevice" entry. - */ RemoteIgnoredDevice remoteIgnoredDevice = new RemoteIgnoredDevice(); remoteIgnoredDevice.deviceID = deviceId; - Iterator it = mConfig.pendingDevices.iterator(); - while (it.hasNext()) { - PendingDevice pendingDevice = it.next(); - if (deviceId.equals(pendingDevice.deviceID)) { - // Move over information stored in the "pendingDevice" entry. - remoteIgnoredDevice.address = pendingDevice.address; - remoteIgnoredDevice.name = pendingDevice.name; - remoteIgnoredDevice.time = pendingDevice.time; - it.remove(); - break; - } - } + remoteIgnoredDevice.address = deviceAddress; + remoteIgnoredDevice.name = deviceName; + remoteIgnoredDevice.time = dateString(new Date()); mConfig.remoteIgnoredDevices.add(remoteIgnoredDevice); sendConfig(); Log.d(TAG, "Ignored device [" + deviceId + "]"); @@ -305,7 +288,7 @@ public class RestApi { * Ignored folders will not trigger the "FolderRejected" event * in {@link EventProcessor#onEvent}. */ - public void ignoreFolder(String deviceId, String folderId) { + public void ignoreFolder(String deviceId, String folderId, String folderLabel) { synchronized (mConfigLock) { for (Device device : mConfig.devices) { if (deviceId.equals(device.deviceID)) { @@ -326,20 +309,10 @@ public class RestApi { */ IgnoredFolder ignoredFolder = new IgnoredFolder(); ignoredFolder.id = folderId; - Iterator it = device.pendingFolders.iterator(); - while (it.hasNext()) { - PendingFolder pendingFolder = it.next(); - if (folderId.equals(pendingFolder.id)) { - // Move over information stored in the "pendingFolder" entry. - ignoredFolder.label = pendingFolder.label; - ignoredFolder.time = pendingFolder.time; - it.remove(); - break; - } - } + ignoredFolder.label = folderLabel; + ignoredFolder.time = dateString(new Date()); device.ignoredFolders.add(ignoredFolder); if (BuildConfig.DEBUG) { - Log.v(TAG, "device.pendingFolders = " + new Gson().toJson(device.pendingFolders)); Log.v(TAG, "device.ignoredFolders = " + new Gson().toJson(device.ignoredFolders)); } sendConfig(); @@ -744,4 +717,9 @@ public class RestApi { mConfig.options = options; } } + + private String dateString(Date date) { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(date); + } + } diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java index a8c8ef5e..279b7404 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java @@ -90,12 +90,30 @@ public class SyncthingService extends Service { public static final String EXTRA_DEVICE_ID = "com.nutomic.syncthingandroid.service.SyncthingService.EXTRA_DEVICE_ID"; + /** + * Extra used together with ACTION_IGNORE_DEVICE + */ + public static final String EXTRA_DEVICE_NAME = + "com.nutomic.syncthingandroid.service.SyncthingService.EXTRA_DEVICE_NAME"; + + /** + * Extra used together with ACTION_IGNORE_DEVICE + */ + public static final String EXTRA_DEVICE_ADDRESS = + "com.nutomic.syncthingandroid.service.SyncthingService.EXTRA_DEVICE_ADDRESS"; + /** * Extra used together with ACTION_IGNORE_FOLDER */ public static final String EXTRA_FOLDER_ID = "com.nutomic.syncthingandroid.service.SyncthingService.EXTRA_FOLDER_ID"; + /** + * Extra used together with ACTION_IGNORE_FOLDER + */ + public static final String EXTRA_FOLDER_LABEL = + "com.nutomic.syncthingandroid.service.SyncthingService.EXTRA_FOLDER_LABEL"; + public interface OnServiceStateChangeListener { void onServiceStateChange(State currentState); } @@ -251,11 +269,11 @@ public class SyncthingService extends Service { mRunConditionMonitor.updateShouldRunDecision(); } else if (ACTION_IGNORE_DEVICE.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { // mApi is not null due to State.ACTIVE - mApi.ignoreDevice(intent.getStringExtra(EXTRA_DEVICE_ID)); + mApi.ignoreDevice(intent.getStringExtra(EXTRA_DEVICE_ID), intent.getStringExtra(EXTRA_DEVICE_NAME), intent.getStringExtra(EXTRA_DEVICE_ADDRESS)); mNotificationHandler.cancelConsentNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, 0)); } else if (ACTION_IGNORE_FOLDER.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { // mApi is not null due to State.ACTIVE - mApi.ignoreFolder(intent.getStringExtra(EXTRA_DEVICE_ID), intent.getStringExtra(EXTRA_FOLDER_ID)); + mApi.ignoreFolder(intent.getStringExtra(EXTRA_DEVICE_ID), intent.getStringExtra(EXTRA_FOLDER_ID), intent.getStringExtra(EXTRA_FOLDER_LABEL)); mNotificationHandler.cancelConsentNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, 0)); } else if (ACTION_OVERRIDE_CHANGES.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { mApi.overrideChanges(intent.getStringExtra(EXTRA_FOLDER_ID));