feat(PMInstaller): don't relaunch install prompts until result received
This was supposed to fix one type of ROM bug where clicking outside of the install prompt would never return a result to the application. However, the workaround was to keep relaunching the install prompt until the user either actually clicked install or cancel. This apparently is also incorrectly handled by a lot of ROMs and causes the install prompt to keep relaunching, even after pressing the install button. I don't think there's a good solution, so I'll just remove the relaunching behavior since it's more annoying to the user.
This commit is contained in:
parent
bb5a38d85f
commit
300952ad21
2 changed files with 1 additions and 43 deletions
|
|
@ -42,7 +42,7 @@ class PMIntentReceiver : BroadcastReceiver() {
|
|||
private fun handleSessionIntent(context: Context, intent: Intent, sessionId: Int) {
|
||||
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)
|
||||
|
||||
// Launch the user action intent and forward it to PMResultReceiver to keep relaunching it
|
||||
// Launch the user action intent
|
||||
if (status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
|
||||
@Suppress("DEPRECATION")
|
||||
val confirmationIntent = intent
|
||||
|
|
@ -51,15 +51,6 @@ class PMIntentReceiver : BroadcastReceiver() {
|
|||
|
||||
context.startActivity(confirmationIntent)
|
||||
|
||||
if (intent.getBooleanExtra(EXTRA_RELAY_ENABLED, false)) {
|
||||
val relayIntent = Intent(PMResultReceiver.ACTION_RECEIVE_INTENT)
|
||||
.setPackage(BuildConfig.APPLICATION_ID)
|
||||
.putExtra(PMResultReceiver.EXTRA_SESSION_ID, sessionId)
|
||||
.putExtra(PMResultReceiver.EXTRA_USER_ACTION_INTENT, confirmationIntent)
|
||||
|
||||
context.sendBroadcast(relayIntent)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,65 +6,33 @@ import com.aliucord.manager.R
|
|||
import com.aliucord.manager.installers.InstallerResult
|
||||
import com.aliucord.manager.installers.UnknownInstallerError
|
||||
import com.aliucord.manager.util.showToast
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
/**
|
||||
* This receiver is meant to be registered dynamically in combination with [PMIntentReceiver] in order to
|
||||
* relay parsed [PackageInstaller] results back to the running application.
|
||||
* Additionally, it will handle restarting [PackageInstaller] user action intents infinitely until
|
||||
* we have received a result from the system.
|
||||
*/
|
||||
class PMResultReceiver(
|
||||
private val sessionId: Int,
|
||||
private val isUninstall: Boolean,
|
||||
private val onResult: (InstallerResult) -> Unit,
|
||||
) : BroadcastReceiver() {
|
||||
/**
|
||||
* Keep re-launching the user action intent until we have received a result from the PM.
|
||||
* This is necessary because on some ROMs there is no callback intent sent when the user
|
||||
* clicks outside of the package installer dialog, forcing us to keep relaunching the dialog
|
||||
* until the user has clicked one of the buttons, after which the intent has been 'used up' and won't show anymore.
|
||||
*/
|
||||
private val resultReceived = AtomicBoolean(false)
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.getIntExtra(EXTRA_SESSION_ID, -1) != sessionId) return
|
||||
|
||||
try {
|
||||
when (intent.action) {
|
||||
ACTION_RECEIVE_INTENT -> handleIntent(context, intent)
|
||||
ACTION_RECEIVE_RESULT -> handleResult(context, intent)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
resultReceived.set(true)
|
||||
context.unregisterReceiver(this)
|
||||
onResult(UnknownInstallerError(t))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleIntent(context: Context, intent: Intent) {
|
||||
@Suppress("DEPRECATION")
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(EXTRA_USER_ACTION_INTENT)
|
||||
?: return
|
||||
|
||||
// No result yet, keep relaunching user action intent
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
while (true) {
|
||||
context.startActivity(confirmationIntent)
|
||||
delay(1000)
|
||||
|
||||
if (resultReceived.get()) break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleResult(context: Context, intent: Intent) {
|
||||
@Suppress("DEPRECATION")
|
||||
val result = intent.getParcelableExtra<InstallerResult>(EXTRA_RESULT) ?: return
|
||||
|
||||
resultReceived.set(true)
|
||||
|
||||
// Show toast for successful and aborted sessions
|
||||
when (result) {
|
||||
InstallerResult.Success -> {
|
||||
|
|
@ -89,7 +57,6 @@ class PMResultReceiver(
|
|||
const val ACTION_RECEIVE_RESULT = "com.aliucord.manager.RELAY_PM_RESULT"
|
||||
const val EXTRA_RESULT = "installerResult"
|
||||
const val EXTRA_SESSION_ID = "sessionId"
|
||||
const val EXTRA_USER_ACTION_INTENT = "userActionIntent"
|
||||
|
||||
/**
|
||||
* The intent filter this receiver should be registered with to work properly.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue