1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-11-26 14:21:16 +00:00

Adjust to API change regarding pending folders/devices (#1678)

This commit is contained in:
Simon Frei 2021-07-27 12:50:35 +02:00 committed by GitHub
parent 9ba2dd09df
commit 66cf49665c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 93 deletions

View file

@ -8,7 +8,6 @@ public class Config {
public List<Folder> folders; public List<Folder> folders;
public Gui gui; public Gui gui;
public Options options; public Options options;
public List<PendingDevice> pendingDevices;
public List<RemoteIgnoredDevice> remoteIgnoredDevices; public List<RemoteIgnoredDevice> remoteIgnoredDevices;
public class Gui { public class Gui {

View file

@ -12,7 +12,6 @@ public class Device {
public String certName; public String certName;
public boolean introducer; public boolean introducer;
public boolean paused; public boolean paused;
public List<PendingFolder> pendingFolders;
public List<IgnoredFolder> ignoredFolders; public List<IgnoredFolder> ignoredFolders;
/** /**

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -12,6 +12,8 @@ import android.os.Looper;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import androidx.core.util.Consumer;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.nutomic.syncthingandroid.BuildConfig; import com.nutomic.syncthingandroid.BuildConfig;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
@ -24,6 +26,8 @@ import com.nutomic.syncthingandroid.model.Event;
import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.model.Folder;
import java.io.File; import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
@ -101,11 +105,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
mApi.reloadConfig(); mApi.reloadConfig();
} }
break; break;
case "DeviceRejected": case "PendingDevicesChanged":
onDeviceRejected( mapNullable((List<Map<String,String>>) event.data.get("added"), this::onPendingDevicesChanged);
(String) event.data.get("device"), // deviceId
(String) event.data.get("name") // deviceName
);
break; break;
case "FolderCompletion": case "FolderCompletion":
CompletionInfo completionInfo = new CompletionInfo(); CompletionInfo completionInfo = new CompletionInfo();
@ -116,12 +117,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
completionInfo completionInfo
); );
break; break;
case "FolderRejected": case "PendingFoldersChanged":
onFolderRejected( mapNullable((List<Map<String,String>>) event.data.get("added"), this::onPendingFoldersChanged);
(String) event.data.get("device"), // deviceId
(String) event.data.get("folder"), // folderId
(String) event.data.get("folderLabel") // folderLabel
);
break; break;
case "ItemFinished": case "ItemFinished":
String folder = (String) event.data.get("folder"); 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<String, String> added) {
String deviceId = added.get("deviceID");
String deviceName = added.get("name");
String deviceAddress = added.get("address");
if (deviceId == null) { if (deviceId == null) {
return; return;
} }
@ -231,7 +231,9 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
// Prepare "ignore" action. // Prepare "ignore" action.
Intent intentIgnore = new Intent(mContext, SyncthingService.class) Intent intentIgnore = new Intent(mContext, SyncthingService.class)
.putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) .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); intentIgnore.setAction(SyncthingService.ACTION_IGNORE_DEVICE);
PendingIntent piIgnore = PendingIntent.getService(mContext, 0, PendingIntent piIgnore = PendingIntent.getService(mContext, 0,
intentIgnore, PendingIntent.FLAG_UPDATE_CURRENT); intentIgnore, PendingIntent.FLAG_UPDATE_CURRENT);
@ -240,8 +242,10 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore); mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore);
} }
private void onFolderRejected(String deviceId, String folderId, private void onPendingFoldersChanged(Map<String, String> added) {
String folderLabel) { String deviceId = added.get("deviceID");
String folderId = added.get("folderID");
String folderLabel = added.get("folderLabel");
if (deviceId == null || folderId == null) { if (deviceId == null || folderId == null) {
return; return;
} }
@ -276,7 +280,8 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
Intent intentIgnore = new Intent(mContext, SyncthingService.class) Intent intentIgnore = new Intent(mContext, SyncthingService.class)
.putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId) .putExtra(SyncthingService.EXTRA_NOTIFICATION_ID, notificationId)
.putExtra(SyncthingService.EXTRA_DEVICE_ID, deviceId) .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); intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER);
PendingIntent piIgnore = PendingIntent.getService(mContext, 0, PendingIntent piIgnore = PendingIntent.getService(mContext, 0,
intentIgnore, PendingIntent.FLAG_UPDATE_CURRENT); intentIgnore, PendingIntent.FLAG_UPDATE_CURRENT);
@ -284,4 +289,13 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
// Show notification. // Show notification.
mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore); mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore);
} }
private <T> void mapNullable(List<T> l, Consumer<T> c) {
if (l != null) {
for (T m : l) {
c.accept(m);
}
}
}
} }

View file

@ -1,6 +1,5 @@
package com.nutomic.syncthingandroid.service; package com.nutomic.syncthingandroid.service;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.preference.PreferenceManager; 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.FolderStatus;
import com.nutomic.syncthingandroid.model.IgnoredFolder; import com.nutomic.syncthingandroid.model.IgnoredFolder;
import com.nutomic.syncthingandroid.model.Options; 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.RemoteIgnoredDevice;
import com.nutomic.syncthingandroid.model.SystemInfo; import com.nutomic.syncthingandroid.model.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion; import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.service.Constants;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URL; import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject; import javax.inject.Inject;
@ -218,7 +215,6 @@ public class RestApi {
} }
Log.v(TAG, "onReloadConfigComplete: Successfully parsed configuration."); Log.v(TAG, "onReloadConfigComplete: Successfully parsed configuration.");
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Log.v(TAG, "mConfig.pendingDevices = " + new Gson().toJson(mConfig.pendingDevices));
Log.v(TAG, "mConfig.remoteIgnoredDevices = " + new Gson().toJson(mConfig.remoteIgnoredDevices)); 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 * Ignored devices will not trigger the "DeviceRejected" event
* in {@link EventProcessor#onEvent}. * in {@link EventProcessor#onEvent}.
*/ */
public void ignoreDevice(String deviceId) { public void ignoreDevice(String deviceId, String deviceName, String deviceAddress) {
synchronized (mConfigLock) { synchronized (mConfigLock) {
// Check if the device has already been ignored. // Check if the device has already been ignored.
for (RemoteIgnoredDevice remoteIgnoredDevice : mConfig.remoteIgnoredDevices) { 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 remoteIgnoredDevice = new RemoteIgnoredDevice();
remoteIgnoredDevice.deviceID = deviceId; remoteIgnoredDevice.deviceID = deviceId;
Iterator<PendingDevice> it = mConfig.pendingDevices.iterator(); remoteIgnoredDevice.address = deviceAddress;
while (it.hasNext()) { remoteIgnoredDevice.name = deviceName;
PendingDevice pendingDevice = it.next(); remoteIgnoredDevice.time = dateString(new Date());
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;
}
}
mConfig.remoteIgnoredDevices.add(remoteIgnoredDevice); mConfig.remoteIgnoredDevices.add(remoteIgnoredDevice);
sendConfig(); sendConfig();
Log.d(TAG, "Ignored device [" + deviceId + "]"); Log.d(TAG, "Ignored device [" + deviceId + "]");
@ -305,7 +288,7 @@ public class RestApi {
* Ignored folders will not trigger the "FolderRejected" event * Ignored folders will not trigger the "FolderRejected" event
* in {@link EventProcessor#onEvent}. * in {@link EventProcessor#onEvent}.
*/ */
public void ignoreFolder(String deviceId, String folderId) { public void ignoreFolder(String deviceId, String folderId, String folderLabel) {
synchronized (mConfigLock) { synchronized (mConfigLock) {
for (Device device : mConfig.devices) { for (Device device : mConfig.devices) {
if (deviceId.equals(device.deviceID)) { if (deviceId.equals(device.deviceID)) {
@ -326,20 +309,10 @@ public class RestApi {
*/ */
IgnoredFolder ignoredFolder = new IgnoredFolder(); IgnoredFolder ignoredFolder = new IgnoredFolder();
ignoredFolder.id = folderId; ignoredFolder.id = folderId;
Iterator<PendingFolder> it = device.pendingFolders.iterator(); ignoredFolder.label = folderLabel;
while (it.hasNext()) { ignoredFolder.time = dateString(new Date());
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;
}
}
device.ignoredFolders.add(ignoredFolder); device.ignoredFolders.add(ignoredFolder);
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Log.v(TAG, "device.pendingFolders = " + new Gson().toJson(device.pendingFolders));
Log.v(TAG, "device.ignoredFolders = " + new Gson().toJson(device.ignoredFolders)); Log.v(TAG, "device.ignoredFolders = " + new Gson().toJson(device.ignoredFolders));
} }
sendConfig(); sendConfig();
@ -744,4 +717,9 @@ public class RestApi {
mConfig.options = options; mConfig.options = options;
} }
} }
private String dateString(Date date) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(date);
}
} }

View file

@ -90,12 +90,30 @@ public class SyncthingService extends Service {
public static final String EXTRA_DEVICE_ID = public static final String EXTRA_DEVICE_ID =
"com.nutomic.syncthingandroid.service.SyncthingService.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 * Extra used together with ACTION_IGNORE_FOLDER
*/ */
public static final String EXTRA_FOLDER_ID = public static final String EXTRA_FOLDER_ID =
"com.nutomic.syncthingandroid.service.SyncthingService.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 { public interface OnServiceStateChangeListener {
void onServiceStateChange(State currentState); void onServiceStateChange(State currentState);
} }
@ -251,11 +269,11 @@ public class SyncthingService extends Service {
mRunConditionMonitor.updateShouldRunDecision(); mRunConditionMonitor.updateShouldRunDecision();
} else if (ACTION_IGNORE_DEVICE.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { } else if (ACTION_IGNORE_DEVICE.equals(intent.getAction()) && mCurrentState == State.ACTIVE) {
// mApi is not null due to 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)); mNotificationHandler.cancelConsentNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, 0));
} else if (ACTION_IGNORE_FOLDER.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { } else if (ACTION_IGNORE_FOLDER.equals(intent.getAction()) && mCurrentState == State.ACTIVE) {
// mApi is not null due to 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)); mNotificationHandler.cancelConsentNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, 0));
} else if (ACTION_OVERRIDE_CHANGES.equals(intent.getAction()) && mCurrentState == State.ACTIVE) { } else if (ACTION_OVERRIDE_CHANGES.equals(intent.getAction()) && mCurrentState == State.ACTIVE) {
mApi.overrideChanges(intent.getStringExtra(EXTRA_FOLDER_ID)); mApi.overrideChanges(intent.getStringExtra(EXTRA_FOLDER_ID));