Skip to content

Commit d1be9af

Browse files
Add lights and warmth support for Nook Glowlight 4 Plus (bnrv1300) (#592)
Split bnrv1300 out of NOOK_GL4 into a dedicated NOOK_GL4PLUS device ID. Fixes koreader/koreader#14574 Co-authored-by: Justin <backcountrymountains@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e451ad3 commit d1be9af

4 files changed

Lines changed: 122 additions & 3 deletions

File tree

app/src/main/java/org/koreader/launcher/device/DeviceInfo.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ object DeviceInfo {
8181
NABUK,
8282
NOOK,
8383
NOOK_GL4,
84+
NOOK_GL4PLUS,
8485
NOOK_GLPLUS,
8586
OBOOK_P10D,
8687
OBOOK_P78D,
@@ -369,11 +370,15 @@ object DeviceInfo {
369370
MANUFACTURER == "onyx" && MODEL == "nabukreg_hd"
370371
-> Id.NABUK
371372

372-
// Nook Glowlight 4 (4/4e/4plus)
373-
(MANUFACTURER == "barnesandnoble")
374-
&& (MODEL == "bnrv1000" || MODEL == "bnrv1100" || MODEL == "bnrv1300")
373+
// Nook Glowlight 4 / 4e
374+
MANUFACTURER == "barnesandnoble"
375+
&& (MODEL == "bnrv1000" || MODEL == "bnrv1100")
375376
-> Id.NOOK_GL4
376377

378+
// Nook Glowlight 4 Plus
379+
MANUFACTURER == "barnesandnoble" && MODEL == "bnrv1300"
380+
-> Id.NOOK_GL4PLUS
381+
377382
// Nook Glowlight plus 7.8" (2019)
378383
MANUFACTURER == "barnesandnoble" && MODEL == "bnrv700" && PRODUCT == "ntx_6sl"
379384
-> Id.NOOK_GLPLUS

app/src/main/java/org/koreader/launcher/device/EPDFactory.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ object EPDFactory {
6969

7070
DeviceInfo.Id.MOOINKPLUS2C,
7171
DeviceInfo.Id.NOOK_GL4,
72+
DeviceInfo.Id.NOOK_GL4PLUS,
7273
DeviceInfo.Id.TOLINO_EPOS3,
7374
DeviceInfo.Id.TOLINO_VISION6,
7475
DeviceInfo.Id.TOLINO_SHINE4,

app/src/main/java/org/koreader/launcher/device/LightsFactory.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ object LightsFactory {
106106
logController("TolinoNTXNoWarmth")
107107
TolinoNtxNoWarmthController()
108108
}
109+
DeviceInfo.Id.NOOK_GL4PLUS,
110+
-> {
111+
logController("NookGL4plus")
112+
NookGL4plusController()
113+
}
109114
DeviceInfo.Id.NOOK_GL4,
110115
DeviceInfo.Id.TOLINO_EPOS2,
111116
-> {
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.koreader.launcher.device.lights
2+
3+
import android.app.Activity
4+
import android.content.ComponentName
5+
import android.content.Intent
6+
import android.provider.Settings
7+
import android.util.Log
8+
import org.koreader.launcher.device.LightsInterface
9+
10+
/* Controller for Nook Glowlight 4 Plus (bnrv1300) on Android 8.1.
11+
* Brightness via Settings.System. Requires "Modify system settings" special app permission;
12+
* grant with: adb shell appops set org.koreader.launcher WRITE_SETTINGS allow
13+
* Warmth via com.nook.partner GlowLightService (exported, no permission required, no root).
14+
* Sends action_set_color_temperature (0-100 scale); the service rescales to 0-10 for
15+
* the lm3630a_led hardware and calls PowerManager.setFrontlightBrightnessColor() using
16+
* its own DEVICE_POWER privilege.
17+
* see https://github.com/koreader/koreader/issues/14574
18+
*/
19+
class NookGL4plusController : LightsInterface {
20+
21+
companion object {
22+
private const val TAG = "Lights"
23+
private const val BRIGHTNESS_MAX = 100
24+
private const val WARMTH_MAX = 10
25+
private const val MIN = 0
26+
private const val GLOWLIGHT_PACKAGE = "com.nook.partner"
27+
private const val GLOWLIGHT_SERVICE = "com.nook.partner.service.GlowLightService"
28+
private const val ACTION_SET_COLOR_TEMPERATURE = "action_set_color_temperature"
29+
private const val EXTRA_COLOR_TEMPERATURE = "extra_color_temperature"
30+
}
31+
32+
@Volatile private var currentWarmth: Int = MIN
33+
34+
override fun getPlatform(): String = "nook"
35+
override fun hasFallback(): Boolean = false
36+
override fun hasWarmth(): Boolean = true
37+
override fun needsPermission(): Boolean = false
38+
override fun hasStandaloneWarmth(): Boolean = false
39+
override fun enableFrontlightSwitch(activity: Activity): Int = 1
40+
41+
override fun getBrightness(activity: Activity): Int {
42+
return try {
43+
Settings.System.getInt(activity.applicationContext.contentResolver,
44+
Settings.System.SCREEN_BRIGHTNESS)
45+
} catch (e: Exception) {
46+
Log.w(TAG, e.toString())
47+
MIN
48+
}
49+
}
50+
51+
override fun getWarmth(activity: Activity): Int {
52+
return try {
53+
Settings.System.getInt(activity.applicationContext.contentResolver,
54+
"screen_brightness_color")
55+
} catch (e: Exception) {
56+
currentWarmth
57+
}
58+
}
59+
60+
override fun setBrightness(activity: Activity, brightness: Int) {
61+
if (brightness < MIN || brightness > BRIGHTNESS_MAX) {
62+
Log.w(TAG, "brightness value out of range: $brightness")
63+
return
64+
}
65+
Log.v(TAG, "Setting brightness to $brightness")
66+
try {
67+
Settings.System.putInt(activity.applicationContext.contentResolver,
68+
Settings.System.SCREEN_BRIGHTNESS, brightness)
69+
} catch (e: Exception) {
70+
Log.w(TAG, "$e")
71+
}
72+
}
73+
74+
override fun setWarmth(activity: Activity, warmth: Int) {
75+
if (warmth < MIN || warmth > WARMTH_MAX) {
76+
Log.w(TAG, "warmth value out of range: $warmth")
77+
return
78+
}
79+
if (warmth == getWarmth(activity)) return
80+
Log.v(TAG, "Setting warmth to $warmth of $WARMTH_MAX")
81+
setWarmthViaService(activity, warmth)
82+
}
83+
84+
private fun setWarmthViaService(activity: Activity, warmth: Int): Boolean {
85+
return try {
86+
val intent = Intent(ACTION_SET_COLOR_TEMPERATURE).apply {
87+
component = ComponentName(GLOWLIGHT_PACKAGE, GLOWLIGHT_SERVICE)
88+
putExtra(EXTRA_COLOR_TEMPERATURE, warmth * 10)
89+
}
90+
val result = activity.startService(intent)
91+
if (result != null) {
92+
currentWarmth = warmth
93+
true
94+
} else {
95+
Log.w(TAG, "GlowLightService unavailable (com.nook.partner disabled?)")
96+
false
97+
}
98+
} catch (e: Exception) {
99+
Log.w(TAG, "setWarmth via service failed: $e")
100+
false
101+
}
102+
}
103+
104+
override fun getMinBrightness(): Int = MIN
105+
override fun getMaxBrightness(): Int = BRIGHTNESS_MAX
106+
override fun getMinWarmth(): Int = MIN
107+
override fun getMaxWarmth(): Int = WARMTH_MAX
108+
}

0 commit comments

Comments
 (0)