koreader / android-luajit-launcher

Android NativeActivity based launcher for LuaJIT, implementing the main loop within Lua land via FFI
MIT License
131 stars 85 forks source link

Onyx ultrac lights support #436

Closed hugleo closed 10 months ago

hugleo commented 1 year ago

Can use getBrightnessConfig for different values, 6 and 7, but can't use setWarmLightDeviceValue or setColdLightDeviceValue since they internally use the values 2 and 3. Onyx needs to fix that or provide new methods for values 6 and 7.

I tried to use the sysfs class but also encountered permission error:

adb shell cat /sys/class/backlight/onyx_bl_br/brightness is okay,

but inside the code, I received this error: java.io.FileNotFoundException: /sys/class/backlight/onyx_bl_br/brightness: open failed: EACCES (Permission denied).

For now I'm using intent while Onyx doesn't fix these issues. The settings seem to be working and we only see the Onyx controller menu for a short time and disappears. It doesn't look too bad.

onyx-controller


This change is Reviewable

hugleo commented 1 year ago

Good news. Onyx says they will upgrade the SDK in the near future ;-)

hugleo commented 1 year ago

I installed the new firmware beta version and got the same or even more problems. Onyx helped and explained that the reason why some methods don't work is because the Android SDK greater than 29 limits reflections. This needs to be addressed with the following solution: https://github.com/LSPosed/AndroidHiddenApiBypass. I'll study the behavior when I have time. More on that here: https://issuetracker.google.com/issues/150857756, https://stackoverflow.com/questions/55970137/bypass-androids-hidden-api-restrictions or https://copyprogramming.com/howto/bypass-android-s-hidden-api-restrictions or https://androidreverse.org/blog/2023/02/21/android-api-restriction-bypass-for-all-android-versions or for academics: https://diaowenrui.github.io/paper/icse22-yang.pdf It's possible to test on adb first and after that don't know if will be easy without a third party library, but testing on that first...

EDIT: I've tried it here. Double reflection would be easy, but it doesn't work for Android >= 11. Right now, there are two methods to perform the exploit:

1) (Pure Java) https://github.com/LSPosed/AndroidHiddenApiBypass 2) (JNI) https://github.com/ChickenHook/RestrictionBypass

I've imported LSPosed in the gradle for test and it really works (https://github.com/hugleo/android-luajit-launcher/tree/onyx-ultrac-personal-build). For now, it's all I can think of. But the Onyx SDK itself is also using LSPosed for these new devices.

hugleo commented 10 months ago

This will work for the new Onyx devices using the new lights format.

However, need to set hidden API permissions using ADB: adb shell settings put global hidden_api_policy 1

To remove use: adb shell settings delete global hidden_api_policy

hugleo commented 10 months ago

@pazos, can we proceed with this one? Need to set hidden API permissions using ADB...

pazos commented 10 months ago

Need to set hidden API permissions using ADB..

No problem.

Could you please add the instructions to https://github.com/koreader/koreader/wiki/Android-tips-and-tricks#adb-stuff-todo?

hugleo commented 10 months ago

Also good to add to eink test I guess

hugleo commented 10 months ago

Need to set hidden API permissions using ADB..

No problem.

Could you please add the instructions to https://github.com/koreader/koreader/wiki/Android-tips-and-tricks#adb-stuff-todo?

Addressed. Is it better to create a separate PR for the e-ink test?

pazos commented 10 months ago

Addressed

Great, thanks!

Is it better to create a separate PR for the e-ink test?

I think so. Also show a tooltip when the method is selected in the combobox, with a link to the wiki article. After all this is the first driver that requires extra instructions :)

could you do a diff -uNr between the old OnyxSdkLightsController and the new OnyxAdbLightsController?

It looks they're mostly the same. Maybe we can refactor them in the future.

hugleo commented 10 months ago
--- OnyxSdkLightsController.kt  2023-12-26 22:10:17.696547735 -0300
+++ OnyxAdbLightsController.kt  2023-12-26 22:10:17.696547735 -0300
@@ -7,16 +7,16 @@
 import java.lang.Class.forName
 import java.lang.reflect.Method

