Skip to content

Commit 7df3d99

Browse files
authored
Merge pull request #1594 from keymapperorg/develop
Version 3.0.0 Beta 2
2 parents 3b1c880 + 6790b60 commit 7df3d99

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1594
-308
lines changed

CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
1-
## [3.0 Beta 1](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.1)
1+
## [3.0 Beta 2](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.2)
22

33
#### TO BE RELEASED
44

5+
_See the changes from previous 3.0 Beta releases as well._
6+
7+
## Added
8+
9+
- #1560 Action to change flashlight brightness and also set a custom brightness when enabling the flashlight.
10+
- Prompt to unlock device when using a floating button as a trigger from the lock screen
11+
12+
## Changed
13+
14+
- #1577 Move unsupported actions to the bottom of the list and do not allow selecting root actions if root permission is not granted.
15+
- #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.
16+
17+
## Bug fixes
18+
19+
- #1585 Track changes when editing key maps and only prompt to discard changes if there were indeed changes.
20+
21+
## [3.0 Beta 1](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.1)
22+
23+
#### 26 March 2025
24+
525
Most of the codebase has been touched and most of the user interface has been rewritten
626
in Jetpack Compose, resulting in many improvements to the user experience.
727

app/src/main/java/io/github/sds100/keymapper/BaseMainActivity.kt

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@ import com.anggrayudi.storage.extension.toDocumentFile
2929
import io.github.sds100.keymapper.Constants.PACKAGE_NAME
3030
import io.github.sds100.keymapper.compose.ComposeColors
3131
import io.github.sds100.keymapper.databinding.ActivityMainBinding
32-
import io.github.sds100.keymapper.home.HomeViewModel
3332
import io.github.sds100.keymapper.mappings.keymaps.trigger.RecordTriggerController
3433
import io.github.sds100.keymapper.system.accessibility.AccessibilityServiceAdapter
3534
import io.github.sds100.keymapper.system.files.FileUtils
3635
import io.github.sds100.keymapper.system.inputevents.MyMotionEvent
3736
import io.github.sds100.keymapper.system.permissions.AndroidPermissionAdapter
3837
import io.github.sds100.keymapper.system.permissions.RequestPermissionDelegate
39-
import io.github.sds100.keymapper.util.Inject
4038
import io.github.sds100.keymapper.util.launchRepeatOnLifecycle
4139
import io.github.sds100.keymapper.util.ui.showPopups
4240
import kotlinx.coroutines.Dispatchers
@@ -55,8 +53,8 @@ abstract class BaseMainActivity : AppCompatActivity() {
5553
const val ACTION_SHOW_ACCESSIBILITY_SETTINGS_NOT_FOUND_DIALOG =
5654
"$PACKAGE_NAME.ACTION_SHOW_ACCESSIBILITY_SETTINGS_NOT_FOUND_DIALOG"
5755

58-
const val ACTION_USE_ASSISTANT_TRIGGER =
59-
"$PACKAGE_NAME.ACTION_USE_ASSISTANT_TRIGGER"
56+
const val ACTION_USE_FLOATING_BUTTONS =
57+
"$PACKAGE_NAME.ACTION_USE_FLOATING_BUTTONS"
6058

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

77-
private val homeViewModel by viewModels<HomeViewModel> {
78-
Inject.homeViewModel(this)
79-
}
80-
8175
private val currentNightMode: Int
8276
get() = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
8377

@@ -162,16 +156,6 @@ abstract class BaseMainActivity : AppCompatActivity() {
162156
viewModel.onCantFindAccessibilitySettings()
163157
viewModel.handledActivityLaunchIntent = true
164158
}
165-
166-
ACTION_USE_ASSISTANT_TRIGGER -> {
167-
findNavController(R.id.container).navigate(
168-
NavAppDirections.actionToConfigKeymap(
169-
keymapUid = null,
170-
showAdvancedTriggers = true,
171-
),
172-
)
173-
viewModel.handledActivityLaunchIntent = true
174-
}
175159
}
176160
}
177161

