koreader / android-luajit-launcher

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

LightController for Tolinos without/with different warmth #351

Closed pazos closed 2 years ago

pazos commented 2 years ago

Hi, I run KOReader on a "Tolino Shine 3". I think it's an Android 4.4.2, the device has a frontlight and a warmth setting.

The log file doesnt save any test info below "Test logs:", only the device info. So I will type all info below. I hope that is sufficient.

Manufacturer: rakuten kobo inc. Brand: rakutenkobo Model: tolino Device: ntx_6sl Product: ntx_6sl Hardware: e60k00 Platform: imx6

E-Ink works fine on "freescale/ntx" setting.

As for lights: Dimming works with "Tolino (warmth)" setting, but the warmth slider does not change the warmth.

I know there is a TolinoWarmthController somewhere in the code, but it seems it's not working for the shine 3.

Should I attach the report?

EDIT: KOReader version 2021.12.1

Originally posted by @pbethke in https://github.com/koreader/koreader/issues/8482#issuecomment-1011305516

pazos commented 2 years ago

Eink is already supported. What's missing is the light controller without warmth.

pazos commented 2 years ago

Actually, I missed your description. Does indeed has warmth?. In that case you'd need to RE the behaviour of the main app yourself or wait for others :)

pbethke commented 2 years ago

The device has warmth, but the "Tolino (warmth)" warmth slider does not affect it. If it works for other Tolino devices (Vision, Epos, etc) I assume it's implemented slightly differently. What does RE mean?

pbethke commented 2 years ago

app/src/main/java/org/koreader/launcher/device/DeviceInfo.kt has TOLINO_EPOS listed as a light device for the identical (BRAND, MODEL, DEVICE) strings.

pazos commented 2 years ago

https://en.m.wikipedia.org/wiki/Reverse_engineering

pazos commented 2 years ago

app/src/main/java/org/koreader/launcher/device/DeviceInfo.kt has TOLINO_EPOS listed as a light device for the identical (BRAND, MODEL, DEVICE) strings.

Just update to latest nightly and run the compatibility test again. It will show you what drivers are already in use.

If you can please post a screenshot here

pbethke commented 2 years ago

Unfortunately, I don't know how to take a screenshot on the device, BUT i ran the compatibility test again with only the tolino mode (see logs attached). We see that @zwim 's workaround for the EPOS from Pull 6332 fails on the su command. Unlike the EPOS the Tolino Shine does not need root privileges to install KOReader.

I also attached a part of adb logcat output from changing brightness and light warmth via the original tolino app. I think the lines that look like D/FrontLight( 2460): Light====>SYS. brightness orig 124 conv 124 are from changing warmth.

If it helps, /sys/class/backlight contains multiple devices:

lm3630a_led
lm3630a_leda
lm3630a_ledb
mxc_msp430_fl.0

I'll now do nightly. test_2021.12.1.log logcat_output.txt

pbethke commented 2 years ago

Ran nightly tests again. Dimming light works, warmth does not test.log .

pbethke commented 2 years ago

Is there anything else I can try, apart from becoming root?

pazos commented 2 years ago

Is there anything else I can try, apart from becoming root?

From the OP in the issue you've posted:

Wait until somebody writes a driver for that platform. If you want to do the port yourself and need help please open a new ticket in https://github.com/koreader/android-luajit-launcher/issues and attach the report saved on your device in /sdcard/test.log

Since the ticket is already opened and the log attached there's no other thing to do other than wait :/

If you decide to do the RE yourself you can lurk in a lot of past tickets to see how it was implemented for many other devices. Hint: it always involve the android.view.View class, but most of the time you won't need to RE the framework itself. Just RE the app that calls the methods in the framework. Obviously wrong hint that applies to EPD drivers, not light drivers. Sorry :p

pbethke commented 2 years ago

Alright. I've skimmed @zwim's work, it seems the functionality is implemented for the special case of a root user.