-class OnyxSdkLightsController : LightsInterface {
+class OnyxAdbLightsController : LightsInterface {
     companion object {
         private const val TAG = "Lights"
-        private const val BRIGHTNESS_MAX = 255
-        private const val WARMTH_MAX = 255
+        private const val BRIGHTNESS_MAX = 25
+        private const val WARMTH_MAX = 24
         private const val MIN = 0
     }

     override fun getPlatform(): String {
-        return "onyx-sdk-lights"
+        return "onyx-adb-lights"
     }

     override fun hasFallback(): Boolean {
@@ -32,11 +32,11 @@
     }

     override fun getBrightness(activity: Activity): Int {
-        return FrontLight.getCold(activity)
+        return FrontLightAdb.getCold(activity)
     }

     override fun getWarmth(activity: Activity): Int {
-        return FrontLight.getWarm(activity)
+        return FrontLightAdb.getWarm(activity)
     }

     override fun setBrightness(activity: Activity, brightness: Int) {
@@ -45,7 +45,7 @@
             return
         }
         Log.v(TAG, "Setting brightness to $brightness")
-        FrontLight.setCold(brightness, activity)
+        FrontLightAdb.setCold(brightness, activity)
     }

     override fun setWarmth(activity: Activity, warmth: Int) {
@@ -54,7 +54,7 @@
             return
         }
         Log.v(TAG, "Setting warmth to $warmth")
-        FrontLight.setWarm(warmth, activity)
+        FrontLightAdb.setWarm(warmth, activity)
     }

     override fun getMinWarmth(): Int {
@@ -78,8 +78,8 @@
     }
 }

-object FrontLight {
-    private const val TAG = "lights"
+object FrontLightAdb {
+    private const val TAG = "Lights"

     private val flController: Class<*>? = try {
         forName("android.onyx.hardware.DeviceController")
@@ -88,31 +88,25 @@
         null
     }

-    private val setWarmBrightness: Method? = try {
-        flController!!.getMethod("setWarmLightDeviceValue", Context::class.java, Integer.TYPE)
-    } catch (e: Exception) {
-        Log.w(TAG, "$e")
-        null
-    }
-    private val setColdBrightness: Method? = try {
-        flController!!.getMethod("setColdLightDeviceValue", Context::class.java, Integer.TYPE)
+    private val setCoolWarmBrightness: Method? = try {
+        flController!!.getMethod("setLightValue", Integer.TYPE, Integer.TYPE)
     } catch (e: Exception) {
         Log.w(TAG, "$e")
         null
     }

     private val getCoolWarmBrightness: Method? = try {
-        flController!!.getMethod("getBrightnessConfig", Context::class.java, Integer.TYPE)
+        flController!!.getMethod("getLightValue", Integer.TYPE)
     } catch (e: Exception) {
         Log.w(TAG, "$e")
         null
     }
-    private const val BRIGHTNESS_CONFIG_WARM_IDX: Int = 2
-    private const val BRIGHTNESS_CONFIG_COLD_IDX: Int = 3
+    private const val BRIGHTNESS_CONFIG_WARM_IDX: Int = 6
+    private const val BRIGHTNESS_CONFIG_COLD_IDX: Int = 7

     fun getWarm(context: Context?): Int {
         return try {
-            getCoolWarmBrightness!!.invoke(flController!!, context, BRIGHTNESS_CONFIG_WARM_IDX) as Int
+            getCoolWarmBrightness!!.invoke(flController!!, BRIGHTNESS_CONFIG_WARM_IDX) as Int
         } catch (e: Exception) {
             e.printStackTrace()
             0
@@ -121,7 +115,7 @@

     fun getCold(context: Context?): Int {
         return try {
-            getCoolWarmBrightness!!.invoke(flController!!, context, BRIGHTNESS_CONFIG_COLD_IDX) as Int
+            getCoolWarmBrightness!!.invoke(flController!!, BRIGHTNESS_CONFIG_COLD_IDX) as Int
         } catch (e: Exception) {
             e.printStackTrace()
             0
@@ -130,7 +124,7 @@

     fun setWarm(value: Int, context: Context?) {
         try {
-            setWarmBrightness!!.invoke(flController!!, context, value)
+            setCoolWarmBrightness!!.invoke(flController!!, BRIGHTNESS_CONFIG_WARM_IDX, value)
         } catch (e: Exception) {
             e.printStackTrace()
         }
@@ -138,7 +132,7 @@

     fun setCold(value: Int, context: Context?) {
         try {
-            setColdBrightness!!.invoke(flController!!, context, value)
+            setCoolWarmBrightness!!.invoke(flController!!, BRIGHTNESS_CONFIG_COLD_IDX, value)
         } catch (e: Exception) {
             e.printStackTrace()
         }