diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java
index f0636ac810..4601854f92 100644
--- a/app/src/main/java/eu/faircode/email/AdapterMessage.java
+++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java
@@ -5853,11 +5853,11 @@ public class AdapterMessage extends RecyclerView.Adapter.
+
+ Copyright 2018-2022 by Marcel Bokhorst (M66B)
+*/
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.ArrowKeyMovementMethod;
+import android.text.style.URLSpan;
+import android.util.Base64;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+
+import com.google.android.material.textfield.TextInputLayout;
+
+import org.jsoup.nodes.Element;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+
+public class ProtectedContent {
+ static final int MAX_PROTECTED_TEXT = 1500;
+ private static final int DECRYPT_ITERATIONS = 120000;
+ private static final int DECRYPT_KEYLEN = 256;
+ private static final String DECRYPT_DERIVATION = "PBKDF2WithHmacSHA512";
+ private static final int DECRYPT_TAGLEN = 128;
+ private static final String DECRYPT_TRANSFORMATION = "AES/GCM/NoPadding";
+ private static final String DECRYPT_URL = "https://fairemail.net/decrypt/";
+
+ static Uri toUri(Context context, String html, String password)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+ if (html.length() > MAX_PROTECTED_TEXT)
+ throw new IllegalArgumentException(context.getString(R.string.title_style_protect_size));
+
+ SecureRandom random = new SecureRandom();
+
+ byte[] salt = new byte[16]; // 128 bits
+ random.nextBytes(salt);
+
+ byte[] iv = new byte[12]; // 96 bites
+ random.nextBytes(iv);
+
+ // Iterations = 120,000; Keylength = 256 bits = 32 bytes
+ PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, DECRYPT_ITERATIONS, DECRYPT_KEYLEN);
+
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(DECRYPT_DERIVATION);
+ SecretKey key = skf.generateSecret(spec);
+
+ // Authentication tag length = 128 bits = 16 bytes
+ GCMParameterSpec parameterSpec = new GCMParameterSpec(DECRYPT_TAGLEN, iv);
+
+ final Cipher cipher = Cipher.getInstance(DECRYPT_TRANSFORMATION);
+ cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
+
+ byte[] cipherText = cipher.doFinal(html.getBytes(StandardCharsets.UTF_8));
+
+ ByteBuffer out = ByteBuffer.allocate(1 + salt.length + iv.length + cipherText.length);
+ out.put((byte) 1); // version
+ out.put(salt);
+ out.put(iv);
+ out.put(cipherText);
+
+ String fragment = Base64.encodeToString(out.array(), Base64.URL_SAFE | Base64.NO_WRAP);
+ return Uri.parse(DECRYPT_URL + "#" + fragment);
+ }
+
+ static String fromUri(Context context, Uri uri, String password) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+ byte[] msg = Base64.decode(uri.getFragment(), Base64.URL_SAFE | Base64.NO_WRAP);
+
+ int version = msg[0];
+ if (version > 1)
+ throw new IllegalArgumentException("Please update the app");
+
+ byte[] salt = new byte[16]; // 128 bits
+ System.arraycopy(msg, 1, salt, 0, salt.length);
+
+ byte[] iv = new byte[12]; // 96 bites
+ System.arraycopy(msg, 1 + salt.length, iv, 0, iv.length);
+
+ byte[] encrypted = new byte[msg.length - 1 - salt.length - iv.length];
+ System.arraycopy(msg, 1 + salt.length + iv.length, encrypted, 0, encrypted.length);
+
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DECRYPT_DERIVATION);
+ KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, DECRYPT_ITERATIONS, DECRYPT_KEYLEN);
+ SecretKey secret = keyFactory.generateSecret(keySpec);
+ Cipher cipher = Cipher.getInstance(DECRYPT_TRANSFORMATION);
+ IvParameterSpec ivSpec = new IvParameterSpec(iv);
+ cipher.init(Cipher.DECRYPT_MODE, secret, ivSpec);
+ byte[] decrypted = cipher.doFinal(encrypted);
+
+ return new String(decrypted, StandardCharsets.UTF_8);
+ }
+
+ static boolean isProtectedContent(Uri uri) {
+ return uri.toString().startsWith(DECRYPT_URL);
+ }
+
+ public static final class FragmentDialogDecrypt extends FragmentDialogBase {
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ Bundle args = getArguments();
+
+ final Context context = getContext();
+ final View view = LayoutInflater.from(context).inflate(R.layout.dialog_decrypt, null);
+ final TextInputLayout tilPassword = view.findViewById(R.id.tilPassword);
+ final Button btnDecrypt = view.findViewById(R.id.btnDecrypt);
+ final TextView tvContent = view.findViewById(R.id.tvContent);
+ final TextView tvError = view.findViewById(R.id.tvError);
+ final TextView tvErrorDetail = view.findViewById(R.id.tvErrorDetail);
+
+ tilPassword.setVisibility(View.VISIBLE);
+ btnDecrypt.setVisibility(View.VISIBLE);
+ tvContent.setVisibility(View.GONE);
+ tvError.setVisibility(View.GONE);
+ tvErrorDetail.setVisibility(View.GONE);
+
+ String password = args.getString("password");
+ tilPassword.getEditText().setText(password);
+ btnDecrypt.setEnabled(!TextUtils.isEmpty(password));
+
+ tilPassword.getEditText().addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String password = s.toString();
+ btnDecrypt.setEnabled(!TextUtils.isEmpty(password));
+ args.putString("password", password);
+ }
+ });
+
+ btnDecrypt.setEnabled(false);
+
+ tvContent.setMovementMethod(new ArrowKeyMovementMethod() {
+ private GestureDetector gestureDetector = new GestureDetector(context,
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapUp(MotionEvent event) {
+ return onClick(event);
+ }
+
+ private boolean onClick(MotionEvent event) {
+ Spannable buffer = (Spannable) tvContent.getText();
+ int off = Helper.getOffset(tvContent, buffer, event);
+
+ URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
+ if (link.length > 0) {
+ String url = link[0].getURL();
+ Uri uri = Uri.parse(url);
+
+ int start = buffer.getSpanStart(link[0]);
+ int end = buffer.getSpanEnd(link[0]);
+ String title = (start < 0 || end < 0 || end <= start
+ ? null : buffer.subSequence(start, end).toString());
+ if (url.equals(title))
+ title = null;
+
+ Bundle args = new Bundle();
+ args.putParcelable("uri", uri);
+ args.putString("title", title);
+
+ FragmentDialogOpenLink fragment = new FragmentDialogOpenLink();
+ fragment.setArguments(args);
+ fragment.show(getParentFragmentManager(), "open:link");
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+
+ @Override
+ public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
+ return gestureDetector.onTouchEvent(event);
+ }
+ });
+
+ btnDecrypt.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ new SimpleTask() {
+ @Override
+ protected void onPreExecute(Bundle args) {
+ tilPassword.setEnabled(false);
+ btnDecrypt.setEnabled(false);
+ tvError.setVisibility(View.GONE);
+ tvErrorDetail.setVisibility(View.GONE);
+ }
+
+ @Override
+ protected void onPostExecute(Bundle args) {
+ tilPassword.setEnabled(true);
+ btnDecrypt.setEnabled(true);
+ }
+
+ @Override
+ protected Spanned onExecute(Context context, Bundle args) throws Throwable {
+ Uri uri = args.getParcelable("uri");
+ String password = args.getString("password");
+
+ String html = ProtectedContent.fromUri(context, uri, password);
+
+ return HtmlHelper.fromHtml(html, new HtmlHelper.ImageGetterEx() {
+ @Override
+ public Drawable getDrawable(Element element) {
+ return ImageHelper.decodeImage(context,
+ -1, element, true, 0, 1.0f, tvContent);
+ }
+ }, null, context);
+ }
+
+ @Override
+ protected void onExecuted(Bundle args, Spanned content) {
+ tilPassword.setVisibility(View.GONE);
+ btnDecrypt.setVisibility(View.GONE);
+ tvContent.setText(content);
+ tvContent.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ protected void onException(Bundle args, Throwable ex) {
+ tvError.setText(ex.getMessage());
+ tvErrorDetail.setText(ex.toString());
+ tvError.setVisibility(View.VISIBLE);
+ tvErrorDetail.setVisibility(View.VISIBLE);
+ }
+ }.execute(FragmentDialogDecrypt.this, args, "decypt");
+ }
+ });
+
+ tilPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ btnDecrypt.performClick();
+ return true;
+ } else
+ return false;
+ }
+ });
+
+ if (!TextUtils.isEmpty(password))
+ btnDecrypt.post(new Runnable() {
+ @Override
+ public void run() {
+ btnDecrypt.performClick();
+ }
+ });
+
+ Dialog dialog = new AlertDialog.Builder(context)
+ .setView(view)
+ .setNegativeButton(android.R.string.cancel, null)
+ .create();
+
+ dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+
+ return dialog;
+ }
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/StyleHelper.java b/app/src/main/java/eu/faircode/email/StyleHelper.java
index 3d8f574a35..cd85e841ae 100644
--- a/app/src/main/java/eu/faircode/email/StyleHelper.java
+++ b/app/src/main/java/eu/faircode/email/StyleHelper.java
@@ -19,7 +19,6 @@ package eu.faircode.email;
Copyright 2018-2022 by Marcel Bokhorst (M66B)
*/
-import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -41,7 +40,6 @@ import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
-import android.text.method.ArrowKeyMovementMethod;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.BulletSpan;
@@ -57,22 +55,17 @@ import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.util.Base64;
import android.util.Pair;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
-import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.ContextCompat;
@@ -89,32 +82,13 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-
public class StyleHelper {
- private static final int MAX_PROTECTED_TEXT = 1500;
- private static final int DECRYPT_ITERATIONS = 120000;
- private static final int DECRYPT_KEYLEN = 256;
- private static final String DECRYPT_DERIVATION = "PBKDF2WithHmacSHA512";
- private static final int DECRYPT_TAGLEN = 128;
- private static final String DECRYPT_TRANSFORMATION = "AES/GCM/NoPadding";
- private static final String DECRYPT_URL = "https://fairemail.net/decrypt/";
-
private static final List> CLEAR_STYLES = Collections.unmodifiableList(Arrays.asList(
StyleSpan.class,
UnderlineSpan.class,
@@ -598,11 +572,11 @@ public class StyleHelper {
}
boolean toolong = false;
- if (end - start > MAX_PROTECTED_TEXT) {
+ if (end - start > ProtectedContent.MAX_PROTECTED_TEXT) {
toolong = true;
} else {
String html = getProtectedContent((Spanned) edit.subSequence(start, end));
- if (html.length() > MAX_PROTECTED_TEXT)
+ if (html.length() > ProtectedContent.MAX_PROTECTED_TEXT)
toolong = true;
}
if (toolong) {
@@ -637,52 +611,18 @@ public class StyleHelper {
args.putInt("start", start);
args.putInt("end", end);
- new SimpleTask() {
+ new SimpleTask() {
@Override
- protected String onExecute(Context context, Bundle args) throws Throwable {
+ protected Uri onExecute(Context context, Bundle args) throws Throwable {
Spanned text = (Spanned) args.getCharSequence("text");
String password = args.getString("password");
String html = getProtectedContent(text);
- if (html.length() > MAX_PROTECTED_TEXT)
- throw new IllegalArgumentException(context.getString(R.string.title_style_protect_size));
-
- SecureRandom random = new SecureRandom();
-
- byte[] salt = new byte[16]; // 128 bits
- random.nextBytes(salt);
-
- byte[] iv = new byte[12]; // 96 bites
- random.nextBytes(iv);
-
- // Iterations = 120,000; Keylength = 256 bits = 32 bytes
- PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, DECRYPT_ITERATIONS, DECRYPT_KEYLEN);
-
- SecretKeyFactory skf = SecretKeyFactory.getInstance(DECRYPT_DERIVATION);
- SecretKey key = skf.generateSecret(spec);
-
- // Authentication tag length = 128 bits = 16 bytes
- GCMParameterSpec parameterSpec = new GCMParameterSpec(DECRYPT_TAGLEN, iv);
-
- final Cipher cipher = Cipher.getInstance(DECRYPT_TRANSFORMATION);
- cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
-
- byte[] cipherText = cipher.doFinal(html.getBytes(StandardCharsets.UTF_8));
-
- ByteBuffer out = ByteBuffer.allocate(1 + salt.length + iv.length + cipherText.length);
- out.put((byte) 1); // version
- out.put(salt);
- out.put(iv);
- out.put(cipherText);
-
- String fragment = Base64.encodeToString(out.array(), Base64.URL_SAFE | Base64.NO_WRAP);
- String url = DECRYPT_URL + "#" + fragment;
-
- return url;
+ return ProtectedContent.toUri(context, html, password);
}
@Override
- protected void onExecuted(Bundle args, String url) {
+ protected void onExecuted(Bundle args, Uri uri) {
if (etBody.getSelectionStart() != start ||
etBody.getSelectionEnd() != end)
return;
@@ -690,7 +630,7 @@ public class StyleHelper {
String title = context.getString(R.string.title_decrypt);
edit.delete(start, end);
edit.insert(start, title);
- edit.setSpan(new URLSpan(url), start, start + title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ edit.setSpan(new URLSpan(uri.toString()), start, start + title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
etBody.setSelection(start + title.length());
}
@@ -1478,203 +1418,5 @@ public class StyleHelper {
}
}
- public static boolean isProtectedContent(Uri uri) {
- return uri.toString().startsWith(DECRYPT_URL);
- }
-
- public static final class FragmentDialogDecrypt extends FragmentDialogBase {
- @NonNull
- @Override
- public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
- Bundle args = getArguments();
-
- final Context context = getContext();
- final View view = LayoutInflater.from(context).inflate(R.layout.dialog_decrypt, null);
- final TextInputLayout tilPassword = view.findViewById(R.id.tilPassword);
- final Button btnDecrypt = view.findViewById(R.id.btnDecrypt);
- final TextView tvContent = view.findViewById(R.id.tvContent);
- final TextView tvError = view.findViewById(R.id.tvError);
- final TextView tvErrorDetail = view.findViewById(R.id.tvErrorDetail);
-
- tilPassword.setVisibility(View.VISIBLE);
- btnDecrypt.setVisibility(View.VISIBLE);
- tvContent.setVisibility(View.GONE);
- tvError.setVisibility(View.GONE);
- tvErrorDetail.setVisibility(View.GONE);
-
- String password = args.getString("password");
- tilPassword.getEditText().setText(password);
- btnDecrypt.setEnabled(!TextUtils.isEmpty(password));
-
- tilPassword.getEditText().addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // Do nothing
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // Do nothing
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- String password = s.toString();
- btnDecrypt.setEnabled(!TextUtils.isEmpty(password));
- args.putString("password", password);
- }
- });
-
- btnDecrypt.setEnabled(false);
-
- tvContent.setMovementMethod(new ArrowKeyMovementMethod() {
- private GestureDetector gestureDetector = new GestureDetector(context,
- new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onSingleTapUp(MotionEvent event) {
- return onClick(event);
- }
-
- private boolean onClick(MotionEvent event) {
- Spannable buffer = (Spannable) tvContent.getText();
- int off = Helper.getOffset(tvContent, buffer, event);
-
- URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
- if (link.length > 0) {
- String url = link[0].getURL();
- Uri uri = Uri.parse(url);
-
- int start = buffer.getSpanStart(link[0]);
- int end = buffer.getSpanEnd(link[0]);
- String title = (start < 0 || end < 0 || end <= start
- ? null : buffer.subSequence(start, end).toString());
- if (url.equals(title))
- title = null;
-
- Bundle args = new Bundle();
- args.putParcelable("uri", uri);
- args.putString("title", title);
-
- FragmentDialogOpenLink fragment = new FragmentDialogOpenLink();
- fragment.setArguments(args);
- fragment.show(getParentFragmentManager(), "open:link");
-
- return true;
- }
-
- return false;
- }
- });
-
- @Override
- public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
- return gestureDetector.onTouchEvent(event);
- }
- });
-
- btnDecrypt.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new SimpleTask() {
- @Override
- protected void onPreExecute(Bundle args) {
- tilPassword.setEnabled(false);
- btnDecrypt.setEnabled(false);
- tvError.setVisibility(View.GONE);
- tvErrorDetail.setVisibility(View.GONE);
- }
-
- @Override
- protected void onPostExecute(Bundle args) {
- tilPassword.setEnabled(true);
- btnDecrypt.setEnabled(true);
- }
-
- @Override
- protected Spanned onExecute(Context context, Bundle args) throws Throwable {
- Uri uri = args.getParcelable("uri");
- String password = args.getString("password");
-
- byte[] msg = Base64.decode(uri.getFragment(), Base64.URL_SAFE | Base64.NO_WRAP);
-
- int version = msg[0];
-
- byte[] salt = new byte[16]; // 128 bits
- System.arraycopy(msg, 1, salt, 0, salt.length);
-
- byte[] iv = new byte[12]; // 96 bites
- System.arraycopy(msg, 1 + salt.length, iv, 0, iv.length);
-
- byte[] encrypted = new byte[msg.length - 1 - salt.length - iv.length];
- System.arraycopy(msg, 1 + salt.length + iv.length, encrypted, 0, encrypted.length);
-
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DECRYPT_DERIVATION);
- KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, DECRYPT_ITERATIONS, DECRYPT_KEYLEN);
- SecretKey secret = keyFactory.generateSecret(keySpec);
- Cipher cipher = Cipher.getInstance(DECRYPT_TRANSFORMATION);
- IvParameterSpec ivSpec = new IvParameterSpec(iv);
- cipher.init(Cipher.DECRYPT_MODE, secret, ivSpec);
- byte[] decrypted = cipher.doFinal(encrypted);
-
- String html = new String(decrypted, StandardCharsets.UTF_8);
-
- return HtmlHelper.fromHtml(html, new HtmlHelper.ImageGetterEx() {
- @Override
- public Drawable getDrawable(Element element) {
- return ImageHelper.decodeImage(context,
- -1, element, true, 0, 1.0f, tvContent);
- }
- }, null, context);
- }
-
- @Override
- protected void onExecuted(Bundle args, Spanned content) {
- tilPassword.setVisibility(View.GONE);
- btnDecrypt.setVisibility(View.GONE);
- tvContent.setText(content);
- tvContent.setVisibility(View.VISIBLE);
- }
-
- @Override
- protected void onException(Bundle args, Throwable ex) {
- tvError.setText(ex.getMessage());
- tvErrorDetail.setText(ex.toString());
- tvError.setVisibility(View.VISIBLE);
- tvErrorDetail.setVisibility(View.VISIBLE);
- }
- }.execute(FragmentDialogDecrypt.this, args, "decypt");
- }
- });
-
- tilPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- btnDecrypt.performClick();
- return true;
- } else
- return false;
- }
- });
-
- if (!TextUtils.isEmpty(password))
- btnDecrypt.post(new Runnable() {
- @Override
- public void run() {
- btnDecrypt.performClick();
- }
- });
-
- Dialog dialog = new AlertDialog.Builder(context)
- .setView(view)
- .setNegativeButton(android.R.string.cancel, null)
- .create();
-
- dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
-
- return dialog;
- }
- }
-
//TextUtils.dumpSpans(text, new LogPrinter(android.util.Log.INFO, "FairEmail"), "afterTextChanged ");
}