Skip to content

Commit 2a8527f

Browse files
fix(control): verify dongle is attached when returning to screen
1 parent 8eb5cf9 commit 2a8527f

File tree

4 files changed

+48
-8
lines changed

4 files changed

+48
-8
lines changed

app/config/detekt/baseline.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ManuallySuppressedIssues></ManuallySuppressedIssues>
44
<CurrentIssues>
55
<ID>CyclomaticComplexMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, modifier: Modifier = Modifier, topScrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(), bottomScrollBehavior: BottomAppBarScrollBehavior? = null, profileListState: LazyStaggeredGridState = rememberLazyStaggeredGridState(), snackBarHostState: SnackbarHostState = remember { SnackbarHostState() }, profiles: LazyPagingItems&lt;Profile&gt; = UnsupportedUsbDongle.profileFlow().collectAsLazyPagingItems(), usbDongle: UsbDongle = UnsupportedUsbDongle, isLoading: Boolean = false, onNavigateToSettings: () -&gt; Unit = {}, onRefresh: () -&gt; Unit = {}, onReset: () -&gt; Unit = {}, onProfileShortcutAdd: (Profile) -&gt; Unit = {}, onProfileShortcutRemove: (Profile) -&gt; Unit = {}, onProfileDelete: (Profile) -&gt; Unit = { _ -&gt; }, onProfileApply: (Profile) -&gt; Unit = { _ -&gt; }, onProfileExport: (String) -&gt; Unit = { _ -&gt; }, onChannelBalanceSelected: (Int) -&gt; Unit = { _ -&gt; }, onDacModeSelected: (Byte) -&gt; Unit = { _ -&gt; }, onDisplayBrightnessSelected: (Int) -&gt; Unit = { _ -&gt; }, onDisplayTimeoutSelected: (Int) -&gt; Unit = { _ -&gt; }, onDisplayInvertChange: (Boolean) -&gt; Unit = { _ -&gt; }, onFilterSelected: (Byte) -&gt; Unit = { _ -&gt; }, onGainSelected: (Byte) -&gt; Unit = { _ -&gt; }, onHardwareMuteEnabledSelected: (Boolean) -&gt; Unit = { _ -&gt; }, onHidModeSelected: (Byte) -&gt; Unit = { _ -&gt; }, onIndicatorStateSelected: (Byte) -&gt; Unit = { _ -&gt; }, onSpdifOutEnabledSelected: (Boolean) -&gt; Unit = { _ -&gt; }, onVolumeLevelSelected: (Int) -&gt; Unit = { _ -&gt; }, onVolumeModeSelected: (Byte) -&gt; Unit = { _ -&gt; } )</ID>
6-
<ID>CyclomaticComplexMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, viewModel: ControlViewModel, onNavigateToSettings: () -&gt; Unit, onNavigateUp: () -&gt; Unit )</ID>
6+
<ID>CyclomaticComplexMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, navController: NavController, viewModel: ControlViewModel, onNavigateToSettings: () -&gt; Unit, onNavigateToSetup: () -&gt; Unit )</ID>
77
<ID>DestructuringDeclarationWithTooManyEntries:SettingsAudioItem.kt$val (icon, title, subtitle, checkbox) = createRefs()</ID>
88
<ID>EmptyFunctionBlock:ItemAudio.kt$&lt;no name provided&gt;${ }</ID>
99
<ID>EmptyFunctionBlock:ItemDisplay.kt$&lt;no name provided&gt;${ }</ID>
@@ -12,7 +12,7 @@
1212
<ID>LargeClass:FiioKa5UsbRepository.kt$FiioKa5UsbRepository : UsbRepository</ID>
1313
<ID>LongMethod:ControlDropDownMenu.kt$@Composable fun ControlDropdownMenu( windowSizeClass: WindowSizeClass, modifier: Modifier = Modifier, isExpanded: Boolean = false, onDismissRequest: () -&gt; Unit = {}, onRefresh: () -&gt; Unit = {}, onReset: () -&gt; Unit = {}, onProfileExport: (String) -&gt; Unit = {}, onNavigateToSettings: () -&gt; Unit = {} )</ID>
1414
<ID>LongMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, modifier: Modifier = Modifier, topScrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(), bottomScrollBehavior: BottomAppBarScrollBehavior? = null, profileListState: LazyStaggeredGridState = rememberLazyStaggeredGridState(), snackBarHostState: SnackbarHostState = remember { SnackbarHostState() }, profiles: LazyPagingItems&lt;Profile&gt; = UnsupportedUsbDongle.profileFlow().collectAsLazyPagingItems(), usbDongle: UsbDongle = UnsupportedUsbDongle, isLoading: Boolean = false, onNavigateToSettings: () -&gt; Unit = {}, onRefresh: () -&gt; Unit = {}, onReset: () -&gt; Unit = {}, onProfileShortcutAdd: (Profile) -&gt; Unit = {}, onProfileShortcutRemove: (Profile) -&gt; Unit = {}, onProfileDelete: (Profile) -&gt; Unit = { _ -&gt; }, onProfileApply: (Profile) -&gt; Unit = { _ -&gt; }, onProfileExport: (String) -&gt; Unit = { _ -&gt; }, onChannelBalanceSelected: (Int) -&gt; Unit = { _ -&gt; }, onDacModeSelected: (Byte) -&gt; Unit = { _ -&gt; }, onDisplayBrightnessSelected: (Int) -&gt; Unit = { _ -&gt; }, onDisplayTimeoutSelected: (Int) -&gt; Unit = { _ -&gt; }, onDisplayInvertChange: (Boolean) -&gt; Unit = { _ -&gt; }, onFilterSelected: (Byte) -&gt; Unit = { _ -&gt; }, onGainSelected: (Byte) -&gt; Unit = { _ -&gt; }, onHardwareMuteEnabledSelected: (Boolean) -&gt; Unit = { _ -&gt; }, onHidModeSelected: (Byte) -&gt; Unit = { _ -&gt; }, onIndicatorStateSelected: (Byte) -&gt; Unit = { _ -&gt; }, onSpdifOutEnabledSelected: (Boolean) -&gt; Unit = { _ -&gt; }, onVolumeLevelSelected: (Int) -&gt; Unit = { _ -&gt; }, onVolumeModeSelected: (Byte) -&gt; Unit = { _ -&gt; } )</ID>
15-
<ID>LongMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, viewModel: ControlViewModel, onNavigateToSettings: () -&gt; Unit, onNavigateUp: () -&gt; Unit )</ID>
15+
<ID>LongMethod:ControlScreen.kt$@Composable fun ControlScreen( windowSizeClass: WindowSizeClass, navController: NavController, viewModel: ControlViewModel, onNavigateToSettings: () -&gt; Unit, onNavigateToSetup: () -&gt; Unit )</ID>
1616
<ID>LongMethod:FiioKa13UsbRepository.kt$FiioKa13UsbRepository$suspend fun setVolumeLevel(fiioKa13: FiioKa13, volumeLevel: VolumeLevel): Result&lt;FiioKa13&gt;</ID>
1717
<ID>LongMethod:FiioKa5Items.kt$@Composable fun FiioKa5Items( modifier: Modifier = Modifier, fiioKa5: FiioKa5 = FiioKa5(), onChannelBalanceSelected: (Int) -&gt; Unit = {}, onVolumeLevelSelected: (Int) -&gt; Unit = {}, onVolumeModeSelected: (Byte) -&gt; Unit = {}, onDisplayBrightnessSelected: (Int) -&gt; Unit = {}, onDisplayTimeoutSelected: (Int) -&gt; Unit = {}, onDisplayInvertSelected: (Boolean) -&gt; Unit = {}, onGainSelected: (Byte) -&gt; Unit = {}, onFilterSelected: (Byte) -&gt; Unit = {}, onSpdifOutSelected: (Boolean) -&gt; Unit = {}, onHardwareMuteSelected: (Boolean) -&gt; Unit = {}, onDacModeSelected: (Byte) -&gt; Unit = {}, onHidModeSelected: (Byte) -&gt; Unit = {} )</ID>
1818
<ID>LongMethod:FiioKa5UsbRepository.kt$FiioKa5UsbRepository$suspend fun getCurrentState(usbDongle: FiioKa5): Result&lt;FiioKa5&gt;</ID>

