Skip to content

Commit

Permalink
fix(share_plus): Recover ShareSuccessManager state after error (#2817)
Browse files Browse the repository at this point in the history
  • Loading branch information
miquelbeltran committed Apr 7, 2024
1 parent ca6a39c commit 2b12d8a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,72 +8,68 @@ import java.io.IOException
/** Handles the method calls for the plugin. */
internal class MethodCallHandler(
private val share: Share,
private val manager: ShareSuccessManager
private val manager: ShareSuccessManager,
) : MethodChannel.MethodCallHandler {

override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
expectMapArguments(call)

// The user used a *WithResult method
val isResultRequested = call.method.endsWith("WithResult")
// We don't attempt to return a result if the current API version doesn't support it
val isWithResult = isResultRequested && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
val isWithResult =
isResultRequested && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1

when (call.method) {
"shareUri" -> {
expectMapArguments(call)
share.share(
call.argument<Any>("uri") as String,
subject = null,
withResult= false
)
if (!isWithResult) {
result.success(null)
}
}
"share", "shareWithResult" -> {
expectMapArguments(call)
if (isWithResult && !manager.setCallback(result)) return
if (isWithResult && !manager.setCallback(result)) return

// Android does not support showing the share sheet at a particular point on screen.
share.share(
call.argument<Any>("text") as String,
call.argument<Any>("subject") as String?,
isWithResult,
)
try {
when (call.method) {
"shareUri" -> {
share.share(
call.argument<Any>("uri") as String, subject = null, withResult = false
)
success(isWithResult, isResultRequested, result)
}

if (!isWithResult) {
if (isResultRequested) {
result.success("dev.fluttercommunity.plus/share/unavailable")
} else {
result.success(null)
}
"share", "shareWithResult" -> {
share.share(
call.argument<Any>("text") as String,
call.argument<Any>("subject") as String?,
isWithResult,
)
success(isWithResult, isResultRequested, result)
}
}
"shareFiles", "shareFilesWithResult" -> {
expectMapArguments(call)
if (isWithResult && !manager.setCallback(result)) return

// Android does not support showing the share sheet at a particular point on screen.
try {
"shareFiles", "shareFilesWithResult" -> {
share.shareFiles(
call.argument<List<String>>("paths")!!,
call.argument<List<String>?>("mimeTypes"),
call.argument<String?>("text"),
call.argument<String?>("subject"),
isWithResult,
)

if (!isWithResult) {
if (isResultRequested) {
result.success("dev.fluttercommunity.plus/share/unavailable")
} else {
result.success(null)
}
}
} catch (e: IOException) {
result.error("Share failed", e.message, null)
success(isWithResult, isResultRequested, result)
}

else -> result.notImplemented()
}
} catch (e: Throwable) {
manager.clear()
result.error("Share failed", e.message, e)
}
}

private fun success(
isWithResult: Boolean,
isResultRequested: Boolean,
result: MethodChannel.Result
) {
if (!isWithResult) {
if (isResultRequested) {
result.success("dev.fluttercommunity.plus/share/unavailable")
} else {
result.success(null)
}
else -> result.notImplemented()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ internal class ShareSuccessManager(private val context: Context) : ActivityResul
returnResult(RESULT_UNAVAILABLE)
}

/**
* Must be called on error to avoid deadlocking.
*/
fun clear() {
isCalledBack.set(true)
callback = null
}

/**
* Send the result to flutter by invoking the previously set callback.
*/
Expand Down

0 comments on commit 2b12d8a

Please sign in to comment.