@@ -201,6 +185,8 @@ abstract class BaseMainActivity : AppCompatActivity() {
201185
}
202186

203187
override fun onDestroy() {
188+
UseCases.onboarding(this).shownAppIntro = true
189+
204190
viewModel.previousNightMode = currentNightMode
205191
unregisterReceiver(broadcastReceiver)
206192
super.onDestroy()

app/src/main/java/io/github/sds100/keymapper/UseCases.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ object UseCases {
194194
fun createAction(ctx: Context) = CreateActionUseCaseImpl(
195195
ServiceLocator.inputMethodAdapter(ctx),
196196
ServiceLocator.systemFeatureAdapter(ctx),
197+
ServiceLocator.cameraAdapter(ctx),
198+
ServiceLocator.permissionAdapter(ctx),
197199
)
198200

199201
private fun keyMapperImeMessenger(

app/src/main/java/io/github/sds100/keymapper/actions/ActionData.kt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,19 +180,46 @@ sealed class ActionData : Comparable<ActionData> {
180180
}
181181

182182
@Serializable
183-
data class Toggle(override val lens: CameraLens) : Flashlight() {
183+
data class Toggle(
184+
override val lens: CameraLens,
185+
/**
186+
* Strength is null if the default strength should be used. This is a percentage
187+
* of the flash strength so key maps can be exported to other devices with potentially
188+
* different strength levels.
189+
*/
190+
val strengthPercent: Float?,
191+
) : Flashlight() {
184192
override val id = ActionId.TOGGLE_FLASHLIGHT
185193
}
186194

187195
@Serializable
188-
data class Enable(override val lens: CameraLens) : Flashlight() {
196+
data class Enable(
197+
override val lens: CameraLens,
198+
/**
199+
* Strength is null if the default strength should be used. This is a percentage
200+
* of the flash strength so key maps can be exported to other devices with potentially
201+
* different strength levels.
202+
*/
203+
val strengthPercent: Float?,
204+
) : Flashlight() {
189205
override val id = ActionId.ENABLE_FLASHLIGHT
190206
}
191207

192208
@Serializable
193209
data class Disable(override val lens: CameraLens) : Flashlight() {
194210
override val id = ActionId.DISABLE_FLASHLIGHT
195211
}
212+
213+
@Serializable
214+
data class ChangeStrength(
215+
override val lens: CameraLens,
216+
/**
217+
* This can be positive or negative to increase/decrease respectively.
218+
*/
219+
val percent: Float,
220+
) : Flashlight() {
221+
override val id = ActionId.CHANGE_FLASHLIGHT_STRENGTH
222+
}
196223
}
197224

198225
@Serializable

app/src/main/java/io/github/sds100/keymapper/actions/ActionDataEntityMapper.kt

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -286,26 +286,40 @@ object ActionDataEntityMapper {
286286

287287
ActionId.TOGGLE_FLASHLIGHT,
288288
ActionId.ENABLE_FLASHLIGHT,
289-
ActionId.DISABLE_FLASHLIGHT,
289+
ActionId.CHANGE_FLASHLIGHT_STRENGTH,
290290
-> {
291291
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
292292
LENS_MAP.getKey(it)!!.success()
293293
}.valueOrNull() ?: return null
294294

295-
when (actionId) {
296-
ActionId.TOGGLE_FLASHLIGHT ->
297-
ActionData.Flashlight.Toggle(lens)
298-
299-
ActionId.ENABLE_FLASHLIGHT ->
300-
ActionData.Flashlight.Enable(lens)
295+
val flashStrength = entity.extras.getData(ActionEntity.EXTRA_FLASH_STRENGTH).then {
296+
it.toFloatOrNull().success()
297+
}.valueOrNull()
301298

302-
ActionId.DISABLE_FLASHLIGHT ->
303-
ActionData.Flashlight.Disable(lens)
299+
when (actionId) {
300+
ActionId.TOGGLE_FLASHLIGHT -> ActionData.Flashlight.Toggle(lens, flashStrength)
301+
ActionId.ENABLE_FLASHLIGHT -> ActionData.Flashlight.Enable(lens, flashStrength)
302+
303+
ActionId.CHANGE_FLASHLIGHT_STRENGTH -> {
304+
flashStrength ?: return null
305+
ActionData.Flashlight.ChangeStrength(
306+
lens,
307+
flashStrength,
308+
)
309+
}
304310

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

315+
ActionId.DISABLE_FLASHLIGHT,
316+
-> {
317+
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
318+
LENS_MAP.getKey(it)!!.success()
319+
}.valueOrNull() ?: return null
320+
ActionData.Flashlight.Disable(lens)
321+
}
322+
309323
ActionId.TOGGLE_DND_MODE,
310324
ActionId.ENABLE_DND_MODE,
311325
-> {
@@ -614,9 +628,48 @@ object ActionDataEntityMapper {
614628
),
615629
)
616630

617-
is ActionData.Flashlight -> listOf(
618-
EntityExtra(ActionEntity.EXTRA_LENS, LENS_MAP[data.lens]!!),
619-
)
631+
is ActionData.Flashlight -> {
632+
val lensExtra = EntityExtra(ActionEntity.EXTRA_LENS, LENS_MAP[data.lens]!!)
633+
634+
when (data) {
635+
is ActionData.Flashlight.Toggle -> buildList {
636+
add(lensExtra)
637+
638+
if (data.strengthPercent != null) {
639+
add(
640+
EntityExtra(
641+
ActionEntity.EXTRA_FLASH_STRENGTH,
642+
data.strengthPercent.toString(),
643+
),
644+
)
645+
}
646+
}
647+
648+
is ActionData.Flashlight.Enable -> buildList {
649+
add(lensExtra)
650+
651+
if (data.strengthPercent != null) {
652+
add(
653+
EntityExtra(
654+
ActionEntity.EXTRA_FLASH_STRENGTH,
655+
data.strengthPercent.toString(),
656+
),
657+
)
658+
}
659+
}
660+
661+
is ActionData.Flashlight.Disable -> listOf(lensExtra)
662+
is ActionData.Flashlight.ChangeStrength -> buildList {
663+
add(lensExtra)
664+
add(
665+
EntityExtra(
666+
ActionEntity.EXTRA_FLASH_STRENGTH,
667+
data.percent.toString(),
668+
),
669+
)
670+
}
671+
}
672+
}
620673

621674
is ActionData.SwitchKeyboard -> listOf(
622675
EntityExtra(ActionEntity.EXTRA_IME_ID, data.imeId),
@@ -773,6 +826,7 @@ object ActionDataEntityMapper {
773826
ActionId.TOGGLE_FLASHLIGHT to "toggle_flashlight",
774827
ActionId.ENABLE_FLASHLIGHT to "enable_flashlight",
775828
ActionId.DISABLE_FLASHLIGHT to "disable_flashlight",
829+
ActionId.CHANGE_FLASHLIGHT_STRENGTH to "change_flashlight_strength",
776830

777831
ActionId.ENABLE_NFC to "nfc_enable",
778832
ActionId.DISABLE_NFC to "nfc_disable",

app/src/main/java/io/github/sds100/keymapper/actions/ActionErrorSnapshot.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ class LazyActionErrorSnapshot(
2323
private val soundsManager: SoundsManager,
2424
shizukuAdapter: ShizukuAdapter,
2525
) : ActionErrorSnapshot,
26-
IsActionSupportedUseCase by IsActionSupportedUseCaseImpl(systemFeatureAdapter) {
26+
IsActionSupportedUseCase by IsActionSupportedUseCaseImpl(
27+
systemFeatureAdapter,
28+
cameraAdapter,
29+
permissionAdapter,
30+
) {
2731
private val keyMapperImeHelper = KeyMapperImeHelper(inputMethodAdapter)
2832

2933
private val isCompatibleImeEnabled by lazy { keyMapperImeHelper.isCompatibleImeEnabled() }
@@ -34,11 +38,11 @@ class LazyActionErrorSnapshot(
3438
private val grantedPermissions: MutableMap<Permission, Boolean> = mutableMapOf()
3539
private val flashLenses by lazy {
3640
buildSet {
37-
if (cameraAdapter.hasFlashFacing(CameraLens.FRONT)) {
41+
if (cameraAdapter.getFlashInfo(CameraLens.FRONT) != null) {
3842
add(CameraLens.FRONT)
3943
}
4044

41-
if (cameraAdapter.hasFlashFacing(CameraLens.BACK)) {
45+
if (cameraAdapter.getFlashInfo(CameraLens.BACK) != null) {
4246
add(CameraLens.BACK)
4347
}
4448
}

app/src/main/java/io/github/sds100/keymapper/actions/ActionId.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ enum class ActionId {
8989
TOGGLE_FLASHLIGHT,
9090
ENABLE_FLASHLIGHT,
9191
DISABLE_FLASHLIGHT,
92+
CHANGE_FLASHLIGHT_STRENGTH,
9293

9394
ENABLE_NFC,
9495
DISABLE_NFC,

app/src/main/java/io/github/sds100/keymapper/actions/ActionUiHelper.kt

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.sds100.keymapper.actions
22

3+
import android.os.Build
34
import android.view.KeyEvent
45
import androidx.compose.material.icons.Icons
56
import androidx.compose.material.icons.outlined.Android
@@ -240,15 +241,56 @@ class ActionUiHelper(
240241
)
241242

242243
is ActionData.Flashlight -> {
243-
val resId = when (action) {
244-
is ActionData.Flashlight.Toggle -> R.string.action_toggle_flashlight_formatted
245-
is ActionData.Flashlight.Enable -> R.string.action_enable_flashlight_formatted
246-
is ActionData.Flashlight.Disable -> R.string.action_disable_flashlight_formatted
247-
}
248-
249244
val lensString = getString(CameraLensUtils.getLabel(action.lens))
250245

251-
getString(resId, lensString)
246+
when (action) {
247+
is ActionData.Flashlight.Toggle -> {
248+
if (action.strengthPercent == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
249+
getString(R.string.action_toggle_flashlight_formatted, lensString)
250+
} else {
251+
getString(
252+
R.string.action_toggle_flashlight_with_strength,
253+
arrayOf(
254+
lensString,
255+
(action.strengthPercent * 100).toInt(),
256+
),
257+
)
258+
}
259+
}
260+
261+
is ActionData.Flashlight.Enable -> {
262+
if (action.strengthPercent == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
263+
getString(R.string.action_enable_flashlight_formatted, lensString)
264+
} else {
265+
getString(
266+
R.string.action_enable_flashlight_with_strength,
267+
arrayOf(
268+
lensString,
269+
(action.strengthPercent * 100).toInt(),
270+
),
271+
)
272+
}
273+
}
274+
275+
is ActionData.Flashlight.Disable -> getString(
276+
R.string.action_disable_flashlight_formatted,
277+
lensString,
278+
)
279+
280+
is ActionData.Flashlight.ChangeStrength -> {
281+
if (action.percent > 0) {
282+
getString(
283+
R.string.action_flashlight_increase_strength_formatted,
284+
arrayOf(lensString, (action.percent * 100).toInt()),
285+
)
286+
} else {
287+
getString(
288+
R.string.action_flashlight_decrease_strength_formatted,
289+
arrayOf(lensString, (action.percent * 100).toInt()),
290+
)
291+
}
292+
}
293+
}
252294
}
253295

254296
is ActionData.SwitchKeyboard -> getInputMethodLabel(action.imeId).handle(

0 commit comments

Comments
 (0)