Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

1274 set key mapper as the device assistant to trigger key maps #1297

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
76840fe
chore: add pro build flavor
sds100 Aug 11, 2024
c7445f8
Merge branch 'refs/heads/develop' into develop-pro
sds100 Aug 11, 2024
09bd3c1
#1274 add empty assistant trigger fragment
sds100 Aug 13, 2024
bd4768d
fix KeyMapController
sds100 Aug 13, 2024
b353671
chore: upgrade kotlin version
sds100 Aug 13, 2024
aa9986f
#1274 use build flavor source directory rather than gradle module
sds100 Aug 13, 2024
e92d6d3
#1274 update text for free version
sds100 Aug 13, 2024
a7d3fbc
#1274 add billing library dependency for pro build
sds100 Aug 13, 2024
6d3dde3
Merge branch 'develop' into 1274-set-key-mapper-as-the-device-assista…
sds100 Aug 13, 2024
03242f8
Merge branch 'develop' into 1274-set-key-mapper-as-the-device-assista…
sds100 Sep 14, 2024
e30e30e
delete home tab for assistant trigger
sds100 Sep 14, 2024
f738776
tests: duplicate shared test utils across android and unit tests beca…
sds100 Sep 16, 2024
731a329
#1297: send events to accessibility service asynchronously
sds100 Sep 16, 2024
3c39f57
#1297: make accessibility service controller an abstract class
sds100 Sep 16, 2024
6652bd4
Merge branch 'refs/heads/develop' into 1274-set-key-mapper-as-the-dev…
sds100 Sep 26, 2024
5be22b9
#1297 change trigger screen placeholder text to mention advanced trig…
sds100 Sep 26, 2024
3c5b7e1
#1297 only show the trigger mode buttons if there are keys recorded
sds100 Sep 26, 2024
7cdca46
#1297 add theme for jetpack compose
sds100 Sep 26, 2024
286b0bf
#1297 add empty Jetpack Compose record trigger button
sds100 Sep 26, 2024
8f57a60
#1297 use dynamic Material You colors for compose theme
sds100 Sep 26, 2024
00bf278
fix (ConfigMappingFragment): Don't show the swipe animations for reac…
sds100 Sep 26, 2024
1433ee5
#1297 complete new record trigger button
sds100 Sep 28, 2024
8df65ce
#1297 create empty bottom sheet for choosing advanced triggers
sds100 Sep 29, 2024
6519be5
#1297 create stubbed advanced triggers bottom sheet for free build
sds100 Sep 29, 2024
b16c234
#1297 add NEW! badge to advanced triggers button
sds100 Sep 29, 2024
7f32657
#1297 add system bars padding to advanced triggers bottomsheet
sds100 Sep 29, 2024
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
23 changes: 23 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,22 @@ android {
}
}

flavorDimensions = ["pro"]
productFlavors {
free {
dimension "pro"
}
pro {
dimension "pro"
}
}

buildFeatures {
dataBinding true
viewBinding true
aidl true
buildConfig true
compose true
}

