Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Single tap infrared #992

Merged
merged 15 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [Feature] Add count subfolders for new file manager
- [Feature] Add file downloading for new file manager
- [Feature] Add move-to to new file manager
- [Feature] Single tap for infrared remotes
- [Refactor] Move rename and file create to separated modules
- [Refactor] Improve and refactor new FileManager Editor
- [FIX] Migrate url host from metric.flipperdevices.com to metric.flipp.dev
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private fun KeyScreenState.Ready.toEmulateConfigs(): ImmutableList<EmulateConfig
keyType = FlipperKeyType.INFRARED,
keyPath = this.flipperKey.path,
args = name,
index = index
index = index,
)
}.toImmutableList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import com.flipperdevices.bridge.dao.api.model.FlipperKeyType
/*
Override equals and hashCode to compare emulate key, because emulate time not important
*/
/**
* @param isPressRelease one-time emulate for infrared-only
*/
@Immutable
data class EmulateConfig(
val keyType: FlipperKeyType,
val keyPath: FlipperFilePath,
val minEmulateTime: Long? = null,
val args: String? = null,
val index: Int? = null
val index: Int? = null,
val isPressRelease: Boolean = false
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private fun ComposableActiveStateEmulateInternal(

val buttonActiveModifier = Modifier.onScrollHoldPress(
onTap = {
emulateViewModel.onSinglePress(emulateConfig)
emulateViewModel.onSinglePress(emulateConfig.copy(isPressRelease = true))
},
onLongPressStart = {
emulateViewModel.onStartEmulate(emulateConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.flipperdevices.keyemulate.model.EmulateConfig
import com.flipperdevices.keyemulate.model.FlipperAppError
import com.flipperdevices.protobuf.Flipper
import com.flipperdevices.protobuf.app.Application
import com.flipperdevices.protobuf.app.appButtonPressReleaseRequest
import com.flipperdevices.protobuf.app.appButtonPressRequest
import com.flipperdevices.protobuf.app.appLoadFileRequest
import com.flipperdevices.protobuf.main
Expand All @@ -32,6 +33,7 @@ private const val APP_RETRY_COUNT = 3
private const val APP_RETRY_SLEEP_TIME_MS = 1 * 1000L // 1 second

interface StartEmulateHelper {
@Suppress("LongParameterList")
suspend fun onStart(
scope: CoroutineScope,
serviceApi: FlipperServiceApi,
Expand Down Expand Up @@ -103,7 +105,7 @@ class StartEmulateHelperImpl @Inject constructor(
config = config,
onResultTime = onResultTime,
serviceApi = serviceApi,
isIndexEmulateSupport = indexEmulateSupported
isIndexEmulateSupport = indexEmulateSupported,
)
}

Expand All @@ -125,7 +127,17 @@ class StartEmulateHelperImpl @Inject constructor(
val appButtonPressResponse = serviceApi.requestApi.request(
flowOf(
main {
appButtonPressRequest = getAppButtonPressRequest(config, isIndexEmulateSupport)
if (config.isPressRelease) {
appButtonPressReleaseRequest = getAppButtonPressReleaseRequest(
config,
isIndexEmulateSupport
)
} else {
appButtonPressRequest = getAppButtonPressRequest(
config,
isIndexEmulateSupport
)
}
}.wrapToRequest(FlipperRequestPriority.FOREGROUND)
)
)
Expand Down Expand Up @@ -164,6 +176,29 @@ class StartEmulateHelperImpl @Inject constructor(
}
}

private fun getAppButtonPressReleaseRequest(
config: EmulateConfig,
isIndexEmulateSupport: Boolean,
): Application.AppButtonPressReleaseRequest {
return when (config.keyType) {
FlipperKeyType.INFRARED -> if (isIndexEmulateSupport) {
val indexArgs = config.index ?: error("Index args is null")
info { "#getAppButtonPressReleaseRequest by index with $config" }
appButtonPressReleaseRequest {
index = indexArgs
}
} else {
val configArgs = config.args ?: error("Config args is null")
info { "#getAppButtonPressReleaseRequest by args with $config" }
appButtonPressReleaseRequest {
args = configArgs
}
}

else -> error("#getAppButtonPressReleaseRequest Unknown button press request with config $config")
}
}

private fun getAppButtonPressRequest(
config: EmulateConfig,
isIndexEmulateSupport: Boolean,
Expand All @@ -183,6 +218,7 @@ class StartEmulateHelperImpl @Inject constructor(
args = configArgs
}
}

else -> error("Unknown button press request with config $config")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ class InfraredViewModel @Inject constructor(

try {
appStarted = emulateHelper.startEmulate(
scope,
serviceApi,
config
scope = scope,
serviceApi = serviceApi,
config = config,
)
if (appStarted && timeout != null) {
if (oneTimePress) {
Expand All @@ -150,22 +150,30 @@ class InfraredViewModel @Inject constructor(
}
}
} catch (ignored: AlreadyOpenedAppException) {
emulateHelper.stopEmulateForce(requestApi)
if (!oneTimePress) {
emulateHelper.stopEmulateForce(requestApi)
}
emulateButtonStateFlow.emit(EmulateButtonState.AppAlreadyOpenDialog)
return false
} catch (ignored: ForbiddenFrequencyException) {
emulateHelper.stopEmulateForce(requestApi)
if (!oneTimePress) {
emulateHelper.stopEmulateForce(requestApi)
}
emulateButtonStateFlow.emit(EmulateButtonState.ForbiddenFrequencyDialog)
return false
} catch (fatal: Throwable) {
error(fatal) { "Handle fatal exception on emulate infrared" }
emulateHelper.stopEmulateForce(requestApi)
if (!oneTimePress) {
emulateHelper.stopEmulateForce(requestApi)
}
emulateButtonStateFlow.emit(EmulateButtonState.Inactive())
return false
}
if (!appStarted) {
info { "Failed start emulation" }
emulateHelper.stopEmulateForce(requestApi)
if (!oneTimePress) {
emulateHelper.stopEmulateForce(requestApi)
}
emulateButtonStateFlow.emit(EmulateButtonState.Inactive())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface DispatchSignalApi : InstanceKeeper.Instance {
fun dispatch(
config: EmulateConfig,
identifier: IfrKeyIdentifier,
isOneTime: Boolean = true,
onDispatched: () -> Unit = {}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ class SetupComponentImpl @AssistedInject constructor(
),
keyType = FlipperKeyType.INFRARED,
args = signalModel.remote.name,
index = 0
index = 0,
isPressRelease = true
)
val keyIdentifier = (loadedState.response.signalResponse?.data as? SingleKeyButtonData)
?.keyIdentifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import com.squareup.anvil.annotations.ContributesBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
Expand Down Expand Up @@ -114,12 +113,12 @@ class DispatchSignalViewModel @Inject constructor(
keyPath = ffPath,
keyType = FlipperKeyType.INFRARED,
args = remote.name,
index = i
index = i,
isPressRelease = isOneTime
)
dispatch(
config = config,
identifier = identifier,
isOneTime = isOneTime,
onDispatched = onDispatched
)
}
Expand All @@ -131,7 +130,6 @@ class DispatchSignalViewModel @Inject constructor(
override fun dispatch(
config: EmulateConfig,
identifier: IfrKeyIdentifier,
isOneTime: Boolean,
onDispatched: () -> Unit
) {
if (latestDispatchJob?.isActive == true) return
Expand All @@ -151,11 +149,9 @@ class DispatchSignalViewModel @Inject constructor(
emulateHelper.startEmulate(
scope = this,
serviceApi = serviceApi,
config = config
config = config,
)
if (isOneTime) {
delay(DEFAULT_SIGNAL_DELAY)
emulateHelper.stopEmulate(this, serviceApi.requestApi)
if (config.isPressRelease) {
_state.emit(DispatchSignalApi.State.Pending)
onDispatched.invoke()
}
Expand Down Expand Up @@ -200,7 +196,6 @@ class DispatchSignalViewModel @Inject constructor(
}

companion object {
private const val DEFAULT_SIGNAL_DELAY = 500L
private const val VIBRATOR_TIME = 100L
}
}
Loading