diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index 1ac757d6f..c21c51308 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -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 diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt index 569d8d5dc..1d5a9fd8e 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt @@ -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,24 +48,28 @@ class DebugHandler(private val context: Context) : MethodCallHandler { } } - private fun getContextDirs() = hashMapOf( - "cacheDir" to context.cacheDir, - "filesDir" to context.filesDir, - "obbDir" to context.obbDir, - "externalCacheDir" to context.externalCacheDir, - ).apply { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - putAll( - hashMapOf( - "codeCacheDir" to context.codeCacheDir, - "noBackupFilesDir" to context.noBackupFilesDir, + 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, + "externalCacheDir" to context.externalCacheDir, + ).apply { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + putAll( + hashMapOf( + "codeCacheDir" to context.codeCacheDir, + "noBackupFilesDir" to context.noBackupFilesDir, + ) ) - ) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - put("dataDir", context.dataDir) - } - }.mapValues { it.value?.path } + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + put("dataDir", context.dataDir) + } + }.mapValues { it.value?.path } + + result.success(dirs) + } private fun getBitmapFactoryInfo(call: MethodCall, result: MethodChannel.Result) { val uri = call.argument("uri")?.let { Uri.parse(it) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt index a501a80a0..770f6beac 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt @@ -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) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/StorageHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/StorageHandler.kt index 9710f8962..4a2411bbc 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/StorageHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/StorageHandler.kt @@ -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>() 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 { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/StorageAccessStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/StorageAccessStreamHandler.kt index 0434ceaab..cd7e590a4 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/StorageAccessStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/StorageAccessStreamHandler.kt @@ -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,18 +83,20 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any? putExtra(Intent.EXTRA_TITLE, name) } MainActivity.pendingResultHandlers[MainActivity.CREATE_FILE_REQUEST] = PendingResultHandler(null, { uri -> - try { - activity.contentResolver.openOutputStream(uri)?.use { output -> - output as FileOutputStream - // truncate is necessary when overwriting a longer file - output.channel.truncate(0) - output.write(bytes) + GlobalScope.launch(Dispatchers.IO) { + try { + activity.contentResolver.openOutputStream(uri)?.use { output -> + output as FileOutputStream + // truncate is necessary when overwriting a longer file + output.channel.truncate(0) + output.write(bytes) + } + success(true) + } catch (e: Exception) { + error("createFile-write", "failed to write file at uri=$uri", e.message) } - success(true) - } catch (e: Exception) { - error("createFile-write", "failed to write file at uri=$uri", e.message) + endOfStream() } - endOfStream() }, { success(null) endOfStream() @@ -115,13 +117,15 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any? type = mimeType } MainActivity.pendingResultHandlers[MainActivity.OPEN_FILE_REQUEST] = PendingResultHandler(null, { uri -> - activity.contentResolver.openInputStream(uri)?.use { input -> - val buffer = ByteArray(BUFFER_SIZE) - var len: Int - while (input.read(buffer).also { len = it } != -1) { - success(buffer.copyOf(len)) + GlobalScope.launch(Dispatchers.IO) { + activity.contentResolver.openInputStream(uri)?.use { input -> + val buffer = ByteArray(BUFFER_SIZE) + var len: Int + while (input.read(buffer).also { len = it } != -1) { + success(buffer.copyOf(len)) + } + endOfStream() } - endOfStream() } }, { success(ByteArray(0)) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt index 8a180a0ab..cfb0bb307 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt @@ -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() } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt index 27e5432a3..84d51ecf3 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt @@ -187,14 +187,13 @@ 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 -> - if (volume.isPrimary) { - return "primary" - } - volume.uuid?.let { uuid -> - return uuid.uppercase(Locale.ROOT) - } + val sm = context.getSystemService(Context.STORAGE_SERVICE) as? StorageManager + sm?.getStorageVolume(File(anyPath))?.let { volume -> + if (volume.isPrimary) { + return "primary" + } + volume.uuid?.let { uuid -> + return uuid.uppercase(Locale.ROOT) } } } @@ -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))