Skip to content

Commit 8ce4cc9

Browse files
authored
Merge pull request #1632 from keymapperorg/develop
Version 3.0.0 Beta 5
2 parents 7968414 + ddece2f commit 8ce4cc9

23 files changed

+635
-15
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## [3.0 Beta 5](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.5)
2+
3+
#### 6 April 2025
4+
5+
- #1625 HTTP Request action.
6+
7+
###
8+
9+
## Bug fixes
10+
11+
- #1627 open camera app action does not work when device is locked
12+
113
## [3.0 Beta 4](https://github.com/sds100/KeyMapper/releases/tag/v3.0.0-beta.4)
214

315
#### 2 April 2025

app/build.gradle

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ dependencies {
173173
// kotlin stuff
174174
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
175175
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
176-
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
176+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0"
177177

178178
// random stuff
179179
implementation "com.google.android.material:material:1.13.0-alpha12"
@@ -189,8 +189,9 @@ dependencies {
189189
implementation "dev.rikka.shizuku:api:$shizuku_version"
190190
implementation "dev.rikka.shizuku:provider:$shizuku_version"
191191
implementation "org.lsposed.hiddenapibypass:hiddenapibypass:4.3"
192-
proImplementation 'com.revenuecat.purchases:purchases:8.14.2'
192+
proImplementation 'com.revenuecat.purchases:purchases:8.15.0'
193193
proImplementation "com.airbnb.android:lottie-compose:6.6.3"
194+
implementation("com.squareup.okhttp3:okhttp:4.12.0")
194195

195196
// splitties
196197
implementation "com.louiscad.splitties:splitties-bitflags:$splitties_version"
@@ -220,15 +221,15 @@ dependencies {
220221
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
221222
implementation "androidx.room:room-runtime:$room_version"
222223
implementation "androidx.viewpager2:viewpager2:1.1.0"
223-
implementation "androidx.datastore:datastore-preferences:1.1.3"
224+
implementation "androidx.datastore:datastore-preferences:1.1.4"
224225
implementation "androidx.core:core-splashscreen:1.0.1"
225226
implementation "androidx.activity:activity-compose:1.10.1"
226227
implementation "androidx.navigation:navigation-compose:2.8.9"
227228
implementation "androidx.navigation:navigation-fragment-compose:2.8.9"
228229
ksp "androidx.room:room-compiler:$room_version"
229230

230231
// Compose
231-
Dependency composeBom = platform('androidx.compose:compose-bom-beta:2025.03.00')
232+
Dependency composeBom = platform('androidx.compose:compose-bom-beta:2025.03.01')
232233
implementation composeBom
233234
implementation 'androidx.compose.foundation:foundation'
234235
implementation "androidx.compose.ui:ui-android"
@@ -254,12 +255,12 @@ dependencies {
254255
testImplementation "org.hamcrest:hamcrest-all:1.3"
255256
testImplementation "androidx.test.ext:junit-ktx:$androidXTestExtKotlinRunnerVersion"
256257
testImplementation "androidx.test:core-ktx:1.6.1"
257-
testImplementation "org.robolectric:robolectric:4.12.1"
258+
testImplementation "org.robolectric:robolectric:4.14.1"
258259
testImplementation "androidx.arch.core:core-testing:2.2.0"
259260
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
260261
testImplementation "pl.pragmatists:JUnitParams:1.1.1"
261262
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
262-
testImplementation "org.mockito:mockito-core:5.2.0"
263+
testImplementation "org.mockito:mockito-core:5.15.2"
263264
testImplementation "org.mockito:mockito-inline:5.2.0"
264265

265266
androidTestImplementation "androidx.test.ext:junit:$androidXTestExtKotlinRunnerVersion"

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@
7777
<application
7878
android:name="io.github.sds100.keymapper.KeyMapperApp"
7979
android:allowBackup="true"
80+
android:directBootAware="true"
8081
android:icon="@mipmap/ic_launcher"
8182
android:label="@string/app_name"
82-
android:directBootAware="true"
8383
android:roundIcon="@mipmap/ic_launcher_round"
8484
android:supportsRtl="true"
8585
android:theme="@style/AppTheme.NoActionBar"
86+
android:usesCleartextTraffic="true"
8687
tools:ignore="GoogleAppIndexingWarning">
88+
<!-- Allow clear text traffic due to the HTTP Request Action. -->
8789

8890
<activity
8991
android:name=".MainActivity"

app/src/main/assets/whats-new.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Key Mapper 3.0 is here! 🎉
55
🗂️ Grouping key maps into folders with shared constraints.
66

77
🔦 You can now change the flashlight brightness. Tip: use the constraint for when the flashlight is showing to remap your volume buttons to change the brightness.
8+
🛜 Send HTTP requests with a new action.
89

910
❤️ There are also tonnes of improvements to make your key mapping experience more enjoyable.
1011

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.github.sds100.keymapper.system.camera.CameraLens
55
import io.github.sds100.keymapper.system.display.Orientation
66
import io.github.sds100.keymapper.system.intents.IntentExtraModel
77
import io.github.sds100.keymapper.system.intents.IntentTarget
8+
import io.github.sds100.keymapper.system.network.HttpMethod
89
import io.github.sds100.keymapper.system.volume.DndMode
910
import io.github.sds100.keymapper.system.volume.RingerMode
1011
import io.github.sds100.keymapper.system.volume.VolumeStream
@@ -828,4 +829,20 @@ sealed class ActionData : Comparable<ActionData> {
828829
object DeviceControls : ActionData() {
829830
override val id: ActionId = ActionId.DEVICE_CONTROLS
830831
}
832+
833+
@Serializable
834+
data class HttpRequest(
835+
val description: String,
836+
val method: HttpMethod,
837+
val url: String,
838+
val body: String,
839+
val authorizationHeader: String,
840+
) : ActionData() {
841+
override val id: ActionId = ActionId.HTTP_REQUEST
842+
843+
override fun toString(): String {
844+
// Do not leak sensitive request info to logs.
845+
return "HttpRequest(description=$description)"
846+
}
847+
}
831848
}

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import io.github.sds100.keymapper.data.entities.getData
88
import io.github.sds100.keymapper.system.camera.CameraLens
99
import io.github.sds100.keymapper.system.intents.IntentExtraModel
1010
import io.github.sds100.keymapper.system.intents.IntentTarget
11+
import io.github.sds100.keymapper.system.network.HttpMethod
1112
import io.github.sds100.keymapper.system.volume.DndMode
1213
import io.github.sds100.keymapper.system.volume.RingerMode
1314
import io.github.sds100.keymapper.system.volume.VolumeStream
1415
import io.github.sds100.keymapper.util.getKey
1516
import io.github.sds100.keymapper.util.success
1617
import io.github.sds100.keymapper.util.then
1718
import io.github.sds100.keymapper.util.valueOrNull
18-
import kotlinx.serialization.encodeToString
1919
import kotlinx.serialization.json.Json
2020
import splitties.bitflags.hasFlag
2121

@@ -496,6 +496,32 @@ object ActionDataEntityMapper {
496496
ActionId.ANSWER_PHONE_CALL -> ActionData.AnswerCall
497497
ActionId.END_PHONE_CALL -> ActionData.EndCall
498498
ActionId.DEVICE_CONTROLS -> ActionData.DeviceControls
499+
ActionId.HTTP_REQUEST -> {
500+
val method = entity.extras.getData(ActionEntity.EXTRA_HTTP_METHOD).then {
501+
HTTP_METHOD_MAP.getKey(it)!!.success()
502+
}.valueOrNull() ?: return null
503+
504+
val description =
505+
entity.extras.getData(ActionEntity.EXTRA_HTTP_DESCRIPTION).valueOrNull()
506+
?: return null
507+
508+
val url = entity.extras.getData(ActionEntity.EXTRA_HTTP_URL).valueOrNull()
509+
?: return null
510+
511+
val body = entity.extras.getData(ActionEntity.EXTRA_HTTP_BODY).valueOrNull() ?: ""
512+
513+
val authorizationHeader =
514+
entity.extras.getData(ActionEntity.EXTRA_HTTP_AUTHORIZATION_HEADER)
515+
.valueOrNull() ?: ""
516+
517+
ActionData.HttpRequest(
518+
description = description,
519+
method = method,
520+
url = url,
521+
body = body,
522+
authorizationHeader = authorizationHeader,
523+
)
524+
}
499525
}
500526
}
501527

@@ -713,6 +739,17 @@ object ActionDataEntityMapper {
713739
EntityExtra(ActionEntity.EXTRA_SOUND_FILE_DESCRIPTION, data.soundDescription),
714740
)
715741

742+
is ActionData.HttpRequest -> listOf(
743+
EntityExtra(ActionEntity.EXTRA_HTTP_DESCRIPTION, data.description),
744+
EntityExtra(ActionEntity.EXTRA_HTTP_METHOD, HTTP_METHOD_MAP[data.method]!!),
745+
EntityExtra(ActionEntity.EXTRA_HTTP_URL, data.url),
746+
EntityExtra(ActionEntity.EXTRA_HTTP_BODY, data.body),
747+
EntityExtra(
748+
ActionEntity.EXTRA_HTTP_AUTHORIZATION_HEADER,
749+
data.authorizationHeader,
750+
),
751+
)
752+
716753
else -> emptyList()
717754
}
718755

@@ -750,6 +787,14 @@ object ActionDataEntityMapper {
750787
IntentTarget.SERVICE to "SERVICE",
751788
)
752789

790+
private val HTTP_METHOD_MAP = mapOf(
791+
HttpMethod.GET to "GET",
792+
HttpMethod.POST to "POST",
793+
HttpMethod.PUT to "PUT",
794+
HttpMethod.DELETE to "DELETE",
795+
HttpMethod.PATCH to "PATCH",
796+
)
797+
753798
/**
754799
* DON'T CHANGE THESE
755800
*/
@@ -865,5 +910,6 @@ object ActionDataEntityMapper {
865910
ActionId.ANSWER_PHONE_CALL to "answer_phone_call",
866911
ActionId.END_PHONE_CALL to "end_phone_call",
867912
ActionId.DEVICE_CONTROLS to "device_controls",
913+
ActionId.HTTP_REQUEST to "http_request",
868914
)
869915
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,6 @@ enum class ActionId {
129129
ANSWER_PHONE_CALL,
130130
END_PHONE_CALL,
131131
DEVICE_CONTROLS,
132+
133+
HTTP_REQUEST,
132134
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ class ActionUiHelper(
528528
ActionData.EndCall -> getString(R.string.action_end_call)
529529

530530
ActionData.DeviceControls -> getString(R.string.action_device_controls)
531+
is ActionData.HttpRequest -> action.description
531532
}
532533

533534
fun getIcon(action: ActionData): ComposeIconInfo = when (action) {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.compose.material.icons.outlined.FlashlightOff
3232
import androidx.compose.material.icons.outlined.FlashlightOn
3333
import androidx.compose.material.icons.outlined.Fullscreen
3434
import androidx.compose.material.icons.outlined.Home
35+
import androidx.compose.material.icons.outlined.Http
3536
import androidx.compose.material.icons.outlined.Keyboard
3637
import androidx.compose.material.icons.outlined.KeyboardHide
3738
import androidx.compose.material.icons.outlined.Link
@@ -220,6 +221,7 @@ object ActionUtils {
220221
ActionId.TEXT_PASTE -> ActionCategory.CONTENT
221222
ActionId.SCREENSHOT -> ActionCategory.CONTENT
222223
ActionId.URL -> ActionCategory.CONTENT
224+
ActionId.HTTP_REQUEST -> ActionCategory.CONTENT
223225

224226
ActionId.PHONE_CALL -> ActionCategory.TELEPHONY
225227
ActionId.ANSWER_PHONE_CALL -> ActionCategory.TELEPHONY
@@ -339,6 +341,7 @@ object ActionUtils {
339341
ActionId.ANSWER_PHONE_CALL -> R.string.action_answer_call
340342
ActionId.END_PHONE_CALL -> R.string.action_end_call
341343
ActionId.DEVICE_CONTROLS -> R.string.action_device_controls
344+
ActionId.HTTP_REQUEST -> R.string.action_http_request
342345
}
343346

344347
@DrawableRes
@@ -433,7 +436,6 @@ object ActionUtils {
433436
ActionId.CONSUME_KEY_EVENT -> null
434437
ActionId.OPEN_SETTINGS -> R.drawable.ic_outline_settings_24
435438
ActionId.SHOW_POWER_MENU -> R.drawable.ic_outline_power_settings_new_24
436-
437439
ActionId.APP -> R.drawable.ic_outline_android_24
438440
ActionId.APP_SHORTCUT -> R.drawable.ic_outline_open_in_new_24
439441
ActionId.KEY_CODE -> R.drawable.ic_q_24
@@ -451,6 +453,7 @@ object ActionUtils {
451453
ActionId.ANSWER_PHONE_CALL -> R.drawable.ic_outline_call_24
452454
ActionId.END_PHONE_CALL -> R.drawable.ic_outline_call_end_24
453455
ActionId.DEVICE_CONTROLS -> R.drawable.ic_home_automation
456+
ActionId.HTTP_REQUEST -> null
454457
}
455458

456459
fun getMinApi(id: ActionId): Int = when (id) {
@@ -766,6 +769,7 @@ object ActionUtils {
766769
ActionId.ANSWER_PHONE_CALL -> Icons.Outlined.Call
767770
ActionId.END_PHONE_CALL -> Icons.Outlined.CallEnd
768771
ActionId.DEVICE_CONTROLS -> KeyMapperIcons.HomeIotDevice
772+
ActionId.HTTP_REQUEST -> Icons.Outlined.Http
769773
}
770774
}
771775

@@ -817,6 +821,7 @@ fun ActionData.isEditable(): Boolean = when (this) {
817821
is ActionData.Text,
818822
is ActionData.Url,
819823
is ActionData.PhoneCall,
824+
is ActionData.HttpRequest,
820825
-> true
821826

822827
else -> false

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fun ActionsScreen(modifier: Modifier = Modifier, viewModel: ConfigActionsViewMod
6868

6969
EnableFlashlightActionBottomSheet(viewModel.createActionDelegate)
7070
ChangeFlashlightStrengthActionBottomSheet(viewModel.createActionDelegate)
71+
HttpRequestBottomSheet(viewModel.createActionDelegate)
7172

7273
ActionsScreen(
7374
modifier = modifier,

0 commit comments

Comments
 (0)