diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-09-15 10:19:55 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-09-15 10:19:55 +0200 |
commit | 53bc417f8f77a9f92786457281d02431ef614ca7 (patch) | |
tree | f3b09c51520a6d7b4483cd3ca17136dc94e91251 /OpenKeychain/src/main | |
parent | 88bbce831c30c1220e03439ffca4c8f390506ba6 (diff) | |
download | open-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/main')
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> |