app/src/main/kotlin/io/github/tommygeenexus/usbdonglecontrol/control/business/ControlViewModel.kt

+20
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,26 @@ class ControlViewModel @Inject constructor(
149149
}
150150
}
151151

152+
fun verifyUsbDongleIsAttachedAndUsbPermissionIsGranted() = intent {
153+
reduce {
154+
state.copy(loadingTasks = state.plusLoadingTask())
155+
}
156+
val result = usbRepository.getFirstAttachedUsbDongle()
157+
reduce {
158+
state.copy(loadingTasks = state.minusLoadingTask())
159+
}
160+
if (result.isSuccess) {
161+
val (_, _, isUsbPermissionGranted) = result.getOrThrow()
162+
if (!isUsbPermissionGranted) {
163+
// Device has been detached then attached again without permission auto-grant
164+
// while in another screen
165+
postSideEffect(ControlSideEffect.UsbCommunication.Get.Failure)
166+
}
167+
} else {
168+
postSideEffect(ControlSideEffect.UsbCommunication.Get.Failure)
169+
}
170+
}
171+
152172
fun setProfile(profile: Profile) = intent {
153173
reduce {
154174
state.copy(loadingTasks = state.plusLoadingTask())

app/src/main/kotlin/io/github/tommygeenexus/usbdonglecontrol/control/ui/ControlScreen.kt

+23-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ import androidx.compose.ui.platform.LocalContext
7575
import androidx.compose.ui.platform.LocalLayoutDirection
7676
import androidx.compose.ui.res.stringResource
7777
import androidx.core.content.ContextCompat
78+
import androidx.lifecycle.Lifecycle
7879
import androidx.lifecycle.compose.LocalLifecycleOwner
80+
import androidx.lifecycle.repeatOnLifecycle
81+
import androidx.navigation.NavController
7982
import androidx.paging.compose.LazyPagingItems
8083
import androidx.paging.compose.collectAsLazyPagingItems
8184
import io.github.tommygeenexus.usbdonglecontrol.R
@@ -98,6 +101,7 @@ import io.github.tommygeenexus.usbdonglecontrol.dongle.fiio.ka13.ui.FiioKa13Item
98101
import io.github.tommygeenexus.usbdonglecontrol.dongle.fiio.ka5.ui.FiioKa5Items
99102
import io.github.tommygeenexus.usbdonglecontrol.dongle.moondrop.dawn.ui.MoondropDawnItems
100103
import io.github.tommygeenexus.usbdonglecontrol.dongle.moondrop.moonriver2ti.ui.MoondropMoonriver2TiItems
104+
import io.github.tommygeenexus.usbdonglecontrol.navigation.NavDestinations
101105
import io.github.tommygeenexus.usbdonglecontrol.theme.getHorizontalCardPadding
102106
import io.github.tommygeenexus.usbdonglecontrol.volume.ui.UsbService
103107
import kotlinx.coroutines.launch
@@ -107,9 +111,10 @@ import org.orbitmvi.orbit.compose.collectSideEffect
107111
@Composable
108112
fun ControlScreen(
109113
windowSizeClass: WindowSizeClass,
114+
navController: NavController,
110115
viewModel: ControlViewModel,
111116
onNavigateToSettings: () -> Unit,
112-
onNavigateUp: () -> Unit
117+
onNavigateToSetup: () -> Unit
113118
) {
114119
val context = LocalContext.current
115120
val scope = rememberCoroutineScope()
@@ -239,7 +244,7 @@ fun ControlScreen(
239244
}
240245
}
241246
ControlSideEffect.UsbCommunication.Get.Failure -> {
242-
onNavigateUp()
247+
onNavigateToSetup()
243248
}
244249
is ControlSideEffect.UsbCommunication.Get.Success -> {
245250
viewModel.getCurrentStateForUsbDongle(usbDongle = sideEffect.usbDongle)
@@ -274,15 +279,29 @@ fun ControlScreen(
274279
} else {
275280
null
276281
}
277-
DisposableEffect(LocalLifecycleOwner.current) {
282+
val lifecycleOwner = LocalLifecycleOwner.current
283+
LaunchedEffect(lifecycleOwner) {
284+
lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
285+
navController.currentBackStackEntryFlow.collect { navBackStackEntry ->
286+
if (navBackStackEntry
287+
.destination
288+
.route
289+
?.endsWith(NavDestinations.Control.toString()) == true
290+
) {
291+
viewModel.verifyUsbDongleIsAttachedAndUsbPermissionIsGranted()
292+
}
293+
}
294+
}
295+
}
296+
DisposableEffect(lifecycleOwner) {
278297
val usbReceiver = UsbDeviceAttachDetachPermissionReceiver(
279298
onAttachedDevicesChanged = { isAttached ->
280299
if (!isAttached) {
281300
topScrollBehavior.state.heightOffset = 0f
282301
topScrollBehavior.state.contentOffset = 0f
283302
bottomScrollBehavior?.state?.heightOffset = 0f
284303
bottomScrollBehavior?.state?.contentOffset = 0f
285-
onNavigateUp()
304+
onNavigateToSetup()
286305
}
287306
}
288307
)

app/src/main/kotlin/io/github/tommygeenexus/usbdonglecontrol/navigation/NavGraph.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ fun NavGraph(
9191
) {
9292
ControlScreen(
9393
windowSizeClass = windowSizeClass,
94+
navController = navController,
9495
viewModel = hiltViewModel(),
9596
onNavigateToSettings = {
9697
navController.navigate(NavDestinations.Settings)
9798
},
98-
onNavigateUp = {
99-
navController.navigateUp()
99+
onNavigateToSetup = {
100+
navController.navigate(NavDestinations.Setup)
100101
}
101102
)
102103
}

0 commit comments

Comments
 (0)