aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-09-15 10:19:55 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-09-15 10:19:55 +0200
commit53bc417f8f77a9f92786457281d02431ef614ca7 (patch)
treef3b09c51520a6d7b4483cd3ca17136dc94e91251 /OpenKeychain/src
parent88bbce831c30c1220e03439ffca4c8f390506ba6 (diff)
downloadopen-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.tar.gz
open-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.tar.bz2
open-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.zip
New decrypt activity design (WIP), saner UTF8 decoding (replacing non-decodable characters)
Diffstat (limited to 'OpenKeychain/src')
-rw-r--r--OpenKeychain/src/main/AndroidManifest.xml171
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java57
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java113
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java)34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptOldActivity.java)130
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java)101
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java53
-rw-r--r--OpenKeychain/src/main/res/layout-large/decrypt_activity.xml18
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_activity.xml11
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_content.xml78
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_files_activity.xml14
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_text_activity.xml14
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml (renamed from OpenKeychain/src/main/res/layout/decrypt_message_fragment.xml)23
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_file_content.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_text_content.xml2
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml1
19 files changed, 532 insertions, 307 deletions
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml
index 63ffc8acd..f684cdc6a 100644
--- a/OpenKeychain/src/main/AndroidManifest.xml
+++ b/OpenKeychain/src/main/AndroidManifest.xml
@@ -139,11 +139,6 @@
android:label="@string/title_select_recipients"
android:launchMode="singleTop" />
<activity
- android:name=".ui.SelectSecretKeyActivity"
- android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:label="@string/title_select_secret_key"
- android:launchMode="singleTop" />
- <activity
android:name=".ui.EncryptFileActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_encrypt_files"
@@ -196,38 +191,22 @@
</intent-filter>
</activity>
<activity
- android:name=".ui.DecryptOldActivity"
+ android:name=".ui.DecryptActivity"
+ android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
+ android:label="@string/title_decrypt"
+ android:windowSoftInputMode="stateHidden" />
+ <activity
+ android:name=".ui.DecryptTextActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_decrypt"
android:windowSoftInputMode="stateHidden">
- <!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
- <intent-filter android:label="@string/intent_send_decrypt">
- <action android:name="android.intent.action.VIEW" />
-
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
-
- <!-- mime type as defined in http://tools.ietf.org/html/rfc3156 -->
- <data android:mimeType="application/octet-stream" />
- <data android:mimeType="application/pgp" />
- <data android:mimeType="text/pgp" />
- </intent-filter>
<!-- Keychain's own Actions -->
<!-- DECRYPT with text as extra -->
<intent-filter>
- <action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
-
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <!-- DECRYPT with data Uri -->
- <intent-filter>
- <action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
+ <action android:name="org.sufficientlysecure.keychain.action.DECRYPT_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
-
- <data android:scheme="file" />
- <data android:scheme="content" />
</intent-filter>
<!-- Android's Send Action -->
<intent-filter android:label="@string/intent_send_decrypt">
@@ -235,129 +214,12 @@
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="*/*" />
- </intent-filter>
- <!-- Linking "Decrypt" to file types -->
- <intent-filter android:label="@string/intent_decrypt_file">
- <action android:name="android.intent.action.VIEW" />
-
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
-
- <data android:host="*" />
- <data android:scheme="file" />
- <data android:scheme="content" />
-
- <!-- GnuPG ASCII data, mostly keys, but sometimes signatures and encrypted data -->
- <data android:pathPattern=".*\\.asc" />
- <data android:pathPattern=".*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <!-- GnuPG binary encrypted/signed data, binary format -->
- <data android:pathPattern=".*\\.gpg" />
- <data android:pathPattern=".*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <!-- PGP encrypted data, binary format -->
- <data android:pathPattern=".*\\.pgp" />
- <data android:pathPattern=".*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <!-- on some mail clients, PGP attachments show up as *.bin -->
- <data android:pathPattern=".*\\.bin" />
- <data android:pathPattern=".*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- </intent-filter>
- <!--
- Some apps will only respect these file associations
- if the mimeType is not set, and other apps will only respect them if mimeType is set
- to */*. Therefore we have two whole copies of the same thing, besides setting the mimeType.
- -->
- <intent-filter android:label="@string/intent_decrypt_file">
- <action android:name="android.intent.action.VIEW" />
-
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
-
- <data android:host="*" />
- <data android:scheme="file" />
- <data android:scheme="content" />
-
- <data android:mimeType="*/*" />
-
- <!-- GnuPG ASCII data, mostly keys, but sometimes signatures and encrypted data -->
- <data android:pathPattern=".*\\.asc" />
- <data android:pathPattern=".*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.asc" />
- <!-- GnuPG binary encrypted/signed data, binary format -->
- <data android:pathPattern=".*\\.gpg" />
- <data android:pathPattern=".*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.gpg" />
- <!-- PGP encrypted data, binary format -->
- <data android:pathPattern=".*\\.pgp" />
- <data android:pathPattern=".*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.pgp" />
- <!-- on some mail clients, PGP attachments show up as *.bin -->
- <data android:pathPattern=".*\\.bin" />
- <data android:pathPattern=".*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
- <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
+ <data android:mimeType="text/*" />
+ <data android:mimeType="message/*" />
</intent-filter>
</activity>
<activity
- android:name=".ui.DecryptActivity"
+ android:name=".ui.DecryptFilesActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_decrypt"
android:windowSoftInputMode="stateHidden">
@@ -375,12 +237,6 @@
<data android:mimeType="text/pgp" />
</intent-filter>
<!-- Keychain's own Actions -->
- <!-- DECRYPT with text as extra -->
- <intent-filter>
- <action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
-
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
<!-- DECRYPT with data Uri -->
<intent-filter>
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
@@ -396,7 +252,12 @@
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="*/*" />
+ <!-- everything except text/* and message/* -->
+ <data android:mimeType="image/*" />
+ <data android:mimeType="audio/*" />
+ <data android:mimeType="video/*" />
+ <data android:mimeType="application/*" />
+ <data android:mimeType="multipart/*" />
</intent-filter>
<!-- Linking "Decrypt" to file types -->
<intent-filter android:label="@string/intent_decrypt_file">
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
index d64c3ea55..04f2c3dfb 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
@@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.service.results.OperationResultParcel.Log
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Utf8Util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -365,7 +366,7 @@ public class UncachedKeyRing {
ArrayList<byte[]> processedUserIds = new ArrayList<byte[]>();
for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) {
- String userId = Strings.fromUTF8ByteArray(rawUserId);
+ String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
// check for duplicate user ids
if (processedUserIds.contains(rawUserId)) {
@@ -439,7 +440,7 @@ public class UncachedKeyRing {
continue;
}
// warn user if the signature was made with bad encoding
- if (!cert.verifySignature(masterKey, userId)) {
+ if (!Utf8Util.isValidUTF8(rawUserId)) {
log.add(LogLevel.WARN, LogType.MSG_KC_UID_WARN_ENCODING, indent);
}
} catch (PgpGeneralException e) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
index e27190bc7..7f08d121e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
@@ -32,6 +32,7 @@ import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Utf8Util;
import java.util.ArrayList;
import java.util.Arrays;
@@ -185,7 +186,7 @@ public class UncachedPublicKey {
}
}
if (found != null) {
- return Strings.fromUTF8ByteArray(found);
+ return Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(found);
} else {
return null;
}
@@ -204,8 +205,9 @@ public class UncachedPublicKey {
public ArrayList<String> getUnorderedUserIds() {
ArrayList<String> userIds = new ArrayList<String>();
- for (String userId : new IterableIterator<String>(mPublicKey.getUserIDs())) {
- userIds.add(userId);
+ for (byte[] rawUserId : new IterableIterator<byte[]>(mPublicKey.getRawUserIDs())) {
+ // use our decoding method
+ userIds.add(Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId));
}
return userIds;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 8e6a0dfa5..ed65b87bd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -65,6 +65,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
import org.sufficientlysecure.keychain.util.ProgressScaler;
+import org.sufficientlysecure.keychain.util.Utf8Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -437,8 +438,7 @@ public class ProviderHelper {
List<UserIdItem> uids = new ArrayList<UserIdItem>();
for (byte[] rawUserId : new IterableIterator<byte[]>(
masterKey.getUnorderedRawUserIds().iterator())) {
- String userId = Strings.fromUTF8ByteArray(rawUserId);
- Log.d(Constants.TAG, "userId: "+userId);
+ String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
UserIdItem item = new UserIdItem();
uids.add(item);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
new file mode 100644
index 000000000..37382051b
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+import org.sufficientlysecure.keychain.R;
+
+public class DecryptActivity extends DrawerActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.decrypt_activity);
+
+ activateDrawerNavigation(savedInstanceState);
+
+ View actionFile = findViewById(R.id.decrypt_files);
+ View actionFromClipboard = findViewById(R.id.decrypt_from_clipboard);
+
+ actionFile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent filesDecrypt = new Intent(DecryptActivity.this, DecryptFilesActivity.class);
+ filesDecrypt.setAction(DecryptFilesActivity.ACTION_DECRYPT_DATA_OPEN);
+ startActivity(filesDecrypt);
+ }
+ });
+
+ actionFromClipboard.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent clipboardDecrypt = new Intent(DecryptActivity.this, DecryptTextActivity.class);
+ clipboardDecrypt.setAction(DecryptTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
+ startActivity(clipboardDecrypt);
+ }
+ });
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java
new file mode 100644
index 000000000..9d972d8c0
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
+import org.sufficientlysecure.keychain.util.Log;
+
+public class DecryptFilesActivity extends ActionBarActivity {
+
+ /* Intents */
+ public static final String ACTION_DECRYPT_DATA = OpenKeychainIntents.DECRYPT_DATA;
+
+ // intern
+ public static final String ACTION_DECRYPT_DATA_OPEN = Constants.INTENT_PREFIX + "DECRYPT_DATA_OPEN";
+
+ DecryptFilesFragment mFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.decrypt_files_activity);
+
+ // Handle intent actions
+ handleActions(savedInstanceState, getIntent());
+ }
+
+ /**
+ * Handles all actions with this intent
+ *
+ * @param intent
+ */
+ private void handleActions(Bundle savedInstanceState, Intent intent) {
+ String action = intent.getAction();
+ String type = intent.getType();
+ Uri uri = intent.getData();
+
+ Bundle mFileFragmentBundle = new Bundle();
+
+ /*
+ * Android's Action
+ */
+ if (Intent.ACTION_SEND.equals(action) && type != null) {
+ // When sending to Keychain Decrypt via share menu
+ // Binary via content provider (could also be files)
+ // override uri to get stream from send
+ uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
+ action = ACTION_DECRYPT_DATA;
+ } else if (Intent.ACTION_VIEW.equals(action)) {
+ // Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
+
+ // override action
+ action = ACTION_DECRYPT_DATA;
+ }
+
+ /**
+ * Main Actions
+ */
+ if (ACTION_DECRYPT_DATA.equals(action) && uri != null) {
+ mFileFragmentBundle.putParcelable(DecryptFilesFragment.ARG_URI, uri);
+
+ loadFragment(savedInstanceState, uri, false);
+ } else if (ACTION_DECRYPT_DATA_OPEN.equals(action)) {
+ loadFragment(savedInstanceState, null, true);
+ } else if (ACTION_DECRYPT_DATA.equals(action)) {
+ Log.e(Constants.TAG,
+ "Include an Uri with setData() in your Intent!");
+ }
+ }
+
+ private void loadFragment(Bundle savedInstanceState, Uri uri, boolean openDialog) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
+
+ // Create an instance of the fragment
+ mFragment = DecryptFilesFragment.newInstance(uri, openDialog);
+
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.decrypt_files_fragment_container, mFragment)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
index 7d9b2b9b3..ccfcfc2c5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
@@ -46,9 +46,10 @@ import org.sufficientlysecure.keychain.util.Notify;
import java.io.File;
-public class DecryptFileFragment extends DecryptFragment {
+public class DecryptFilesFragment extends DecryptFragment {
public static final String ARG_URI = "uri";
- public static final String ARG_FROM_VIEW_INTENT = "view_intent";
+// public static final String ARG_FROM_VIEW_INTENT = "view_intent";
+ public static final String ARG_OPEN_DIRECTLY = "open_directly";
private static final int REQUEST_CODE_INPUT = 0x00007003;
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
@@ -63,6 +64,22 @@ public class DecryptFileFragment extends DecryptFragment {
private Uri mOutputUri = null;
/**
+ * Creates new instance of this fragment
+ */
+ public static DecryptFilesFragment newInstance(Uri uri, boolean openDirectly) {
+ DecryptFilesFragment frag = new DecryptFilesFragment();
+
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_URI, uri);
+// args.putBoolean(ARG_FROM_VIEW_INTENT, fromViewIntent);
+ args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ /**
* Inflate the layout for this fragment
*/
@Override
@@ -75,9 +92,9 @@ public class DecryptFileFragment extends DecryptFragment {
view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- FileHelper.openDocument(DecryptFileFragment.this, "*/*", REQUEST_CODE_INPUT);
+ FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT);
} else {
- FileHelper.openFile(DecryptFileFragment.this, mInputUri, "*/*",
+ FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*",
REQUEST_CODE_INPUT);
}
}
@@ -97,6 +114,15 @@ public class DecryptFileFragment extends DecryptFragment {
super.onActivityCreated(savedInstanceState);
setInputUri(getArguments().<Uri>getParcelable(ARG_URI));
+
+ if (getArguments().getBoolean(ARG_OPEN_DIRECTLY, false)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT);
+ } else {
+ FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*",
+ REQUEST_CODE_INPUT);
+ }
+ }
}
private void setInputUri(Uri inputUri) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptOldActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
index f6dfed5d7..5d46b351b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptOldActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
@@ -19,83 +19,56 @@
package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.view.PagerTabStrip;
-import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
+import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.regex.Matcher;
-public class DecryptOldActivity extends DrawerActivity {
+public class DecryptTextActivity extends ActionBarActivity {
/* Intents */
- public static final String ACTION_DECRYPT = OpenKeychainIntents.DECRYPT;
-
- /* EXTRA keys for input */
+ public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
public static final String EXTRA_TEXT = OpenKeychainIntents.DECRYPT_EXTRA_TEXT;
- ViewPager mViewPager;
- PagerTabStrip mPagerTabStrip;
- PagerTabStripAdapter mTabsAdapter;
-
- Bundle mMessageFragmentBundle = new Bundle();
- Bundle mFileFragmentBundle = new Bundle();
- int mSwitchToTab = PAGER_TAB_MESSAGE;
-
- private static final int PAGER_TAB_MESSAGE = 0;
- private static final int PAGER_TAB_FILE = 1;
-
- private void initView() {
- mViewPager = (ViewPager) findViewById(R.id.decrypt_pager);
- mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip);
+ // intern
+ public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_TEXT_FROM_CLIPBOARD";
- mTabsAdapter = new PagerTabStripAdapter(this);
- mViewPager.setAdapter(mTabsAdapter);
- }
+ DecryptTextFragment mFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.decrypt_activity_old);
-
- initView();
-
- activateDrawerNavigation(savedInstanceState);
-
- // Handle intent actions, maybe changes the bundles
- handleActions(getIntent());
+ setContentView(R.layout.decrypt_text_activity);
- mTabsAdapter.addTab(DecryptMessageFragment.class,
- mMessageFragmentBundle, getString(R.string.label_message));
- mTabsAdapter.addTab(DecryptFileFragment.class,
- mFileFragmentBundle, getString(R.string.label_file));
- mViewPager.setCurrentItem(mSwitchToTab);
+ // Handle intent actions
+ handleActions(savedInstanceState, getIntent());
}
-
/**
* Handles all actions with this intent
*
* @param intent
*/
- private void handleActions(Intent intent) {
+ private void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
String type = intent.getType();
- Uri uri = intent.getData();
if (extras == null) {
extras = new Bundle();
}
+ String textData = null;
+
/*
* Android's Action
*/
@@ -106,30 +79,17 @@ public class DecryptOldActivity extends DrawerActivity {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// handle like normal text decryption, override action and extras to later
- // executeServiceMethod ACTION_DECRYPT in main actions
- extras.putString(EXTRA_TEXT, sharedText);
- action = ACTION_DECRYPT;
+ // executeServiceMethod ACTION_DECRYPT_TEXT in main actions
+ textData = sharedText;
}
- } else {
- // Binary via content provider (could also be files)
- // override uri to get stream from send
- uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
- action = ACTION_DECRYPT;
}
- } else if (Intent.ACTION_VIEW.equals(action)) {
- // Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
-
- // override action
- action = ACTION_DECRYPT;
- mFileFragmentBundle.putBoolean(DecryptFileFragment.ARG_FROM_VIEW_INTENT, true);
}
- String textData = extras.getString(EXTRA_TEXT);
-
/**
* Main Actions
*/
- if (ACTION_DECRYPT.equals(action) && textData != null) {
+ textData = extras.getString(EXTRA_TEXT);
+ if (ACTION_DECRYPT_TEXT.equals(action) && textData != null) {
Log.d(Constants.TAG, "textData not null, matching text ...");
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
if (matcher.matches()) {
@@ -137,9 +97,6 @@ public class DecryptOldActivity extends DrawerActivity {
textData = matcher.group(1);
// replace non breakable spaces
textData = textData.replaceAll("\\xa0", " ");
-
- mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
- mSwitchToTab = PAGER_TAB_MESSAGE;
} else {
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData);
if (matcher.matches()) {
@@ -147,20 +104,55 @@ public class DecryptOldActivity extends DrawerActivity {
textData = matcher.group(1);
// replace non breakable spaces
textData = textData.replaceAll("\\xa0", " ");
-
- mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
- mSwitchToTab = PAGER_TAB_MESSAGE;
} else {
+ Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
Log.d(Constants.TAG, "Nothing matched!");
}
}
- } else if (ACTION_DECRYPT.equals(action) && uri != null) {
- mFileFragmentBundle.putParcelable(DecryptFileFragment.ARG_URI, uri);
- mSwitchToTab = PAGER_TAB_FILE;
- } else if (ACTION_DECRYPT.equals(action)) {
+ } else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
+ CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
+
+ // only decrypt if clipboard content is available and a pgp message or cleartext signature
+ if (clipboardText != null) {
+ Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
+ if (!matcher.matches()) {
+ matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText);
+ }
+ if (matcher.matches()) {
+ textData = matcher.group(1);
+ } else {
+ Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
+ }
+ } else {
+ Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
+ }
+ } else if (ACTION_DECRYPT_TEXT.equals(action)) {
Log.e(Constants.TAG,
- "Include the extra 'text' or an Uri with setData() in your Intent!");
+ "Include the extra 'text' in your Intent!");
}
+
+ loadFragment(savedInstanceState, textData);
+ }
+
+
+ private void loadFragment(Bundle savedInstanceState, String ciphertext) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
+
+ // Create an instance of the fragment
+ mFragment = DecryptTextFragment.newInstance(ciphertext);
+
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.decrypt_text_fragment_container, mFragment)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index a7a630be1..13dab6673 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -24,62 +24,70 @@ import android.os.Message;
import android.os.Messenger;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.EditText;
+import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.service.results.DecryptVerifyResult;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.Notify;
-
-import java.util.regex.Matcher;
-public class DecryptMessageFragment extends DecryptFragment {
+public class DecryptTextFragment extends DecryptFragment {
public static final String ARG_CIPHERTEXT = "ciphertext";
- // view
- private EditText mMessage;
- private View mDecryptButton;
- private View mDecryptFromCLipboardButton;
-
- // model
+// // view
+ private TextView mMessage;
+// private View mDecryptButton;
+// private View mDecryptFromCLipboardButton;
+//
+// // model
private String mCiphertext;
/**
+ * Creates new instance of this fragment
+ */
+ public static DecryptTextFragment newInstance(String ciphertext) {
+ DecryptTextFragment frag = new DecryptTextFragment();
+
+ Bundle args = new Bundle();
+ args.putString(ARG_CIPHERTEXT, ciphertext);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ /**
* Inflate the layout for this fragment
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false);
-
- mMessage = (EditText) view.findViewById(R.id.message);
- mDecryptButton = view.findViewById(R.id.action_decrypt);
- mDecryptFromCLipboardButton = view.findViewById(R.id.action_decrypt_from_clipboard);
- mDecryptButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- decryptClicked();
- }
- });
- mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- decryptFromClipboardClicked();
- }
- });
+ View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
+
+ mMessage = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
+// mDecryptButton = view.findViewById(R.id.action_decrypt);
+// mDecryptFromCLipboardButton = view.findViewById(R.id.action_decrypt_from_clipboard);
+// mDecryptButton.setOnClickListener(new OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// decryptClicked();
+// }
+// });
+// mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// decryptFromClipboardClicked();
+// }
+// });
return view;
}
@Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
if (ciphertext != null) {
@@ -88,31 +96,6 @@ public class DecryptMessageFragment extends DecryptFragment {
}
}
- private void decryptClicked() {
- mCiphertext = mMessage.getText().toString();
- decryptStart(null);
- }
-
- private void decryptFromClipboardClicked() {
- CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
-
- // only decrypt if clipboard content is available and a pgp message or cleartext signature
- if (clipboardText != null) {
- Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
- if (!matcher.matches()) {
- matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText);
- }
- if (matcher.matches()) {
- mCiphertext = matcher.group(1);
- decryptStart(null);
- } else {
- Notify.showNotify(getActivity(), R.string.error_invalid_data, Notify.Style.ERROR);
- }
- } else {
- Notify.showNotify(getActivity(), R.string.error_invalid_data, Notify.Style.ERROR);
- }
- }
-
@Override
protected void decryptStart(String passphrase) {
Log.d(Constants.TAG, "decryptStart");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java
new file mode 100644
index 000000000..bed3e28ed
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.util;
+
+import org.sufficientlysecure.keychain.Constants;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
+
+public class Utf8Util {
+
+ public static boolean isValidUTF8(byte[] input) {
+ CharsetDecoder cs = Charset.forName("UTF-8").newDecoder();
+
+ try {
+ cs.decode(ByteBuffer.wrap(input));
+ return true;
+ } catch (CharacterCodingException e) {
+ return false;
+ }
+ }
+
+ public static String fromUTF8ByteArrayReplaceBadEncoding(byte[] input) {
+ final CharsetDecoder charsetDecoder = Charset.forName("UTF-8").newDecoder();
+ charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE);
+ charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+
+ try {
+ return charsetDecoder.decode(ByteBuffer.wrap(input)).toString();
+ } catch (CharacterCodingException e) {
+ Log.e(Constants.TAG, "Decoding failed!", e);
+ return charsetDecoder.replacement();
+ }
+ }
+}
diff --git a/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml b/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
new file mode 100644
index 000000000..06487a982
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v4.widget.FixedDrawerLayout
+ android:id="@+id/drawer_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/drawer_list" />
+
+ </android.support.v4.widget.FixedDrawerLayout>
+
+ <include layout="@layout/decrypt_content" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_activity.xml
new file mode 100644
index 000000000..bb0e463b3
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/decrypt_activity.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/drawer_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/decrypt_content"/>
+
+ <include layout="@layout/drawer_list" />
+
+</android.support.v4.widget.FixedDrawerLayout>
diff --git a/OpenKeychain/src/main/res/layout/decrypt_content.xml b/OpenKeychain/src/main/res/layout/decrypt_content.xml
new file mode 100644
index 000000000..1fa6ea848
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/decrypt_content.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/content_frame"
+ android:layout_marginLeft="@dimen/drawer_content_padding"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <include layout="@layout/notify_area" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="4dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="Files" />
+
+
+ <TextView
+ android:id="@+id/decrypt_files"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="Decrypt files"
+ android:drawableRight="@drawable/ic_action_collection"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:layout_marginBottom="8dp" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="32dp"
+ android:text="Text" />
+
+ <TextView
+ android:id="@+id/decrypt_from_clipboard"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="Decrypt from clipboard"
+ android:drawableRight="@drawable/ic_action_paste"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:layout_marginBottom="8dp" />
+
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
new file mode 100644
index 000000000..0380787db
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/decrypt_files_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
new file mode 100644
index 000000000..e08ecb39e
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/decrypt_text_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_message_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
index 3b4eba3ef..5e9189fd3 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_message_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
@@ -25,24 +25,25 @@
android:paddingRight="16dp"
android:orientation="vertical">
-
- <EditText
- android:id="@+id/message"
+ <TextView
+ android:id="@+id/decrypt_text_plaintext"
+ android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="0dip"
android:gravity="top"
- android:hint="@string/decrypt_content_edit_text_hint"
- android:inputType="text|textCapSentences|textMultiLine|textLongMessage|textNoSuggestions"
+ android:hint=""
android:scrollHorizontally="true"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ android:textIsSelectable="true" />
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider" />
+
<LinearLayout
- android:id="@+id/action_decrypt"
+ android:id="@+id/action_encrypt_share_plaintext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
@@ -57,7 +58,9 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:text="@string/btn_decrypt_verify_message"
+ android:text="Share plaintext"
+ android:drawableRight="@drawable/ic_action_share"
+ android:drawablePadding="8dp"
android:gravity="center_vertical"
android:layout_weight="1" />
@@ -70,11 +73,11 @@
android:background="?android:attr/listDivider" />
<ImageButton
- android:id="@+id/action_decrypt_from_clipboard"
+ android:id="@+id/action_copy_plaintext"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
- android:src="@drawable/ic_action_paste"
+ android:src="@drawable/ic_action_copy"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
diff --git a/OpenKeychain/src/main/res/layout/encrypt_file_content.xml b/OpenKeychain/src/main/res/layout/encrypt_file_content.xml
index 34f6eadda..5bf652780 100644
--- a/OpenKeychain/src/main/res/layout/encrypt_file_content.xml
+++ b/OpenKeychain/src/main/res/layout/encrypt_file_content.xml
@@ -16,7 +16,7 @@
android:orientation="vertical" />
<fragment
- android:id="@+id/certify_key_fragment"
+ android:id="@+id/encrypt_file_fragment"
android:name="org.sufficientlysecure.keychain.ui.EncryptFileFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/OpenKeychain/src/main/res/layout/encrypt_text_content.xml b/OpenKeychain/src/main/res/layout/encrypt_text_content.xml
index ee87b8a7e..809f00204 100644
--- a/OpenKeychain/src/main/res/layout/encrypt_text_content.xml
+++ b/OpenKeychain/src/main/res/layout/encrypt_text_content.xml
@@ -16,7 +16,7 @@
android:orientation="vertical" />
<fragment
- android:id="@+id/certify_key_fragment"
+ android:id="@+id/encrypt_text_fragment"
android:name="org.sufficientlysecure.keychain.ui.EncryptTextFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index e1fcf4a0b..b4f1a2753 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -521,7 +521,6 @@
<!-- hints -->
<string name="encrypt_content_edit_text_hint">"Type text"</string>
- <string name="decrypt_content_edit_text_hint">"Enter ciphertext here to decrypt and/or verify…"</string>
<!-- certs -->
<string name="cert_default">"default"</string>