WIP: further refactor on old jobs
parent
2ceb9e2bf4
commit
b494088c3d
@ -1,12 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
public interface ConstraintObserver {
|
|
||||||
|
|
||||||
void register(@NonNull Notifier notifier);
|
|
||||||
|
|
||||||
interface Notifier {
|
|
||||||
void onConstraintMet(@NonNull String reason);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.session.libsession.messaging.jobs.Job;
|
|
||||||
import org.session.libsession.messaging.utilities.Data;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class JobInstantiator {
|
|
||||||
|
|
||||||
private final Map<String, Job.Factory> jobFactories;
|
|
||||||
|
|
||||||
JobInstantiator(@NonNull Map<String, Job.Factory> jobFactories) {
|
|
||||||
this.jobFactories = new HashMap<>(jobFactories);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NonNull Job instantiate(@NonNull String jobFactoryKey, @NonNull Data data) {
|
|
||||||
if (jobFactories.containsKey(jobFactoryKey)) {
|
|
||||||
return jobFactories.get(jobFactoryKey).create(data);
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("Tried to instantiate a job with key '" + jobFactoryKey + "', but no matching factory was found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.session.libsignal.utilities.Log;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the scheduling of durable jobs that will be run as early as possible.
|
|
||||||
*/
|
|
||||||
public class JobManager implements ConstraintObserver.Notifier {
|
|
||||||
|
|
||||||
private static final String TAG = JobManager.class.getSimpleName();
|
|
||||||
|
|
||||||
private final ExecutorService executor;
|
|
||||||
|
|
||||||
private final Set<EmptyQueueListener> emptyQueueListeners = new CopyOnWriteArraySet<>();
|
|
||||||
|
|
||||||
public JobManager(@NonNull Application application, @NonNull Configuration configuration) {
|
|
||||||
this.executor = configuration.getExecutorFactory().newSingleThreadExecutor("JobManager");
|
|
||||||
|
|
||||||
executor.execute(() -> {
|
|
||||||
for (ConstraintObserver constraintObserver : configuration.getConstraintObservers()) {
|
|
||||||
constraintObserver.register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < 26) {
|
|
||||||
application.startService(new Intent(application, KeepAliveService.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
wakeUp();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a listener to that will be notified when the job queue has been drained.
|
|
||||||
*/
|
|
||||||
void addOnEmptyQueueListener(@NonNull EmptyQueueListener listener) {
|
|
||||||
executor.execute(() -> {
|
|
||||||
emptyQueueListeners.add(listener);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a listener that was added via {@link #addOnEmptyQueueListener(EmptyQueueListener)}.
|
|
||||||
*/
|
|
||||||
void removeOnEmptyQueueListener(@NonNull EmptyQueueListener listener) {
|
|
||||||
executor.execute(() -> {
|
|
||||||
emptyQueueListeners.remove(listener);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConstraintMet(@NonNull String reason) {
|
|
||||||
Log.i(TAG, "onConstraintMet(" + reason + ")");
|
|
||||||
wakeUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pokes the system to take another pass at the job queue.
|
|
||||||
*/
|
|
||||||
void wakeUp() {}
|
|
||||||
|
|
||||||
public interface EmptyQueueListener {
|
|
||||||
void onQueueEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Configuration {
|
|
||||||
|
|
||||||
private final ExecutorFactory executorFactory;
|
|
||||||
private final List<ConstraintObserver> constraintObservers;
|
|
||||||
|
|
||||||
private Configuration(@NonNull ExecutorFactory executorFactory,
|
|
||||||
@NonNull List<ConstraintObserver> constraintObservers)
|
|
||||||
{
|
|
||||||
this.executorFactory = executorFactory;
|
|
||||||
this.constraintObservers = constraintObservers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull ExecutorFactory getExecutorFactory() {
|
|
||||||
return executorFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull List<ConstraintObserver> getConstraintObservers() {
|
|
||||||
return constraintObservers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
|
|
||||||
private ExecutorFactory executorFactory = new DefaultExecutorFactory();
|
|
||||||
private List<ConstraintObserver> constraintObservers = new ArrayList<>();
|
|
||||||
|
|
||||||
public @NonNull Builder setConstraintObservers(@NonNull List<ConstraintObserver> constraintObservers) {
|
|
||||||
this.constraintObservers = constraintObservers;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NonNull Configuration build() {
|
|
||||||
return new Configuration(executorFactory,
|
|
||||||
new ArrayList<>(constraintObservers));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.app.job.JobInfo;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
|
||||||
import org.thoughtcrime.securesms.sms.TelephonyServiceState;
|
|
||||||
|
|
||||||
public class CellServiceConstraint implements Constraint {
|
|
||||||
|
|
||||||
public static final String KEY = "CellServiceConstraint";
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
public CellServiceConstraint(@NonNull Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull String getFactoryKey() {
|
|
||||||
return KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isMet() {
|
|
||||||
TelephonyServiceState telephonyServiceState = new TelephonyServiceState();
|
|
||||||
return telephonyServiceState.isConnected(application);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Factory implements Constraint.Factory<CellServiceConstraint> {
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
public Factory(@NonNull Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CellServiceConstraint create() {
|
|
||||||
return new CellServiceConstraint(application);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Context;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.telephony.PhoneStateListener;
|
|
||||||
import android.telephony.ServiceState;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
|
||||||
|
|
||||||
public class CellServiceConstraintObserver implements ConstraintObserver {
|
|
||||||
|
|
||||||
private static final String REASON = CellServiceConstraintObserver.class.getSimpleName();
|
|
||||||
|
|
||||||
private Notifier notifier;
|
|
||||||
|
|
||||||
public CellServiceConstraintObserver(@NonNull Application application) {
|
|
||||||
TelephonyManager telephonyManager = (TelephonyManager) application.getSystemService(Context.TELEPHONY_SERVICE);
|
|
||||||
ServiceStateListener serviceStateListener = new ServiceStateListener();
|
|
||||||
|
|
||||||
telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(@NonNull Notifier notifier) {
|
|
||||||
this.notifier = notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ServiceStateListener extends PhoneStateListener {
|
|
||||||
@Override
|
|
||||||
public void onServiceStateChanged(ServiceState serviceState) {
|
|
||||||
if (serviceState.getState() == ServiceState.STATE_IN_SERVICE && notifier != null) {
|
|
||||||
notifier.onConstraintMet(REASON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
|
||||||
|
|
||||||
public class NetworkConstraintObserver implements ConstraintObserver {
|
|
||||||
|
|
||||||
private static final String REASON = NetworkConstraintObserver.class.getSimpleName();
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
public NetworkConstraintObserver(Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(@NonNull Notifier notifier) {
|
|
||||||
application.registerReceiver(new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
NetworkConstraint constraint = new NetworkConstraint.Factory(application).create();
|
|
||||||
|
|
||||||
if (constraint.isMet()) {
|
|
||||||
notifier.onConstraintMet(REASON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.app.job.JobInfo;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
|
||||||
|
|
||||||
public class NetworkOrCellServiceConstraint implements Constraint {
|
|
||||||
|
|
||||||
public static final String KEY = "NetworkOrCellServiceConstraint";
|
|
||||||
|
|
||||||
private final NetworkConstraint networkConstraint;
|
|
||||||
private final CellServiceConstraint serviceConstraint;
|
|
||||||
|
|
||||||
public NetworkOrCellServiceConstraint(@NonNull Application application) {
|
|
||||||
networkConstraint = new NetworkConstraint.Factory(application).create();
|
|
||||||
serviceConstraint = new CellServiceConstraint.Factory(application).create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull String getFactoryKey() {
|
|
||||||
return KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isMet() {
|
|
||||||
return networkConstraint.isMet() || serviceConstraint.isMet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Factory implements Constraint.Factory<NetworkOrCellServiceConstraint> {
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
public Factory(@NonNull Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NetworkOrCellServiceConstraint create() {
|
|
||||||
return new NetworkOrCellServiceConstraint(application);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.app.job.JobInfo;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
|
||||||
|
|
||||||
public class SqlCipherMigrationConstraint implements Constraint {
|
|
||||||
|
|
||||||
public static final String KEY = "SqlCipherMigrationConstraint";
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
private SqlCipherMigrationConstraint(@NonNull Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isMet() {
|
|
||||||
return !TextSecurePreferences.getNeedsSqlCipherMigration(application);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String getFactoryKey() {
|
|
||||||
return KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Factory implements Constraint.Factory<SqlCipherMigrationConstraint> {
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
|
|
||||||
public Factory(@NonNull Application application) {
|
|
||||||
this.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlCipherMigrationConstraint create() {
|
|
||||||
return new SqlCipherMigrationConstraint(application);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobmanager.impl;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
|
||||||
|
|
||||||
public class SqlCipherMigrationConstraintObserver implements ConstraintObserver {
|
|
||||||
|
|
||||||
private static final String REASON = SqlCipherMigrationConstraintObserver.class.getSimpleName();
|
|
||||||
|
|
||||||
private Notifier notifier;
|
|
||||||
|
|
||||||
public SqlCipherMigrationConstraintObserver() {
|
|
||||||
EventBus.getDefault().register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(@NonNull Notifier notifier) {
|
|
||||||
this.notifier = notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
||||||
public void onEvent(SqlCipherNeedsMigrationEvent event) {
|
|
||||||
if (notifier != null) notifier.onConstraintMet(REASON);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SqlCipherNeedsMigrationEvent {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.jobs;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.session.libsession.messaging.jobs.Job;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.Constraint;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
|
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class JobManagerFactories {
|
|
||||||
|
|
||||||
private static Collection<String> factoryKeys = new ArrayList<>();
|
|
||||||
|
|
||||||
public static Map<String, Job.Factory> getJobFactories() {
|
|
||||||
HashMap<String, Job.Factory> factoryHashMap = new HashMap<String, Job.Factory>() {{
|
|
||||||
put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory());
|
|
||||||
put(RetrieveProfileAvatarJob.Companion.getKEY(), new RetrieveProfileAvatarJob.Factory());
|
|
||||||
put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory());
|
|
||||||
}};
|
|
||||||
factoryKeys.addAll(factoryHashMap.keySet());
|
|
||||||
return factoryHashMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, Constraint.Factory> getConstraintFactories(@NonNull Application application) {
|
|
||||||
return new HashMap<String, Constraint.Factory>() {{
|
|
||||||
put(CellServiceConstraint.KEY, new CellServiceConstraint.Factory(application));
|
|
||||||
put(NetworkConstraint.KEY, new NetworkConstraint.Factory(application));
|
|
||||||
put(NetworkOrCellServiceConstraint.KEY, new NetworkOrCellServiceConstraint.Factory(application));
|
|
||||||
put(SqlCipherMigrationConstraint.KEY, new SqlCipherMigrationConstraint.Factory(application));
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ConstraintObserver> getConstraintObservers(@NonNull Application application) {
|
|
||||||
return Arrays.asList(new CellServiceConstraintObserver(application),
|
|
||||||
new NetworkConstraintObserver(application),
|
|
||||||
new SqlCipherMigrationConstraintObserver());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasFactoryForKey(String factoryKey) {
|
|
||||||
return factoryKeys.contains(factoryKey);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue