Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
183cfe0
Merge branch 'develop' into feature/1507-flashlight-brightness
sds100 Mar 26, 2025
5aeb442
#1560 feat: configure flashlight brightness on Android 13+ and if the…
sds100 Mar 26, 2025
4aa9563
#1560 feat: test flashlight brightness while configuring the action
sds100 Mar 26, 2025
b86edcf
chore: set version to 3.0.0-beta.2
sds100 Mar 27, 2025
2642226
docs: fix redirects for floating buttons
sds100 Mar 27, 2025
bb00071
#1585 fix: Track changes when editing key maps and only prompt to dis…
sds100 Mar 27, 2025
1ef092e
Merge branch 'develop' into feature/1507-flashlight-brightness
sds100 Mar 27, 2025
e245658
#1560 add action to change flashlight brightness
sds100 Mar 27, 2025
897c7fb
#1560 docs for change flashlight brightness
sds100 Mar 27, 2025
0082cac
fix tests
sds100 Mar 27, 2025
2366068
#1369 fix: add content description for FABs
sds100 Mar 27, 2025
66a4b96
Merge pull request #1565 from keymapperorg/feature/1507-flashlight-br…
sds100 Mar 27, 2025
07a3544
#1560 chore: add to changelog
sds100 Mar 27, 2025
282c06e
show a notification for floating buttons
sds100 Mar 27, 2025
85edf19
#1582 show trigger shortcuts in similar way to action and constraint …
sds100 Mar 27, 2025
9d7c8d2
#1577 Move unsupported actions to the bottom of the list and do not a…
sds100 Mar 27, 2025
b547478
chore: bump version code
sds100 Mar 27, 2025
b7a3b1c
update changelog
sds100 Mar 27, 2025
9b76ed4
show max 5 action and constraint shortcuts
sds100 Mar 27, 2025
8d0b388
#1593 Deprecate open menu action
sds100 Mar 27, 2025
3daffd5
Merge branch 'master' into develop
sds100 Mar 27, 2025
6790b60
tests: delete FakeOnboardingUseCase.kt
sds100 Mar 27, 2025
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
22 changes: 21 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
## [3.0 Beta 1](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.1)
## [3.0 Beta 2](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.2)

#### TO BE RELEASED

_See the changes from previous 3.0 Beta releases as well._

## Added

- #1560 Action to change flashlight brightness and also set a custom brightness when enabling the flashlight.
- Prompt to unlock device when using a floating button as a trigger from the lock screen

## Changed

- #1577 Move unsupported actions to the bottom of the list and do not allow selecting root actions if root permission is not granted.
- #1593 Deprecate the 'Open menu' action by not letting new key maps use it. It is a relic of the past when most apps had a 3-dot menu with a consistent content description making it somewhat easy to identify.

## Bug fixes

- #1585 Track changes when editing key maps and only prompt to discard changes if there were indeed changes.

## [3.0 Beta 1](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.1)

#### 26 March 2025

Most of the codebase has been touched and most of the user interface has been rewritten
in Jetpack Compose, resulting in many improvements to the user experience.

Expand Down
22 changes: 4 additions & 18 deletions app/src/main/java/io/github/sds100/keymapper/BaseMainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ import com.anggrayudi.storage.extension.toDocumentFile
import io.github.sds100.keymapper.Constants.PACKAGE_NAME
import io.github.sds100.keymapper.compose.ComposeColors
import io.github.sds100.keymapper.databinding.ActivityMainBinding
import io.github.sds100.keymapper.home.HomeViewModel
import io.github.sds100.keymapper.mappings.keymaps.trigger.RecordTriggerController
import io.github.sds100.keymapper.system.accessibility.AccessibilityServiceAdapter
import io.github.sds100.keymapper.system.files.FileUtils
import io.github.sds100.keymapper.system.inputevents.MyMotionEvent
import io.github.sds100.keymapper.system.permissions.AndroidPermissionAdapter
import io.github.sds100.keymapper.system.permissions.RequestPermissionDelegate
import io.github.sds100.keymapper.util.Inject
import io.github.sds100.keymapper.util.launchRepeatOnLifecycle
import io.github.sds100.keymapper.util.ui.showPopups
import kotlinx.coroutines.Dispatchers
Expand All @@ -55,8 +53,8 @@ abstract class BaseMainActivity : AppCompatActivity() {
const val ACTION_SHOW_ACCESSIBILITY_SETTINGS_NOT_FOUND_DIALOG =
"$PACKAGE_NAME.ACTION_SHOW_ACCESSIBILITY_SETTINGS_NOT_FOUND_DIALOG"

const val ACTION_USE_ASSISTANT_TRIGGER =
"$PACKAGE_NAME.ACTION_USE_ASSISTANT_TRIGGER"
const val ACTION_USE_FLOATING_BUTTONS =
"$PACKAGE_NAME.ACTION_USE_FLOATING_BUTTONS"

const val ACTION_SAVE_FILE = "$PACKAGE_NAME.ACTION_SAVE_FILE"
const val EXTRA_FILE_URI = "$PACKAGE_NAME.EXTRA_FILE_URI"
Expand All @@ -74,10 +72,6 @@ abstract class BaseMainActivity : AppCompatActivity() {
ActivityViewModel.Factory(ServiceLocator.resourceProvider(this))
}

private val homeViewModel by viewModels<HomeViewModel> {
Inject.homeViewModel(this)
}

private val currentNightMode: Int
get() = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK

Expand Down Expand Up @@ -162,16 +156,6 @@ abstract class BaseMainActivity : AppCompatActivity() {
viewModel.onCantFindAccessibilitySettings()
viewModel.handledActivityLaunchIntent = true
}

ACTION_USE_ASSISTANT_TRIGGER -> {
findNavController(R.id.container).navigate(
NavAppDirections.actionToConfigKeymap(
keymapUid = null,
showAdvancedTriggers = true,
),
)
viewModel.handledActivityLaunchIntent = true
}
}
}

Expand Down Expand Up @@ -201,6 +185,8 @@ abstract class BaseMainActivity : AppCompatActivity() {
}

override fun onDestroy() {
UseCases.onboarding(this).shownAppIntro = true

viewModel.previousNightMode = currentNightMode
unregisterReceiver(broadcastReceiver)
super.onDestroy()
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/io/github/sds100/keymapper/UseCases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ object UseCases {
fun createAction(ctx: Context) = CreateActionUseCaseImpl(
ServiceLocator.inputMethodAdapter(ctx),
ServiceLocator.systemFeatureAdapter(ctx),
ServiceLocator.cameraAdapter(ctx),
ServiceLocator.permissionAdapter(ctx),
)

private fun keyMapperImeMessenger(
Expand Down
31 changes: 29 additions & 2 deletions app/src/main/java/io/github/sds100/keymapper/actions/ActionData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,46 @@ sealed class ActionData : Comparable<ActionData> {
}

@Serializable
data class Toggle(override val lens: CameraLens) : Flashlight() {
data class Toggle(
override val lens: CameraLens,
/**
* Strength is null if the default strength should be used. This is a percentage
* of the flash strength so key maps can be exported to other devices with potentially
* different strength levels.
*/
val strengthPercent: Float?,
) : Flashlight() {
override val id = ActionId.TOGGLE_FLASHLIGHT
}

@Serializable
data class Enable(override val lens: CameraLens) : Flashlight() {
data class Enable(
override val lens: CameraLens,
/**
* Strength is null if the default strength should be used. This is a percentage
* of the flash strength so key maps can be exported to other devices with potentially
* different strength levels.
*/
val strengthPercent: Float?,
) : Flashlight() {
override val id = ActionId.ENABLE_FLASHLIGHT
}

@Serializable
data class Disable(override val lens: CameraLens) : Flashlight() {
override val id = ActionId.DISABLE_FLASHLIGHT
}

@Serializable
data class ChangeStrength(
override val lens: CameraLens,
/**
* This can be positive or negative to increase/decrease respectively.
*/
val percent: Float,
) : Flashlight() {
override val id = ActionId.CHANGE_FLASHLIGHT_STRENGTH
}
}

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,26 +286,40 @@ object ActionDataEntityMapper {

ActionId.TOGGLE_FLASHLIGHT,
ActionId.ENABLE_FLASHLIGHT,
ActionId.DISABLE_FLASHLIGHT,
ActionId.CHANGE_FLASHLIGHT_STRENGTH,
-> {
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
LENS_MAP.getKey(it)!!.success()
}.valueOrNull() ?: return null

when (actionId) {
ActionId.TOGGLE_FLASHLIGHT ->
ActionData.Flashlight.Toggle(lens)

ActionId.ENABLE_FLASHLIGHT ->
ActionData.Flashlight.Enable(lens)
val flashStrength = entity.extras.getData(ActionEntity.EXTRA_FLASH_STRENGTH).then {
it.toFloatOrNull().success()
}.valueOrNull()

ActionId.DISABLE_FLASHLIGHT ->
ActionData.Flashlight.Disable(lens)
when (actionId) {
ActionId.TOGGLE_FLASHLIGHT -> ActionData.Flashlight.Toggle(lens, flashStrength)
ActionId.ENABLE_FLASHLIGHT -> ActionData.Flashlight.Enable(lens, flashStrength)

ActionId.CHANGE_FLASHLIGHT_STRENGTH -> {
flashStrength ?: return null
ActionData.Flashlight.ChangeStrength(
lens,
flashStrength,
)
}

else -> throw Exception("don't know how to create system action for $actionId")
}
}

ActionId.DISABLE_FLASHLIGHT,
-> {
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
LENS_MAP.getKey(it)!!.success()
}.valueOrNull() ?: return null
ActionData.Flashlight.Disable(lens)
}

ActionId.TOGGLE_DND_MODE,
ActionId.ENABLE_DND_MODE,
-> {
Expand Down Expand Up @@ -614,9 +628,48 @@ object ActionDataEntityMapper {
),
)

is ActionData.Flashlight -> listOf(
EntityExtra(ActionEntity.EXTRA_LENS, LENS_MAP[data.lens]!!),
)
is ActionData.Flashlight -> {
val lensExtra = EntityExtra(ActionEntity.EXTRA_LENS, LENS_MAP[data.lens]!!)

when (data) {
is ActionData.Flashlight.Toggle -> buildList {
add(lensExtra)

if (data.strengthPercent != null) {
add(
EntityExtra(
ActionEntity.EXTRA_FLASH_STRENGTH,
data.strengthPercent.toString(),
),
)
}
}

is ActionData.Flashlight.Enable -> buildList {
add(lensExtra)

if (data.strengthPercent != null) {
add(
EntityExtra(
ActionEntity.EXTRA_FLASH_STRENGTH,
data.strengthPercent.toString(),
),
)
}
}

is ActionData.Flashlight.Disable -> listOf(lensExtra)
is ActionData.Flashlight.ChangeStrength -> buildList {
add(lensExtra)
add(
EntityExtra(
ActionEntity.EXTRA_FLASH_STRENGTH,
data.percent.toString(),
),
)
}
}
}

is ActionData.SwitchKeyboard -> listOf(
EntityExtra(ActionEntity.EXTRA_IME_ID, data.imeId),
Expand Down Expand Up @@ -773,6 +826,7 @@ object ActionDataEntityMapper {
ActionId.TOGGLE_FLASHLIGHT to "toggle_flashlight",
ActionId.ENABLE_FLASHLIGHT to "enable_flashlight",
ActionId.DISABLE_FLASHLIGHT to "disable_flashlight",
ActionId.CHANGE_FLASHLIGHT_STRENGTH to "change_flashlight_strength",

ActionId.ENABLE_NFC to "nfc_enable",
ActionId.DISABLE_NFC to "nfc_disable",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ class LazyActionErrorSnapshot(
private val soundsManager: SoundsManager,
shizukuAdapter: ShizukuAdapter,
) : ActionErrorSnapshot,
IsActionSupportedUseCase by IsActionSupportedUseCaseImpl(systemFeatureAdapter) {
IsActionSupportedUseCase by IsActionSupportedUseCaseImpl(
systemFeatureAdapter,
cameraAdapter,
permissionAdapter,
) {
private val keyMapperImeHelper = KeyMapperImeHelper(inputMethodAdapter)

private val isCompatibleImeEnabled by lazy { keyMapperImeHelper.isCompatibleImeEnabled() }
Expand All @@ -34,11 +38,11 @@ class LazyActionErrorSnapshot(
private val grantedPermissions: MutableMap<Permission, Boolean> = mutableMapOf()
private val flashLenses by lazy {
buildSet {
if (cameraAdapter.hasFlashFacing(CameraLens.FRONT)) {
if (cameraAdapter.getFlashInfo(CameraLens.FRONT) != null) {
add(CameraLens.FRONT)
}

if (cameraAdapter.hasFlashFacing(CameraLens.BACK)) {
if (cameraAdapter.getFlashInfo(CameraLens.BACK) != null) {
add(CameraLens.BACK)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum class ActionId {
TOGGLE_FLASHLIGHT,
ENABLE_FLASHLIGHT,
DISABLE_FLASHLIGHT,
CHANGE_FLASHLIGHT_STRENGTH,

ENABLE_NFC,
DISABLE_NFC,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.sds100.keymapper.actions

import android.os.Build
import android.view.KeyEvent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Android
Expand Down Expand Up @@ -240,15 +241,56 @@ class ActionUiHelper(
)

is ActionData.Flashlight -> {
val resId = when (action) {
is ActionData.Flashlight.Toggle -> R.string.action_toggle_flashlight_formatted
is ActionData.Flashlight.Enable -> R.string.action_enable_flashlight_formatted
is ActionData.Flashlight.Disable -> R.string.action_disable_flashlight_formatted
}

val lensString = getString(CameraLensUtils.getLabel(action.lens))

getString(resId, lensString)
when (action) {
is ActionData.Flashlight.Toggle -> {
if (action.strengthPercent == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
getString(R.string.action_toggle_flashlight_formatted, lensString)
} else {
getString(
R.string.action_toggle_flashlight_with_strength,
arrayOf(
lensString,
(action.strengthPercent * 100).toInt(),
),
)
}
}

is ActionData.Flashlight.Enable -> {
if (action.strengthPercent == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
getString(R.string.action_enable_flashlight_formatted, lensString)
} else {
getString(
R.string.action_enable_flashlight_with_strength,
arrayOf(
lensString,
(action.strengthPercent * 100).toInt(),
),
)
}
}

is ActionData.Flashlight.Disable -> getString(
R.string.action_disable_flashlight_formatted,
lensString,
)

is ActionData.Flashlight.ChangeStrength -> {
if (action.percent > 0) {
getString(
R.string.action_flashlight_increase_strength_formatted,
arrayOf(lensString, (action.percent * 100).toInt()),
)
} else {
getString(
R.string.action_flashlight_decrease_strength_formatted,
arrayOf(lensString, (action.percent * 100).toInt()),
)
}
}
}
}

is ActionData.SwitchKeyboard -> getInputMethodLabel(action.imeId).handle(
Expand Down
Loading