From 35821d444e9fb9cfb1b4ec481335ece4638cbab3 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sun, 16 Nov 2014 16:15:12 -0800 Subject: [PATCH] Move responsibility for Context injection out of JavaSerializer. // FREEBIE --- .../jobqueue/JobManagerTest.java | 8 ++--- .../dependencies/ContextDependent.java | 34 +++++++++++-------- .../persistence/JavaJobSerializer.java | 25 ++------------ .../persistence/PersistentStorage.java | 27 ++++++++++++--- .../securesms/ApplicationContext.java | 2 +- .../persistence/EncryptingJobSerializer.java | 10 +++--- 6 files changed, 52 insertions(+), 54 deletions(-) diff --git a/jobqueue/src/androidTest/java/org/whispersystems/jobqueue/JobManagerTest.java b/jobqueue/src/androidTest/java/org/whispersystems/jobqueue/JobManagerTest.java index e7f3d67f4..62030f284 100644 --- a/jobqueue/src/androidTest/java/org/whispersystems/jobqueue/JobManagerTest.java +++ b/jobqueue/src/androidTest/java/org/whispersystems/jobqueue/JobManagerTest.java @@ -122,7 +122,7 @@ public class JobManagerTest extends AndroidTestCase { PersistentTestJob testJob = new PersistentTestJob(requirement); JobManager jobManager = JobManager.newBuilder(getContext()) .withName("persistent-requirement-test3") - .withJobSerializer(new JavaJobSerializer(getContext())) + .withJobSerializer(new JavaJobSerializer()) .withConsumerThreads(1) .build(); @@ -138,7 +138,7 @@ public class JobManagerTest extends AndroidTestCase { jobManager = JobManager.newBuilder(getContext()) .withName("persistent-requirement-test3") - .withJobSerializer(new JavaJobSerializer(getContext())) + .withJobSerializer(new JavaJobSerializer()) .withConsumerThreads(1) .build(); @@ -151,7 +151,7 @@ public class JobManagerTest extends AndroidTestCase { PersistentTestJob testJob = new PersistentTestJob(requirement, keys); JobManager jobManager = JobManager.newBuilder(getContext()) .withName("persistent-requirement-test4") - .withJobSerializer(new JavaJobSerializer(getContext())) + .withJobSerializer(new JavaJobSerializer()) .withConsumerThreads(1) .build(); @@ -168,7 +168,7 @@ public class JobManagerTest extends AndroidTestCase { PersistentRequirement.getInstance().setPresent(true); jobManager = JobManager.newBuilder(getContext()) .withName("persistent-requirement-test4") - .withJobSerializer(new JavaJobSerializer(getContext())) + .withJobSerializer(new JavaJobSerializer()) .withConsumerThreads(1) .build(); diff --git a/jobqueue/src/main/java/org/whispersystems/jobqueue/dependencies/ContextDependent.java b/jobqueue/src/main/java/org/whispersystems/jobqueue/dependencies/ContextDependent.java index 582caf7ef..1cdaadc64 100644 --- a/jobqueue/src/main/java/org/whispersystems/jobqueue/dependencies/ContextDependent.java +++ b/jobqueue/src/main/java/org/whispersystems/jobqueue/dependencies/ContextDependent.java @@ -1,23 +1,27 @@ /** - * Copyright (C) 2014 Open Whisper Systems - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +* Copyright (C) 2014 Open Whisper Systems +* +* 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 +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ package org.whispersystems.jobqueue.dependencies; 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 void setContext(Context context); } diff --git a/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/JavaJobSerializer.java b/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/JavaJobSerializer.java index 1933ce10b..ebb088644 100644 --- a/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/JavaJobSerializer.java +++ b/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/JavaJobSerializer.java @@ -16,13 +16,10 @@ */ package org.whispersystems.jobqueue.persistence; -import android.content.Context; import android.util.Base64; import org.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.Job; -import org.whispersystems.jobqueue.dependencies.ContextDependent; -import org.whispersystems.jobqueue.requirements.Requirement; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -36,11 +33,7 @@ import java.io.ObjectOutputStream; */ public class JavaJobSerializer implements JobSerializer { - private final Context context; - - public JavaJobSerializer(Context context) { - this.context = context; - } + public JavaJobSerializer() {} @Override 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)); ObjectInputStream ois = new ObjectInputStream(bais); - Job job = (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; + return (Job)ois.readObject(); } catch (ClassNotFoundException e) { throw new IOException(e); } diff --git a/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/PersistentStorage.java b/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/PersistentStorage.java index 0047fda05..dda9c985e 100644 --- a/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/PersistentStorage.java +++ b/jobqueue/src/main/java/org/whispersystems/jobqueue/persistence/PersistentStorage.java @@ -25,7 +25,9 @@ import android.util.Log; import org.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.Job; +import org.whispersystems.jobqueue.dependencies.ContextDependent; import org.whispersystems.jobqueue.dependencies.DependencyInjector; +import org.whispersystems.jobqueue.requirements.Requirement; import java.io.IOException; 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);", TABLE_NAME, ID, ITEM, ENCRYPTED); + private final Context context; private final DatabaseHelper databaseHelper; private final JobSerializer jobSerializer; private final DependencyInjector dependencyInjector; @@ -52,6 +55,7 @@ public class PersistentStorage { DependencyInjector dependencyInjector) { this.databaseHelper = new DatabaseHelper(context, "_jobqueue-" + name); + this.context = context; this.jobSerializer = serializer; this.dependencyInjector = dependencyInjector; } @@ -90,10 +94,8 @@ public class PersistentStorage { Job job = jobSerializer.deserialize(keys, encrypted, item); job.setPersistentId(id); - - if (dependencyInjector != null) { - dependencyInjector.injectDependencies(job); - } + job.setEncryptionKeys(keys); + injectDependencies(job); results.add(job); } catch (IOException e) { @@ -109,12 +111,27 @@ public class PersistentStorage { return results; } - public void remove(long id) { databaseHelper.getWritableDatabase() .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 { public DatabaseHelper(Context context, String name) { diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index fbd330ee2..80aa395bf 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -79,7 +79,7 @@ public class ApplicationContext extends Application implements DependencyInjecto this.jobManager = JobManager.newBuilder(this) .withName("TextSecureJobs") .withDependencyInjector(this) - .withJobSerializer(new EncryptingJobSerializer(this)) + .withJobSerializer(new EncryptingJobSerializer()) .withRequirementProviders(new MasterSecretRequirementProvider(this), new ServiceRequirementProvider(this), new NetworkRequirementProvider(this)) diff --git a/src/org/thoughtcrime/securesms/jobs/persistence/EncryptingJobSerializer.java b/src/org/thoughtcrime/securesms/jobs/persistence/EncryptingJobSerializer.java index 0ae906395..32e9f4cef 100644 --- a/src/org/thoughtcrime/securesms/jobs/persistence/EncryptingJobSerializer.java +++ b/src/org/thoughtcrime/securesms/jobs/persistence/EncryptingJobSerializer.java @@ -1,15 +1,13 @@ 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.whispersystems.jobqueue.EncryptionKeys; import org.whispersystems.jobqueue.Job; import org.whispersystems.jobqueue.persistence.JavaJobSerializer; import org.whispersystems.jobqueue.persistence.JobSerializer; import org.whispersystems.libaxolotl.InvalidMessageException; -import org.thoughtcrime.securesms.crypto.MasterCipher; -import org.thoughtcrime.securesms.crypto.MasterSecret; import java.io.IOException; @@ -17,8 +15,8 @@ public class EncryptingJobSerializer implements JobSerializer { private final JavaJobSerializer delegate; - public EncryptingJobSerializer(Context context) { - this.delegate = new JavaJobSerializer(context); + public EncryptingJobSerializer() { + this.delegate = new JavaJobSerializer(); } @Override