forked from thunderbird/thunderbird-android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
604 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.fsck.k9 | ||
|
||
import android.app.Activity | ||
import android.support.annotation.StringRes | ||
import android.widget.Toast | ||
|
||
fun Activity.finishWithErrorToast(@StringRes errorRes: Int, vararg formatArgs: String) { | ||
val text = getString(errorRes, *formatArgs) | ||
Toast.makeText(this, text, Toast.LENGTH_LONG).show() | ||
finish() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
k9mail/src/main/java/com/fsck/k9/autocrypt/AutocryptTransferMessageUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.fsck.k9.autocrypt; | ||
|
||
|
||
import java.util.Date; | ||
|
||
import android.content.res.Resources; | ||
|
||
import com.fsck.k9.K9; | ||
import com.fsck.k9.R; | ||
import com.fsck.k9.mail.Address; | ||
import com.fsck.k9.mail.Flag; | ||
import com.fsck.k9.mail.Message; | ||
import com.fsck.k9.mail.Message.RecipientType; | ||
import com.fsck.k9.mail.MessagingException; | ||
import com.fsck.k9.mail.internet.MimeBodyPart; | ||
import com.fsck.k9.mail.internet.MimeHeader; | ||
import com.fsck.k9.mail.internet.MimeMessage; | ||
import com.fsck.k9.mail.internet.MimeMessageHelper; | ||
import com.fsck.k9.mail.internet.MimeMultipart; | ||
import com.fsck.k9.mail.internet.TextBody; | ||
import com.fsck.k9.mailstore.BinaryMemoryBody; | ||
|
||
|
||
public class AutocryptTransferMessageUtil { | ||
public static Message createAutocryptTransferMessage(Resources resources, byte[] data, Address address) { | ||
try { | ||
String subjectText = resources.getString(R.string.ac_transfer_msg_subject); | ||
String messageText = resources.getString(R.string.ac_transfer_msg_body); | ||
|
||
MimeBodyPart textBodyPart = new MimeBodyPart(new TextBody(messageText)); | ||
MimeBodyPart dataBodyPart = new MimeBodyPart(new BinaryMemoryBody(data, "7bit")); | ||
dataBodyPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "application/autocrypt-setup"); | ||
dataBodyPart.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, "attachment; filename=\"autocrypt-setup-message\""); | ||
|
||
MimeMultipart messageBody = MimeMultipart.newInstance(); | ||
messageBody.addBodyPart(textBodyPart); | ||
messageBody.addBodyPart(dataBodyPart); | ||
|
||
MimeMessage message = new MimeMessage(); | ||
MimeMessageHelper.setBody(message, messageBody); | ||
|
||
Date nowDate = new Date(); | ||
|
||
message.setFlag(Flag.X_DOWNLOADED_FULL, true); | ||
message.setSubject(subjectText); | ||
message.setHeader("Autocrypt-Setup-Message", "v1"); | ||
message.setInternalDate(nowDate); | ||
message.addSentDate(nowDate, K9.hideTimeZone()); | ||
message.setFrom(address); | ||
message.setRecipients(RecipientType.TO, new Address[] { address }); | ||
|
||
return message; | ||
} catch (MessagingException e) { | ||
throw new AssertionError(e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.fsck.k9.crypto | ||
|
||
import org.koin.dsl.module.applicationContext | ||
import org.openintents.openpgp.OpenPgpApiManager | ||
|
||
val openPgpModule = applicationContext { | ||
factory { params -> OpenPgpApiManager(get(), params["lifecycle"]) } | ||
} |
132 changes: 132 additions & 0 deletions
132
k9mail/src/main/java/com/fsck/k9/ui/endtoend/AutocryptKeyTransferActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package com.fsck.k9.ui.endtoend | ||
|
||
|
||
import android.app.PendingIntent | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.content.IntentSender.SendIntentException | ||
import android.os.Build | ||
import android.os.Bundle | ||
import android.transition.TransitionInflater | ||
import android.transition.TransitionManager | ||
import android.view.View | ||
import com.fsck.k9.R | ||
import com.fsck.k9.activity.K9Activity | ||
import com.fsck.k9.finishWithErrorToast | ||
import com.fsck.k9.mail.TransportProvider | ||
import com.fsck.k9.view.StatusIndicator | ||
import kotlinx.android.synthetic.main.crypto_key_transfer.* | ||
import org.koin.android.architecture.ext.viewModel | ||
import org.koin.android.ext.android.inject | ||
import org.openintents.openpgp.OpenPgpApiManager | ||
import timber.log.Timber | ||
|
||
|
||
class AutocryptKeyTransferActivity : K9Activity() { | ||
private val viewModel: AutocryptKeyTransferViewModel by viewModel() | ||
private val transportProvider: TransportProvider by inject() | ||
private val openPgpApiManager: OpenPgpApiManager by inject { mapOf("lifecycle" to lifecycle) } | ||
private lateinit var presenter: AutocryptKeyTransferPresenter | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.crypto_key_transfer) | ||
|
||
val account = intent.getStringExtra(EXTRA_ACCOUNT) | ||
|
||
presenter = AutocryptKeyTransferPresenter(applicationContext, this, viewModel, openPgpApiManager, transportProvider) | ||
presenter.initFromIntent(account) | ||
|
||
transfer_send_button.setOnClickListener { presenter.onClickTransferSend() } | ||
transfer_show_code_button.setOnClickListener { presenter.onClickShowTransferCode() } | ||
} | ||
|
||
fun setAddress(address: String) { | ||
transfer_address_1.text = address | ||
transfer_address_2.text = address | ||
} | ||
|
||
fun sceneBegin() { | ||
transfer_send_button.visibility = View.VISIBLE | ||
transfer_msg_info.visibility = View.VISIBLE | ||
transfer_layout_generating.visibility = View.GONE | ||
transfer_layout_sending.visibility = View.GONE | ||
transfer_layout_finish.visibility = View.GONE | ||
transfer_show_code_button.visibility = View.GONE | ||
} | ||
|
||
fun sceneGeneratingAndSending() { | ||
setupSceneTransition() | ||
|
||
transfer_send_button.visibility = View.GONE | ||
transfer_msg_info.visibility = View.GONE | ||
transfer_layout_generating.visibility = View.VISIBLE | ||
transfer_layout_sending.visibility = View.VISIBLE | ||
transfer_layout_finish.visibility = View.GONE | ||
transfer_show_code_button.visibility = View.GONE | ||
} | ||
|
||
fun sceneFinished() { | ||
setupSceneTransition() | ||
|
||
transfer_send_button.visibility = View.GONE | ||
transfer_msg_info.visibility = View.GONE | ||
transfer_layout_generating.visibility = View.VISIBLE | ||
transfer_layout_sending.visibility = View.VISIBLE | ||
transfer_layout_finish.visibility = View.VISIBLE | ||
transfer_show_code_button.visibility = View.VISIBLE | ||
} | ||
|
||
fun setLoadingStateGenerating() { | ||
transfer_progress_generating.setDisplayedChild(StatusIndicator.Status.PROGRESS) | ||
transfer_progress_sending.setDisplayedChild(StatusIndicator.Status.IDLE) | ||
} | ||
|
||
fun setLoadingStateSending() { | ||
transfer_progress_generating.setDisplayedChild(StatusIndicator.Status.OK) | ||
transfer_progress_sending.setDisplayedChild(StatusIndicator.Status.PROGRESS) | ||
} | ||
|
||
fun setLoadingStateSendingFailed() { | ||
transfer_progress_generating.setDisplayedChild(StatusIndicator.Status.OK) | ||
transfer_progress_sending.setDisplayedChild(StatusIndicator.Status.ERROR) | ||
} | ||
|
||
fun setLoadingStateFinished() { | ||
transfer_progress_generating.setDisplayedChild(StatusIndicator.Status.OK) | ||
transfer_progress_sending.setDisplayedChild(StatusIndicator.Status.OK) | ||
} | ||
|
||
fun finishWithInvalidAccountError() { | ||
finishWithErrorToast(R.string.toast_account_not_found) | ||
} | ||
|
||
fun finishWithProviderConnectError(providerName: String) { | ||
finishWithErrorToast(R.string.toast_openpgp_provider_error, providerName) | ||
} | ||
|
||
fun launchUserInteractionPendingIntent(pendingIntent: PendingIntent) { | ||
try { | ||
startIntentSender(pendingIntent.intentSender, null, 0, 0, 0) | ||
} catch (e: SendIntentException) { | ||
Timber.e(e) | ||
} | ||
} | ||
|
||
private fun setupSceneTransition() { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||
val transition = TransitionInflater.from(this).inflateTransition(R.transition.transfer_transitions) | ||
TransitionManager.beginDelayedTransition(findViewById(android.R.id.content), transition) | ||
} | ||
} | ||
|
||
companion object { | ||
private const val EXTRA_ACCOUNT = "account" | ||
|
||
fun createIntent(context: Context, accountUuid: String): Intent { | ||
val intent = Intent(context, AutocryptKeyTransferActivity::class.java) | ||
intent.putExtra(EXTRA_ACCOUNT, accountUuid) | ||
return intent | ||
} | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
k9mail/src/main/java/com/fsck/k9/ui/endtoend/AutocryptKeyTransferLiveData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.fsck.k9.ui.endtoend | ||
|
||
import android.app.PendingIntent | ||
import android.arch.lifecycle.LiveData | ||
import android.content.Intent | ||
import android.content.res.Resources | ||
import com.fsck.k9.Account | ||
import com.fsck.k9.autocrypt.AutocryptTransferMessageUtil | ||
import com.fsck.k9.mail.Address | ||
import com.fsck.k9.mail.Message | ||
import kotlinx.coroutines.experimental.android.UI | ||
import kotlinx.coroutines.experimental.launch | ||
import org.jetbrains.anko.coroutines.experimental.bg | ||
import org.openintents.openpgp.util.OpenPgpApi | ||
import java.io.ByteArrayOutputStream | ||
import java.io.InputStream | ||
|
||
class AutocryptKeyTransferLiveData : LiveData<AutocryptKeyTransferLiveData.AutocryptSetupMessage>() { | ||
fun loadAutocryptSetupMessageAsync(resources: Resources, openPgpApi: OpenPgpApi, account: Account) { | ||
launch(UI) { | ||
val setupMessage = bg { | ||
loadAutocryptSetupMessage(resources, openPgpApi, account) | ||
} | ||
|
||
value = setupMessage.await() | ||
} | ||
} | ||
|
||
private fun loadAutocryptSetupMessage(resources: Resources, openPgpApi: OpenPgpApi, account: Account): AutocryptSetupMessage { | ||
val keyIds = longArrayOf(account.openPgpKey) | ||
val address = Address.parse(account.getIdentity(0).email)[0] | ||
|
||
val intent = Intent(OpenPgpApi.ACTION_AUTOCRYPT_KEY_TRANSFER) | ||
intent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIds) | ||
val baos = ByteArrayOutputStream() | ||
val result = openPgpApi.executeApi(intent, null as InputStream?, baos) | ||
|
||
val keyData = baos.toByteArray() | ||
val pi: PendingIntent = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT) | ||
|
||
val setupMessage = AutocryptTransferMessageUtil.createAutocryptTransferMessage(resources, keyData, address) | ||
|
||
return AutocryptSetupMessage(pi, setupMessage) | ||
} | ||
|
||
data class AutocryptSetupMessage(val showTransferCodePi: PendingIntent, val setupMessage: Message) | ||
} |
Oops, something went wrong.