Add removable drive manager with placeholder task implementations.

This commit is contained in:
akwizgran
2021-05-07 12:15:51 +01:00
committed by Torsten Grote
parent 2dd5239b9d
commit 71ce74c633
18 changed files with 357 additions and 9 deletions

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface Consumer<T> {
void accept(T t);
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.bramble.api.plugin;
package org.briarproject.bramble.api.plugin.file;
public interface FileConstants {

View File

@@ -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 {

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<ContactId, RemovableDriveTask>
readers = new ConcurrentHashMap<>();
private final ConcurrentHashMap<ContactId, RemovableDriveTask>
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);
}
}

View File

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

View File

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

View File

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

View File

@@ -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<Observer> 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<Observer> visitor) {
eventExecutor.execute(() -> {
for (Observer o : observers) visitor.accept(o);
});
}
}

View File

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

View File

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

View File

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

View File

@@ -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,