From d5720c085f657195b3560ad04af1b248354cd87a Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Tue, 30 Apr 2013 15:05:23 +0100
Subject: [PATCH] Removed bundle encryption.

Android doesn't currently store bundles persistently, so it's premature
to protect against accidental information leaks through persistent
bundle storage. Protecting against deliberate information leaks by the
OS is probably futile, so there's currently no need for bundle
encryption.
---
 .../net/sf/briar/android/AndroidModule.java   |  3 -
 .../net/sf/briar/android/BriarActivity.java   | 36 ----------
 .../briar/android/BriarFragmentActivity.java  | 36 ----------
 .../sf/briar/android/BundleEncrypterImpl.java | 68 -------------------
 .../sf/briar/android/HomeScreenActivity.java  |  5 +-
 .../net/sf/briar/android/SetupActivity.java   |  5 +-
 .../briar/android/SplashScreenActivity.java   |  2 +-
 .../sf/briar/android/blogs/BlogActivity.java  | 18 +++--
 .../briar/android/blogs/BlogListActivity.java |  6 +-
 .../android/blogs/ConfigureBlogActivity.java  | 12 ++--
 .../android/blogs/CreateBlogActivity.java     | 12 ++--
 .../android/blogs/ManageBlogsActivity.java    |  6 +-
 .../android/blogs/ReadBlogPostActivity.java   | 22 +++---
 .../android/blogs/WriteBlogPostActivity.java  | 20 +-----
 .../android/contact/ContactListActivity.java  |  6 +-
 .../groups/ConfigureGroupActivity.java        | 12 ++--
 .../android/groups/CreateGroupActivity.java   | 12 ++--
 .../briar/android/groups/GroupActivity.java   | 18 +++--
 .../android/groups/GroupListActivity.java     |  6 +-
 .../android/groups/ManageGroupsActivity.java  |  6 +-
 .../android/groups/ReadGroupPostActivity.java | 22 +++---
 .../groups/WriteGroupPostActivity.java        | 20 +-----
 .../identity/CreateIdentityActivity.java      | 12 ++--
 .../invitation/AddContactActivity.java        | 14 ++--
 .../messages/ConversationActivity.java        | 18 +++--
 .../messages/ConversationListActivity.java    |  6 +-
 .../messages/ReadPrivateMessageActivity.java  | 22 +++---
 .../messages/WritePrivateMessageActivity.java | 20 +-----
 .../sf/briar/api/android/BundleEncrypter.java | 27 --------
 .../sf/briar/api/crypto/CryptoComponent.java  | 15 ----
 .../sf/briar/crypto/CryptoComponentImpl.java  | 45 ------------
 31 files changed, 155 insertions(+), 377 deletions(-)
 delete mode 100644 briar-android/src/net/sf/briar/android/BriarActivity.java
 delete mode 100644 briar-android/src/net/sf/briar/android/BriarFragmentActivity.java
 delete mode 100644 briar-android/src/net/sf/briar/android/BundleEncrypterImpl.java
 delete mode 100644 briar-api/src/net/sf/briar/api/android/BundleEncrypter.java

diff --git a/briar-android/src/net/sf/briar/android/AndroidModule.java b/briar-android/src/net/sf/briar/android/AndroidModule.java
index b13d5756f5..ceac1c7a43 100644
--- a/briar-android/src/net/sf/briar/android/AndroidModule.java
+++ b/briar-android/src/net/sf/briar/android/AndroidModule.java
@@ -8,7 +8,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import net.sf.briar.api.android.AndroidExecutor;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.android.ReferenceManager;
 import net.sf.briar.api.crypto.CryptoComponent;
