Move responsibility for Context injection out of JavaSerializer.

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2014-11-16 16:15:12 -08:00
parent 3cd7c2d8e5
commit 35821d444e
6 changed files with 52 additions and 54 deletions

View File

@ -122,7 +122,7 @@ public class JobManagerTest extends AndroidTestCase {
PersistentTestJob testJob = new PersistentTestJob(requirement); PersistentTestJob testJob = new PersistentTestJob(requirement);
JobManager jobManager = JobManager.newBuilder(getContext()) JobManager jobManager = JobManager.newBuilder(getContext())
.withName("persistent-requirement-test3") .withName("persistent-requirement-test3")
.withJobSerializer(new JavaJobSerializer(getContext())) .withJobSerializer(new JavaJobSerializer())
.withConsumerThreads(1) .withConsumerThreads(1)
.build(); .build();
@ -138,7 +138,7 @@ public class JobManagerTest extends AndroidTestCase {
jobManager = JobManager.newBuilder(getContext()) jobManager = JobManager.newBuilder(getContext())
.withName("persistent-requirement-test3") .withName("persistent-requirement-test3")
.withJobSerializer(new JavaJobSerializer(getContext())) .withJobSerializer(new JavaJobSerializer())
.withConsumerThreads(1) .withConsumerThreads(1)
.build(); .build();
@ -151,7 +151,7 @@ public class JobManagerTest extends AndroidTestCase {
PersistentTestJob testJob = new PersistentTestJob(requirement, keys); PersistentTestJob testJob = new PersistentTestJob(requirement, keys);
JobManager jobManager = JobManager.newBuilder(getContext()) JobManager jobManager = JobManager.newBuilder(getContext())
.withName("persistent-requirement-test4") .withName("persistent-requirement-test4")
.withJobSerializer(new JavaJobSerializer(getContext())) .withJobSerializer(new JavaJobSerializer())
.withConsumerThreads(1) .withConsumerThreads(1)
.build(); .build();
@ -168,7 +168,7 @@ public class JobManagerTest extends AndroidTestCase {
PersistentRequirement.getInstance().setPresent(true); PersistentRequirement.getInstance().setPresent(true);
jobManager = JobManager.newBuilder(getContext()) jobManager = JobManager.newBuilder(getContext())
.withName("persistent-requirement-test4") .withName("persistent-requirement-test4")
.withJobSerializer(new JavaJobSerializer(getContext())) .withJobSerializer(new JavaJobSerializer())
.withConsumerThreads(1) .withConsumerThreads(1)
.build(); .build();

View File

@ -1,23 +1,27 @@
/** /**
* Copyright (C) 2014 Open Whisper Systems * Copyright (C) 2014 Open Whisper Systems
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.whispersystems.jobqueue.dependencies; package org.whispersystems.jobqueue.dependencies;
import android.content.Context; import android.content.Context;
/**
* Any Job or Requirement that depends on {@link android.content.Context} can implement this
* interface to receive a Context after being deserialized.
*/
public interface ContextDependent { public interface ContextDependent {
public void setContext(Context context); public void setContext(Context context);
} }

View File

@ -16,13 +16,10 @@
*/ */
package org.whispersystems.jobqueue.persistence; package org.whispersystems.jobqueue.persistence;
import android.content.Context;
import android.util.Base64; import android.util.Base64;
import org.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.EncryptionKeys;
import org.whispersystems.jobqueue.Job; import org.whispersystems.jobqueue.Job;
import org.whispersystems.jobqueue.dependencies.ContextDependent;
import org.whispersystems.jobqueue.requirements.Requirement;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -36,11 +33,7 @@ import java.io.ObjectOutputStream;
*/ */
public class JavaJobSerializer implements JobSerializer { public class JavaJobSerializer implements JobSerializer {
private final Context context; public JavaJobSerializer() {}
public JavaJobSerializer(Context context) {
this.context = context;
}
@Override @Override
public String serialize(Job job) throws IOException { public String serialize(Job job) throws IOException {
@ -57,21 +50,7 @@ public class JavaJobSerializer implements JobSerializer {
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(serialized, Base64.NO_WRAP)); ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(serialized, Base64.NO_WRAP));
ObjectInputStream ois = new ObjectInputStream(bais); ObjectInputStream ois = new ObjectInputStream(bais);
Job job = (Job)ois.readObject(); return (Job)ois.readObject();
if (job instanceof ContextDependent) {
((ContextDependent)job).setContext(context);
}
for (Requirement requirement : job.getRequirements()) {
if (requirement instanceof ContextDependent) {
((ContextDependent)requirement).setContext(context);
}
}
job.setEncryptionKeys(keys);
return job;
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException(e); throw new IOException(e);
} }

View File

@ -25,7 +25,9 @@ import android.util.Log;
import org.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.EncryptionKeys;
import org.whispersystems.jobqueue.Job; import org.whispersystems.jobqueue.Job;
import org.whispersystems.jobqueue.dependencies.ContextDependent;
import org.whispersystems.jobqueue.dependencies.DependencyInjector; import org.whispersystems.jobqueue.dependencies.DependencyInjector;
import org.whispersystems.jobqueue.requirements.Requirement;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedList; import java.util.LinkedList;
@ -43,6 +45,7 @@ public class PersistentStorage {
private static final String DATABASE_CREATE = String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s TEXT NOT NULL, %s INTEGER DEFAULT 0);", private static final String DATABASE_CREATE = String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s TEXT NOT NULL, %s INTEGER DEFAULT 0);",
TABLE_NAME, ID, ITEM, ENCRYPTED); TABLE_NAME, ID, ITEM, ENCRYPTED);
private final Context context;
private final DatabaseHelper databaseHelper; private final DatabaseHelper databaseHelper;
private final JobSerializer jobSerializer; private final JobSerializer jobSerializer;
private final DependencyInjector dependencyInjector; private final DependencyInjector dependencyInjector;
@ -52,6 +55,7 @@ public class PersistentStorage {
DependencyInjector dependencyInjector) DependencyInjector dependencyInjector)
{ {
this.databaseHelper = new DatabaseHelper(context, "_jobqueue-" + name); this.databaseHelper = new DatabaseHelper(context, "_jobqueue-" + name);
this.context = context;
this.jobSerializer = serializer; this.jobSerializer = serializer;
this.dependencyInjector = dependencyInjector; this.dependencyInjector = dependencyInjector;
} }
@ -90,10 +94,8 @@ public class PersistentStorage {
Job job = jobSerializer.deserialize(keys, encrypted, item); Job job = jobSerializer.deserialize(keys, encrypted, item);
job.setPersistentId(id); job.setPersistentId(id);
job.setEncryptionKeys(keys);
if (dependencyInjector != null) { injectDependencies(job);
dependencyInjector.injectDependencies(job);
}
results.add(job); results.add(job);
} catch (IOException e) { } catch (IOException e) {
@ -109,12 +111,27 @@ public class PersistentStorage {
return results; return results;
} }
public void remove(long id) { public void remove(long id) {
databaseHelper.getWritableDatabase() databaseHelper.getWritableDatabase()
.delete(TABLE_NAME, ID + " = ?", new String[] {String.valueOf(id)}); .delete(TABLE_NAME, ID + " = ?", new String[] {String.valueOf(id)});
} }
private void injectDependencies(Job job) {
if (job instanceof ContextDependent) {
((ContextDependent)job).setContext(context);
}
for (Requirement requirement : job.getRequirements()) {
if (requirement instanceof ContextDependent) {
((ContextDependent)requirement).setContext(context);
}
}
if (dependencyInjector != null) {
dependencyInjector.injectDependencies(job);
}
}
private static class DatabaseHelper extends SQLiteOpenHelper { private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name) { public DatabaseHelper(Context context, String name) {

View File

@ -79,7 +79,7 @@ public class ApplicationContext extends Application implements DependencyInjecto
this.jobManager = JobManager.newBuilder(this) this.jobManager = JobManager.newBuilder(this)
.withName("TextSecureJobs") .withName("TextSecureJobs")
.withDependencyInjector(this) .withDependencyInjector(this)
.withJobSerializer(new EncryptingJobSerializer(this)) .withJobSerializer(new EncryptingJobSerializer())
.withRequirementProviders(new MasterSecretRequirementProvider(this), .withRequirementProviders(new MasterSecretRequirementProvider(this),
new ServiceRequirementProvider(this), new ServiceRequirementProvider(this),
new NetworkRequirementProvider(this)) new NetworkRequirementProvider(this))

View File

@ -1,15 +1,13 @@
package org.thoughtcrime.securesms.jobs.persistence; package org.thoughtcrime.securesms.jobs.persistence;
import android.content.Context; import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.ParcelUtil; import org.thoughtcrime.securesms.util.ParcelUtil;
import org.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.EncryptionKeys;
import org.whispersystems.jobqueue.Job; import org.whispersystems.jobqueue.Job;
import org.whispersystems.jobqueue.persistence.JavaJobSerializer; import org.whispersystems.jobqueue.persistence.JavaJobSerializer;
import org.whispersystems.jobqueue.persistence.JobSerializer; import org.whispersystems.jobqueue.persistence.JobSerializer;
import org.whispersystems.libaxolotl.InvalidMessageException; import org.whispersystems.libaxolotl.InvalidMessageException;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import java.io.IOException; import java.io.IOException;
@ -17,8 +15,8 @@ public class EncryptingJobSerializer implements JobSerializer {
private final JavaJobSerializer delegate; private final JavaJobSerializer delegate;
public EncryptingJobSerializer(Context context) { public EncryptingJobSerializer() {
this.delegate = new JavaJobSerializer(context); this.delegate = new JavaJobSerializer();
} }
@Override @Override