aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-09-15 10:19:55 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-09-15 10:19:55 +0200
commit53bc417f8f77a9f92786457281d02431ef614ca7 (patch)
treef3b09c51520a6d7b4483cd3ca17136dc94e91251 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain
parent88bbce831c30c1220e03439ffca4c8f390506ba6 (diff)
downloadopen-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.tar.gz
open-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.tar.bz2
open-keychain-53bc417f8f77a9f92786457281d02431ef614ca7.zip
New decrypt activity design (WIP), saner UTF8 decoding (replacing non-decodable characters)
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java57
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java113
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java)34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptOldActivity.java)130
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java)101
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java53
9 files changed, 366 insertions, 139 deletions
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();
+ }
+ }
+}