@@ -33,8 +32,6 @@ public class AndroidModule extends AbstractModule {
 	@Override
 	protected void configure() {
 		bind(AndroidExecutor.class).to(AndroidExecutorImpl.class);
-		bind(BundleEncrypter.class).to(BundleEncrypterImpl.class).in(
-				Singleton.class);
 		bind(ReferenceManager.class).to(ReferenceManagerImpl.class).in(
 				Singleton.class);
 		// Use a single thread so DB accesses from the UI don't overlap, with
diff --git a/briar-android/src/net/sf/briar/android/BriarActivity.java b/briar-android/src/net/sf/briar/android/BriarActivity.java
deleted file mode 100644
index 5afee39e12..0000000000
--- a/briar-android/src/net/sf/briar/android/BriarActivity.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.sf.briar.android;
-
-import roboguice.activity.RoboActivity;
-import android.os.Bundle;
-
-/**
- * An abstract superclass for activities that overrides the default behaviour
- * to prevent sensitive state from being saved unless the subclass explicitly
- * saves it.
- */
-public abstract class BriarActivity extends RoboActivity {
-
-	@Override
-	public void onCreate(Bundle state) {
-		// Don't pass state through to the superclass
-		super.onCreate(null);
-	}
-
-	@Override
-	public void onRestoreInstanceState(Bundle state) {
-		// Don't pass state through to the superclass
-	}
-
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		// Don't allow the superclass to save state
-	}
-
-	protected void finishOnUiThread() {
-		runOnUiThread(new Runnable() {
-			public void run() {
-				finish();
-			}
-		});
-	}
-}
diff --git a/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java b/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java
deleted file mode 100644
index 44809a3bf2..0000000000
--- a/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.sf.briar.android;
-
-import roboguice.activity.RoboFragmentActivity;
-import android.os.Bundle;
-
-/**
- * An abstract superclass for activities that overrides the default behaviour
- * to prevent sensitive state from being saved unless the subclass explicitly
- * saves it.
- */
-public class BriarFragmentActivity extends RoboFragmentActivity {
-
-	@Override
-	public void onCreate(Bundle state) {
-		// Don't pass state through to the superclass
-		super.onCreate(null);
-	}
-
-	@Override
-	public void onRestoreInstanceState(Bundle state) {
-		// Don't pass state through to the superclass
-	}
-
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		// Don't allow the superclass to save state
-	}
-
-	protected void finishOnUiThread() {
-		runOnUiThread(new Runnable() {
-			public void run() {
-				finish();
-			}
-		});
-	}
-}
diff --git a/briar-android/src/net/sf/briar/android/BundleEncrypterImpl.java b/briar-android/src/net/sf/briar/android/BundleEncrypterImpl.java
deleted file mode 100644
index 34197abd11..0000000000
--- a/briar-android/src/net/sf/briar/android/BundleEncrypterImpl.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.sf.briar.android;
-
-import static java.util.logging.Level.INFO;
-
-import java.util.logging.Logger;
-
-import net.sf.briar.api.android.BundleEncrypter;
-import net.sf.briar.api.crypto.CryptoComponent;
-import net.sf.briar.util.ByteUtils;
-import android.os.Bundle;
-import android.os.Parcel;
-
-import com.google.inject.Inject;
-
-class BundleEncrypterImpl implements BundleEncrypter {
-
-	private static final Logger LOG =
-			Logger.getLogger(BundleEncrypterImpl.class.getName());
-
-	private final CryptoComponent crypto;
-
-	@Inject
-	BundleEncrypterImpl(CryptoComponent crypto) {
-		this.crypto = crypto;
-	}
-
-	@Override
-	public void encrypt(Bundle b) {
-		// Marshall the plaintext contents into a byte array
-		Parcel p = Parcel.obtain();
-		b.writeToParcel(p, 0);
-		byte[] plaintext = p.marshall();
-		p.recycle();
-		if(LOG.isLoggable(INFO)) {
-			LOG.info("Marshalled " + b.size() + " mappings, "
-					+ plaintext.length + " plaintext bytes");
-		}
-		// Encrypt the plaintext
-		byte[] ciphertext = crypto.encryptTemporaryStorage(plaintext);
-		ByteUtils.erase(plaintext);
-		// Replace the plaintext contents with the ciphertext
-		b.clear();
-		b.putByteArray("net.sf.briar.CIPHERTEXT", ciphertext);
-	}
-
-	@Override
-	public boolean decrypt(Bundle b) {
-		// Retrieve the ciphertext
-		byte[] ciphertext = b.getByteArray("net.sf.briar.CIPHERTEXT");
-		if(ciphertext == null) throw new IllegalArgumentException();
-		// Decrypt the ciphertext
-		byte[] plaintext = crypto.decryptTemporaryStorage(ciphertext);
-		if(plaintext == null) return false;
-		// Unmarshall the plaintext
-		Parcel p = Parcel.obtain();
-		p.unmarshall(plaintext, 0, plaintext.length);
-		ByteUtils.erase(plaintext);
-		// Restore the plaintext contents
-		p.setDataPosition(0);
-		b.readFromParcel(p);
-		p.recycle();
-		if(LOG.isLoggable(INFO)) {
-			LOG.info("Unmarshalled " + (b.size() - 1) + " mappings, "
-					+ plaintext.length + " plaintext bytes");
-		}
-		return true;
-	}
-}
diff --git a/briar-android/src/net/sf/briar/android/HomeScreenActivity.java b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
index 7749ef1085..2798b2693e 100644
--- a/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
+++ b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
@@ -36,6 +36,7 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DatabaseConfig;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.util.StringUtils;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
@@ -58,7 +59,7 @@ import android.widget.TextView.OnEditorActionListener;
 
 import com.google.inject.Inject;
 
