mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 03:08:19 +00:00
Rewrite sleep root gesture handler
It now runs on its own thread and keeps old su session for later use.
This commit is contained in:
@@ -302,13 +302,19 @@ class LawnchairPreferences(val context: Context) : SharedPreferences.OnSharedPre
|
||||
}
|
||||
|
||||
open inner class StringBasedPref<T : Any>(key: String, defaultValue: T, onChange: () -> Unit = doNothing,
|
||||
private val fromString: (String) -> T, private val toString: (T) -> String) :
|
||||
private val fromString: (String) -> T,
|
||||
private val toString: (T) -> String,
|
||||
private val dispose: (T) -> Unit) :
|
||||
PrefDelegate<T>(key, defaultValue, onChange) {
|
||||
override fun onGetValue(): T = sharedPrefs.getString(getKey(), null)?.run(fromString) ?: defaultValue
|
||||
|
||||
override fun onSetValue(value: T) {
|
||||
edit { putString(getKey(), toString(value)) }
|
||||
}
|
||||
|
||||
override fun disposeOldValue(oldValue: T) {
|
||||
dispose(oldValue)
|
||||
}
|
||||
}
|
||||
|
||||
open inner class StringPref(key: String, defaultValue: String = "", onChange: () -> Unit = doNothing) :
|
||||
@@ -442,7 +448,7 @@ class LawnchairPreferences(val context: Context) : SharedPreferences.OnSharedPre
|
||||
}
|
||||
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||
cached = false
|
||||
discardCachedValue()
|
||||
onSetValue(value)
|
||||
}
|
||||
|
||||
@@ -461,9 +467,20 @@ class LawnchairPreferences(val context: Context) : SharedPreferences.OnSharedPre
|
||||
internal fun getKey() = key
|
||||
|
||||
private fun onValueChanged() {
|
||||
cached = false
|
||||
discardCachedValue()
|
||||
onChange.invoke()
|
||||
}
|
||||
|
||||
private fun discardCachedValue() {
|
||||
if (cached) {
|
||||
cached = false
|
||||
value.let(::disposeOldValue)
|
||||
}
|
||||
}
|
||||
|
||||
open fun disposeOldValue(oldValue: T) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) {
|
||||
|
||||
@@ -46,7 +46,7 @@ class GestureController(val launcher: LawnchairLauncher) : TouchController {
|
||||
}
|
||||
|
||||
fun createHandlerPref(key: String, defaultValue: GestureHandler = blankGestureHandler) = prefs.StringBasedPref(
|
||||
key, defaultValue, prefs.doNothing, ::createGestureHandler, GestureHandler::toString)
|
||||
key, defaultValue, prefs.doNothing, ::createGestureHandler, GestureHandler::toString, GestureHandler::onDestroy)
|
||||
|
||||
private fun createGestureHandler(jsonString: String) = createGestureHandler(launcher, jsonString, blankGestureHandler)
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ abstract class GestureHandler(val context: Context, val config: JSONObject?) {
|
||||
|
||||
}
|
||||
|
||||
open fun onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return JSONObject().apply {
|
||||
put("class", this@GestureHandler::class.java.name)
|
||||
|
||||
@@ -3,9 +3,10 @@ package ch.deletescape.lawnchair.gestures.handlers
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.provider.Settings
|
||||
import android.support.annotation.Keep
|
||||
import android.view.KeyEvent
|
||||
import ch.deletescape.lawnchair.gestures.GestureController
|
||||
import ch.deletescape.lawnchair.gestures.GestureHandler
|
||||
import com.android.launcher3.R
|
||||
@@ -14,23 +15,79 @@ import org.json.JSONObject
|
||||
import java.io.DataOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
private val suThread = HandlerThread("su").apply { start() }
|
||||
private val suHandler = Handler(suThread.looper)
|
||||
|
||||
@Keep
|
||||
class SleepGestureHandlerRoot(context: Context, config: JSONObject?) : GestureHandler(context, config) {
|
||||
|
||||
override val displayName = context.getString(R.string.action_sleep_root)!!
|
||||
|
||||
private var currentSession: Session? = null
|
||||
private val destroy = Runnable { currentSession?.destroy() }
|
||||
private val sleep = Runnable {
|
||||
getSuSession().run {
|
||||
write("sendevent /dev/input/event1 1 116 1\n")
|
||||
write("sendevent /dev/input/event1 0 0 0\n")
|
||||
write("sendevent /dev/input/event1 1 116 0\n")
|
||||
write("sendevent /dev/input/event1 0 0 0\n")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSuSession(): Session {
|
||||
if (currentSession == null || !currentSession!!.isAlive) {
|
||||
currentSession = Session()
|
||||
}
|
||||
return currentSession!!
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
suHandler.post(destroy)
|
||||
}
|
||||
|
||||
override fun onGestureTrigger(controller: GestureController) {
|
||||
try {
|
||||
val p = Runtime.getRuntime().exec("su")
|
||||
val outputStream = DataOutputStream(p.outputStream)
|
||||
outputStream.writeBytes("input keyevent ${KeyEvent.KEYCODE_POWER}\n")
|
||||
outputStream.writeBytes("exit\n")
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
p.waitFor()
|
||||
p.destroy()
|
||||
} catch (e: IOException) {
|
||||
} catch (e: InterruptedException) {
|
||||
suHandler.post(sleep)
|
||||
}
|
||||
|
||||
class Session {
|
||||
|
||||
private val process = Runtime.getRuntime().exec("su")!!
|
||||
private val outputStream = DataOutputStream(process.outputStream)
|
||||
|
||||
val isAlive get() = isAlive(process)
|
||||
|
||||
fun write(string: String) {
|
||||
try {
|
||||
outputStream.writeBytes(string)
|
||||
outputStream.flush()
|
||||
} catch (e: IOException) {
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
try {
|
||||
if (isAlive) {
|
||||
outputStream.writeBytes("exit\n")
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
}
|
||||
process.waitFor()
|
||||
process.destroy()
|
||||
} catch (e: IOException) {
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAlive(process: Process?): Boolean {
|
||||
if (process == null) return false
|
||||
return try {
|
||||
process.exitValue()
|
||||
false
|
||||
} catch (e: IllegalThreadStateException) {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user