mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-04 16:25:05 -05:00
New decrypt activity design (WIP), saner UTF8 decoding (replacing non-decodable characters)
This commit is contained in:
parent
88bbce831c
commit
53bc417f8f
@ -138,11 +138,6 @@
|
|||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_select_recipients"
|
android:label="@string/title_select_recipients"
|
||||||
android:launchMode="singleTop" />
|
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
|
<activity
|
||||||
android:name=".ui.EncryptFileActivity"
|
android:name=".ui.EncryptFileActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
@ -195,171 +190,38 @@
|
|||||||
<data android:mimeType="message/*" />
|
<data android:mimeType="message/*" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".ui.DecryptOldActivity"
|
|
||||||
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" />
|
|
||||||
|
|
||||||
<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">
|
|
||||||
<action android:name="android.intent.action.SEND" />
|
|
||||||
|
|
||||||
<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" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.DecryptActivity"
|
android:name=".ui.DecryptActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_decrypt"
|
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">
|
||||||
|
|
||||||
|
<!-- Keychain's own Actions -->
|
||||||
|
<!-- DECRYPT with text as extra -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT_TEXT" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
<!-- Android's Send Action -->
|
||||||
|
<intent-filter android:label="@string/intent_send_decrypt">
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
|
<data android:mimeType="text/*" />
|
||||||
|
<data android:mimeType="message/*" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ui.DecryptFilesActivity"
|
||||||
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
|
android:label="@string/title_decrypt"
|
||||||
android:windowSoftInputMode="stateHidden">
|
android:windowSoftInputMode="stateHidden">
|
||||||
|
|
||||||
<!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
|
<!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
|
||||||
@ -375,12 +237,6 @@
|
|||||||
<data android:mimeType="text/pgp" />
|
<data android:mimeType="text/pgp" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<!-- Keychain's own Actions -->
|
<!-- 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 -->
|
<!-- DECRYPT with data Uri -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
|
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
|
||||||
@ -396,7 +252,12 @@
|
|||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<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>
|
</intent-filter>
|
||||||
<!-- Linking "Decrypt" to file types -->
|
<!-- Linking "Decrypt" to file types -->
|
||||||
<intent-filter android:label="@string/intent_decrypt_file">
|
<intent-filter android:label="@string/intent_decrypt_file">
|
||||||
|
@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.service.results.OperationResultParcel.Log
|
|||||||
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.OperationLog;
|
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.Utf8Util;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -365,7 +366,7 @@ public class UncachedKeyRing {
|
|||||||
|
|
||||||
ArrayList<byte[]> processedUserIds = new ArrayList<byte[]>();
|
ArrayList<byte[]> processedUserIds = new ArrayList<byte[]>();
|
||||||
for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) {
|
for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) {
|
||||||
String userId = Strings.fromUTF8ByteArray(rawUserId);
|
String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
|
||||||
|
|
||||||
// check for duplicate user ids
|
// check for duplicate user ids
|
||||||
if (processedUserIds.contains(rawUserId)) {
|
if (processedUserIds.contains(rawUserId)) {
|
||||||
@ -439,7 +440,7 @@ public class UncachedKeyRing {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// warn user if the signature was made with bad encoding
|
// 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);
|
log.add(LogLevel.WARN, LogType.MSG_KC_UID_WARN_ENCODING, indent);
|
||||||
}
|
}
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
|
@ -32,6 +32,7 @@ import org.spongycastle.util.Strings;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.Utf8Util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -185,7 +186,7 @@ public class UncachedPublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
return Strings.fromUTF8ByteArray(found);
|
return Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(found);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -204,8 +205,9 @@ public class UncachedPublicKey {
|
|||||||
|
|
||||||
public ArrayList<String> getUnorderedUserIds() {
|
public ArrayList<String> getUnorderedUserIds() {
|
||||||
ArrayList<String> userIds = new ArrayList<String>();
|
ArrayList<String> userIds = new ArrayList<String>();
|
||||||
for (String userId : new IterableIterator<String>(mPublicKey.getUserIDs())) {
|
for (byte[] rawUserId : new IterableIterator<byte[]>(mPublicKey.getRawUserIDs())) {
|
||||||
userIds.add(userId);
|
// use our decoding method
|
||||||
|
userIds.add(Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId));
|
||||||
}
|
}
|
||||||
return userIds;
|
return userIds;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
|
|||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
|
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
|
||||||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||||
|
import org.sufficientlysecure.keychain.util.Utf8Util;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -437,8 +438,7 @@ public class ProviderHelper {
|
|||||||
List<UserIdItem> uids = new ArrayList<UserIdItem>();
|
List<UserIdItem> uids = new ArrayList<UserIdItem>();
|
||||||
for (byte[] rawUserId : new IterableIterator<byte[]>(
|
for (byte[] rawUserId : new IterableIterator<byte[]>(
|
||||||
masterKey.getUnorderedRawUserIds().iterator())) {
|
masterKey.getUnorderedRawUserIds().iterator())) {
|
||||||
String userId = Strings.fromUTF8ByteArray(rawUserId);
|
String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
|
||||||
Log.d(Constants.TAG, "userId: "+userId);
|
|
||||||
|
|
||||||
UserIdItem item = new UserIdItem();
|
UserIdItem item = new UserIdItem();
|
||||||
uids.add(item);
|
uids.add(item);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -46,9 +46,10 @@ import org.sufficientlysecure.keychain.util.Notify;
|
|||||||
|
|
||||||
import java.io.File;
|
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_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_INPUT = 0x00007003;
|
||||||
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
||||||
@ -62,6 +63,22 @@ public class DecryptFileFragment extends DecryptFragment {
|
|||||||
private Uri mInputUri = null;
|
private Uri mInputUri = null;
|
||||||
private Uri mOutputUri = null;
|
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
|
* Inflate the layout for this fragment
|
||||||
*/
|
*/
|
||||||
@ -75,9 +92,9 @@ public class DecryptFileFragment extends DecryptFragment {
|
|||||||
view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() {
|
view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
FileHelper.openDocument(DecryptFileFragment.this, "*/*", REQUEST_CODE_INPUT);
|
FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT);
|
||||||
} else {
|
} else {
|
||||||
FileHelper.openFile(DecryptFileFragment.this, mInputUri, "*/*",
|
FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*",
|
||||||
REQUEST_CODE_INPUT);
|
REQUEST_CODE_INPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +114,15 @@ public class DecryptFileFragment extends DecryptFragment {
|
|||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
setInputUri(getArguments().<Uri>getParcelable(ARG_URI));
|
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) {
|
private void setInputUri(Uri inputUri) {
|
@ -19,83 +19,56 @@
|
|||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.view.PagerTabStrip;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
import android.support.v4.view.ViewPager;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
||||||
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.Notify;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
public class DecryptOldActivity extends DrawerActivity {
|
public class DecryptTextActivity extends ActionBarActivity {
|
||||||
|
|
||||||
/* Intents */
|
/* Intents */
|
||||||
public static final String ACTION_DECRYPT = OpenKeychainIntents.DECRYPT;
|
public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
|
||||||
|
|
||||||
/* EXTRA keys for input */
|
|
||||||
public static final String EXTRA_TEXT = OpenKeychainIntents.DECRYPT_EXTRA_TEXT;
|
public static final String EXTRA_TEXT = OpenKeychainIntents.DECRYPT_EXTRA_TEXT;
|
||||||
|
|
||||||
ViewPager mViewPager;
|
// intern
|
||||||
PagerTabStrip mPagerTabStrip;
|
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_TEXT_FROM_CLIPBOARD";
|
||||||
PagerTabStripAdapter mTabsAdapter;
|
|
||||||
|
|
||||||
Bundle mMessageFragmentBundle = new Bundle();
|
DecryptTextFragment mFragment;
|
||||||
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);
|
|
||||||
|
|
||||||
mTabsAdapter = new PagerTabStripAdapter(this);
|
|
||||||
mViewPager.setAdapter(mTabsAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.decrypt_activity_old);
|
setContentView(R.layout.decrypt_text_activity);
|
||||||
|
|
||||||
initView();
|
// Handle intent actions
|
||||||
|
handleActions(savedInstanceState, getIntent());
|
||||||
activateDrawerNavigation(savedInstanceState);
|
|
||||||
|
|
||||||
// Handle intent actions, maybe changes the bundles
|
|
||||||
handleActions(getIntent());
|
|
||||||
|
|
||||||
mTabsAdapter.addTab(DecryptMessageFragment.class,
|
|
||||||
mMessageFragmentBundle, getString(R.string.label_message));
|
|
||||||
mTabsAdapter.addTab(DecryptFileFragment.class,
|
|
||||||
mFileFragmentBundle, getString(R.string.label_file));
|
|
||||||
mViewPager.setCurrentItem(mSwitchToTab);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all actions with this intent
|
* Handles all actions with this intent
|
||||||
*
|
*
|
||||||
* @param intent
|
* @param intent
|
||||||
*/
|
*/
|
||||||
private void handleActions(Intent intent) {
|
private void handleActions(Bundle savedInstanceState, Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
String type = intent.getType();
|
String type = intent.getType();
|
||||||
Uri uri = intent.getData();
|
|
||||||
|
|
||||||
if (extras == null) {
|
if (extras == null) {
|
||||||
extras = new Bundle();
|
extras = new Bundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String textData = null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Android's Action
|
* Android's Action
|
||||||
*/
|
*/
|
||||||
@ -106,30 +79,17 @@ public class DecryptOldActivity extends DrawerActivity {
|
|||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
if (sharedText != null) {
|
if (sharedText != null) {
|
||||||
// handle like normal text decryption, override action and extras to later
|
// handle like normal text decryption, override action and extras to later
|
||||||
// executeServiceMethod ACTION_DECRYPT in main actions
|
// executeServiceMethod ACTION_DECRYPT_TEXT in main actions
|
||||||
extras.putString(EXTRA_TEXT, sharedText);
|
textData = sharedText;
|
||||||
action = ACTION_DECRYPT;
|
|
||||||
}
|
}
|
||||||
} 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
|
* 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 ...");
|
Log.d(Constants.TAG, "textData not null, matching text ...");
|
||||||
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
|
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
@ -137,9 +97,6 @@ public class DecryptOldActivity extends DrawerActivity {
|
|||||||
textData = matcher.group(1);
|
textData = matcher.group(1);
|
||||||
// replace non breakable spaces
|
// replace non breakable spaces
|
||||||
textData = textData.replaceAll("\\xa0", " ");
|
textData = textData.replaceAll("\\xa0", " ");
|
||||||
|
|
||||||
mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
|
|
||||||
mSwitchToTab = PAGER_TAB_MESSAGE;
|
|
||||||
} else {
|
} else {
|
||||||
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData);
|
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
@ -147,20 +104,55 @@ public class DecryptOldActivity extends DrawerActivity {
|
|||||||
textData = matcher.group(1);
|
textData = matcher.group(1);
|
||||||
// replace non breakable spaces
|
// replace non breakable spaces
|
||||||
textData = textData.replaceAll("\\xa0", " ");
|
textData = textData.replaceAll("\\xa0", " ");
|
||||||
|
|
||||||
mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
|
|
||||||
mSwitchToTab = PAGER_TAB_MESSAGE;
|
|
||||||
} else {
|
} else {
|
||||||
|
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
||||||
Log.d(Constants.TAG, "Nothing matched!");
|
Log.d(Constants.TAG, "Nothing matched!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ACTION_DECRYPT.equals(action) && uri != null) {
|
} else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
|
||||||
mFileFragmentBundle.putParcelable(DecryptFileFragment.ARG_URI, uri);
|
CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
|
||||||
mSwitchToTab = PAGER_TAB_FILE;
|
|
||||||
} else if (ACTION_DECRYPT.equals(action)) {
|
// only decrypt if clipboard content is available and a pgp message or cleartext signature
|
||||||
Log.e(Constants.TAG,
|
if (clipboardText != null) {
|
||||||
"Include the extra 'text' or an Uri with setData() in your Intent!");
|
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' 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -24,62 +24,70 @@ import android.os.Message;
|
|||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.EditText;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
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.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.DecryptVerifyResult;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Notify;
|
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
public class DecryptTextFragment extends DecryptFragment {
|
||||||
|
|
||||||
public class DecryptMessageFragment extends DecryptFragment {
|
|
||||||
public static final String ARG_CIPHERTEXT = "ciphertext";
|
public static final String ARG_CIPHERTEXT = "ciphertext";
|
||||||
|
|
||||||
// view
|
// // view
|
||||||
private EditText mMessage;
|
private TextView mMessage;
|
||||||
private View mDecryptButton;
|
// private View mDecryptButton;
|
||||||
private View mDecryptFromCLipboardButton;
|
// private View mDecryptFromCLipboardButton;
|
||||||
|
//
|
||||||
// model
|
// // model
|
||||||
private String mCiphertext;
|
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
|
* Inflate the layout for this fragment
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false);
|
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
|
||||||
|
|
||||||
mMessage = (EditText) view.findViewById(R.id.message);
|
mMessage = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
|
||||||
mDecryptButton = view.findViewById(R.id.action_decrypt);
|
// mDecryptButton = view.findViewById(R.id.action_decrypt);
|
||||||
mDecryptFromCLipboardButton = view.findViewById(R.id.action_decrypt_from_clipboard);
|
// mDecryptFromCLipboardButton = view.findViewById(R.id.action_decrypt_from_clipboard);
|
||||||
mDecryptButton.setOnClickListener(new OnClickListener() {
|
// mDecryptButton.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onClick(View v) {
|
// public void onClick(View v) {
|
||||||
decryptClicked();
|
// decryptClicked();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() {
|
// mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onClick(View v) {
|
// public void onClick(View v) {
|
||||||
decryptFromClipboardClicked();
|
// decryptFromClipboardClicked();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
|
String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
|
||||||
if (ciphertext != null) {
|
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
|
@Override
|
||||||
protected void decryptStart(String passphrase) {
|
protected void decryptStart(String passphrase) {
|
||||||
Log.d(Constants.TAG, "decryptStart");
|
Log.d(Constants.TAG, "decryptStart");
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
Normal file
18
OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
Normal file
@ -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>
|
11
OpenKeychain/src/main/res/layout/decrypt_activity.xml
Normal file
11
OpenKeychain/src/main/res/layout/decrypt_activity.xml
Normal file
@ -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>
|
78
OpenKeychain/src/main/res/layout/decrypt_content.xml
Normal file
78
OpenKeychain/src/main/res/layout/decrypt_content.xml
Normal file
@ -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>
|
14
OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
Normal file
14
OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
Normal file
@ -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>
|
14
OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
Normal file
14
OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
Normal file
@ -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>
|
@ -25,24 +25,25 @@
|
|||||||
android:paddingRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
<EditText
|
android:id="@+id/decrypt_text_plaintext"
|
||||||
android:id="@+id/message"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dip"
|
android:layout_height="0dip"
|
||||||
android:gravity="top"
|
android:gravity="top"
|
||||||
android:hint="@string/decrypt_content_edit_text_hint"
|
android:hint=""
|
||||||
android:inputType="text|textCapSentences|textMultiLine|textLongMessage|textNoSuggestions"
|
|
||||||
android:scrollHorizontally="true"
|
android:scrollHorizontally="true"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1"
|
||||||
|
android:textIsSelectable="true" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dip"
|
android:layout_height="1dip"
|
||||||
android:background="?android:attr/listDivider" />
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/action_decrypt"
|
android:id="@+id/action_encrypt_share_plaintext"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
@ -57,7 +58,9 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
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:gravity="center_vertical"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
@ -70,11 +73,11 @@
|
|||||||
android:background="?android:attr/listDivider" />
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/action_decrypt_from_clipboard"
|
android:id="@+id/action_copy_plaintext"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:src="@drawable/ic_action_paste"
|
android:src="@drawable/ic_action_copy"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
style="@style/SelectableItem" />
|
style="@style/SelectableItem" />
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
android:orientation="vertical" />
|
android:orientation="vertical" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/certify_key_fragment"
|
android:id="@+id/encrypt_file_fragment"
|
||||||
android:name="org.sufficientlysecure.keychain.ui.EncryptFileFragment"
|
android:name="org.sufficientlysecure.keychain.ui.EncryptFileFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
android:orientation="vertical" />
|
android:orientation="vertical" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/certify_key_fragment"
|
android:id="@+id/encrypt_text_fragment"
|
||||||
android:name="org.sufficientlysecure.keychain.ui.EncryptTextFragment"
|
android:name="org.sufficientlysecure.keychain.ui.EncryptTextFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
@ -521,7 +521,6 @@
|
|||||||
|
|
||||||
<!-- hints -->
|
<!-- hints -->
|
||||||
<string name="encrypt_content_edit_text_hint">"Type text"</string>
|
<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 -->
|
<!-- certs -->
|
||||||
<string name="cert_default">"default"</string>
|
<string name="cert_default">"default"</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user