KeyHandler: Integrate in tri-state-key handling via UEventObserver API

This basically adds required code to support both switch and extcon
based tri-state-key. This also adds tri-state-key-calibrate script for
devices that need to be calibrated on boot (OnePlus7+)

Change-Id: I2e6c5d2861569750bead05edacf6e328a5227077
This commit is contained in:
Timi Rautamäki
2021-10-19 13:08:14 +00:00
committed by LuK1337
parent acbbb33e8f
commit 75ea79851b
14 changed files with 118 additions and 465 deletions

View File

@@ -17,3 +17,10 @@ android_app {
proguard_flags_files: ["proguard.flags"],
},
}
sh_binary {
name: "tri-state-key-calibrate",
init_rc: ["tri-state-key-calibrate.rc"],
src: "tri-state-key-calibrate.sh",
vendor: true,
}

View File

@@ -17,6 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.system"
package="org.lineageos.settings.device">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
@@ -26,6 +27,15 @@
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
<receiver
android:name="org.lineageos.settings.device.BootCompletedReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<provider
android:name=".ConfigPanelSearchIndexablesProvider"
android:authorities="org.lineageos.settings.device"
@@ -49,6 +59,9 @@
</intent-filter>
</activity>
<activity android:name=".KeyHandler" />
</application>
<service
android:name=".KeyHandler"
android:permission="KeyHandlerService"
android:exported="false" />
</application>
</manifest>

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.device
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Starting")
context.startService(Intent(context, KeyHandler::class.java))
}
companion object {
private const val TAG = "KeyHandler"
}
}

View File

@@ -6,30 +6,27 @@
package org.lineageos.settings.device
import android.app.NotificationManager
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.media.AudioManager
import android.media.AudioSystem
import android.os.IBinder
import android.os.UEventObserver
import android.os.VibrationEffect
import android.os.Vibrator
import android.provider.Settings
import android.view.KeyEvent
import com.android.internal.os.DeviceKeyHandler
import androidx.preference.PreferenceManager
class KeyHandler(context: Context) : DeviceKeyHandler {
private val audioManager = context.getSystemService(AudioManager::class.java)
private val notificationManager = context.getSystemService(NotificationManager::class.java)
private val vibrator = context.getSystemService(Vibrator::class.java)
private val packageContext = context.createPackageContext(
KeyHandler::class.java.getPackage()!!.name, 0
)
private val sharedPreferences
get() = packageContext.getSharedPreferences(
packageContext.packageName + "_preferences",
Context.MODE_PRIVATE or Context.MODE_MULTI_PROCESS
)
class KeyHandler : Service() {
private lateinit var audioManager: AudioManager
private lateinit var notificationManager: NotificationManager
private lateinit var vibrator: Vibrator
private lateinit var sharedPreferences: SharedPreferences
private var wasMuted = false
private val broadcastReceiver = object : BroadcastReceiver() {
@@ -42,30 +39,50 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
}
}
init {
context.registerReceiver(
broadcastReceiver,
IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION)
)
}
private val alertSliderEventObserver = object : UEventObserver() {
private val lock = Any()
override fun handleKeyEvent(event: KeyEvent): KeyEvent {
if (event.action == KeyEvent.ACTION_DOWN) {
when (event.scanCode) {
POSITION_TOP -> {
handleMode(sharedPreferences.getString(ALERT_SLIDER_TOP_KEY, "0")!!.toInt())
override fun onUEvent(event: UEvent) {
synchronized(lock) {
event.get("SWITCH_STATE")?.let {
handleMode(it.toInt())
return
}
POSITION_MIDDLE -> {
handleMode(sharedPreferences.getString(ALERT_SLIDER_MIDDLE_KEY, "1")!!.toInt())
}
POSITION_BOTTOM -> {
handleMode(sharedPreferences.getString(ALERT_SLIDER_BOTTOM_KEY, "2")!!.toInt())
event.get("STATE")?.let {
val none = it.contains("USB=0")
val vibration = it.contains("HOST=0")
val silent = it.contains("null)=0")
if (none && !vibration && !silent) {
handleMode(POSITION_BOTTOM)
} else if (!none && vibration && !silent) {
handleMode(POSITION_MIDDLE)
} else if (!none && !vibration && silent) {
handleMode(POSITION_TOP)
}
return
}
}
}
return event
}
override fun onCreate() {
audioManager = getSystemService(AudioManager::class.java)
notificationManager = getSystemService(NotificationManager::class.java)
vibrator = getSystemService(Vibrator::class.java)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
registerReceiver(
broadcastReceiver,
IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION)
)
alertSliderEventObserver.startObserving("tri-state-key")
alertSliderEventObserver.startObserving("tri_state_key")
}
override fun onBind(intent: Intent?): IBinder? = null
private fun vibrateIfNeeded(mode: Int) {
when (mode) {
AudioManager.RINGER_MODE_VIBRATE -> vibrator.vibrate(MODE_VIBRATION_EFFECT)
@@ -73,9 +90,16 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
}
}
private fun handleMode(mode: Int) {
private fun handleMode(position: Int) {
val muteMedia = sharedPreferences.getBoolean(MUTE_MEDIA_WITH_SILENT, false)
val mode = when (position) {
POSITION_TOP -> sharedPreferences.getString(ALERT_SLIDER_TOP_KEY, "0")!!.toInt()
POSITION_MIDDLE -> sharedPreferences.getString(ALERT_SLIDER_MIDDLE_KEY, "1")!!.toInt()
POSITION_BOTTOM -> sharedPreferences.getString(ALERT_SLIDER_BOTTOM_KEY, "2")!!.toInt()
else -> return
}
when (mode) {
AudioManager.RINGER_MODE_SILENT -> {
notificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG)
@@ -106,10 +130,10 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
companion object {
private const val TAG = "KeyHandler"
// Slider key codes
private const val POSITION_TOP = 601
private const val POSITION_MIDDLE = 602
private const val POSITION_BOTTOM = 603
// Slider key positions
private const val POSITION_TOP = 1
private const val POSITION_MIDDLE = 2
private const val POSITION_BOTTOM = 3
// Preference keys
private const val ALERT_SLIDER_TOP_KEY = "config_top_position"

View File

@@ -0,0 +1,9 @@
service vendor.tri-state-key-calibrate /vendor/bin/tri-state-key-calibrate
class main
user system
group system
oneshot
disabled
on post-fs-data
start vendor.tri-state-key-calibrate

View File

@@ -0,0 +1,6 @@
#!/vendor/bin/sh
if [[ -f /mnt/vendor/persist/engineermode/tri_state_hall_data ]]; then
CALIBRATION_DATA="$(cat /mnt/vendor/persist/engineermode/tri_state_hall_data)"
CALIBRATION_DATA="${CALIBRATION_DATA//;/,}"
echo -n $CALIBRATION_DATA > /sys/devices/platform/soc/soc:tri_state_key/hall_data_calib
fi