From 71ce74c633518b69cdcbd825385ab98cfa2cbf80 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 7 May 2021 12:15:51 +0100 Subject: [PATCH] Add removable drive manager with placeholder task implementations. --- .../file/AndroidRemovableDrivePlugin.java | 2 +- .../AndroidRemovableDrivePluginFactory.java | 2 +- .../briarproject/bramble/api/Consumer.java | 9 ++ .../api/plugin/{ => file}/FileConstants.java | 2 +- .../{ => file}/RemovableDriveConstants.java | 4 +- .../plugin/file/RemovableDriveManager.java | 40 +++++++++ .../api/plugin/file/RemovableDriveTask.java | 34 ++++++++ .../file/AbstractRemovableDrivePlugin.java | 2 +- .../bramble/plugin/file/FilePlugin.java | 2 +- .../file/RemovableDriveManagerImpl.java | 83 +++++++++++++++++++ .../plugin/file/RemovableDriveModule.java | 19 +++++ .../plugin/file/RemovableDrivePlugin.java | 2 +- .../file/RemovableDrivePluginFactory.java | 2 +- .../plugin/file/RemovableDriveTaskImpl.java | 54 ++++++++++++ .../file/RemovableDriveTaskRegistry.java | 13 +++ .../file/RemovableDriverReaderTask.java | 46 ++++++++++ .../file/RemovableDriverWriterTask.java | 46 ++++++++++ .../briar/android/AndroidComponent.java | 4 +- 18 files changed, 357 insertions(+), 9 deletions(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/Consumer.java rename bramble-api/src/main/java/org/briarproject/bramble/api/plugin/{ => file}/FileConstants.java (56%) rename bramble-api/src/main/java/org/briarproject/bramble/api/plugin/{ => file}/RemovableDriveConstants.java (61%) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveTask.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveModule.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskImpl.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskRegistry.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverReaderTask.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverWriterTask.java diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePlugin.java index bee061db1..05e569f7c 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePlugin.java @@ -12,7 +12,7 @@ import java.io.OutputStream; import javax.annotation.concurrent.Immutable; -import static org.briarproject.bramble.api.plugin.RemovableDriveConstants.PROP_URI; +import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.PROP_URI; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @Immutable diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePluginFactory.java index 68d32d924..64f6cf534 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/file/AndroidRemovableDrivePluginFactory.java @@ -13,7 +13,7 @@ import javax.annotation.concurrent.Immutable; import javax.inject.Inject; import static java.util.concurrent.TimeUnit.DAYS; -import static org.briarproject.bramble.api.plugin.RemovableDriveConstants.ID; +import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.ID; @Immutable @NotNullByDefault diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/Consumer.java b/bramble-api/src/main/java/org/briarproject/bramble/api/Consumer.java new file mode 100644 index 000000000..4e025a728 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/Consumer.java @@ -0,0 +1,9 @@ +package org.briarproject.bramble.api; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault +public interface Consumer { + + void accept(T t); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/FileConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/FileConstants.java similarity index 56% rename from bramble-api/src/main/java/org/briarproject/bramble/api/plugin/FileConstants.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/FileConstants.java index bed296874..1564f415d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/FileConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/FileConstants.java @@ -1,4 +1,4 @@ -package org.briarproject.bramble.api.plugin; +package org.briarproject.bramble.api.plugin.file; public interface FileConstants { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/RemovableDriveConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveConstants.java similarity index 61% rename from bramble-api/src/main/java/org/briarproject/bramble/api/plugin/RemovableDriveConstants.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveConstants.java index 98caf96c3..927e197df 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/RemovableDriveConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveConstants.java @@ -1,4 +1,6 @@ -package org.briarproject.bramble.api.plugin; +package org.briarproject.bramble.api.plugin.file; + +import org.briarproject.bramble.api.plugin.TransportId; public interface RemovableDriveConstants { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java new file mode 100644 index 000000000..241582dab --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveManager.java @@ -0,0 +1,40 @@ +package org.briarproject.bramble.api.plugin.file; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.io.File; + +import javax.annotation.Nullable; + +@NotNullByDefault +public interface RemovableDriveManager { + + /** + * Returns the currently running reader task for the given contact, + * or null if no task is running. + */ + @Nullable + RemovableDriveTask getCurrentReaderTask(ContactId c); + + /** + * Returns the currently running writer task for the given contact, + * or null if no task is running. + */ + @Nullable + RemovableDriveTask getCurrentWriterTask(ContactId c); + + /** + * Starts and returns a reader task for the given contact, reading from + * the given file. If a reader task for the contact is already running, + * it will be returned and the file argument will be ignored. + */ + RemovableDriveTask startReaderTask(ContactId c, File f); + + /** + * Starts and returns a writer task for the given contact, writing to + * the given file. If a writer task for the contact is already running, + * it will be returned and the file argument will be ignored. + */ + RemovableDriveTask startWriterTask(ContactId c, File f); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveTask.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveTask.java new file mode 100644 index 000000000..08165c267 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/file/RemovableDriveTask.java @@ -0,0 +1,34 @@ +package org.briarproject.bramble.api.plugin.file; + +import org.briarproject.bramble.api.event.EventExecutor; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.io.File; + +@NotNullByDefault +public interface RemovableDriveTask { + + /** + * Returns the file that this task is reading from or writing to. + */ + File getFile(); + + /** + * Adds an observer to the task. + */ + void addObserver(Observer o); + + /** + * Removes an observer from the task. + */ + void removeObserver(Observer o); + + interface Observer { + + @EventExecutor + void onProgress(long written, long total); + + @EventExecutor + void onCompletion(boolean success); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/AbstractRemovableDrivePlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/AbstractRemovableDrivePlugin.java index 3fdc9c908..356186355 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/AbstractRemovableDrivePlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/AbstractRemovableDrivePlugin.java @@ -20,7 +20,7 @@ import javax.annotation.concurrent.Immutable; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; -import static org.briarproject.bramble.api.plugin.RemovableDriveConstants.ID; +import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.ID; import static org.briarproject.bramble.util.LogUtils.logException; @Immutable diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java index 8a2673a7a..34ca014f2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java @@ -15,8 +15,8 @@ import java.util.logging.Logger; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; -import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; +import static org.briarproject.bramble.api.plugin.file.FileConstants.PROP_PATH; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java new file mode 100644 index 000000000..4b6d9dffc --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveManagerImpl.java @@ -0,0 +1,83 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.event.EventExecutor; +import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.file.RemovableDriveManager; +import org.briarproject.bramble.api.plugin.file.RemovableDriveTask; + +import java.io.File; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; +import javax.inject.Inject; + +@ThreadSafe +@NotNullByDefault +class RemovableDriveManagerImpl + implements RemovableDriveManager, RemovableDriveTaskRegistry { + + private final Executor ioExecutor, eventExecutor; + private final ConcurrentHashMap + readers = new ConcurrentHashMap<>(); + private final ConcurrentHashMap + writers = new ConcurrentHashMap<>(); + + @Inject + RemovableDriveManagerImpl(@IoExecutor Executor ioExecutor, + @EventExecutor Executor eventExecutor) { + this.ioExecutor = ioExecutor; + this.eventExecutor = eventExecutor; + } + + @Nullable + @Override + public RemovableDriveTask getCurrentReaderTask(ContactId c) { + return readers.get(c); + } + + @Nullable + @Override + public RemovableDriveTask getCurrentWriterTask(ContactId c) { + return writers.get(c); + } + + @Override + public RemovableDriveTask startReaderTask(ContactId c, File f) { + RemovableDriverReaderTask task = + new RemovableDriverReaderTask(eventExecutor, this, c, f); + RemovableDriveTask old = readers.putIfAbsent(c, task); + if (old == null) { + ioExecutor.execute(task); + return task; + } else { + return old; + } + } + + @Override + public RemovableDriveTask startWriterTask(ContactId c, File f) { + RemovableDriverWriterTask task = + new RemovableDriverWriterTask(eventExecutor, this, c, f); + RemovableDriveTask old = writers.putIfAbsent(c, task); + if (old == null) { + ioExecutor.execute(task); + return task; + } else { + return old; + } + } + + @Override + public void removeReader(ContactId c, RemovableDriveTask task) { + readers.remove(c, task); + } + + @Override + public void removeWriter(ContactId c, RemovableDriveTask task) { + writers.remove(c, task); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveModule.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveModule.java new file mode 100644 index 000000000..92455bb3a --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveModule.java @@ -0,0 +1,19 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.plugin.file.RemovableDriveManager; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class RemovableDriveModule { + + @Provides + @Singleton + RemovableDriveManager provideRemovableDriveManager( + RemovableDriveManagerImpl removableDriveManager) { + return removableDriveManager; + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePlugin.java index 9904ff834..cb6653134 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePlugin.java @@ -11,7 +11,7 @@ import java.io.OutputStream; import javax.annotation.concurrent.Immutable; -import static org.briarproject.bramble.api.plugin.RemovableDriveConstants.PROP_PATH; +import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.PROP_PATH; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @Immutable diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java index e43a89d93..6f1ad7564 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDrivePluginFactory.java @@ -11,7 +11,7 @@ import javax.annotation.concurrent.Immutable; import javax.inject.Inject; import static java.util.concurrent.TimeUnit.DAYS; -import static org.briarproject.bramble.api.plugin.RemovableDriveConstants.ID; +import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.ID; @Immutable @NotNullByDefault diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskImpl.java new file mode 100644 index 000000000..0af720b77 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskImpl.java @@ -0,0 +1,54 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.Consumer; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.file.RemovableDriveTask; + +import java.io.File; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +@NotNullByDefault +abstract class RemovableDriveTaskImpl implements RemovableDriveTask, Runnable { + + private final Executor eventExecutor; + final RemovableDriveTaskRegistry registry; + final ContactId contactId; + final File file; + private final List observers = new CopyOnWriteArrayList<>(); + + RemovableDriveTaskImpl(Executor eventExecutor, + RemovableDriveTaskRegistry registry, ContactId contactId, + File file) { + this.contactId = contactId; + this.file = file; + this.registry = registry; + this.eventExecutor = eventExecutor; + } + + @Override + public File getFile() { + return file; + } + + @Override + public void addObserver(Observer o) { + observers.add(o); + } + + @Override + public void removeObserver(Observer o) { + observers.remove(o); + } + + void visitObservers(Consumer visitor) { + eventExecutor.execute(() -> { + for (Observer o : observers) visitor.accept(o); + }); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskRegistry.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskRegistry.java new file mode 100644 index 000000000..84ee40092 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriveTaskRegistry.java @@ -0,0 +1,13 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.file.RemovableDriveTask; + +@NotNullByDefault +interface RemovableDriveTaskRegistry { + + void removeReader(ContactId c, RemovableDriveTask task); + + void removeWriter(ContactId c, RemovableDriveTask task); +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverReaderTask.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverReaderTask.java new file mode 100644 index 000000000..3cc53c7b4 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverReaderTask.java @@ -0,0 +1,46 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.IoUtils.tryToClose; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class RemovableDriverReaderTask extends RemovableDriveTaskImpl { + + private final static Logger LOG = + getLogger(RemovableDriverReaderTask.class.getName()); + + RemovableDriverReaderTask(Executor eventExecutor, + RemovableDriveTaskRegistry registry, ContactId contactId, + File file) { + super(eventExecutor, registry, contactId, file); + } + + @Override + public void run() { + // TODO + InputStream in = null; + try { + visitObservers(o -> o.onProgress(0, 100)); + in = new FileInputStream(file); + visitObservers(o -> o.onCompletion(true)); + } catch (IOException e) { + logException(LOG, WARNING, e); + visitObservers(o -> o.onCompletion(false)); + } finally { + tryToClose(in, LOG, WARNING); + registry.removeReader(contactId, this); + } + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverWriterTask.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverWriterTask.java new file mode 100644 index 000000000..ed0715d16 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/RemovableDriverWriterTask.java @@ -0,0 +1,46 @@ +package org.briarproject.bramble.plugin.file; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.IoUtils.tryToClose; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class RemovableDriverWriterTask extends RemovableDriveTaskImpl { + + private static final Logger LOG = + getLogger(RemovableDriverWriterTask.class.getName()); + + RemovableDriverWriterTask(Executor eventExecutor, + RemovableDriveTaskRegistry registry, ContactId contactId, + File file) { + super(eventExecutor, registry, contactId, file); + } + + @Override + public void run() { + // TODO + OutputStream out = null; + try { + visitObservers(o -> o.onProgress(0, 100)); + out = new FileOutputStream(file); + visitObservers(o -> o.onCompletion(true)); + } catch (IOException e) { + logException(LOG, WARNING, e); + visitObservers(o -> o.onCompletion(false)); + } finally { + tryToClose(out, LOG, WARNING); + registry.removeWriter(contactId, this); + } + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index aeed5817f..f2b3d6197 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -28,6 +28,7 @@ import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidWakeLockManager; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.plugin.file.RemovableDriveModule; import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.system.ClockModule; import org.briarproject.briar.BriarCoreEagerSingletons; @@ -83,7 +84,8 @@ import dagger.Component; AppModule.class, AttachmentModule.class, ClockModule.class, - MediaModule.class + MediaModule.class, + RemovableDriveModule.class }) public interface AndroidComponent extends BrambleCoreEagerSingletons, BrambleAndroidEagerSingletons,