The problem with Tolino's is that almost all functionality is implemented in a single apk. This is an intriguing problem, but i might not know enough about android to try. I'll have another look. Thanks for your support!

hasezoey commented 2 years ago

as a note, the warmth slider also does nothing on a "Tolino Vision 5"

KoReader compat:

Device Info:


Misc info:


Tolino Logcat from when moving the "Color Temperature" Slider ```txt I/ActivityManager( 2470): START u0 {cmp=de.telekom.epub/.ui.lightSettings.LightSettingsMenuActivity} from pid 8265 D/HomeActivity( 8265): post deregisterBroadcastReceiver() D/ScreenHelper( 8265): disableMandatoryMode() D/ReflectionUtil( 8265): view_setUpdateModeMandatory I/View ( 8265): Waveform mandatory mode is now disabled. D/DialogFactory( 8265): createSingleButtonDialog(de.telekom.epub.ui.lightSettings.LightSettingsMenuActivity@649b6508, Did you know? D/TelekomAlertDialog( 8265): TelekomAlertDialog: created from LightSettingsMenuActivity D/DialogFactory( 8265): createSingleButtonDialog(de.telekom.epub.ui.lightSettings.LightSettingsMenuActivity@649b6508, Did you know? D/TelekomAlertDialog( 8265): TelekomAlertDialog: created from LightSettingsMenuActivity D/ReflectionUtil( 8265): isFrontLightOn: true D/wingAndyBsystem( 2470): setFrontLightState with: on:true and fromButton:false D/ReflectionUtil( 8265): setFrontlightState: true D/PhoneStatusBarPolicy( 2522): received intent :android.intent.action.FL_CHANGED D/PhoneStatusBarPolicy( 2522): update:E70K00 D/ReflectionUtil( 8265): updateFrontLightStatusBarIcon D/LightSettingsController( 8265): setFrontLightBrightness: 35 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setBacklightBrightness(int) D/ElectronBeam( 2470): dismiss D/LightSettingsController( 8265): setFrontLightTemperature: 45 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/Libnightmode binder client( 8265): IEpdNightMode::IEpdNightMode() D/ ( 8265): BpEpdNightMode::BpEpdNightMode() D/Libnightmode binder client( 8265): BpEpdNightMode::push parcel to be sent: D/Libnightmode binder service( 2092): BnEpdNightMode::onTransact(1) 16 D/Libnightmode binder service( 2092): BnEpdNightMode::onTransact got 0 D/Libnightmode binder service( 2092): EpdNightMode::push(0) D/Libnightmode binder client( 8265): BpEpdNightMode::push parcel reply: D/Libnightmode binder client( 8265): BpEpdNightMode::push(0) D/Libnightmode binder client( 8265): IEpdNightMode::~IEpdNightMode() D/FrontLight( 2470): Light====>SYS. brightness orig 39 conv 39 I/ActivityManager( 2470): Displayed de.telekom.epub/.ui.lightSettings.LightSettingsMenuActivity: +732ms D/HomeActivity( 8265): onDestroy from Activity: HomeActivity D/LightSettingsController( 8265): setFrontLightTemperature: 46 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 46 D/LightSettingsController( 8265): setFrontLightTemperature: 45 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 45 D/LightSettingsController( 8265): setFrontLightTemperature: 44 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 44 D/LightSettingsController( 8265): setFrontLightTemperature: 43 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 43 D/LightSettingsController( 8265): setFrontLightTemperature: 42 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 42 D/LightSettingsController( 8265): setFrontLightTemperature: 41 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 41 D/LightSettingsController( 8265): setFrontLightTemperature: 40 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 40 D/LightSettingsController( 8265): setFrontLightTemperature: 39 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 39 D/LightSettingsController( 8265): setFrontLightTemperature: 37 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 37 D/LightSettingsController( 8265): setFrontLightTemperature: 38 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 38 D/LightSettingsController( 8265): setFrontLightTemperature: 39 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 39 D/LightSettingsController( 8265): setFrontLightTemperature: 40 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 40 D/LightSettingsController( 8265): setFrontLightTemperature: 41 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 41 D/LightSettingsController( 8265): setFrontLightTemperature: 42 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 42 D/LightSettingsController( 8265): setFrontLightTemperature: 43 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 43 D/LightSettingsController( 8265): setFrontLightTemperature: 42 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 42 D/LightSettingsController( 8265): setFrontLightTemperature: 38 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 38 D/LightSettingsController( 8265): setFrontLightTemperature: 34 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 34 D/LightSettingsController( 8265): setFrontLightTemperature: 30 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 30 D/LightSettingsController( 8265): setFrontLightTemperature: 27 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 27 D/LightSettingsController( 8265): setFrontLightTemperature: 24 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 24 D/LightSettingsController( 8265): setFrontLightTemperature: 22 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 22 D/LightSettingsController( 8265): setFrontLightTemperature: 21 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 21 D/LightSettingsController( 8265): setFrontLightTemperature: 19 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 19 D/LightSettingsController( 8265): setFrontLightTemperature: 18 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 18 D/LightSettingsController( 8265): setFrontLightTemperature: 22 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 22 D/LightSettingsController( 8265): setFrontLightTemperature: 25 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 25 D/LightSettingsController( 8265): setFrontLightTemperature: 27 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 27 D/LightSettingsController( 8265): setFrontLightTemperature: 30 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 30 D/LightSettingsController( 8265): setFrontLightTemperature: 33 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 33 D/LightSettingsController( 8265): setFrontLightTemperature: 35 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 35 D/LightSettingsController( 8265): setFrontLightTemperature: 37 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 37 D/LightSettingsController( 8265): setFrontLightTemperature: 38 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 38 D/LightSettingsController( 8265): setFrontLightTemperature: 39 D/ReflectionUtil( 8265): getMethodFromClass resultMethod: public void android.os.PowerManager.setFrontlightBrightnessColor(int) D/lights ( 2470): ================ brightness_color = 39 ```
hasezoey commented 2 years ago