compileOptions {
Expand All @@ -95,6 +106,10 @@ android {
kapt {
correctErrorTypes = true
}

composeOptions {
kotlinCompilerExtensionVersion "1.5.10"
}
}

android.sourceSets {
Expand Down Expand Up @@ -145,6 +160,8 @@ dependencies {
implementation "dev.rikka.shizuku:api:$shizuku_version"
implementation "dev.rikka.shizuku:provider:$shizuku_version"
implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3'
proImplementation "com.android.billingclient:billing:7.1.0"
proImplementation "com.android.billingclient:billing-ktx:7.1.0"

// splitties
implementation "com.louiscad.splitties:splitties-bitflags:$splitties_version"
Expand Down Expand Up @@ -179,6 +196,12 @@ dependencies {
implementation "androidx.core:core-splashscreen:1.0.1"
kapt "androidx.room:room-compiler:$room_version"

// Compose
implementation 'androidx.compose.ui:ui-android:1.7.2'
implementation 'androidx.compose.material3:material3-android:1.3.0'
implementation 'androidx.compose.ui:ui-tooling-preview-android:1.7.2'
debugImplementation 'androidx.compose.ui:ui-tooling:1.7.2'

// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6'

def junitVersion = "4.13.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.github.sds100.keymapper.mappings.keymaps.trigger

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SheetState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import io.github.sds100.keymapper.R
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AdvancedTriggersBottomSheet(
modifier: Modifier = Modifier,
onDismissRequest: () -> Unit,
sheetState: SheetState,
) {
val scope = rememberCoroutineScope()

ModalBottomSheet(
modifier = modifier,
onDismissRequest = onDismissRequest,
sheetState = sheetState,
) {
Text("I am free build.")
IconButton(onClick = {
scope.launch {
sheetState.hide()
onDismissRequest()
}
}) {
Icon(
Icons.Default.Close,
contentDescription = stringResource(R.string.button_dismiss_advanced_triggers_sheet_content_description),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.github.sds100.keymapper.system.accessibility

import io.github.sds100.keymapper.actions.PerformActionsUseCase
import io.github.sds100.keymapper.constraints.DetectConstraintsUseCase
import io.github.sds100.keymapper.data.repositories.PreferenceRepository
import io.github.sds100.keymapper.mappings.PauseMappingsUseCase
import io.github.sds100.keymapper.mappings.fingerprintmaps.DetectFingerprintMapsUseCase
import io.github.sds100.keymapper.mappings.keymaps.detection.DetectKeyMapsUseCase
import io.github.sds100.keymapper.reroutekeyevents.RerouteKeyEventsUseCase
import io.github.sds100.keymapper.system.devices.DevicesAdapter
import io.github.sds100.keymapper.system.inputmethod.InputMethodAdapter
import io.github.sds100.keymapper.system.root.SuAdapter
import io.github.sds100.keymapper.util.ServiceEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow

class AccessibilityServiceController(
coroutineScope: CoroutineScope,
accessibilityService: IAccessibilityService,
inputEvents: SharedFlow<ServiceEvent>,
outputEvents: MutableSharedFlow<ServiceEvent>,
detectConstraintsUseCase: DetectConstraintsUseCase,
performActionsUseCase: PerformActionsUseCase,
detectKeyMapsUseCase: DetectKeyMapsUseCase,
detectFingerprintMapsUseCase: DetectFingerprintMapsUseCase,
rerouteKeyEventsUseCase: RerouteKeyEventsUseCase,
pauseMappingsUseCase: PauseMappingsUseCase,
devicesAdapter: DevicesAdapter,
suAdapter: SuAdapter,
inputMethodAdapter: InputMethodAdapter,
settingsRepository: PreferenceRepository,
) : BaseAccessibilityServiceController(
coroutineScope,
accessibilityService,
inputEvents,
outputEvents,
detectConstraintsUseCase,
performActionsUseCase,
detectKeyMapsUseCase,
detectFingerprintMapsUseCase,
rerouteKeyEventsUseCase,
pauseMappingsUseCase,
devicesAdapter,
suAdapter,
inputMethodAdapter,
settingsRepository
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.github.sds100.keymapper.compose

import androidx.compose.ui.graphics.Color

object ComposeColors {
val primaryLight = Color(0xFF175DB2)
val onPrimaryLight = Color(0xFFFFFFFF)
val primaryContainerLight = Color(0xFFD6E3FF)
val onPrimaryContainerLight = Color(0xFF001B3F)
val secondaryLight = Color(0xFF005EB5)
val onSecondaryLight = Color(0xFFFFFFFF)
val secondaryContainerLight = Color(0xFF001B3D)
val onSecondaryContainerLight = Color(0xFFD4E3FF)
val tertiaryLight = Color(0xFF0061A3)
val onTertiaryLight = Color(0xFFFFFFFF)
val tertiaryContainerLight = Color(0xFFCFE4FF)
val onTertiaryContainerLight = Color(0xFF001D36)
val errorLight = Color(0xFFBA1B1B)
val onErrorLight = Color(0xFFFFFFFF)
val errorContainerLight = Color(0xFFFFDAD4)
val onErrorContainerLight = Color(0xFF410001)
val backgroundLight = Color(0xFFFDFBFF)
val onBackgroundLight = Color(0xFF1A1B1F)
val surfaceLight = Color(0xFFFDFBFF)
val onSurfaceLight = Color(0xFF1A1B1F)
val surfaceVariantLight = Color(0xFFE0E2EC)
val onSurfaceVariantLight = Color(0xFF44474F)
val outlineLight = Color(0xFF74777F)
val outlineVariantLight = Color(0xFFBFC8CA)
val inverseSurfaceLight = Color(0xFF2F3034)
val inverseOnSurfaceLight = Color(0xFFF2F0F4)
val inversePrimaryLight = Color(0xFFA8C7FF)
val redLight = Color(0xffd32f2f)
val onRedLight = Color(0xFFFFFFFF)

val primaryDark = Color(0xFFA8C7FF)
val onPrimaryDark = Color(0xFF002F66)
val primaryContainerDark = Color(0xFF004590)
val onPrimaryContainerDark = Color(0xFFD6E3FF)
val secondaryDark = Color(0xFFB1CBD0)
val onSecondaryDark = Color(0xFF003063)
val secondaryContainerDark = Color(0xFF00468A)
val onSecondaryContainerDark = Color(0xFFD4E3FF)
val tertiaryDark = Color(0xFF9BCAFF)
val onTertiaryDark = Color(0xFF003259)
val tertiaryContainerDark = Color(0xFF00497E)
val onTertiaryContainerDark = Color(0xFFCFE4FF)
val errorDark = Color(0xFFFFB4A9)
val onErrorDark = Color(0xFF930006)
val errorContainerDark = Color(0xFF93000A)
val onErrorContainerDark = Color(0xFFFFDAD4)
val backgroundDark = Color(0xFF1A1B1F)
val onBackgroundDark = Color(0xFFE3E2E6)
val surfaceDark = Color(0xFF1A1B1F)
val onSurfaceDark = Color(0xFFE3E2E6)
val surfaceVariantDark = Color(0xFF44474F)
val onSurfaceVariantDark = Color(0xFFC4C6CF)
val outlineDark = Color(0xFF8D9099)
val outlineVariantDark = Color(0xFF3F484A)
val inverseSurfaceDark = Color(0xFFE3E2E6)
val inverseOnSurfaceDark = Color(0xFF1A1B1F)
val redDark = Color(0xffff7961)
val onRedDark = Color(0xFFFFFFFF)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.sds100.keymapper.compose

import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.Color

/**
* Stores the custom colors in a palette that changes
* depending on the light/dark theme. A CompositionLocalProvider
* is used in the KeyMapperTheme to provide the correct palette in a similar
* way to how MaterialTheme.current works.
*/
@Immutable
data class ComposeCustomColors(
val red: Color = Color.Unspecified,
val onRed: Color = Color.Unspecified,
) {
companion object {
val LightPalette = ComposeCustomColors(
red = ComposeColors.redLight,
onRed = ComposeColors.onRedLight,
)

val DarkPalette = ComposeCustomColors(
red = ComposeColors.redDark,
onRed = ComposeColors.onRedDark,
)
}
}
119 changes: 119 additions & 0 deletions app/src/main/java/io/github/sds100/keymapper/compose/ComposeTheme.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package io.github.sds100.keymapper.compose

import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat

object ComposeTheme {
val lightScheme = lightColorScheme(
primary = ComposeColors.primaryLight,
onPrimary = ComposeColors.onPrimaryLight,
primaryContainer = ComposeColors.primaryContainerLight,
onPrimaryContainer = ComposeColors.onPrimaryContainerLight,
secondary = ComposeColors.secondaryLight,
onSecondary = ComposeColors.onSecondaryLight,
secondaryContainer = ComposeColors.secondaryContainerLight,
onSecondaryContainer = ComposeColors.onSecondaryContainerLight,
tertiary = ComposeColors.tertiaryLight,
onTertiary = ComposeColors.onTertiaryLight,
tertiaryContainer = ComposeColors.tertiaryContainerLight,
onTertiaryContainer = ComposeColors.onTertiaryContainerLight,
error = ComposeColors.errorLight,
onError = ComposeColors.onErrorLight,
errorContainer = ComposeColors.errorContainerLight,
onErrorContainer = ComposeColors.onErrorContainerLight,
background = ComposeColors.backgroundLight,
onBackground = ComposeColors.onBackgroundLight,
surface = ComposeColors.surfaceLight,
onSurface = ComposeColors.onSurfaceLight,
surfaceVariant = ComposeColors.surfaceVariantLight,
onSurfaceVariant = ComposeColors.onSurfaceVariantLight,
outline = ComposeColors.outlineLight,
outlineVariant = ComposeColors.outlineVariantLight,
inverseSurface = ComposeColors.inverseSurfaceLight,
inverseOnSurface = ComposeColors.inverseOnSurfaceLight,
inversePrimary = ComposeColors.inversePrimaryLight,
)

val darkScheme =
darkColorScheme(
primary = ComposeColors.primaryDark,
onPrimary = ComposeColors.onPrimaryDark,
primaryContainer = ComposeColors.primaryContainerDark,
onPrimaryContainer = ComposeColors.onPrimaryContainerDark,
secondary = ComposeColors.secondaryDark,
onSecondary = ComposeColors.onSecondaryDark,
secondaryContainer = ComposeColors.secondaryContainerDark,
onSecondaryContainer = ComposeColors.onSecondaryContainerDark,
tertiary = ComposeColors.tertiaryDark,
onTertiary = ComposeColors.onTertiaryDark,
tertiaryContainer = ComposeColors.tertiaryContainerDark,
onTertiaryContainer = ComposeColors.onTertiaryContainerDark,
error = ComposeColors.errorDark,
onError = ComposeColors.onErrorDark,
errorContainer = ComposeColors.errorContainerDark,
onErrorContainer = ComposeColors.onErrorContainerDark,
background = ComposeColors.backgroundDark,
onBackground = ComposeColors.onBackgroundDark,
surface = ComposeColors.surfaceDark,
onSurface = ComposeColors.onSurfaceDark,
surfaceVariant = ComposeColors.surfaceVariantDark,
onSurfaceVariant = ComposeColors.onSurfaceVariantDark,
outline = ComposeColors.outlineDark,
outlineVariant = ComposeColors.outlineVariantDark,
inverseSurface = ComposeColors.inverseSurfaceDark,
inverseOnSurface = ComposeColors.inverseOnSurfaceDark,
)
}

val LocalCustomColorsPalette = staticCompositionLocalOf { ComposeCustomColors() }

@Composable
fun KeyMapperTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colorScheme = when {
dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
darkTheme -> ComposeTheme.darkScheme
else -> ComposeTheme.lightScheme
}

val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colorScheme.surfaceContainer.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
}
}

val customColorsPalette =
if (darkTheme) ComposeCustomColors.DarkPalette else ComposeCustomColors.LightPalette

CompositionLocalProvider(
LocalCustomColorsPalette provides customColorsPalette,
) {
MaterialTheme(
colorScheme = colorScheme,
typography = Typography(),
content = content,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import io.github.sds100.keymapper.util.Inject
import io.github.sds100.keymapper.util.QuickStartGuideTapTarget
import io.github.sds100.keymapper.util.launchRepeatOnLifecycle
import io.github.sds100.keymapper.util.str
import io.github.sds100.keymapper.util.strArray
import io.github.sds100.keymapper.util.ui.TextListItem
import io.github.sds100.keymapper.util.ui.setupNavigation
import io.github.sds100.keymapper.util.ui.showPopups
Expand Down Expand Up @@ -130,7 +129,8 @@ class HomeFragment : Fragment() {
binding.viewPager.adapter = pagerAdapter

TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = strArray(R.array.home_tab_titles)[position]
val tabId = homeViewModel.tabsState.value.tabs[position]
tab.text = str(HomePagerAdapter.TAB_NAMES[tabId]!!)
}.apply {
attach()
}
Expand Down
Loading
Loading