Skip to content

Commit 93c8bf9

Browse files
committed
#1788 feat: dismiss lockscreen when launching app action from lockscreen
1 parent 64e5fd2 commit 93c8bf9

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
or you record different physical keys from the same device with the same key code.
99
- Redesign the Settings screen.
1010
- Shortcuts on the trigger screen that guide you how to set up different types of buttons.
11+
- #1788 dismiss lockscreen when launching app action from lockscreen
1112

1213
## Removed
1314

system/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,12 @@
9898
android:name=".notifications.ObserveNotificationListenersJob"
9999
android:permission="android.permission.BIND_JOB_SERVICE" />
100100

101+
<activity
102+
android:name=".apps.TrampolineActivity"
103+
android:excludeFromRecents="true"
104+
android:exported="true"
105+
android:finishOnTaskLaunch="true"
106+
android:launchMode="singleInstance"
107+
android:theme="@android:style/Theme.NoDisplay"></activity>
101108
</application>
102109
</manifest>

system/src/main/java/io/github/sds100/keymapper/system/apps/AndroidPackageManagerAdapter.kt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.github.sds100.keymapper.system.apps
22

33
import android.annotation.SuppressLint
44
import android.app.ActivityOptions
5+
import android.app.KeyguardManager
56
import android.app.PendingIntent
67
import android.content.ActivityNotFoundException
78
import android.content.BroadcastReceiver
@@ -48,6 +49,10 @@ class AndroidPackageManagerAdapter @Inject constructor(
4849
private val ctx: Context = context.applicationContext
4950
private val packageManager: PackageManager = ctx.packageManager
5051

52+
private val keyguardManager: KeyguardManager by lazy {
53+
ctx.getSystemService(KeyguardManager::class.java)
54+
}
55+
5156
private val fetchPackages: MutableSharedFlow<Unit> = MutableSharedFlow()
5257
override val onPackagesChanged: MutableSharedFlow<Unit> = MutableSharedFlow()
5358
override val installedPackages = MutableStateFlow<State<List<PackageInfo>>>(State.Loading)
@@ -62,7 +67,7 @@ class AndroidPackageManagerAdapter @Inject constructor(
6267
Intent.ACTION_PACKAGE_ADDED,
6368
Intent.ACTION_PACKAGE_REMOVED,
6469
Intent.ACTION_PACKAGE_REPLACED,
65-
-> {
70+
-> {
6671
coroutineScope.launch {
6772
fetchPackages.emit(Unit)
6873
onPackagesChanged.emit(Unit)
@@ -233,10 +238,10 @@ class AndroidPackageManagerAdapter @Inject constructor(
233238
val leanbackIntent = packageManager.getLeanbackLaunchIntentForPackage(packageName)
234239
val normalIntent = packageManager.getLaunchIntentForPackage(packageName)
235240

236-
val intent = leanbackIntent ?: normalIntent
241+
val packageIntent = leanbackIntent ?: normalIntent
237242

238243
// intent = null if the app doesn't exist
239-
if (intent == null) {
244+
if (packageIntent == null) {
240245
try {
241246
val appInfo = ctx.packageManager.getApplicationInfo(packageName, 0)
242247

@@ -250,12 +255,18 @@ class AndroidPackageManagerAdapter @Inject constructor(
250255
return KMError.AppNotFound(packageName)
251256
}
252257
} else {
253-
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
254-
PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_IMMUTABLE)
258+
// Use a trampoline activity that will dismiss the keyguard when it is locked.
259+
val intent = if (keyguardManager.isKeyguardLocked) {
260+
Intent(ctx, TrampolineActivity::class.java).apply {
261+
putExtra(TrampolineActivity.EXTRA_INTENT, packageIntent)
262+
}
255263
} else {
256-
PendingIntent.getActivity(ctx, 0, intent, 0)
264+
packageIntent
257265
}
258266

267+
val pendingIntent =
268+
PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_IMMUTABLE)
269+
259270
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
260271
val bundle = ActivityOptions.makeBasic()
261272
.setPendingIntentBackgroundActivityStartMode(
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.github.sds100.keymapper.system.apps
2+
3+
import android.app.ActivityOptions
4+
import android.app.KeyguardManager
5+
import android.app.PendingIntent
6+
import android.content.Intent
7+
import android.os.Build
8+
import android.os.Bundle
9+
import androidx.activity.ComponentActivity
10+
import androidx.core.os.BundleCompat
11+
12+
/**
13+
* Use an activity trampoline so that the keyguard is dismissed when launching activities from
14+
* the lock screen.
15+
*/
16+
class TrampolineActivity : ComponentActivity() {
17+
companion object {
18+
const val EXTRA_INTENT = "io.github.sds100.keymapper.EXTRA_INTENT"
19+
}
20+
21+
private val keyguardManager: KeyguardManager by lazy {
22+
getSystemService(KeyguardManager::class.java)
23+
}
24+
25+
override fun onCreate(savedInstanceState: Bundle?) {
26+
super.onCreate(savedInstanceState)
27+
28+
keyguardManager.requestDismissKeyguard(this, null)
29+
30+
val intentExtras = intent?.extras ?: return finish()
31+
32+
val activityIntent: Intent? =
33+
BundleCompat.getParcelable(intentExtras, EXTRA_INTENT, Intent::class.java)
34+
35+
if (activityIntent != null) {
36+
val pendingIntent =
37+
PendingIntent.getActivity(this, 0, activityIntent, PendingIntent.FLAG_IMMUTABLE)
38+
39+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
40+
val bundle = ActivityOptions.makeBasic()
41+
.setPendingIntentBackgroundActivityStartMode(
42+
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED,
43+
)
44+
.toBundle()
45+
46+
pendingIntent.send(bundle)
47+
} else {
48+
pendingIntent.send()
49+
}
50+
}
51+
52+
finish()
53+
}
54+
}

0 commit comments

Comments
 (0)