Add support for background activity start mode
See https://developer.android.com/about/versions/14/behavior-changes-14#background-activity-restrictions
This commit is contained in:
parent
62fbfa0102
commit
1c4925b05d
10 changed files with 109 additions and 57 deletions
|
@ -118,6 +118,7 @@ import com.fsck.k9.ui.helper.SizeFormatter;
|
||||||
import com.fsck.k9.ui.messagelist.DefaultFolderProvider;
|
import com.fsck.k9.ui.messagelist.DefaultFolderProvider;
|
||||||
import org.openintents.openpgp.OpenPgpApiManager;
|
import org.openintents.openpgp.OpenPgpApiManager;
|
||||||
import org.openintents.openpgp.util.OpenPgpApi;
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpIntentStarter;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1622,7 +1623,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
||||||
public void onMessageBuildReturnPendingIntent(PendingIntent pendingIntent, int requestCode) {
|
public void onMessageBuildReturnPendingIntent(PendingIntent pendingIntent, int requestCode) {
|
||||||
requestCode |= REQUEST_MASK_MESSAGE_BUILDER;
|
requestCode |= REQUEST_MASK_MESSAGE_BUILDER;
|
||||||
try {
|
try {
|
||||||
startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null, 0, 0, 0);
|
OpenPgpIntentStarter.startIntentSenderForResult(this, pendingIntent.getIntentSender(), requestCode);
|
||||||
} catch (SendIntentException e) {
|
} catch (SendIntentException e) {
|
||||||
Timber.e(e, "Error starting pending intent from builder!");
|
Timber.e(e, "Error starting pending intent from builder!");
|
||||||
}
|
}
|
||||||
|
@ -1631,9 +1632,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
||||||
public void launchUserInteractionPendingIntent(PendingIntent pendingIntent, int requestCode) {
|
public void launchUserInteractionPendingIntent(PendingIntent pendingIntent, int requestCode) {
|
||||||
requestCode |= REQUEST_MASK_RECIPIENT_PRESENTER;
|
requestCode |= REQUEST_MASK_RECIPIENT_PRESENTER;
|
||||||
try {
|
try {
|
||||||
startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null, 0, 0, 0);
|
OpenPgpIntentStarter.startIntentSenderForResult(this, pendingIntent.getIntentSender(), requestCode);
|
||||||
} catch (SendIntentException e) {
|
} catch (SendIntentException e) {
|
||||||
e.printStackTrace();
|
Timber.e(e, "Error starting pending intent from builder!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1689,11 +1690,10 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
|
public boolean startIntentSenderForMessageLoaderHelper(IntentSender intentSender, int requestCode) {
|
||||||
int flagsMask, int flagValues, int extraFlags) {
|
|
||||||
try {
|
try {
|
||||||
requestCode |= REQUEST_MASK_LOADER_HELPER;
|
requestCode |= REQUEST_MASK_LOADER_HELPER;
|
||||||
startIntentSenderForResult(si, requestCode, fillIntent, flagsMask, flagValues, extraFlags);
|
OpenPgpIntentStarter.startIntentSenderForResult(MessageCompose.this, intentSender, requestCode);
|
||||||
} catch (SendIntentException e) {
|
} catch (SendIntentException e) {
|
||||||
Timber.e(e, "Irrecoverable error calling PendingIntent!");
|
Timber.e(e, "Irrecoverable error calling PendingIntent!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,14 +357,12 @@ public class MessageLoaderHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
|
public boolean startPendingIntentForCryptoHelper(IntentSender intentSender, int requestCode) {
|
||||||
int flagsMask, int flagValues, int extraFlags) {
|
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
throw new IllegalStateException("unexpected call when callback is already detached");
|
throw new IllegalStateException("unexpected call when callback is already detached");
|
||||||
}
|
}
|
||||||
|
|
||||||
return callback.startIntentSenderForMessageLoaderHelper(si, requestCode, fillIntent,
|
return callback.startIntentSenderForMessageLoaderHelper(intentSender, requestCode);
|
||||||
flagsMask, flagValues, extraFlags);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -524,8 +522,7 @@ public class MessageLoaderHelper {
|
||||||
|
|
||||||
void setLoadingProgress(int current, int max);
|
void setLoadingProgress(int current, int max);
|
||||||
|
|
||||||
boolean startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
|
boolean startIntentSenderForMessageLoaderHelper(IntentSender intentSender, int requestCode);
|
||||||
int flagsMask, int flagValues, int extraFlags);
|
|
||||||
|
|
||||||
void onDownloadErrorMessageNotFound();
|
void onDownloadErrorMessageNotFound();
|
||||||
void onDownloadErrorNetworkError();
|
void onDownloadErrorNetworkError();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.fsck.k9.ui.crypto;
|
package com.fsck.k9.ui.crypto;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
|
|
||||||
import com.fsck.k9.mailstore.MessageCryptoAnnotations;
|
import com.fsck.k9.mailstore.MessageCryptoAnnotations;
|
||||||
|
@ -10,6 +9,5 @@ import com.fsck.k9.mailstore.MessageCryptoAnnotations;
|
||||||
public interface MessageCryptoCallback {
|
public interface MessageCryptoCallback {
|
||||||
void onCryptoHelperProgress(int current, int max);
|
void onCryptoHelperProgress(int current, int max);
|
||||||
void onCryptoOperationsFinished(MessageCryptoAnnotations annotations);
|
void onCryptoOperationsFinished(MessageCryptoAnnotations annotations);
|
||||||
boolean startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
|
boolean startPendingIntentForCryptoHelper(IntentSender intentSender, int requestCode);
|
||||||
int flagsMask, int flagValues, int extraFlags);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -795,7 +795,7 @@ public class MessageCryptoHelper {
|
||||||
callback.onCryptoOperationsFinished(queuedResult);
|
callback.onCryptoOperationsFinished(queuedResult);
|
||||||
} else if (queuedPendingIntent != null) {
|
} else if (queuedPendingIntent != null) {
|
||||||
boolean pendingIntentHandled = callback.startPendingIntentForCryptoHelper(
|
boolean pendingIntentHandled = callback.startPendingIntentForCryptoHelper(
|
||||||
queuedPendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0);
|
queuedPendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION);
|
||||||
if (pendingIntentHandled) {
|
if (pendingIntentHandled) {
|
||||||
queuedPendingIntent = null;
|
queuedPendingIntent = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.fsck.k9.view.StatusIndicator
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import org.openintents.openpgp.util.OpenPgpIntentStarter
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class AutocryptKeyTransferActivity : K9Activity() {
|
class AutocryptKeyTransferActivity : K9Activity() {
|
||||||
|
@ -161,9 +162,9 @@ class AutocryptKeyTransferActivity : K9Activity() {
|
||||||
|
|
||||||
fun launchUserInteractionPendingIntent(pendingIntent: PendingIntent) {
|
fun launchUserInteractionPendingIntent(pendingIntent: PendingIntent) {
|
||||||
try {
|
try {
|
||||||
startIntentSender(pendingIntent.intentSender, null, 0, 0, 0)
|
OpenPgpIntentStarter.startIntentSender(this, pendingIntent.intentSender)
|
||||||
} catch (e: SendIntentException) {
|
} catch (e: SendIntentException) {
|
||||||
Timber.e(e)
|
Timber.e(e, "Error starting PendingIntent")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.fsck.k9.ui.messagedetails
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.IntentSender.SendIntentException
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -36,6 +37,8 @@ import com.mikepenz.fastadapter.listeners.ClickEventHook
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import org.openintents.openpgp.util.OpenPgpIntentStarter
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
class MessageDetailsFragment : ToolbarBottomSheetDialogFragment() {
|
class MessageDetailsFragment : ToolbarBottomSheetDialogFragment() {
|
||||||
private val viewModel: MessageDetailsViewModel by viewModel()
|
private val viewModel: MessageDetailsViewModel by viewModel()
|
||||||
|
@ -333,7 +336,11 @@ class MessageDetailsFragment : ToolbarBottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showCryptoKeys(pendingIntent: PendingIntent) {
|
private fun showCryptoKeys(pendingIntent: PendingIntent) {
|
||||||
requireActivity().startIntentSender(pendingIntent.intentSender, null, 0, 0, 0)
|
try {
|
||||||
|
OpenPgpIntentStarter.startIntentSender(requireActivity(), pendingIntent.intentSender)
|
||||||
|
} catch (e: SendIntentException) {
|
||||||
|
Timber.e(e, "Error starting PendingIntent")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchCryptoKeys() {
|
private fun searchCryptoKeys() {
|
||||||
|
|
|
@ -120,7 +120,7 @@ public class MessageCryptoPresenter {
|
||||||
PendingIntent pendingIntent = cryptoResultAnnotation.getOpenPgpSigningKeyIntentIfAny();
|
PendingIntent pendingIntent = cryptoResultAnnotation.getOpenPgpSigningKeyIntentIfAny();
|
||||||
if (pendingIntent != null) {
|
if (pendingIntent != null) {
|
||||||
messageCryptoMvpView.startPendingIntentForCryptoPresenter(
|
messageCryptoMvpView.startPendingIntentForCryptoPresenter(
|
||||||
pendingIntent.getIntentSender(), REQUEST_CODE_UNKNOWN_KEY, null, 0, 0, 0);
|
pendingIntent.getIntentSender(), REQUEST_CODE_UNKNOWN_KEY);
|
||||||
}
|
}
|
||||||
} catch (IntentSender.SendIntentException e) {
|
} catch (IntentSender.SendIntentException e) {
|
||||||
Timber.e(e, "SendIntentException");
|
Timber.e(e, "SendIntentException");
|
||||||
|
@ -136,7 +136,7 @@ public class MessageCryptoPresenter {
|
||||||
PendingIntent pendingIntent = cryptoResultAnnotation.getOpenPgpInsecureWarningPendingIntent();
|
PendingIntent pendingIntent = cryptoResultAnnotation.getOpenPgpInsecureWarningPendingIntent();
|
||||||
if (pendingIntent != null) {
|
if (pendingIntent != null) {
|
||||||
messageCryptoMvpView.startPendingIntentForCryptoPresenter(
|
messageCryptoMvpView.startPendingIntentForCryptoPresenter(
|
||||||
pendingIntent.getIntentSender(), REQUEST_CODE_SECURITY_WARNING, null, 0, 0, 0);
|
pendingIntent.getIntentSender(), REQUEST_CODE_SECURITY_WARNING);
|
||||||
}
|
}
|
||||||
} catch (IntentSender.SendIntentException e) {
|
} catch (IntentSender.SendIntentException e) {
|
||||||
Timber.e(e, "SendIntentException");
|
Timber.e(e, "SendIntentException");
|
||||||
|
@ -171,8 +171,8 @@ public class MessageCryptoPresenter {
|
||||||
void redisplayMessage();
|
void redisplayMessage();
|
||||||
void restartMessageCryptoProcessing();
|
void restartMessageCryptoProcessing();
|
||||||
|
|
||||||
void startPendingIntentForCryptoPresenter(IntentSender si, Integer requestCode, Intent fillIntent,
|
void startPendingIntentForCryptoPresenter(IntentSender intentSender, Integer requestCode)
|
||||||
int flagsMask, int flagValues, int extraFlags) throws IntentSender.SendIntentException;
|
throws IntentSender.SendIntentException;
|
||||||
|
|
||||||
void showCryptoConfigDialog();
|
void showCryptoConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ import com.fsck.k9.ui.share.ShareIntentBuilder
|
||||||
import com.fsck.k9.ui.withArguments
|
import com.fsck.k9.ui.withArguments
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
import org.openintents.openpgp.util.OpenPgpIntentStarter
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class MessageViewFragment :
|
class MessageViewFragment :
|
||||||
|
@ -828,24 +829,9 @@ class MessageViewFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SendIntentException::class)
|
@Throws(SendIntentException::class)
|
||||||
override fun startPendingIntentForCryptoPresenter(
|
override fun startPendingIntentForCryptoPresenter(intentSender: IntentSender, requestCode: Int) {
|
||||||
intentSender: IntentSender,
|
|
||||||
requestCode: Int,
|
|
||||||
fillIntent: Intent?,
|
|
||||||
flagsMask: Int,
|
|
||||||
flagValues: Int,
|
|
||||||
extraFlags: Int,
|
|
||||||
) {
|
|
||||||
val maskedRequestCode = requestCode or REQUEST_MASK_CRYPTO_PRESENTER
|
val maskedRequestCode = requestCode or REQUEST_MASK_CRYPTO_PRESENTER
|
||||||
startIntentSenderForResult(
|
OpenPgpIntentStarter.startIntentSenderForResult(this@MessageViewFragment, intentSender, maskedRequestCode)
|
||||||
intentSender,
|
|
||||||
maskedRequestCode,
|
|
||||||
fillIntent,
|
|
||||||
flagsMask,
|
|
||||||
flagValues,
|
|
||||||
extraFlags,
|
|
||||||
null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun restartMessageCryptoProcessing() {
|
override fun restartMessageCryptoProcessing() {
|
||||||
|
@ -921,27 +907,16 @@ class MessageViewFragment :
|
||||||
Toast.makeText(requireContext(), R.string.status_network_error, Toast.LENGTH_LONG).show()
|
Toast.makeText(requireContext(), R.string.status_network_error, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startIntentSenderForMessageLoaderHelper(
|
override fun startIntentSenderForMessageLoaderHelper(intentSender: IntentSender, requestCode: Int): Boolean {
|
||||||
intentSender: IntentSender,
|
|
||||||
requestCode: Int,
|
|
||||||
fillIntent: Intent?,
|
|
||||||
flagsMask: Int,
|
|
||||||
flagValues: Int,
|
|
||||||
extraFlags: Int,
|
|
||||||
): Boolean {
|
|
||||||
if (!isActive) return false
|
if (!isActive) return false
|
||||||
|
|
||||||
showProgressThreshold = null
|
showProgressThreshold = null
|
||||||
try {
|
try {
|
||||||
val maskedRequestCode = requestCode or REQUEST_MASK_LOADER_HELPER
|
val maskedRequestCode = requestCode or REQUEST_MASK_LOADER_HELPER
|
||||||
startIntentSenderForResult(
|
OpenPgpIntentStarter.startIntentSenderForResult(
|
||||||
|
this@MessageViewFragment,
|
||||||
intentSender,
|
intentSender,
|
||||||
maskedRequestCode,
|
maskedRequestCode,
|
||||||
fillIntent,
|
|
||||||
flagsMask,
|
|
||||||
flagValues,
|
|
||||||
extraFlags,
|
|
||||||
null,
|
|
||||||
)
|
)
|
||||||
} catch (e: SendIntentException) {
|
} catch (e: SendIntentException) {
|
||||||
Timber.e(e, "Irrecoverable error calling PendingIntent!")
|
Timber.e(e, "Irrecoverable error calling PendingIntent!")
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.openintents.openpgp.util
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.ActivityOptions
|
||||||
|
import android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
|
||||||
|
import android.content.IntentSender
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start OpenPGP crypto provider intents.
|
||||||
|
*
|
||||||
|
* On Android 14+ we need to use [MODE_BACKGROUND_ACTIVITY_START_ALLOWED] in order to start those intents.
|
||||||
|
*/
|
||||||
|
object OpenPgpIntentStarter {
|
||||||
|
@Throws(IntentSender.SendIntentException::class)
|
||||||
|
fun startIntentSender(activity: Activity, intentSender: IntentSender) {
|
||||||
|
val options = buildOptionsBundle()
|
||||||
|
|
||||||
|
activity.startIntentSender(
|
||||||
|
intentSender,
|
||||||
|
/* fillInIntent = */ null,
|
||||||
|
/* flagsMask = */ 0,
|
||||||
|
/* flagsValues = */ 0,
|
||||||
|
/* extraFlags = */ 0,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Throws(IntentSender.SendIntentException::class)
|
||||||
|
fun startIntentSenderForResult(activity: Activity, intentSender: IntentSender, requestCode: Int) {
|
||||||
|
val options = buildOptionsBundle()
|
||||||
|
|
||||||
|
activity.startIntentSenderForResult(
|
||||||
|
intentSender,
|
||||||
|
requestCode,
|
||||||
|
/* fillInIntent = */ null,
|
||||||
|
/* flagsMask = */ 0,
|
||||||
|
/* flagsValues = */ 0,
|
||||||
|
/* extraFlags = */ 0,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Throws(IntentSender.SendIntentException::class)
|
||||||
|
fun startIntentSenderForResult(fragment: Fragment, intentSender: IntentSender, requestCode: Int) {
|
||||||
|
val options = buildOptionsBundle()
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
fragment.startIntentSenderForResult(
|
||||||
|
intentSender,
|
||||||
|
requestCode,
|
||||||
|
/* fillInIntent = */ null,
|
||||||
|
/* flagsMask = */ 0,
|
||||||
|
/* flagsValues = */ 0,
|
||||||
|
/* extraFlags = */ 0,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildOptionsBundle(): Bundle? {
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
ActivityOptions.makeBasic().apply {
|
||||||
|
setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
|
||||||
|
setShareIdentityEnabled(true)
|
||||||
|
}.toBundle()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -196,9 +196,8 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
intentSenderFragment
|
OpenPgpIntentStarter.startIntentSenderForResult(intentSenderFragment,
|
||||||
.startIntentSenderForResult(pendingIntentSelectKey.getIntentSender(), REQUEST_CODE_KEY_PREFERENCE,
|
pendingIntentSelectKey.getIntentSender(), REQUEST_CODE_KEY_PREFERENCE);
|
||||||
null, 0, 0, 0, null);
|
|
||||||
} catch (IntentSender.SendIntentException e) {
|
} catch (IntentSender.SendIntentException e) {
|
||||||
Timber.e(e,"Error launching pending intent");
|
Timber.e(e,"Error launching pending intent");
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in a new issue