mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 11:21:29 +00:00
parent
34faf02e3c
commit
55915d7956
10 changed files with 176 additions and 15 deletions
|
@ -8,8 +8,8 @@ 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<String> ignoredFolders;
|
public List<PendingDevice> pendingDevices;
|
||||||
public List<String> ignoredDevices;
|
public List<RemoteIgnoredDevice> remoteIgnoredDevices;
|
||||||
|
|
||||||
public class Gui {
|
public class Gui {
|
||||||
public boolean enabled;
|
public boolean enabled;
|
||||||
|
|
|
@ -12,6 +12,8 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the device name, or the first characters of the ID if the name is empty.
|
* Returns the device name, or the first characters of the ID if the name is empty.
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.nutomic.syncthingandroid.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To avoid name confusion:
|
||||||
|
* This is the exclude and include items list associated with every folder.
|
||||||
|
*/
|
||||||
|
public class FolderIgnoreList {
|
||||||
|
public String[] expanded;
|
||||||
|
public String[] ignore;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.nutomic.syncthingandroid.model;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
public class IgnoredFolder {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.nutomic.syncthingandroid.model;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
public class RemoteIgnoredDevice {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -275,6 +275,7 @@ 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_FOLDER_ID, folderId);
|
.putExtra(SyncthingService.EXTRA_FOLDER_ID, folderId);
|
||||||
intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER);
|
intentIgnore.setAction(SyncthingService.ACTION_IGNORE_FOLDER);
|
||||||
PendingIntent piIgnore = PendingIntent.getService(mContext, 0,
|
PendingIntent piIgnore = PendingIntent.getService(mContext, 0,
|
||||||
|
|
|
@ -30,7 +30,11 @@ import com.nutomic.syncthingandroid.model.Device;
|
||||||
import com.nutomic.syncthingandroid.model.Event;
|
import com.nutomic.syncthingandroid.model.Event;
|
||||||
import com.nutomic.syncthingandroid.model.Folder;
|
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.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.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 com.nutomic.syncthingandroid.service.Constants;
|
||||||
|
@ -213,6 +217,10 @@ public class RestApi {
|
||||||
throw new RuntimeException("config is null: " + result);
|
throw new RuntimeException("config is null: " + result);
|
||||||
}
|
}
|
||||||
Log.v(TAG, "onReloadConfigComplete: Successfully parsed configuration.");
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
// Update cached device and folder information stored in the mCompletion model.
|
// Update cached device and folder information stored in the mCompletion model.
|
||||||
mCompletion.updateFromConfig(getDevices(true), getFolders());
|
mCompletion.updateFromConfig(getDevices(true), getFolders());
|
||||||
|
@ -259,11 +267,36 @@ public class RestApi {
|
||||||
*/
|
*/
|
||||||
public void ignoreDevice(String deviceId) {
|
public void ignoreDevice(String deviceId) {
|
||||||
synchronized (mConfigLock) {
|
synchronized (mConfigLock) {
|
||||||
if (!mConfig.ignoredDevices.contains(deviceId)) {
|
// Check if the device has already been ignored.
|
||||||
mConfig.ignoredDevices.add(deviceId);
|
for (RemoteIgnoredDevice remoteIgnoredDevice : mConfig.remoteIgnoredDevices) {
|
||||||
sendConfig();
|
if (deviceId.equals(remoteIgnoredDevice.deviceID)) {
|
||||||
Log.d(TAG, "Ignored device [" + deviceId + "]");
|
// Device already ignored.
|
||||||
|
Log.d(TAG, "Device already ignored [" + deviceId + "]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore device by moving its corresponding "pendingDevice" entry to
|
||||||
|
* a newly created "remotePendingDevice" entry.
|
||||||
|
*/
|
||||||
|
RemoteIgnoredDevice remoteIgnoredDevice = new RemoteIgnoredDevice();
|
||||||
|
remoteIgnoredDevice.deviceID = deviceId;
|
||||||
|
Iterator<PendingDevice> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mConfig.remoteIgnoredDevices.add(remoteIgnoredDevice);
|
||||||
|
sendConfig();
|
||||||
|
Log.d(TAG, "Ignored device [" + deviceId + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,12 +305,49 @@ 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 folderId) {
|
public void ignoreFolder(String deviceId, String folderId) {
|
||||||
synchronized (mConfigLock) {
|
synchronized (mConfigLock) {
|
||||||
if (!mConfig.ignoredFolders.contains(folderId)) {
|
for (Device device : mConfig.devices) {
|
||||||
mConfig.ignoredFolders.add(folderId);
|
if (deviceId.equals(device.deviceID)) {
|
||||||
sendConfig();
|
/**
|
||||||
Log.d(TAG, "Ignored folder [" + folderId + "]");
|
* Check if the folder has already been ignored.
|
||||||
|
*/
|
||||||
|
for (IgnoredFolder ignoredFolder : device.ignoredFolders) {
|
||||||
|
if (folderId.equals(ignoredFolder.id)) {
|
||||||
|
// Folder already ignored.
|
||||||
|
Log.d(TAG, "Folder [" + folderId + "] already ignored on device [" + deviceId + "]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore folder by moving its corresponding "pendingFolder" entry to
|
||||||
|
* a newly created "ignoredFolder" entry.
|
||||||
|
*/
|
||||||
|
IgnoredFolder ignoredFolder = new IgnoredFolder();
|
||||||
|
ignoredFolder.id = folderId;
|
||||||
|
Iterator<PendingFolder> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
Log.d(TAG, "Ignored folder [" + folderId + "] announced by device [" + deviceId + "]");
|
||||||
|
|
||||||
|
// Given deviceId handled.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,8 +358,10 @@ public class RestApi {
|
||||||
public void undoIgnoredDevicesAndFolders() {
|
public void undoIgnoredDevicesAndFolders() {
|
||||||
Log.d(TAG, "Undo ignoring devices and folders ...");
|
Log.d(TAG, "Undo ignoring devices and folders ...");
|
||||||
synchronized (mConfigLock) {
|
synchronized (mConfigLock) {
|
||||||
mConfig.ignoredDevices.clear();
|
mConfig.remoteIgnoredDevices.clear();
|
||||||
mConfig.ignoredFolders.clear();
|
for (Device device : mConfig.devices) {
|
||||||
|
device.ignoredFolders.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +485,10 @@ public class RestApi {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Device device = it.next();
|
Device device = it.next();
|
||||||
boolean isLocalDevice = Objects.equal(mLocalDeviceId, device.deviceID);
|
boolean isLocalDevice = Objects.equal(mLocalDeviceId, device.deviceID);
|
||||||
if (!includeLocal && isLocalDevice)
|
if (!includeLocal && isLocalDevice) {
|
||||||
it.remove();
|
it.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ public class SyncthingService extends Service {
|
||||||
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_FOLDER_ID));
|
mApi.ignoreFolder(intent.getStringExtra(EXTRA_DEVICE_ID), intent.getStringExtra(EXTRA_FOLDER_ID));
|
||||||
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));
|
||||||
|
|
Loading…
Reference in a new issue