OpenPGP improvements

Refs #43
This commit is contained in:
M66B 2018-08-25 18:51:01 +00:00
parent cd8c1fabe6
commit 2663cd1e42
4 changed files with 115 additions and 80 deletions

View File

@ -86,13 +86,15 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
private BillingClient billingClient = null;
private boolean newIntent = false;
private long attachment = -1;
private static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes
static final int REQUEST_VIEW = 1;
static final int REQUEST_UNSEEN = 2;
static final int REQUEST_OPENPGP = 3;
static final int REQUEST_ATTACHMENT_OFFSET = 10;
static final int REQUEST_ATTACHMENT = 1;
static final int REQUEST_OPENPGP = 2;
static final String ACTION_VIEW_MESSAGES = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGES";
static final String ACTION_VIEW_MESSAGE = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGE";
@ -705,11 +707,12 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
}
private void onStoreAttachment(Intent intent) {
attachment = intent.getLongExtra("id", -1);
Intent create = new Intent(Intent.ACTION_CREATE_DOCUMENT);
create.addCategory(Intent.CATEGORY_OPENABLE);
create.setType(intent.getStringExtra("type"));
create.putExtra(Intent.EXTRA_TITLE, intent.getStringExtra("name"));
startActivityForResult(create, (int) intent.getLongExtra("id", -1) + REQUEST_ATTACHMENT_OFFSET);
startActivityForResult(create, REQUEST_ATTACHMENT);
}
private void onActivatePro(Intent intent) {
@ -740,67 +743,69 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode > REQUEST_ATTACHMENT_OFFSET) {
Bundle args = new Bundle();
args.putLong("id", requestCode - REQUEST_ATTACHMENT_OFFSET);
args.putParcelable("uri", data.getData());
new SimpleTask<Void>() {
@Override
protected Void onLoad(Context context, Bundle args) throws Throwable {
long id = args.getLong("id");
Uri uri = args.getParcelable("uri");
Log.i(Helper.TAG, "View onActivityResult request=" + requestCode + " result=" + resultCode + " data=" + data);
if (resultCode == Activity.RESULT_OK)
if (requestCode == REQUEST_ATTACHMENT) {
Bundle args = new Bundle();
args.putLong("id", attachment);
args.putParcelable("uri", data.getData());
new SimpleTask<Void>() {
@Override
protected Void onLoad(Context context, Bundle args) throws Throwable {
long id = args.getLong("id");
Uri uri = args.getParcelable("uri");
File file = EntityAttachment.getFile(context, id);
File file = EntityAttachment.getFile(context, id);
ParcelFileDescriptor pfd = null;
FileOutputStream fos = null;
FileInputStream fis = null;
try {
pfd = context.getContentResolver().openFileDescriptor(uri, "w");
fos = new FileOutputStream(pfd.getFileDescriptor());
fis = new FileInputStream(file);
ParcelFileDescriptor pfd = null;
FileOutputStream fos = null;
FileInputStream fis = null;
try {
pfd = context.getContentResolver().openFileDescriptor(uri, "w");
fos = new FileOutputStream(pfd.getFileDescriptor());
fis = new FileInputStream(file);
byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE];
int read;
while ((read = fis.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
} finally {
try {
if (pfd != null)
pfd.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
try {
if (fos != null)
fos.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
try {
if (fis != null)
fis.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE];
int read;
while ((read = fis.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
} finally {
try {
if (pfd != null)
pfd.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
try {
if (fos != null)
fos.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
try {
if (fis != null)
fis.close();
} catch (Throwable ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
}
return null;
}
return null;
}
@Override
protected void onLoaded(Bundle args, Void data) {
Toast.makeText(ActivityView.this, R.string.title_attachment_saved, Toast.LENGTH_LONG).show();
}
@Override
protected void onLoaded(Bundle args, Void data) {
Toast.makeText(ActivityView.this, R.string.title_attachment_saved, Toast.LENGTH_LONG).show();
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(ActivityView.this, ex.toString(), Toast.LENGTH_LONG).show();
}
}.load(this, args);
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(ActivityView.this, ex.toString(), Toast.LENGTH_LONG).show();
}
}.load(this, args);
}
}
private BillingClientStateListener billingClientStateListener = new BillingClientStateListener() {

View File

@ -28,6 +28,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.OpenableColumns;
import android.text.Html;
@ -428,14 +429,15 @@ public class FragmentCompose extends FragmentEx {
private void onMenuEncrypt() {
Log.i(Helper.TAG, "On encrypt");
try {
if (openPgpConnection == null)
throw new IllegalArgumentException();
if (!openPgpConnection.isBound())
throw new IllegalArgumentException("OpenPgp not available");
if (!PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("pro", false))
throw new IllegalArgumentException(getString(R.string.title_pro_feature));
if (openPgpConnection == null || !openPgpConnection.isBound())
throw new IllegalArgumentException(getString(R.string.title_no_openpgp));
EntityIdentity identity = (EntityIdentity) spFrom.getSelectedItem();
if (identity == null)
throw new IllegalArgumentException("No identity selected");
throw new IllegalArgumentException(getString(R.string.title_from_missing));
Intent data = new Intent();
data.setAction(OpenPgpApi.ACTION_ENCRYPT);
@ -463,32 +465,39 @@ public class FragmentCompose extends FragmentEx {
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
Log.i(Helper.TAG, "User interaction");
PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
getActivity().startIntentSenderForResult(
startIntentSenderForResult(
pi.getIntentSender(),
ActivityCompose.REQUEST_OPENPGP,
null, 0, 0, 0);
null, 0, 0, 0,
new Bundle());
break;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
Log.e(Helper.TAG, error.getMessage());
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
throw new IllegalArgumentException(error.getMessage());
}
}
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
}
});
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(Helper.TAG, "Compose onActivityResult request=" + requestCode + " result=" + resultCode + " data=" + data);
if (resultCode == RESULT_OK) {
if (requestCode == ActivityCompose.REQUEST_ATTACHMENT) {
if (data != null)
@ -846,11 +855,16 @@ public class FragmentCompose extends FragmentEx {
new SimpleTask<Spanned>() {
@Override
protected Spanned onLoad(Context context, Bundle args) throws Throwable {
return Html.fromHtml(EntityMessage.read(context, args.getLong("id")));
String body = EntityMessage.read(context, args.getLong("id"));
if (body != null && body.startsWith("-----BEGIN PGP MESSAGE-----"))
args.putString("encrypted", body);
return Html.fromHtml(body);
}
@Override
protected void onLoaded(Bundle args, Spanned body) {
FragmentCompose.this.encrypted = args.getString("encrypted");
getActivity().invalidateOptionsMenu();
etBody.setText(body);
etBody.setSelection(0);
}

View File

@ -55,6 +55,7 @@ import android.widget.Toast;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpApi;
@ -353,6 +354,7 @@ public class FragmentMessage extends FragmentEx {
outState.putInt("tag_cc", (int) tvCc.getTag());
outState.putInt("tag_error", (int) tvError.getTag());
}
outState.putString("decrypted", decrypted);
}
@Override
@ -407,6 +409,7 @@ public class FragmentMessage extends FragmentEx {
rvAttachment.setTag(savedInstanceState.getInt("tag_attachment"));
tvError.setTag(savedInstanceState.getInt("tag_error"));
}
decrypted = savedInstanceState.getString("decrypted");
}
getActivity().invalidateOptionsMenu();
@ -424,7 +427,7 @@ public class FragmentMessage extends FragmentEx {
protected Spanned onLoad(final Context context, final Bundle args) throws Throwable {
final long id = args.getLong("id");
final boolean show_images = args.getBoolean("show_images");
String body = EntityMessage.read(context, id);
String body = (decrypted == null ? EntityMessage.read(context, id) : decrypted);
args.putInt("size", body.length());
return Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false), new Html.ImageGetter() {
@ -755,10 +758,14 @@ public class FragmentMessage extends FragmentEx {
private void onMenuDecrypt(EntityMessage message) {
Log.i(Helper.TAG, "On decrypt");
try {
if (openPgpConnection == null)
throw new IllegalArgumentException();
if (!openPgpConnection.isBound())
throw new IllegalArgumentException("OpenPgp not available");
if (!PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("pro", false))
throw new IllegalArgumentException(getString(R.string.title_pro_feature));
if (openPgpConnection == null || !openPgpConnection.isBound())
throw new IllegalArgumentException(getString(R.string.title_no_openpgp));
if (message.to == null || message.to.length == 0)
throw new IllegalArgumentException(getString(R.string.title_to_missing));
InternetAddress to = (InternetAddress) message.to[0];
@ -787,32 +794,39 @@ public class FragmentMessage extends FragmentEx {
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
Log.i(Helper.TAG, "User interaction");
PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
getActivity().startIntentSenderForResult(
startIntentSenderForResult(
pi.getIntentSender(),
ActivityView.REQUEST_OPENPGP,
null, 0, 0, 0);
null, 0, 0, 0,
new Bundle());
break;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
Log.e(Helper.TAG, error.getMessage());
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
throw new IllegalArgumentException(error.getMessage());
}
}
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
}
});
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Toast.makeText(getContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(Helper.TAG, "Message onActivityResult request=" + requestCode + " result=" + resultCode + " data=" + data);
if (resultCode == RESULT_OK) {
if (requestCode == ActivityView.REQUEST_OPENPGP && message != null) {
Log.i(Helper.TAG, "User interacted");

View File

@ -160,6 +160,7 @@
<string name="title_show_addresses">Show CC/BCC</string>
<string name="title_add_attachment">Add attachment</string>
<string name="title_no_openpgp">OpenPGP not available</string>
<string name="title_encrypt">Encrypt</string>
<string name="title_decrypt">Decrypt</string>
@ -179,6 +180,7 @@
<string name="title_legend_connected">Connected</string>
<string name="title_legend_closing">Closing</string>
<string name="title_pro_feature">This is a pro feature</string>
<string name="title_pro_activated">All pro features are activated</string>
<string name="title_pro_valid">All pro features activated</string>
<string name="title_pro_invalid">Invalid response</string>