@@ -17,11 +17,10 @@ import eu.darken.butler.common.files.APath
1717import eu.darken.butler.common.files.GatewaySwitch
1818import eu.darken.butler.common.files.LocalPath
1919import eu.darken.butler.common.hasApiLevel
20- import eu.darken.butler.common. permissions.Permission
20+ import eu.darken.butler.workspace.core. permissions.PathPermissionChecker
2121import eu.darken.butler.explorer.R
2222import eu.darken.butler.explorer.core.ExplorerNavigation
23- import eu.darken.butler.workspace.core.permissions.WorkspacePermissions
24- import eu.darken.butler.workspace.core.permissions.PermissionRequirement
23+ import eu.darken.butler.workspace.core.permissions.PermissionState
2524import kotlinx.coroutines.Dispatchers
2625import kotlinx.coroutines.flow.Flow
2726import kotlinx.coroutines.flow.flow
@@ -31,73 +30,31 @@ import javax.inject.Inject
3130class ExplorerEngine @Inject constructor(
3231 @ApplicationContext private val context : Context ,
3332 private val gatewaySwitch : GatewaySwitch ,
33+ private val pathPermissionChecker : PathPermissionChecker ,
3434) {
3535
3636 internal var subTag: String = " "
3737 private val tag by lazy { logTag(" Explorer" , " Engine" , subTag) }
3838
39- private fun checkLocationPermissions (target : ExplorerNavigation .Target ): WorkspacePermissions {
39+ private fun checkLocationPermissions (target : ExplorerNavigation .Target ): PermissionState {
4040 log(tag) { " checkLocationPermissions(): Checking permissions for $target " }
4141
4242 return when (target) {
4343 is ExplorerNavigation .Target .Home ,
4444 is ExplorerNavigation .Target .Device -> {
4545 // Home and Device views don't require permissions
46- WorkspacePermissions (
46+ PermissionState (
4747 requirements = emptyList(),
4848 hasSufficientPermissions = true ,
4949 missingCritical = emptyList(),
5050 )
5151 }
5252 is ExplorerNavigation .Target .Directory -> {
53- checkDirectoryPermissions (target.path)
53+ pathPermissionChecker.check (target.path)
5454 }
5555 }
5656 }
5757
58- private fun checkDirectoryPermissions (path : APath ): WorkspacePermissions {
59- val pathString = when (path) {
60- is LocalPath -> path.path
61- else -> path.path
62- }
63-
64- // Check if this is internal storage that requires permissions
65- val internalStoragePath = Environment .getExternalStorageDirectory().absolutePath
66- val requiresStoragePermission = pathString.startsWith(internalStoragePath) ||
67- pathString.startsWith(" /storage/emulated/" ) ||
68- pathString.startsWith(" /sdcard" )
69-
70- if (! requiresStoragePermission) {
71- // App-specific directories or other paths that don't need special permissions
72- return WorkspacePermissions (
73- requirements = emptyList(),
74- hasSufficientPermissions = true ,
75- missingCritical = emptyList(),
76- )
77- }
78-
79- // Determine which storage permission is needed based on API level
80- val requiredPermission = when {
81- hasApiLevel(30 ) -> Permission .MANAGE_EXTERNAL_STORAGE
82- else -> Permission .WRITE_EXTERNAL_STORAGE
83- }
84-
85- val isGranted = requiredPermission.isGranted(context)
86- log(tag) { " checkDirectoryPermissions(): $requiredPermission isGranted=$isGranted for path=$pathString " }
87-
88- val requirement = PermissionRequirement (
89- permission = requiredPermission,
90- isRequired = true ,
91- reason = R .string.explorer_permission_generic_description.toCaString(),
92- alternativeAccess = null ,
93- )
94-
95- return WorkspacePermissions (
96- requirements = listOf (requirement),
97- hasSufficientPermissions = isGranted,
98- missingCritical = if (! isGranted) listOf (requiredPermission) else emptyList(),
99- )
100- }
10158
10259 private suspend fun getHomeEntry (): ExplorerLocation = withContext(Dispatchers .IO ) {
10360 val shortcuts = listOf (
0 commit comments