i took a look at the code and what i had suspected from the log was true, the tolino app calls setFrontlightBrightnessColor from the android power manager:

Method method = ReflectionUtil.getMethodFromClass(this.mPowerManager.getClass(), "setFrontlightBrightnessColor");
if (method != null)
  try {
    PowerManager powerManager = this.mPowerManager;
    byte b = 1;
    if (Globals.isOreoOrLater())
      b = 10; 
    method.invoke(powerManager, new Object[] { Integer.valueOf(paramInt / b) });
  } catch (Exception exception) {
    Log.e(TAG, "Error calling PowerManager.setFrontlightBrightnessColor", exception);
  }  
}

with a minimal of 0 and max of 100

but i have no clue where to add this or how to test this, though if anyone can make a PR i would be glad to test that (if i can get it to compile)

note mPowerManager is set like the following:

import android.os.PowerManager;
// later
this.mPowerManager = (PowerManager)paramContext.getSystemService("power");

PS: it also sets it via

ContentResolver contentResolver = paramContext.getContentResolver()
Settings.System.putInt(contentResolver, "screen_brightness_color", i / paramInt);

but i have no clue what contentResolver is in this case paramContext is Context from import android.content.Context;

hasezoey commented 2 years ago

i have tried playing around with this to implement it, but it seems like Settings.System.putInt does not have any effect

and using the invoke method required android.permission.DEVICE_POWER, which i seemingly cannot provide

my test case was: TolinoWarmthController.kt.patch

hasezoey commented 2 years ago

Update: i found that /dev/ntx_io can be used for frontlight setting AND Color the id's i have found are:

for anyone interested in ever using manipulating /dev/ntx_io on-the-fly, i have a patch that replaces the filemanager "Create Folder" (+ button) with a input for values usage would look like 248 0, where the first number is the ID and the second the VALUE separated by a SPACE

