11package org.koreader.launcher.device.lights
22
33import android.app.Activity
4+ import android.content.Context
45import android.util.Log
56import org.koreader.launcher.device.LightsInterface
6- import android.content.Context
7- import java.lang.Class.forName
87import java.lang.reflect.Method
98
109// ─── Constants mirroring FrontLightController / BaseBrightnessProvider ────────
1110
12- private const val LIGHT_TYPE_FL = 1 // FLBrightnessProvider — single channel
13- private const val LIGHT_TYPE_CTM_WARM = 2 // WarmBrightnessProvider — warm channel
14- private const val LIGHT_TYPE_CTM_COLD = 3 // ColdBrightnessProvider — cold channel
15- private const val LIGHT_TYPE_CTM_ALL = 4 // open/close the whole CTM unit
16- private const val LIGHT_TYPE_TEMP = 6 // CTMTemperatureProvider — CTM warmth param
17- private const val LIGHT_TYPE_CTM_BR = 7 // CTMBrightnessProvider — CTM brightness param
11+ private const val LIGHT_TYPE_FL = 1 // FLBrightnessProvider — single channel
12+ private const val LIGHT_TYPE_CTM_WARM = 2 // WarmBrightnessProvider — warm channel
13+ private const val LIGHT_TYPE_CTM_COLD = 3 // ColdBrightnessProvider — cold channel
14+ private const val LIGHT_TYPE_CTM_ALL = 4 // open/close the whole CTM unit
15+ private const val LIGHT_TYPE_TEMP = 6 // CTMTemperatureProvider — CTM warmth param
16+ private const val LIGHT_TYPE_CTM_BR = 7 // CTMBrightnessProvider — CTM brightness param
1817
1918// Mirrors BrightnessType enum
2019enum class OnyxBrightnessType { FL , WARM_AND_COLD , CTM , NONE }
@@ -35,12 +34,11 @@ class OnyxSdkLightsController : LightsInterface {
3534 override fun hasStandaloneWarmth (): Boolean = false
3635
3736 override fun hasWarmth (): Boolean {
38- // We can't easily re-init here without Activity/Context,
39- // but we can trust the previous detection if it found warmth.
4037 return when (OnyxDevice .brightnessType) {
4138 OnyxBrightnessType .WARM_AND_COLD ,
4239 OnyxBrightnessType .CTM -> true
43- else -> ! OnyxDevice .isInitialized // optimistic before init
40+
41+ else -> ! OnyxDevice .isInitialized // optimistic before init
4442 }
4543 }
4644
@@ -49,19 +47,19 @@ class OnyxSdkLightsController : LightsInterface {
4947 override fun getBrightness (activity : Activity ): Int {
5048 OnyxDevice .init (activity)
5149 return when (OnyxDevice .brightnessType) {
52- OnyxBrightnessType .FL -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_FL ) ? : 0
50+ OnyxBrightnessType .FL -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_FL ) ? : 0
5351 OnyxBrightnessType .WARM_AND_COLD -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_CTM_COLD ) ? : 0
54- OnyxBrightnessType .CTM -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_CTM_BR ) ? : 0
55- OnyxBrightnessType .NONE -> 0
52+ OnyxBrightnessType .CTM -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_CTM_BR ) ? : 0
53+ OnyxBrightnessType .NONE -> 0
5654 }
5755 }
5856
5957 override fun getWarmth (activity : Activity ): Int {
6058 OnyxDevice .init (activity)
6159 return when (OnyxDevice .brightnessType) {
6260 OnyxBrightnessType .WARM_AND_COLD -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_CTM_WARM ) ? : 0
63- OnyxBrightnessType .CTM -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_TEMP ) ? : 0
64- else -> 0
61+ OnyxBrightnessType .CTM -> OnyxDevice .getLightValue(activity, LIGHT_TYPE_TEMP ) ? : 0
62+ else -> 0
6563 }
6664 }
6765
@@ -78,10 +76,13 @@ class OnyxSdkLightsController : LightsInterface {
7876 when (OnyxDevice .brightnessType) {
7977 OnyxBrightnessType .FL ->
8078 OnyxDevice .setLight(activity, LIGHT_TYPE_FL , brightness)
79+
8180 OnyxBrightnessType .WARM_AND_COLD ->
8281 OnyxDevice .setLight(activity, LIGHT_TYPE_CTM_COLD , brightness)
82+
8383 OnyxBrightnessType .CTM ->
8484 OnyxDevice .setLight(activity, LIGHT_TYPE_CTM_BR , brightness)
85+
8586 OnyxBrightnessType .NONE -> Unit
8687 }
8788 }
@@ -97,28 +98,30 @@ class OnyxSdkLightsController : LightsInterface {
9798 when (OnyxDevice .brightnessType) {
9899 OnyxBrightnessType .WARM_AND_COLD ->
99100 OnyxDevice .setLight(activity, LIGHT_TYPE_CTM_WARM , warmth)
101+
100102 OnyxBrightnessType .CTM ->
101103 OnyxDevice .setLight(activity, LIGHT_TYPE_TEMP , warmth)
104+
102105 else -> Unit
103106 }
104107 }
105108
106109 // ── Range ─────────────────────────────────────────────────────────────────
107110
108111 override fun getMinBrightness (): Int = MIN
109- override fun getMinWarmth (): Int = MIN
112+ override fun getMinWarmth (): Int = MIN
110113
111114 override fun getMaxBrightness (): Int = when (OnyxDevice .brightnessType) {
112- OnyxBrightnessType .FL -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_FL ) ? : FALLBACK_MAX
115+ OnyxBrightnessType .FL -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_FL ) ? : FALLBACK_MAX
113116 OnyxBrightnessType .WARM_AND_COLD -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_CTM_COLD ) ? : FALLBACK_MAX
114- OnyxBrightnessType .CTM -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_CTM_BR ) ? : FALLBACK_MAX
115- OnyxBrightnessType .NONE -> FALLBACK_MAX
117+ OnyxBrightnessType .CTM -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_CTM_BR ) ? : FALLBACK_MAX
118+ OnyxBrightnessType .NONE -> FALLBACK_MAX
116119 }
117120
118121 override fun getMaxWarmth (): Int = when (OnyxDevice .brightnessType) {
119122 OnyxBrightnessType .WARM_AND_COLD -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_CTM_WARM ) ? : FALLBACK_MAX
120- OnyxBrightnessType .CTM -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_TEMP ) ? : FALLBACK_MAX
121- else -> FALLBACK_MAX
123+ OnyxBrightnessType .CTM -> OnyxDevice .getMaxLightValue(LIGHT_TYPE_TEMP ) ? : FALLBACK_MAX
124+ else -> FALLBACK_MAX
122125 }
123126
124127 override fun enableFrontlightSwitch (activity : Activity ): Int = 1
@@ -136,27 +139,35 @@ object OnyxDevice {
136139 }
137140
138141 // Integer getLightValue(int type)
139- private val mGetLightValue: Method ? = method(" getLightValue" , Integer .TYPE )
140- ? : method(" getLightValues" , Integer .TYPE )
142+ private val mGetLightValue: Method ? = method(" getLightValue" , Integer .TYPE )
143+ ? : method(" getLightValues" , Integer .TYPE )
144+
141145 // Integer getMaxLightValue(int type)
142146 private val mGetMaxLightValue: Method ? = method(" getMaxLightValue" , Integer .TYPE )
143- ? : method(" getMaxLightValues" , Integer .TYPE )
147+ ? : method(" getMaxLightValues" , Integer .TYPE )
148+
144149 // boolean setLightValue(int type, int value)
145- private val mSetLightValue: Method ? = method(" setLightValue" , Integer .TYPE , Integer .TYPE )
146- ? : method(" setLightValues" , Integer .TYPE , Integer .TYPE )
150+ private val mSetLightValue: Method ? = method(" setLightValue" , Integer .TYPE , Integer .TYPE )
151+ ? : method(" setLightValues" , Integer .TYPE , Integer .TYPE )
152+
147153 // boolean openFrontLight(int type)
148- private val mOpenFrontLight: Method ? = method(" openFrontLight" , Integer .TYPE )
154+ private val mOpenFrontLight: Method ? = method(" openFrontLight" , Integer .TYPE )
155+
149156 // boolean closeFrontLight(int type)
150- private val mCloseFrontLight: Method ? = method(" closeFrontLight" , Integer .TYPE )
157+ private val mCloseFrontLight: Method ? = method(" closeFrontLight" , Integer .TYPE )
158+
151159 // boolean isLightOn(int type)
152- private val mIsLightOn: Method ? = method(" isLightOn" , Context ::class .java, Integer .TYPE )
153- ? : method(" isLightOn" , Integer .TYPE )
160+ private val mIsLightOn: Method ? = method(" isLightOn" , Context ::class .java, Integer .TYPE )
161+ ? : method(" isLightOn" , Integer .TYPE )
162+
154163 // boolean hasFLBrightness(Context)
155- private val mHasFLBrightness: Method ? = method(" hasFLBrightness" , Context ::class .java)
164+ private val mHasFLBrightness: Method ? = method(" hasFLBrightness" , Context ::class .java)
165+
156166 // boolean hasCTMBrightness(Context)
157167 private val mHasCTMBrightness: Method ? = method(" hasCTMBrightness" , Context ::class .java)
168+
158169 // boolean checkCTM()
159- private val mCheckCTM: Method ? = method(" checkCTM" )
170+ private val mCheckCTM: Method ? = method(" checkCTM" )
160171
161172 var brightnessType: OnyxBrightnessType = OnyxBrightnessType .NONE
162173 private set
@@ -177,33 +188,36 @@ object OnyxDevice {
177188 if (isInitialized && brightnessType != OnyxBrightnessType .NONE && brightnessType != OnyxBrightnessType .FL ) return
178189
179190 val checkCTM = mCheckCTM?.invoke(controller) as ? Boolean ? : false
180- val hasFL = mHasFLBrightness?.invoke(controller, context) as ? Boolean ? : false
181- val hasCTM = mHasCTMBrightness?.invoke(controller, context) as ? Boolean ? : false
191+ val hasFL = mHasFLBrightness?.invoke(controller, context) as ? Boolean ? : false
192+ val hasCTM = mHasCTMBrightness?.invoke(controller, context) as ? Boolean ? : false
182193
183194 // Check actual hardware channel availability as fallback/confirmation
184- val maxCTM = getMaxLightValue(LIGHT_TYPE_TEMP ) ? : 0
195+ val maxCTM = getMaxLightValue(LIGHT_TYPE_TEMP ) ? : 0
185196 val maxWarm = getMaxLightValue(LIGHT_TYPE_CTM_WARM ) ? : 0
186197
187198 val oldType = brightnessType
188199 brightnessType = when {
189200 checkCTM || maxCTM > 0 -> OnyxBrightnessType .CTM
190- hasCTM || maxWarm > 0 -> OnyxBrightnessType .WARM_AND_COLD
191- hasFL -> OnyxBrightnessType .FL
192- else -> OnyxBrightnessType .NONE
201+ hasCTM || maxWarm > 0 -> OnyxBrightnessType .WARM_AND_COLD
202+ hasFL -> OnyxBrightnessType .FL
203+ else -> OnyxBrightnessType .NONE
193204 }
194205
195206 if (brightnessType != OnyxBrightnessType .NONE ) {
196207 isInitialized = true
197208 }
198209
199210 if (oldType != brightnessType) {
200- Log .d(TAG , " Detection: checkCTM=$checkCTM hasCTM=$hasCTM hasFL=$hasFL maxCTM=$maxCTM maxWarm=$maxWarm → $brightnessType " )
211+ Log .d(
212+ TAG ,
213+ " Detection: checkCTM=$checkCTM hasCTM=$hasCTM hasFL=$hasFL maxCTM=$maxCTM maxWarm=$maxWarm → $brightnessType "
214+ )
201215 }
202216 }
203217
204218 // ── Reads ─────────────────────────────────────────────────────────────────
205219
206- fun getLightValue (context : Context , type : Int ): Int? = mGetLightValue?.invoke(controller, type) as ? Int
220+ fun getLightValue (context : Context , type : Int ): Int? = mGetLightValue?.invoke(controller, type) as ? Int
207221 fun getMaxLightValue (type : Int ): Int? {
208222 val max = mGetMaxLightValue?.invoke(controller, type) as ? Number
209223 return if (max == null || max.toInt() == 0 ) null else max.toInt()
@@ -218,36 +232,15 @@ object OnyxDevice {
218232 } as ? Boolean ? : false
219233
220234 // ── Write ─────────────────────────────────────────────────────────────────
221- //
222- // Two different axes — this is the source of both bugs:
223- //
224- // open/close → operates on the HARDWARE CHANNEL:
225- // LIGHT_TYPE_CTM_ALL (4) for CTM mode (types 6 and 7 are logical params,
226- // not hardware channels — opening
227- // type 6 or 7 individually does nothing)
228- // LIGHT_TYPE_CTM_WARM (2) / LIGHT_TYPE_CTM_COLD (3) for WARM_AND_COLD
229- // LIGHT_TYPE_FL (1) for FL
230- //
231- // setLightValue → operates on the LOGICAL PARAMETER (type passed as-is):
232- // type 6 = temperature, type 7 = brightness in CTM mode
233- // type 2 = warm, type 3 = cold in WARM_AND_COLD mode
234- // type 1 = brightness in FL mode
235- //
236- // Bug 1 — "Off mode": channel is powered down; setLightValue() alone is ignored.
237- // Fix: call openFrontLight(channelType) before setLightValue().
238- //
239- // Bug 2 — "Custom mode warmth": setLight(LIGHT_TYPE_TEMP=6, ...) was calling
240- // openFrontLight(6), but type 6 is not a hardware channel — only type 4 is.
241- // Fix: map types 6 and 7 to channelType = LIGHT_TYPE_CTM_ALL (4) for open/close.
242235
243236 fun setLight (context : Context , type : Int , value : Int ): Boolean {
244237 // Map logical parameter type → physical channel type for open/close.
245238 // For CTM, type 4 (ALL) controls the master switch.
246239 // For WARM_AND_COLD, channels 2 and 3 are independent.
247240 val channelType = when (type) {
248241 LIGHT_TYPE_CTM_BR ,
249- LIGHT_TYPE_TEMP -> LIGHT_TYPE_CTM_ALL // CTM: always open/close the whole unit
250- else -> type // FL / WARM / COLD: direct channel
242+ LIGHT_TYPE_TEMP -> LIGHT_TYPE_CTM_ALL // CTM: always open/close the whole unit
243+ else -> type // FL / WARM / COLD: direct channel
251244 }
252245
253246 return if (value == 0 ) {
@@ -258,6 +251,7 @@ object OnyxDevice {
258251 LIGHT_TYPE_CTM_BR ,
259252 LIGHT_TYPE_CTM_COLD ,
260253 LIGHT_TYPE_CTM_WARM -> true
254+
261255 else -> false
262256 }
263257
0 commit comments