-public class HomeScreenActivity extends BriarActivity {
+public class HomeScreenActivity extends RoboActivity {
 
 	// This build expires at the beginning of June 2013
 	private static final long EXPIRY_DATE = 1370044800000L;
@@ -84,7 +85,7 @@ public class HomeScreenActivity extends BriarActivity {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		Intent i = getIntent();
 		boolean quit = i.getBooleanExtra("net.sf.briar.QUIT", false);
 		long handle = i.getLongExtra("net.sf.briar.LOCAL_AUTHOR_HANDLE", -1);
diff --git a/briar-android/src/net/sf/briar/android/SetupActivity.java b/briar-android/src/net/sf/briar/android/SetupActivity.java
index fbae8b829d..f54e4e6746 100644
--- a/briar-android/src/net/sf/briar/android/SetupActivity.java
+++ b/briar-android/src/net/sf/briar/android/SetupActivity.java
@@ -25,6 +25,7 @@ import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.CryptoExecutor;
 import net.sf.briar.api.db.DatabaseConfig;
 import net.sf.briar.util.StringUtils;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
@@ -40,7 +41,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class SetupActivity extends BriarActivity implements OnClickListener {
+public class SetupActivity extends RoboActivity implements OnClickListener {
 
 	private static final int MIN_PASSWORD_LENGTH = 8;
 
@@ -58,7 +59,7 @@ public class SetupActivity extends BriarActivity implements OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
diff --git a/briar-android/src/net/sf/briar/android/SplashScreenActivity.java b/briar-android/src/net/sf/briar/android/SplashScreenActivity.java
index 2c1e600056..2ff1a7d050 100644
--- a/briar-android/src/net/sf/briar/android/SplashScreenActivity.java
+++ b/briar-android/src/net/sf/briar/android/SplashScreenActivity.java
@@ -22,7 +22,7 @@ public class SplashScreenActivity extends RoboSplashActivity {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setGravity(CENTER);
diff --git a/briar-android/src/net/sf/briar/android/blogs/BlogActivity.java b/briar-android/src/net/sf/briar/android/blogs/BlogActivity.java
index 4e8095e9a3..c1c0cf0776 100644
--- a/briar-android/src/net/sf/briar/android/blogs/BlogActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/BlogActivity.java
@@ -15,7 +15,6 @@ import java.util.logging.Logger;
 
 import net.sf.briar.R;
 import net.sf.briar.android.AscendingHeaderComparator;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -32,6 +31,7 @@ import net.sf.briar.api.db.event.MessageExpiredEvent;
 import net.sf.briar.api.db.event.RatingChangedEvent;
 import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.GroupId;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -44,7 +44,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class BlogActivity extends BriarFragmentActivity
+public class BlogActivity extends RoboFragmentActivity
 implements DatabaseListener, OnClickListener, OnItemClickListener {
 
 	private static final Logger LOG =
@@ -65,7 +65,7 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -125,7 +125,11 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 					displayHeaders(headers);
 				} catch(NoSuchSubscriptionException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -204,7 +208,11 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 			SubscriptionRemovedEvent s = (SubscriptionRemovedEvent) e;
 			if(s.getGroup().getId().equals(groupId)) {
 				if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		}
 	}
diff --git a/briar-android/src/net/sf/briar/android/blogs/BlogListActivity.java b/briar-android/src/net/sf/briar/android/blogs/BlogListActivity.java
index c7a8f1d0c6..adbca52d6e 100644
--- a/briar-android/src/net/sf/briar/android/blogs/BlogListActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/BlogListActivity.java
@@ -19,7 +19,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -39,6 +38,7 @@ import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
 import net.sf.briar.api.messaging.GroupStatus;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -51,7 +51,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class BlogListActivity extends BriarFragmentActivity
+public class BlogListActivity extends RoboFragmentActivity
 implements DatabaseListener, OnClickListener, NoBlogsDialog.Listener,
 OnItemClickListener {
 
@@ -72,7 +72,7 @@ OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
diff --git a/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java b/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
index e21a4f9117..420eebf2bc 100644
--- a/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
@@ -15,7 +15,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.contact.SelectContactsDialog;
@@ -28,6 +27,7 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -41,7 +41,7 @@ import android.widget.RadioGroup;
 
 import com.google.inject.Inject;
 
-public class ConfigureBlogActivity extends BriarFragmentActivity
+public class ConfigureBlogActivity extends RoboFragmentActivity
 implements OnClickListener, NoContactsDialog.Listener,
 SelectContactsDialog.Listener {
 
@@ -66,7 +66,7 @@ SelectContactsDialog.Listener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -227,7 +227,11 @@ SelectContactsDialog.Listener {
 						LOG.info("Interrupted while waiting for service");
 					Thread.currentThread().interrupt();
 				}
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		});
 	}
diff --git a/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java b/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
index 26444d0f28..fe7d99ae64 100644
--- a/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/CreateBlogActivity.java
@@ -21,7 +21,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.contact.SelectContactsDialog;
@@ -36,6 +35,7 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.messaging.GroupFactory;
 import net.sf.briar.api.messaging.LocalGroup;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.KeyEvent;
@@ -53,7 +53,7 @@ import android.widget.TextView.OnEditorActionListener;
 
 import com.google.inject.Inject;
 
-public class CreateBlogActivity extends BriarFragmentActivity
+public class CreateBlogActivity extends RoboFragmentActivity
 implements OnEditorActionListener, OnClickListener, NoContactsDialog.Listener,
 SelectContactsDialog.Listener {
 
@@ -79,7 +79,7 @@ SelectContactsDialog.Listener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
@@ -254,7 +254,11 @@ SelectContactsDialog.Listener {
 						LOG.info("Interrupted while waiting for service");
 					Thread.currentThread().interrupt();
 				}
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		});
 	}
diff --git a/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java b/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
index 539203a68e..32b453e9d7 100644
--- a/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
@@ -13,7 +13,6 @@ import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.api.android.DatabaseUiExecutor;
@@ -26,6 +25,7 @@ import net.sf.briar.api.db.event.SubscriptionAddedEvent;
 import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupStatus;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -35,7 +35,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ManageBlogsActivity extends BriarFragmentActivity
+public class ManageBlogsActivity extends RoboFragmentActivity
 implements DatabaseListener, OnItemClickListener {
 
 	private static final Logger LOG =
@@ -53,7 +53,7 @@ implements DatabaseListener, OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		adapter = new ManageBlogsAdapter(this);
 		list = new ListView(this);
diff --git a/briar-android/src/net/sf/briar/android/blogs/ReadBlogPostActivity.java b/briar-android/src/net/sf/briar/android/blogs/ReadBlogPostActivity.java
index f27e0ae4a3..51f0993049 100644
--- a/briar-android/src/net/sf/briar/android/blogs/ReadBlogPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/ReadBlogPostActivity.java
@@ -19,12 +19,10 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
 import net.sf.briar.android.widgets.HorizontalSpace;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
@@ -32,6 +30,7 @@ import net.sf.briar.api.db.NoSuchMessageException;
 import net.sf.briar.api.messaging.GroupId;
 import net.sf.briar.api.messaging.MessageId;
 import net.sf.briar.api.messaging.Rating;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Bundle;
@@ -46,7 +45,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class ReadBlogPostActivity extends BriarFragmentActivity
+public class ReadBlogPostActivity extends RoboFragmentActivity
 implements OnClickListener {
 
 	static final int RESULT_REPLY = RESULT_FIRST_USER;
@@ -59,7 +58,6 @@ implements OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	private GroupId groupId = null;
 	private boolean postable = false;
 	private Rating rating = UNRATED;
@@ -76,7 +74,7 @@ implements OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -97,11 +95,11 @@ implements OnClickListener {
 		long timestamp = i.getLongExtra("net.sf.briar.TIMESTAMP", -1);
 		if(timestamp == -1) throw new IllegalStateException();
 
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			read = state.getBoolean("net.sf.briar.READ");
-		} else {
+		if(state == null) {
 			read = false;
 			setReadInDatabase(true);
+		} else {
+			read = state.getBoolean("net.sf.briar.READ");
 		}
 
 		LinearLayout layout = new LinearLayout(this);
@@ -255,7 +253,11 @@ implements OnClickListener {
 					});
 				} catch(NoSuchMessageException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Message removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -272,8 +274,8 @@ implements OnClickListener {
 
 	@Override
 	public void onSaveInstanceState(Bundle state) {
+		super.onSaveInstanceState(state);
 		state.putBoolean("net.sf.briar.READ", read);
-		bundleEncrypter.encrypt(state);
 	}
 
 	@Override
diff --git a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
index a6e3ab9703..e8242ba17c 100644
--- a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
@@ -17,7 +17,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.identity.CreateIdentityActivity;
@@ -26,7 +25,6 @@ import net.sf.briar.android.identity.LocalAuthorItemComparator;
 import net.sf.briar.android.identity.LocalAuthorSpinnerAdapter;
 import net.sf.briar.android.widgets.HorizontalSpace;
 import net.sf.briar.api.LocalAuthor;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.KeyParser;
@@ -37,9 +35,9 @@ import net.sf.briar.api.messaging.LocalGroup;
 import net.sf.briar.api.messaging.Message;
 import net.sf.briar.api.messaging.MessageFactory;
 import net.sf.briar.api.messaging.MessageId;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.Parcelable;
 import android.text.InputType;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -53,7 +51,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class WriteBlogPostActivity extends BriarActivity
+public class WriteBlogPostActivity extends RoboActivity
 implements OnItemSelectedListener, OnClickListener {
 
 	private static final Logger LOG =
@@ -62,7 +60,6 @@ implements OnItemSelectedListener, OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	@Inject private CryptoComponent crypto;
 	@Inject private MessageFactory messageFactory;
 	private LocalAuthorSpinnerAdapter fromAdapter = null;
@@ -81,7 +78,7 @@ implements OnItemSelectedListener, OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -142,10 +139,6 @@ implements OnItemSelectedListener, OnClickListener {
 		int inputType = TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE
 				| TYPE_TEXT_FLAG_CAP_SENTENCES;
 		content.setInputType(inputType);
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
-			if(p != null) content.onRestoreInstanceState(p);
-		}
 		layout.addView(content);
 
 		setContentView(layout);
@@ -241,13 +234,6 @@ implements OnItemSelectedListener, OnClickListener {
 		});
 	}
 
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		Parcelable p = content.onSaveInstanceState();
-		state.putParcelable("net.sf.briar.CONTENT", p);
-		bundleEncrypter.encrypt(state);
-	}
-
 	@Override
 	public void onDestroy() {
 		super.onDestroy();
diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
index f6ee26f870..ccc41eb1b0 100644
--- a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
+++ b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
@@ -20,7 +20,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.invitation.AddContactActivity;
@@ -37,6 +36,7 @@ import net.sf.briar.api.db.event.DatabaseEvent;
 import net.sf.briar.api.db.event.DatabaseListener;
 import net.sf.briar.api.transport.ConnectionListener;
 import net.sf.briar.api.transport.ConnectionRegistry;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
@@ -48,7 +48,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ContactListActivity extends BriarActivity
+public class ContactListActivity extends RoboActivity
 implements OnClickListener, DatabaseListener, ConnectionListener {
 
 	private static final Logger LOG =
@@ -68,7 +68,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
diff --git a/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java b/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
index be63993446..d432b28334 100644
--- a/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
@@ -15,7 +15,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.contact.SelectContactsDialog;
@@ -28,6 +27,7 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -41,7 +41,7 @@ import android.widget.RadioGroup;
 
 import com.google.inject.Inject;
 
-public class ConfigureGroupActivity extends BriarFragmentActivity
+public class ConfigureGroupActivity extends RoboFragmentActivity
 implements OnClickListener, NoContactsDialog.Listener,
 SelectContactsDialog.Listener {
 
@@ -66,7 +66,7 @@ SelectContactsDialog.Listener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -225,7 +225,11 @@ SelectContactsDialog.Listener {
 						LOG.info("Interrupted while waiting for service");
 					Thread.currentThread().interrupt();
 				}
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		});
 	}
diff --git a/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java b/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
index ee0dbafd20..04bd359254 100644
--- a/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/CreateGroupActivity.java
@@ -20,7 +20,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.contact.SelectContactsDialog;
@@ -33,6 +32,7 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupFactory;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.KeyEvent;
@@ -50,7 +50,7 @@ import android.widget.TextView.OnEditorActionListener;
 
 import com.google.inject.Inject;
 
-public class CreateGroupActivity extends BriarFragmentActivity
+public class CreateGroupActivity extends RoboFragmentActivity
 implements OnEditorActionListener, OnClickListener, NoContactsDialog.Listener,
 SelectContactsDialog.Listener {
 
@@ -74,7 +74,7 @@ SelectContactsDialog.Listener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
@@ -188,7 +188,11 @@ SelectContactsDialog.Listener {
 					} catch(IOException e) {
 						throw new RuntimeException(e);
 					}
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				}
 			});
 		}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
index ee389d2feb..9604a5c828 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
@@ -15,7 +15,6 @@ import java.util.logging.Logger;
 
 import net.sf.briar.R;
 import net.sf.briar.android.AscendingHeaderComparator;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -32,6 +31,7 @@ import net.sf.briar.api.db.event.MessageExpiredEvent;
 import net.sf.briar.api.db.event.RatingChangedEvent;
 import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.GroupId;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -44,7 +44,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class GroupActivity extends BriarActivity implements DatabaseListener,
+public class GroupActivity extends RoboActivity implements DatabaseListener,
 OnClickListener, OnItemClickListener {
 
 	private static final Logger LOG =
@@ -64,7 +64,7 @@ OnClickListener, OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -123,7 +123,11 @@ OnClickListener, OnItemClickListener {
 					displayHeaders(headers);
 				} catch(NoSuchSubscriptionException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -202,7 +206,11 @@ OnClickListener, OnItemClickListener {
 			SubscriptionRemovedEvent s = (SubscriptionRemovedEvent) e;
 			if(s.getGroup().getId().equals(groupId)) {
 				if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		}
 	}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
index dcab38c8c3..1601f97f27 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
@@ -17,7 +17,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -37,6 +36,7 @@ import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
 import net.sf.briar.api.messaging.GroupStatus;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -49,7 +49,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class GroupListActivity extends BriarFragmentActivity
+public class GroupListActivity extends RoboFragmentActivity
 implements DatabaseListener, OnClickListener, NoGroupsDialog.Listener,
 OnItemClickListener {
 
@@ -70,7 +70,7 @@ OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
diff --git a/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java b/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
index 976f8b9a55..a62f607c33 100644
--- a/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
@@ -13,7 +13,6 @@ import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.api.android.DatabaseUiExecutor;
@@ -26,6 +25,7 @@ import net.sf.briar.api.db.event.SubscriptionAddedEvent;
 import net.sf.briar.api.db.event.SubscriptionRemovedEvent;
 import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupStatus;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -35,7 +35,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ManageGroupsActivity extends BriarFragmentActivity
+public class ManageGroupsActivity extends RoboFragmentActivity
 implements DatabaseListener, OnItemClickListener {
 
 	private static final Logger LOG =
@@ -53,7 +53,7 @@ implements DatabaseListener, OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		adapter = new ManageGroupsAdapter(this);
 		list = new ListView(this);
diff --git a/briar-android/src/net/sf/briar/android/groups/ReadGroupPostActivity.java b/briar-android/src/net/sf/briar/android/groups/ReadGroupPostActivity.java
index bc5a33a3d7..9576d90ef2 100644
--- a/briar-android/src/net/sf/briar/android/groups/ReadGroupPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ReadGroupPostActivity.java
@@ -19,13 +19,11 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
 import net.sf.briar.android.widgets.HorizontalSpace;
 import net.sf.briar.api.AuthorId;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
@@ -33,6 +31,7 @@ import net.sf.briar.api.db.NoSuchMessageException;
 import net.sf.briar.api.messaging.GroupId;
 import net.sf.briar.api.messaging.MessageId;
 import net.sf.briar.api.messaging.Rating;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Bundle;
@@ -47,7 +46,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class ReadGroupPostActivity extends BriarActivity
+public class ReadGroupPostActivity extends RoboActivity
 implements OnClickListener {
 
 	static final int RESULT_REPLY = RESULT_FIRST_USER;
@@ -60,7 +59,6 @@ implements OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	private GroupId groupId = null;
 	private Rating rating = UNRATED;
 	private boolean read;
@@ -78,7 +76,7 @@ implements OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -104,11 +102,11 @@ implements OnClickListener {
 		long timestamp = i.getLongExtra("net.sf.briar.TIMESTAMP", -1);
 		if(timestamp == -1) throw new IllegalStateException();
 
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			read = state.getBoolean("net.sf.briar.READ");
-		} else {
+		if(state == null) {
 			read = false;
 			setReadInDatabase(true);
+		} else {
+			read = state.getBoolean("net.sf.briar.READ");
 		}
 
 		LinearLayout layout = new LinearLayout(this);
@@ -279,7 +277,11 @@ implements OnClickListener {
 					});
 				} catch(NoSuchMessageException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Message removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -296,8 +298,8 @@ implements OnClickListener {
 
 	@Override
 	public void onSaveInstanceState(Bundle state) {
+		super.onSaveInstanceState(state);
 		state.putBoolean("net.sf.briar.READ", read);
-		bundleEncrypter.encrypt(state);
 	}
 
 	@Override
diff --git a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
index afacecf6fc..cb05d3266c 100644
--- a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
@@ -20,7 +20,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.identity.CreateIdentityActivity;
@@ -29,7 +28,6 @@ import net.sf.briar.android.identity.LocalAuthorItemComparator;
 import net.sf.briar.android.identity.LocalAuthorSpinnerAdapter;
 import net.sf.briar.android.widgets.HorizontalSpace;
 import net.sf.briar.api.LocalAuthor;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.KeyParser;
@@ -40,9 +38,9 @@ import net.sf.briar.api.messaging.GroupId;
 import net.sf.briar.api.messaging.Message;
 import net.sf.briar.api.messaging.MessageFactory;
 import net.sf.briar.api.messaging.MessageId;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.Parcelable;
 import android.text.InputType;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -56,7 +54,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class WriteGroupPostActivity extends BriarActivity
+public class WriteGroupPostActivity extends RoboActivity
 implements OnItemSelectedListener, OnClickListener {
 
 	private static final Logger LOG =
@@ -65,7 +63,6 @@ implements OnItemSelectedListener, OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	@Inject private CryptoComponent crypto;
 	@Inject private MessageFactory messageFactory;
 	private LocalAuthorSpinnerAdapter fromAdapter = null;
@@ -84,7 +81,7 @@ implements OnItemSelectedListener, OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
@@ -145,10 +142,6 @@ implements OnItemSelectedListener, OnClickListener {
 		int inputType = TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE
 				| TYPE_TEXT_FLAG_CAP_SENTENCES;
 		content.setInputType(inputType);
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
-			if(p != null) content.onRestoreInstanceState(p);
-		}
 		layout.addView(content);
 
 		setContentView(layout);
@@ -246,13 +239,6 @@ implements OnItemSelectedListener, OnClickListener {
 		});
 	}
 
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		Parcelable p = content.onSaveInstanceState();
-		state.putParcelable("net.sf.briar.CONTENT", p);
-		bundleEncrypter.encrypt(state);
-	}
-
 	@Override
 	public void onDestroy() {
 		super.onDestroy();
diff --git a/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java b/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
index f5928c8efc..eeadc22e68 100644
--- a/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
+++ b/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
@@ -20,7 +20,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.api.AuthorFactory;
@@ -30,6 +29,7 @@ import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.CryptoExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.KeyEvent;
@@ -45,7 +45,7 @@ import android.widget.TextView.OnEditorActionListener;
 
 import com.google.inject.Inject;
 
-public class CreateIdentityActivity extends BriarActivity
+public class CreateIdentityActivity extends RoboActivity
 implements OnEditorActionListener, OnClickListener {
 
 	private static final Logger LOG =
@@ -67,7 +67,7 @@ implements OnEditorActionListener, OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
@@ -168,7 +168,11 @@ implements OnEditorActionListener, OnClickListener {
 						LOG.info("Interrupted while waiting for service");
 					Thread.currentThread().interrupt();
 				}
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		});
 	}
diff --git a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
index 33a43d4ade..43378046d1 100644
--- a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
+++ b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
@@ -12,7 +12,6 @@ import java.util.Collection;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.identity.LocalAuthorItem;
@@ -20,7 +19,6 @@ import net.sf.briar.android.identity.LocalAuthorItemComparator;
 import net.sf.briar.android.identity.LocalAuthorSpinnerAdapter;
 import net.sf.briar.api.AuthorId;
 import net.sf.briar.api.LocalAuthor;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.android.ReferenceManager;
 import net.sf.briar.api.crypto.CryptoComponent;
@@ -30,6 +28,7 @@ import net.sf.briar.api.invitation.InvitationListener;
 import net.sf.briar.api.invitation.InvitationState;
 import net.sf.briar.api.invitation.InvitationTask;
 import net.sf.briar.api.invitation.InvitationTaskFactory;
+import roboguice.activity.RoboActivity;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -41,7 +40,7 @@ import android.os.Bundle;
 
 import com.google.inject.Inject;
 
-public class AddContactActivity extends BriarActivity
+public class AddContactActivity extends RoboActivity
 implements InvitationListener {
 
 	private static final Logger LOG =
@@ -50,7 +49,6 @@ implements InvitationListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	@Inject private CryptoComponent crypto;
 	@Inject private InvitationTaskFactory invitationTaskFactory;
 	@Inject private ReferenceManager referenceManager;
@@ -73,9 +71,9 @@ implements InvitationListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
-		if(state == null || !bundleEncrypter.decrypt(state)) {
-			// This is a new activity or the app has restarted
+		super.onCreate(state);
+		if(state == null) {
+			// This is a new activity
 			setView(new NetworkSetupView(this));
 		} else {
 			// Restore the activity's state
@@ -174,6 +172,7 @@ implements InvitationListener {
 
 	@Override
 	public void onSaveInstanceState(Bundle state) {
+		super.onSaveInstanceState(state);
 		if(localAuthorId != null) {
 			state.putByteArray("net.sf.briar.LOCAL_AUTHOR_ID",
 					localAuthorId.getBytes());
@@ -183,7 +182,6 @@ implements InvitationListener {
 		state.putBoolean("net.sf.briar.FAILED", connectionFailed);
 		state.putString("net.sf.briar.CONTACT_NAME", contactName);
 		if(task != null) state.putLong("net.sf.briar.TASK_HANDLE", taskHandle);
-		bundleEncrypter.encrypt(state);
 	}
 
 	@Override
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
index b93b8be7f5..68bcd1391e 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
@@ -13,7 +13,6 @@ import java.util.logging.Logger;
 
 import net.sf.briar.R;
 import net.sf.briar.android.AscendingHeaderComparator;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -29,6 +28,7 @@ import net.sf.briar.api.db.event.DatabaseEvent;
 import net.sf.briar.api.db.event.DatabaseListener;
 import net.sf.briar.api.db.event.MessageExpiredEvent;
 import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -41,7 +41,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ConversationActivity extends BriarActivity
+public class ConversationActivity extends RoboActivity
 implements DatabaseListener, OnClickListener, OnItemClickListener {
 
 	private static final Logger LOG =
@@ -62,7 +62,7 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		int id = i.getIntExtra("net.sf.briar.CONTACT_ID", -1);
@@ -124,7 +124,11 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 					displayHeaders(headers);
 				} catch(NoSuchContactException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Contact removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -192,7 +196,11 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
 			ContactRemovedEvent c = (ContactRemovedEvent) e;
 			if(c.getContactId().equals(contactId)) {
 				if(LOG.isLoggable(INFO)) LOG.info("Contact removed");
-				finishOnUiThread();
+				runOnUiThread(new Runnable() {
+					public void run() {
+						finish();
+					}
+				});
 			}
 		} else if(e instanceof MessageExpiredEvent) {
 			if(LOG.isLoggable(INFO)) LOG.info("Message expired, reloading");
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
index 379cedee61..eacfcc1ecc 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
@@ -13,7 +13,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.invitation.AddContactActivity;
@@ -30,6 +29,7 @@ import net.sf.briar.api.db.event.DatabaseEvent;
 import net.sf.briar.api.db.event.DatabaseListener;
 import net.sf.briar.api.db.event.MessageExpiredEvent;
 import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
+import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
@@ -40,7 +40,7 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ConversationListActivity extends BriarFragmentActivity
+public class ConversationListActivity extends RoboFragmentActivity
 implements OnClickListener, DatabaseListener, NoContactsDialog.Listener {
 
 	private static final Logger LOG =
@@ -58,7 +58,7 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 		LinearLayout layout = new LinearLayout(this);
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
diff --git a/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
index 811bbd27ad..d1b7d3d87b 100644
--- a/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
@@ -19,19 +19,18 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
 import net.sf.briar.android.widgets.HorizontalSpace;
 import net.sf.briar.api.ContactId;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.NoSuchMessageException;
 import net.sf.briar.api.messaging.MessageId;
 import net.sf.briar.api.messaging.Rating;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Bundle;
@@ -46,7 +45,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class ReadPrivateMessageActivity extends BriarActivity
+public class ReadPrivateMessageActivity extends RoboActivity
 implements OnClickListener {
 
 	static final int RESULT_REPLY = RESULT_FIRST_USER;
@@ -59,7 +58,6 @@ implements OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	private ContactId contactId = null;
 	private Rating rating = UNRATED;
 	private boolean read;
@@ -74,7 +72,7 @@ implements OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		int id = i.getIntExtra("net.sf.briar.CONTACT_ID", -1);
@@ -96,11 +94,11 @@ implements OnClickListener {
 		long timestamp = i.getLongExtra("net.sf.briar.TIMESTAMP", -1);
 		if(timestamp == -1) throw new IllegalStateException();
 
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			read = state.getBoolean("net.sf.briar.READ");
-		} else {
+		if(state == null) {
 			read = false;
 			setReadInDatabase(true);
+		} else {
+			read = state.getBoolean("net.sf.briar.READ");
 		}
 
 		LinearLayout layout = new LinearLayout(this);
@@ -249,7 +247,11 @@ implements OnClickListener {
 					});
 				} catch(NoSuchMessageException e) {
 					if(LOG.isLoggable(INFO)) LOG.info("Message removed");
-					finishOnUiThread();
+					runOnUiThread(new Runnable() {
+						public void run() {
+							finish();
+						}
+					});
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -266,8 +268,8 @@ implements OnClickListener {
 
 	@Override
 	public void onSaveInstanceState(Bundle state) {
+		super.onSaveInstanceState(state);
 		state.putBoolean("net.sf.briar.READ", read);
-		bundleEncrypter.encrypt(state);
 	}
 
 	@Override
diff --git a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
index ef421fcc59..734652ef9f 100644
--- a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
@@ -17,7 +17,6 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.contact.ContactItem;
@@ -29,16 +28,15 @@ import net.sf.briar.api.AuthorId;
 import net.sf.briar.api.Contact;
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.LocalAuthor;
-import net.sf.briar.api.android.BundleEncrypter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.messaging.Message;
 import net.sf.briar.api.messaging.MessageFactory;
 import net.sf.briar.api.messaging.MessageId;
+import roboguice.activity.RoboActivity;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.Parcelable;
 import android.text.InputType;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -52,7 +50,7 @@ import android.widget.TextView;
 
 import com.google.inject.Inject;
 
-public class WritePrivateMessageActivity extends BriarActivity
+public class WritePrivateMessageActivity extends RoboActivity
 implements OnItemSelectedListener, OnClickListener {
 
 	private static final Logger LOG =
@@ -61,7 +59,6 @@ implements OnItemSelectedListener, OnClickListener {
 	private final BriarServiceConnection serviceConnection =
 			new BriarServiceConnection();
 
-	@Inject private BundleEncrypter bundleEncrypter;
 	private TextView from = null;
 	private ContactSpinnerAdapter adapter = null;
 	private Spinner spinner = null;
@@ -78,7 +75,7 @@ implements OnItemSelectedListener, OnClickListener {
 
 	@Override
 	public void onCreate(Bundle state) {
-		super.onCreate(null);
+		super.onCreate(state);
 
 		Intent i = getIntent();
 		int id = i.getIntExtra("net.sf.briar.CONTACT_ID", -1);
@@ -133,10 +130,6 @@ implements OnItemSelectedListener, OnClickListener {
 		int inputType = TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE
 				| TYPE_TEXT_FLAG_CAP_SENTENCES;
 		content.setInputType(inputType);
-		if(state != null && bundleEncrypter.decrypt(state)) {
-			Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
-			if(p != null) content.onRestoreInstanceState(p);
-		}
 		layout.addView(content);
 
 		setContentView(layout);
@@ -195,13 +188,6 @@ implements OnItemSelectedListener, OnClickListener {
 		});
 	}
 
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		Parcelable p = content.onSaveInstanceState();
-		state.putParcelable("net.sf.briar.CONTENT", p);
-		bundleEncrypter.encrypt(state);
-	}
-
 	@Override
 	public void onDestroy() {
 		super.onDestroy();
diff --git a/briar-api/src/net/sf/briar/api/android/BundleEncrypter.java b/briar-api/src/net/sf/briar/api/android/BundleEncrypter.java
deleted file mode 100644
index e2af1a8324..0000000000
--- a/briar-api/src/net/sf/briar/api/android/BundleEncrypter.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.sf.briar.api.android;
-
-import android.os.Bundle;
-
-/**
- * Encrypts and decrypts the contents of bundles in case the operating system
- * writes them to unencrypted storage.
- * <p>
- * This interface is designed to be accessed from the UI thread, so
- * implementations may not be thread-safe.
- */
-public interface BundleEncrypter {
-
-	/**
-	 * Encrypts the given bundle, replacing its contents with the encrypted
-	 * data.
-	 */
-	void encrypt(Bundle b);
-
-	/**
-	 * Decrypts the given bundle, replacing its contents with the decrypted
-	 * data, or returns false if the bundle contains invalid data, which may
-	 * occur if the process that created the encrypted bundle was terminated
-	 * and replaced by the current process.
-	 */
-	boolean decrypt(Bundle b);
-}
diff --git a/briar-api/src/net/sf/briar/api/crypto/CryptoComponent.java b/briar-api/src/net/sf/briar/api/crypto/CryptoComponent.java
index 517a7c6d2a..3515588e01 100644
--- a/briar-api/src/net/sf/briar/api/crypto/CryptoComponent.java
+++ b/briar-api/src/net/sf/briar/api/crypto/CryptoComponent.java
@@ -95,21 +95,6 @@ public interface CryptoComponent {
 	void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
 			long connection);
 
-	/**
-	 * Encrypts and authenticates the given plaintext so it can be written to
-	 * temporary storage. The ciphertext will not be decryptable after the app
-	 * restarts.
-	 */
-	byte[] encryptTemporaryStorage(byte[] plaintext);
-
-	/**
-	 * Decrypts and authenticates the given ciphertext that has been read from
-	 * temporary storage. Returns null if the ciphertext cannot be decrypted
-	 * and authenticated (for example, if it was written before the app
-	 * restarted).
-	 */
-	byte[] decryptTemporaryStorage(byte[] ciphertext);
-
 	/**
 	 * Encrypts and authenticates the given plaintext so it can be written to
 	 * storage. The encryption and authentication keys are derived from the
diff --git a/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java b/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
index c846af33a5..d16009c13d 100644
--- a/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/net/sf/briar/crypto/CryptoComponentImpl.java
@@ -133,7 +133,6 @@ class CryptoComponentImpl implements CryptoComponent {
 	private final KeyPairGenerator agreementKeyPairGenerator;
 	private final KeyPairGenerator signatureKeyPairGenerator;
 	private final SecureRandom secureRandom;
-	private final ErasableKey temporaryStorageKey;
 
 	CryptoComponentImpl() {
 		Security.addProvider(new BouncyCastleProvider());
@@ -156,7 +155,6 @@ class CryptoComponentImpl implements CryptoComponent {
 			throw new RuntimeException(e);
 		}
 		secureRandom = new SecureRandom();
-		temporaryStorageKey = generateSecretKey();
 	}
 
 	public ErasableKey generateSecretKey() {
@@ -372,49 +370,6 @@ class CryptoComponentImpl implements CryptoComponent {
 		}
 	}
 
-	public byte[] encryptTemporaryStorage(byte[] input) {
-		// Generate a random IV
-		byte[] ivBytes = new byte[STORAGE_IV_BYTES];
-		secureRandom.nextBytes(ivBytes);
-		IvParameterSpec iv = new IvParameterSpec(ivBytes);
-		// The output contains the IV, ciphertext and MAC
-		int outputLen = STORAGE_IV_BYTES + input.length + GCM_MAC_BYTES;
-		byte[] output = new byte[outputLen];
-		System.arraycopy(ivBytes, 0, output, 0, STORAGE_IV_BYTES);
-		// Initialise the cipher and encrypt the plaintext
-		Cipher cipher;
-		try {
-			cipher = Cipher.getInstance(STORAGE_CIPHER_ALGO, PROVIDER);
-			cipher.init(ENCRYPT_MODE, temporaryStorageKey, iv);
-			cipher.doFinal(input, 0, input.length, output, STORAGE_IV_BYTES);
-			return output;
-		} catch(GeneralSecurityException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	public byte[] decryptTemporaryStorage(byte[] input) {
-		// The input contains the IV, ciphertext and MAC
-		if(input.length < STORAGE_IV_BYTES + GCM_MAC_BYTES)
-			return null; // Invalid
-		IvParameterSpec iv = new IvParameterSpec(input, 0, STORAGE_IV_BYTES);
-		// Initialise the cipher
-		Cipher cipher;
-		try {
-			cipher = Cipher.getInstance(STORAGE_CIPHER_ALGO, PROVIDER);
-			cipher.init(DECRYPT_MODE, temporaryStorageKey, iv);
-		} catch(GeneralSecurityException e) {
-			throw new RuntimeException(e);
-		}
-		// Try to decrypt the ciphertext (may be invalid)
-		try {
-			return cipher.doFinal(input, STORAGE_IV_BYTES,
-					input.length - STORAGE_IV_BYTES);
-		} catch(GeneralSecurityException e) {
-			return null; // Invalid
-		}
-	}
-
 	public byte[] encryptWithPassword(byte[] input, char[] password) {
 		// Generate a random salt
 		byte[] salt = new byte[PBKDF_SALT_BYTES];
-- 
GitLab