android: stricter IO usage

This commit is contained in:
Thibault Deckers 2021-08-02 14:14:29 +09:00
parent 888c5e567f
commit 9b90c7ba84
7 changed files with 76 additions and 54 deletions

View file

@ -31,6 +31,18 @@ class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(LOG_TAG, "onCreate intent=$intent")
// StrictMode.setThreadPolicy(
// StrictMode.ThreadPolicy.Builder()
// .detectAll()
// .penaltyLog()
// .build()
// )
// StrictMode.setVmPolicy(
// StrictMode.VmPolicy.Builder()
// .detectAll()
// .penaltyLog()
// .build()
// )
super.onCreate(savedInstanceState)
val messenger = flutterEngine!!.dartExecutor.binaryMessenger

View file

@ -36,7 +36,7 @@ import java.util.*
class DebugHandler(private val context: Context) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"getContextDirs" -> result.success(getContextDirs())
"getContextDirs" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getContextDirs) }
"getEnv" -> result.success(System.getenv())
"getBitmapFactoryInfo" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getBitmapFactoryInfo) }
"getContentResolverMetadata" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getContentResolverMetadata) }
@ -48,7 +48,8 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
}
}
private fun getContextDirs() = hashMapOf(
private fun getContextDirs(@Suppress("UNUSED_PARAMETER") call: MethodCall, result: MethodChannel.Result) {
val dirs = hashMapOf(
"cacheDir" to context.cacheDir,
"filesDir" to context.filesDir,
"obbDir" to context.obbDir,
@ -67,6 +68,9 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
}
}.mapValues { it.value?.path }
result.success(dirs)
}
private fun getBitmapFactoryInfo(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) }
if (uri == null) {

View file

@ -9,11 +9,14 @@ import deckers.thibault.aves.utils.LogUtils
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class GlobalSearchHandler(private val context: Activity) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"registerCallback" -> safe(call, result, ::registerCallback)
"registerCallback" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::registerCallback) }
else -> result.notImplemented()
}
}
@ -25,7 +28,6 @@ class GlobalSearchHandler(private val context: Activity) : MethodCallHandler {
return
}
Log.i(LOG_TAG, "register global search callback")
context.getSharedPreferences(SearchSuggestionsProvider.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
.edit()
.putLong(SearchSuggestionsProvider.CALLBACK_HANDLE_KEY, callbackHandle)

View file

@ -23,13 +23,13 @@ import java.util.*
class StorageHandler(private val context: Context) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"getStorageVolumes" -> safe(call, result, ::getStorageVolumes)
"getFreeSpace" -> safe(call, result, ::getFreeSpace)
"getGrantedDirectories" -> safe(call, result, ::getGrantedDirectories)
"getInaccessibleDirectories" -> safe(call, result, ::getInaccessibleDirectories)
"getRestrictedDirectories" -> safe(call, result, ::getRestrictedDirectories)
"getStorageVolumes" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getStorageVolumes) }
"getFreeSpace" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getFreeSpace) }
"getGrantedDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getGrantedDirectories) }
"getInaccessibleDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getInaccessibleDirectories) }
"getRestrictedDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getRestrictedDirectories) }
"revokeDirectoryAccess" -> safe(call, result, ::revokeDirectoryAccess)
"deleteEmptyDirectories" -> safe(call, result, ::deleteEmptyDirectories)
"deleteEmptyDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::deleteEmptyDirectories) }
"scanFile" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::scanFile) }
else -> result.notImplemented()
}
@ -38,7 +38,7 @@ class StorageHandler(private val context: Context) : MethodCallHandler {
private fun getStorageVolumes(@Suppress("UNUSED_PARAMETER") call: MethodCall, result: MethodChannel.Result) {
val volumes = ArrayList<Map<String, Any>>()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val sm = context.getSystemService(StorageManager::class.java)
val sm = context.getSystemService(Context.STORAGE_SERVICE) as? StorageManager
if (sm != null) {
for (volumePath in getVolumePaths(context)) {
try {

View file

@ -39,7 +39,7 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
handler = Handler(Looper.getMainLooper())
when (op) {
"requestVolumeAccess" -> requestVolumeAccess()
"requestVolumeAccess" -> GlobalScope.launch(Dispatchers.IO) { requestVolumeAccess() }
"createFile" -> GlobalScope.launch(Dispatchers.IO) { createFile() }
"openFile" -> GlobalScope.launch(Dispatchers.IO) { openFile() }
"selectDirectory" -> GlobalScope.launch(Dispatchers.IO) { selectDirectory() }
@ -83,6 +83,7 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
putExtra(Intent.EXTRA_TITLE, name)
}
MainActivity.pendingResultHandlers[MainActivity.CREATE_FILE_REQUEST] = PendingResultHandler(null, { uri ->
GlobalScope.launch(Dispatchers.IO) {
try {
activity.contentResolver.openOutputStream(uri)?.use { output ->
output as FileOutputStream
@ -95,6 +96,7 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
error("createFile-write", "failed to write file at uri=$uri", e.message)
}
endOfStream()
}
}, {
success(null)
endOfStream()
@ -115,6 +117,7 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
type = mimeType
}
MainActivity.pendingResultHandlers[MainActivity.OPEN_FILE_REQUEST] = PendingResultHandler(null, { uri ->
GlobalScope.launch(Dispatchers.IO) {
activity.contentResolver.openInputStream(uri)?.use { input ->
val buffer = ByteArray(BUFFER_SIZE)
var len: Int
@ -123,6 +126,7 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
}
endOfStream()
}
}
}, {
success(ByteArray(0))
endOfStream()

View file

@ -25,7 +25,7 @@ object PermissionManager {
var intent: Intent? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val sm = activity.getSystemService(StorageManager::class.java)
val sm = activity.getSystemService(Context.STORAGE_SERVICE) as? StorageManager
intent = sm?.getStorageVolume(File(path))?.createOpenDocumentTreeIntent()
}

View file

@ -187,8 +187,8 @@ object StorageUtils {
// /storage/10F9-3F13/Pictures/ -> 10F9-3F13
private fun getVolumeUuidForTreeUri(context: Context, anyPath: String): String? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.getSystemService(StorageManager::class.java)?.let { sm ->
sm.getStorageVolume(File(anyPath))?.let { volume ->
val sm = context.getSystemService(Context.STORAGE_SERVICE) as? StorageManager
sm?.getStorageVolume(File(anyPath))?.let { volume ->
if (volume.isPrimary) {
return "primary"
}
@ -197,7 +197,6 @@ object StorageUtils {
}
}
}
}
// fallback for <N
getVolumePath(context, anyPath)?.let { volumePath ->
@ -222,7 +221,8 @@ object StorageUtils {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.getSystemService(StorageManager::class.java)?.let { sm ->
val sm = context.getSystemService(Context.STORAGE_SERVICE) as? StorageManager
if (sm != null) {
for (volumePath in getVolumePaths(context)) {
try {
val volume = sm.getStorageVolume(File(volumePath))