filemanager.lua.patch.txt (there is a ioctl binary available for use in adb shell, but using it seems to crash the device)

pazos commented 2 years ago

@hasezoey:

i have tried playing around with this to implement it, but it seems like Settings.System.putInt does not have any effect

and using the invoke method required android.permission.DEVICE_POWER, which i seemingly cannot provide

Yup. Some permissions, like this one, are reserved to system apps.

NiLuJe commented 2 years ago

@hasezoey:

Excerpts from arch/arm/mach-imx/imx_ntx_io.c in a Kobo Mk. 7 kernel

#define CM_FL_LM3630_SET 239
#define CM_FRONT_LIGHT_SET 241
#define CM_FL_LM3630_TABLE 248

I can't vouch for the implementation of the LM3630 commands because they're a NOP on Kobo kernels ;o).

But we do use CM_FRONT_LIGHT_SET for the brightness on Kobo, c.f., https://github.com/koreader/koreader-base/blob/master/ffi/kobolight.lua We also have a dumb standalone ioctl implementation for startup scripts: https://github.com/koreader/koreader/blob/master/frontend/device/kobo/ntx_io.lua used in https://github.com/koreader/koreader/blob/6f5c229c90fac58ce3b3c485dd9f16de518d951b/platform/kobo/koreader.sh#L199

(I also noticed that there's an old ioctl binary in the Kobo FW, but I've never actually tried it ;)).

hasezoey commented 2 years ago

@NiLuJe i am currently trying to implement this with https://github.com/koreader/koreader/pull/9503, but kinda hit a wall, because i try to use a new device/tolino/powerd that inherits from device/android/powerd i get a error that self.device cannot be accesed, even though i (think) i am correctly setting everything

hasezoey commented 2 years ago

my sources for the ntx_io numbers to try i have used https://github.com/kobolabs/Kobo-Reader/blob/master/hw/imx6sll-libra2/kernel.tar.bz2 (file ./arch/arm/mach-imx/imx_ntx_io.c) Edit: the proper file for Vision5 is https://github.com/kobolabs/Kobo-Reader/blob/master/hw/imx6sll-librah2o/kernel.tar.bz2 (file ./arch/arm/mach-imx/imx_ntx_io.c)

i have also tried to add this to https://github.com/koreader/koreader/pull/9503, but i could not get the warmth setting to trigger in lua, and i dont know enough to implement it in java / kotlin with JNI or to execute a command to trigger ntx_io.lua in java (because from what i know it will require ioctl)

Nepochal commented 1 year ago

Hi, do I miss something here? This issue was opened because the warmth settings did not work on non rooted tolino shine 3 devices. It was closed with the merge of #382 which resolved the problem on tolino vision 5 devices but not on the tolino shine 3. I use both devices and can confirm that it now works on the vision 5 but not on the shine 3.

hasezoey commented 1 year ago

@Nepochal the PR only added explicit control for e70k00, though it may also work on other model numbers as long as firmware 15 (or maybe higher) is used, though that will need some explicit testing - i dont know how to do it without manually compiling and adding e60k00 and trying it out though

Nepochal commented 1 year ago

I can confirm that the Tolino ntx driver works on the e60k00 in the compatibility test. Due to personal and professional commitments I have no time to do the coding and compiling but if someone is interested in implementing I would be glad to help testing on my Tolino Shine 3 and my Tolino Vision 5.

hasezoey commented 1 year ago

I can confirm that the Tolino ntx driver works on the e60k00 in the compatibility test.

does the warmth setting with Tolino NTX also work on the Shine 3?

Nepochal commented 1 year ago

I can confirm that the Tolino ntx driver works on the e60k00 in the compatibility test.

does the warmth setting with Tolino NTX also work on the Shine 3?

Yes it works just as well as with the Vision 5.

Nepochal commented 1 year ago

I will open a new issue for the device. I hope that is okay for you.