picker: prevent security exception
This commit is contained in:
parent
2932e0b80f
commit
1058aba262
1 changed files with 40 additions and 24 deletions
|
@ -432,8 +432,13 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
|
|
||||||
open fun submitPickedItems(call: MethodCall, result: MethodChannel.Result) {
|
open fun submitPickedItems(call: MethodCall, result: MethodChannel.Result) {
|
||||||
val pickedUris = call.argument<List<String>>("uris")
|
val pickedUris = call.argument<List<String>>("uris")
|
||||||
try {
|
if (pickedUris.isNullOrEmpty()) {
|
||||||
if (!pickedUris.isNullOrEmpty()) {
|
setResult(RESULT_CANCELED)
|
||||||
|
// move code triggering `Binder` call off the main thread
|
||||||
|
defaultScope.launch { finish() }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
|
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) }
|
||||||
val intent = Intent().apply {
|
val intent = Intent().apply {
|
||||||
val firstUri = toUri(pickedUris.first())
|
val firstUri = toUri(pickedUris.first())
|
||||||
|
@ -446,19 +451,30 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||||
}
|
|
||||||
setResult(RESULT_OK, intent)
|
|
||||||
} else {
|
|
||||||
setResult(RESULT_CANCELED)
|
|
||||||
}
|
}
|
||||||
// move code triggering `Binder` call off the main thread
|
// move code triggering `Binder` call off the main thread
|
||||||
defaultScope.launch { finish() }
|
defaultScope.launch {
|
||||||
|
submitPickedItemsIntent(intent, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun submitPickedItemsIntent(intent: Intent, result: MethodChannel.Result) {
|
||||||
|
try {
|
||||||
|
setResult(RESULT_OK, intent)
|
||||||
|
finish()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
|
if (e is SecurityException && intent.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION != 0) {
|
||||||
result.error("submitPickedItems-large", "transaction too large with ${pickedUris?.size} URIs", e)
|
// in some environments, providing the write flag yields a `SecurityException`:
|
||||||
|
// "UID XXXX does not have permission to content://XXXX"
|
||||||
|
// so we retry without it
|
||||||
|
Log.i(LOG_TAG, "retry submitting picked items without FLAG_GRANT_WRITE_URI_PERMISSION")
|
||||||
|
intent.flags = intent.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION.inv()
|
||||||
|
submitPickedItemsIntent(intent, result)
|
||||||
|
} else if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
|
||||||
|
result.error("submitPickedItems-large", "transaction too large with ${intent.clipData?.itemCount} URIs", e)
|
||||||
} else {
|
} else {
|
||||||
result.error("submitPickedItems-exception", "failed to pick ${pickedUris?.size} URIs", e)
|
result.error("submitPickedItems-exception", "failed to pick ${intent.clipData?.itemCount} URIs", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue