converge threads after decryption, and handle PendingIntents

This commit is contained in:
Vincent Breitmoser 2015-01-29 12:57:04 +01:00
parent bcd570f884
commit 1046308a38
3 changed files with 83 additions and 41 deletions

View File

@ -51,7 +51,6 @@ import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.Searchfield;
import com.fsck.k9.view.MessageHeader;
import com.fsck.k9.ui.messageview.MessageOpenPgpViewOld;
import com.fsck.k9.view.MessageTitleView;
import com.fsck.k9.view.ViewSwitcher;
import com.fsck.k9.view.ViewSwitcher.OnSwitchCompleteListener;
@ -88,6 +87,8 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
private static final int PREVIOUS = 1;
private static final int NEXT = 2;
public static final int REQUEST_CODE_CRYPTO = 1;
public static void actionDisplaySearch(Context context, SearchSpecification search,
boolean noThreading, boolean newTask) {
actionDisplaySearch(context, search, noThreading, newTask, true);
@ -1562,12 +1563,12 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// handle OpenPGP results from PendingIntents in OpenPGP view
// must be handled in this main activity, because startIntentSenderForResult() does not support Fragments
MessageOpenPgpViewOld openPgpView = (MessageOpenPgpViewOld) findViewById(R.id.layout_decrypt_openpgp);
if (openPgpView != null && openPgpView.handleOnActivityResult(requestCode, resultCode, data)) {
return;
switch (requestCode) {
case REQUEST_CODE_CRYPTO:
mMessageViewFragment.handleCryptoResult(resultCode, data);
break;
}
}

View File

@ -329,7 +329,7 @@ public class MessageOpenPgpViewOld extends LinearLayout {
mMissingKeyPI = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
mProgress.setVisibility(View.GONE);
mFragment.setMessageWithOpenPgp(output, sigResult);
// mFragment.setMessageWithOpenPgp(output, sigResult);
} catch (UnsupportedEncodingException e) {
Log.e(K9.LOG_TAG, "UnsupportedEncodingException", e);
}

View File

@ -9,6 +9,7 @@ import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import android.app.Activity;
import android.app.DialogFragment;
@ -20,6 +21,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.Loader;
import android.net.Uri;
import android.os.AsyncTask;
@ -41,6 +43,7 @@ import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
import com.fsck.k9.activity.ChooseFolder;
import com.fsck.k9.activity.MessageList;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
@ -68,6 +71,7 @@ import com.fsck.k9.ui.message.DecodeMessageLoader;
import com.fsck.k9.ui.message.LocalMessageLoader;
import com.fsck.k9.view.MessageHeader;
import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback;
@ -136,6 +140,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
private Deque<Part> partsToDecrypt;
private OpenPgpApi openPgpApi;
private Part currentlyDecryptingPart;
private Intent currentDecryptingResult;
@Override
@ -329,15 +334,17 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
intent.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, accountName);
try {
final CountDownLatch latch = new CountDownLatch(1);
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedData();
PipedOutputStream decryptedOutputStream = getPipedOutputStreamForDecryptedData();
PipedOutputStream decryptedOutputStream = getPipedOutputStreamForDecryptedData(latch);
openPgpApi.executeApiAsync(intent, pipedInputStream, decryptedOutputStream, new IOpenPgpCallback() {
@Override
public void onReturn(Intent result) {
//TODO: check result code
//TODO: signal to AsyncTask in getPipedOutputStreamForDecryptedData() that we have a result code
//TODO: handle RESULT_INTENT
Log.d(K9.LOG_TAG, "on result!");
currentDecryptingResult = result;
latch.countDown();
}
});
} catch (IOException e) {
@ -366,40 +373,89 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
return pipedInputStream;
}
private PipedOutputStream getPipedOutputStreamForDecryptedData() throws IOException {
private PipedOutputStream getPipedOutputStreamForDecryptedData(final CountDownLatch latch) throws IOException {
PipedOutputStream decryptedOutputStream = new PipedOutputStream();
final PipedInputStream decryptedInputStream = new PipedInputStream(decryptedOutputStream);
new AsyncTask<Void, Void, DecryptedBodyPart>() {
@Override
protected DecryptedBodyPart doInBackground(Void... params) {
DecryptedBodyPart decryptedPart = null;
try {
DecryptedBodyPart decryptedPart =
DecryptStreamParser.parse(currentlyDecryptingPart, decryptedInputStream);
decryptedPart = DecryptStreamParser.parse(currentlyDecryptingPart, decryptedInputStream);
//TODO: wait for IOpenPgpCallback.onReturn() to get the result code and only use
// decryptedPart when the decryption was successful
return decryptedPart;
latch.await();
} catch (InterruptedException e) {
Log.e(K9.LOG_TAG, "we were interrupted while waiting for onReturn!", e);
} catch (Exception e) {
Log.e(K9.LOG_TAG, "Something went wrong while parsing the decrypted MIME part", e);
//TODO: pass error to main thread and display error message to user
}
return null;
return decryptedPart;
}
@Override
protected void onPostExecute(DecryptedBodyPart decryptedPart) {
if (decryptedPart == null) {
onDecryptionFailed();
} else {
onDecryptionSuccess(decryptedPart);
}
onDecryptionConverge(decryptedPart);
}
}.execute();
return decryptedOutputStream;
}
private void onDecryptionConverge (DecryptedBodyPart decryptedPart) {
try {
if (currentDecryptingResult == null) {
Log.e(K9.LOG_TAG, "internal error, we should have a result here!");
return;
}
int resultCode = currentDecryptingResult.getIntExtra(OpenPgpApi.RESULT_CODE, -1);
Log.d(K9.LOG_TAG, "result: " + resultCode);
switch (resultCode) {
case -1:
Log.e(K9.LOG_TAG, "internal error: no result code!");
return;
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
PendingIntent pendingIntent = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
if (pendingIntent == null) {
throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!");
}
try {
getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(),
MessageList.REQUEST_CODE_CRYPTO, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.e(K9.LOG_TAG, "internal error on starting pendingintent!", e);
}
return;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
Log.e(K9.LOG_TAG, "error msg: " + currentDecryptingResult.getStringExtra(OpenPgpApi.RESULT_ERROR));
onDecryptionFailed();
return;
}
case OpenPgpApi.RESULT_CODE_SUCCESS: {
onDecryptionSuccess(decryptedPart);
}
}
} finally {
currentDecryptingResult = null;
}
}
public void handleCryptoResult(int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
decryptNextPartOrStartExtractingTextAndAttachments();
} else {
onDecryptionFailed();
}
}
private void onDecryptionSuccess(DecryptedBodyPart decryptedPart) {
addDecryptedPartToMessage(decryptedPart);
onDecryptionFinished();
@ -411,7 +467,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
}
private void onDecryptionFailed() {
//TODO: display error to user?
// TODO: display error to user?
onDecryptionFinished();
}
@ -716,21 +772,6 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
destFolderName, null);
}
/**
* Used by MessageOpenPgpView
*/
public void setMessageWithOpenPgp(String decryptedData, OpenPgpSignatureResult signatureResult) {
try {
// TODO: get rid of PgpData?
PgpData data = new PgpData();
data.setDecryptedData(decryptedData);
data.setSignatureResult(signatureResult);
mMessageView.setMessage(mAccount, messageViewInfo);
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
}
}
private void showDialog(int dialogId) {
DialogFragment fragment;
switch (dialogId) {