Skip to content

Latest commit

 

History

History
778 lines (669 loc) · 19.7 KB

mce-hybris.c

File metadata and controls

778 lines (669 loc) · 19.7 KB
 
May 17, 2019
May 17, 2019
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @file mce-hybris.c
* Mode Control Entity - android hal access
* <p>
* Copyright (C) 2013-2019 Jolla Ltd.
* <p>
* @author Simo Piiroinen <simo.piiroinen@jollamobile.com>
*
* mce is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* mce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mce. If not, see <http://www.gnu.org/licenses/>.
*/
Apr 30, 2013
Apr 30, 2013
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* ========================================================================= *
* Most of the functions in this module are just thunks that load and call
* the real functionality from hybris-plugin on demand. If the hybris plugin
* is not installed or underlying android code does not support some hw
* elements these functions turn in to "NOP and return failure".
*
* In addition to the above this module also:
* - moves sensor input data via pipe from worker thread context to the
* thread that is running the glib mainloop.
* - proxies diagnostic output from hybris-plugin to mce_log()
* ========================================================================= */
#define MCE_HYBRIS_INTERNAL 1
#include "mce-hybris.h"
May 27, 2014
May 27, 2014
36
Jan 14, 2014
Jan 14, 2014
37
#include "mce.h"
Apr 30, 2013
Apr 30, 2013
38
39
40
41
42
43
44
45
46
47
#include "mce-log.h"
#include "mce-conf.h"
#include "mce-modules.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
Sep 12, 2019
Sep 12, 2019
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/* ========================================================================= *
* On some devices using in theory supported hybris functionality can lead
* to problems. As a solution mce side configuration files can be used to
* disable individual features.
* ========================================================================= */
#define MCE_CONF_FEATURE_HYBRIS_GROUP "FeatureHybris"
#define MCE_CONF_FEATURE_HYBRIS_FRAMEBUFFER "FrameBuffer"
#define MCE_CONF_FEATURE_HYBRIS_BACKLIGHT "BackLight"
#define MCE_CONF_FEATURE_HYBRIS_KEYPAD "KeyPad"
#define MCE_CONF_FEATURE_HYBRIS_INDICATOR_LED "IndicatorLed"
#define MCE_CONF_FEATURE_HYBRIS_PROXIMITY_SENSOR "ProximitySensor"
#define MCE_CONF_FEATURE_HYBRIS_LIGHT_SENSOR "LightSensor"
static bool
mce_hybris_feature_supported(const char *key)
{
bool res = mce_conf_get_bool(MCE_CONF_FEATURE_HYBRIS_GROUP, key, true);
mce_log(LL_WARN, "hybris feature %s is %s", key, res ? "allowed" : "denied");
return res;
}
Apr 30, 2013
Apr 30, 2013
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
static void mce_hybris_ps_set_hook(mce_hybris_ps_fn cb);
static void mce_hybris_als_set_hook(mce_hybris_als_fn cb);
/* ------------------------------------------------------------------------- *
* Feeding sensor data via pipe to glib mainloop goes roughly as follows
*
* --- mce-libhybris-plugin worker thread --
* 1) uses blocking poll_dev->poll() function to read sensor data
* 2) uses a set of callbacks to write the data to a pipe
* --- mce-libhybris-module --
* 3) iowatch reads the data from pipe
* 4) and passes the data to mce via another set of callbacks
* --- mce sensor handling code --
* 5) can act on the data in the context that runs gmainloop
* ------------------------------------------------------------------------- */
/** Sensor enumeration for mux @ worker thread -> pipe -> demux @ mainloop */
enum
{
EVEPIPE_ALS,
EVEPIPE_PS,
};
/** Sensor data passed over pipe */
typedef struct
{
int64_t time; // time stamp from android side
int32_t type; // EVEPIPE_ALS or EVEPIPE_PS
float value; // sensor data from android side
} evepipe_t;
/** Initialize once flag for sensor data pipe */
static bool evepipe_done = false;
/** Callback for handling proximity data */
static mce_hybris_ps_fn evepipe_ps_cb = 0;
/** Callback for handling ambient light data */
static mce_hybris_als_fn evepipe_als_cb = 0;
/** The sensor data pipe */
static int evepipe_fd[2] = { -1, -1 };
/** I/O watch id for the sensor data pipe */
static guint evepipe_id = 0;
/** I/O watch callback for handling pipe input
*
* @param channel (not used)
* @param condition (not used)
* @param data (not used)
*
* @return TRUE to keep the iowatch alive, or FALSE to remove it
*/
static gboolean evepipe_recv_cb(GIOChannel *channel,
GIOCondition condition,
gpointer data)
{
/* we just want the cb ... */
(void)channel; (void)condition; (void)data;
gboolean keep_going = TRUE;
evepipe_t eve[64];
Mar 14, 2014
Mar 14, 2014
136
137
138
139
140
if( condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) )
{
keep_going = FALSE;
}
Apr 30, 2013
Apr 30, 2013
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
int rc = read(evepipe_fd[0], eve, sizeof eve);
if( rc < 0 ) {
switch( errno ) {
case EINTR:
case EAGAIN:
break;
default:
mce_log(LL_ERR, "failed to read sensor events: %m");
keep_going = FALSE;
break;
}
goto cleanup;
}
rc /= sizeof *eve;
for( int i = 0; i < rc; ++i ) {
switch( eve[i].type ) {
case EVEPIPE_PS:
if( evepipe_ps_cb ) {
evepipe_ps_cb(eve[i].time, eve[i].value);
}
break;
case EVEPIPE_ALS:
if( evepipe_als_cb ) {
evepipe_als_cb(eve[i].time, eve[i].value);
}
break;
default:
break;
}
}
cleanup:
if( !keep_going ) {
mce_log(LL_CRIT, "disabling sensor event pipe iowatch");
evepipe_id = 0;
}
return keep_going;
}
/** Write sensor data to the pipe
*
* @param timestamp nanoseconds
* @param type EVEPIPE_ALS or EVEPIPE_PS
* @param data sensor data
*/
static void evepipe_send(int64_t timestamp, int32_t type, float data)
{
evepipe_t eve =
{
.time = timestamp,
.type = type,
.value = data,
};
int rc = TEMP_FAILURE_RETRY(write(evepipe_fd[1], &eve, sizeof eve));
if( rc != sizeof eve ) {
// TODO: since this happens from separate thread, we might want
// to do something bit more clever in case the sensor data
// overflows the pipe ...
Jan 14, 2014
Jan 14, 2014
209
mce_abort();
Apr 30, 2013
Apr 30, 2013
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
}
}
/** Write PS data to the sensor data pipe
*
* @param timestamp nanoseconds
* @param distance centimeters
*/
static void evepipe_send_ps(int64_t timestamp, float distance)
{
evepipe_send(timestamp, EVEPIPE_PS, distance);
}
/** Write ALS data to the sensor data pipe
* @param timestamp nanoseconds
* @param ligt lux
*/
static void evepipe_send_als(int64_t timestamp, float light)
{
evepipe_send(timestamp, EVEPIPE_ALS, light);
}
/** Close sensor data pipe
*
* @param reset_done true if we wish to return to uninitialized
* state, or false to preserve "already tried
* but failed" state
*/
static void evepipe_quit(bool reset_done)
{
/* remove io watch */
if( evepipe_id ) g_source_remove(evepipe_id), evepipe_id = 0;
/* close pipe file descriptors */
if( evepipe_fd[1] != -1 ) close(evepipe_fd[1]), evepipe_fd[1] = -1;
if( evepipe_fd[0] != -1 ) close(evepipe_fd[0]), evepipe_fd[0] = -1;
if( reset_done ) evepipe_done = false;
}
/** Initialize sensor data pipe
*
* @return true on success, or false in case of errors
*/
static bool evepipe_init(void)
{
GIOChannel *chn = 0;
if( evepipe_done ) {
goto EXIT;
}
evepipe_done = true;
if( pipe(evepipe_fd) == -1 ) {
goto EXIT;
}
if( !(chn = g_io_channel_unix_new(evepipe_fd[0])) ) {
goto EXIT;
}
Mar 14, 2014
Mar 14, 2014
272
evepipe_id = g_io_add_watch(chn,
May 13, 2014
May 13, 2014
273
274
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
evepipe_recv_cb, 0);
Apr 30, 2013
Apr 30, 2013
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
if( !evepipe_id ) {
goto EXIT;
}
EXIT:
if( chn != 0 ) g_io_channel_unref(chn);
if( !evepipe_id ) {
evepipe_quit(false);
}
return evepipe_id != 0;
}
/** Callback for forwarding logging from hybris-plugin to mce_log()
*
* @param lev syslog priority (=mce_log level) i.e. LOG_ERR etc
* @param file source code path
* @param func name of function within file
* @param text diagnostic message to output
*/
static void log_cb(int lev, const char *file, const char *func,
const char *text)
{
mce_log_file(lev, file, func, "%s", text);
}
/** INTERNAL Set up hybris-plugin -> mce_log() proxy
*
* @param base handle for hybris-plugin
*/
static void mce_hybris_set_logging_proxy(void *base)
{
static const char name[] = "mce_hybris_set_log_hook";
void (*func)(mce_hybris_log_fn cb) = 0;
if( (func = dlsym(base, name)) ) {
func(log_cb);
}
}
/** INTERNAL Lookup path to hybris plugin DSO
*
* @return path to DSO, or NULL in case of errors
*/
static char *mce_hybris_module_path(void)
{
static const char module_name[] = "hybris.so";
gchar *module_dir = 0;
char *module_path = 0;
module_dir = mce_conf_get_string(MCE_CONF_MODULES_GROUP,
MCE_CONF_MODULES_PATH,
DEFAULT_MCE_MODULE_PATH);
if( !module_dir ) {
goto EXIT;
}
if( asprintf(&module_path, "%s/%s", module_dir, module_name) < 0 ) {
module_path = 0;
}
EXIT:
g_free(module_dir);
return module_path;
}
/** Lookup function address from hybris plugin
*
* @name function name
*
* @return function address, or NULL in case of errors
*/
static void *mce_hybris_lookup_function(const char *name)
{
static void *base = 0;
static bool done = false;
void *addr = 0;
if( !done ) {
char *path = 0;
done = true;
if( !(path = mce_hybris_module_path()) ) {
mce_log(LL_WARN, "could not locate hybris plugin");
}
Aug 12, 2013
Aug 12, 2013
366
367
368
else if( access(path, F_OK) == -1 && errno == ENOENT ) {
mce_log(LL_NOTICE, "%s: not installed", path);
}
Aug 3, 2021
Aug 3, 2021
369
370
371
372
373
374
375
else {
int flags = RTLD_NOW | RTLD_LOCAL;
/* Note: RTLD_DEEPBIND is needed at least in Jolla1 for
* preventing symbol leakage from/to mce-plugin-libhybris
* (which accesses android bionic libc code via libhybris).
*/
Apr 19, 2021
Apr 19, 2021
376
#if defined(RTLD_DEEPBIND)
Aug 3, 2021
Aug 3, 2021
377
flags |= RTLD_DEEPBIND;
Apr 19, 2021
Apr 19, 2021
378
#else
Aug 3, 2021
Aug 3, 2021
379
mce_log(LL_WARN, "RTLD_DEEPBIND is not supported");
Apr 19, 2021
Apr 19, 2021
380
#endif
Aug 3, 2021
Aug 3, 2021
381
382
383
384
385
386
387
388
if( !(base = dlopen(path, flags)) ) {
mce_log(LL_WARN, "%s: failed to load: %s", path, dlerror());
}
else {
mce_log(LL_NOTICE, "loaded hybris plugin");
mce_hybris_set_logging_proxy(base);
}
Apr 30, 2013
Apr 30, 2013
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
}
free(path);
}
if( base ) {
if( !(addr = dlsym(base, name)) ) {
mce_log(LL_ERR, "%s: failed to lookup: %s", name, dlerror());
}
}
return addr;
}
/** Glue macro to perform function address lookup once
*
* Assumes a local function pointer variable 'real' exists,
* and the local function name is the same as the function
* we want to lookup from the plugin.so
*/
#define RESOLVE do {\
static bool done = false; \
if( !done ) { \
done = true;\
real = mce_hybris_lookup_function(__FUNCTION__);\
}\
} while(0);
/* Thunk functions that will either call the real functionality
* from the hybris plugin, or fall back to NOP with appropriate
* return value to signal failure.
*/
/** Release all resources allocated by this module */
void mce_hybris_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
evepipe_quit(true);
if( real ) real();
}
/* ------------------------------------------------------------------------- *
* framebuffer device
* ------------------------------------------------------------------------- */
/** Start using libhybris for frame buffer power control
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_framebuffer_init(void)
{
static bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
443
444
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_FRAMEBUFFER) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
return !real ? false : real();
}
/** Stop using libhybris for frame buffer power control
*/
void mce_hybris_framebuffer_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
if( real ) real();
}
/** Turn frame buffer power on/off via libhybris
*
* @param state true for power on, false for power off
*
* @return true on success, or false on failure
*/
bool mce_hybris_framebuffer_set_power(bool state)
{
static bool (*real)(bool) = 0;
RESOLVE;
return !real ? false : real(state);
}
/* ------------------------------------------------------------------------- *
* display backlight device
* ------------------------------------------------------------------------- */
/** Start using libhybris for display backlight brightness control
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_backlight_init(void)
{
static bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
481
482
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_BACKLIGHT) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
return !real ? false : real();
}
/** Stop using libhybris for display backlight brightness control
*/
void mce_hybris_backlight_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
if( real ) real();
}
/** Set display backlight brightness via libhybris
*
* @param level 0 for off, ..., 255 for maximum brightness
*
* @return true on success, or false on failure
*/
bool mce_hybris_backlight_set_brightness(int level)
{
static bool (*real)(int) = 0;
RESOLVE;
return !real ? false : real(level);
}
/* ------------------------------------------------------------------------- *
* keypad backlight device
* ------------------------------------------------------------------------- */
/** Start using libhybris for keypad backlight brightness control
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_keypad_init(void)
{
static bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
519
520
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_KEYPAD) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
return !real ? false : real();
}
/** Stop using libhybris for keypad backlight brightness control
*/
void mce_hybris_keypad_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
if( real ) real();
}
/** Set keypad backlight brightness via libhybris
*
* @param level 0 for off, ..., 255 for maximum brightness
*
* @return true on success, or false on failure
*/
bool mce_hybris_keypad_set_brightness(int level)
{
static bool (*real)(int) = 0;
RESOLVE;
return !real ? false : real(level);
}
/* ------------------------------------------------------------------------- *
* indicator led device
* ------------------------------------------------------------------------- */
/** Start using libhybris for indicator led control
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_indicator_init(void)
{
static bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
557
558
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_INDICATOR_LED) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
return !real ? false : real();
}
/** Stop using libhybris for indicator led control
*/
void mce_hybris_indicator_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
if( real ) real();
}
/** Set indicator led pattern via libhybris
*
* @param r red intensity 0 ... 255
* @param g green intensity 0 ... 255
* @param b blue intensity 0 ... 255
* @param ms_on milliseconds to keep the led on, or 0 for no flashing
* @param ms_on milliseconds to keep the led off, or 0 for no flashing
*
* @return true on success, or false on failure
*/
bool mce_hybris_indicator_set_pattern(int r, int g, int b, int ms_on, int ms_off)
{
static bool (*real)(int,int,int,int,int) = 0;
RESOLVE;
return !real ? false : real(r,g,b, ms_on, ms_off);
Aug 8, 2014
Aug 8, 2014
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
}
/** Query if currently active led backend can support breathing
*
* @return true if breathing can be requested, false otherwise
*/
bool
mce_hybris_indicator_can_breathe(void)
{
static bool (*real)(void) = 0;
RESOLVE;
/* If the plugin does not have this method, err on the safe side
* and assume that breathing is not ok */
return !real ? false : real();
Apr 30, 2013
Apr 30, 2013
602
603
}
Apr 29, 2014
Apr 29, 2014
604
605
606
607
608
609
610
611
612
613
614
/** Enable/disable timer based led breathing
*
* @param enable true for smooth sw transitions, false for hw blinking only
*/
void mce_hybris_indicator_enable_breathing(bool enable)
{
static void (*real)(bool) = 0;
RESOLVE;
if( real ) real(enable);
}
Jun 3, 2014
Jun 3, 2014
615
616
617
618
619
620
621
622
623
624
625
626
627
/** Set indicator led brightness
*
* @param level 1=minimum, 255=maximum
*
* @return true on success, or false on failure
*/
bool mce_hybris_indicator_set_brightness(int level)
{
static bool (*real)(int) = 0;
RESOLVE;
return !real ? false : real(level);
}
Apr 30, 2013
Apr 30, 2013
628
629
630
631
632
633
634
635
636
637
638
/* ------------------------------------------------------------------------- *
* proximity sensor
* ------------------------------------------------------------------------- */
/** Start using libhybris for proximity sensor input
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_ps_init(void)
{
bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
639
640
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_PROXIMITY_SENSOR) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
return !real ? false : real();
}
/** Stop using libhybris for proximity sensor input
*/
void mce_hybris_ps_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
evepipe_ps_cb = 0;
if( real ) real();
}
/** Enable/disable proximity sensor events via libhybris
*
* @param state true for enabling events, false for disabling
*
* @return true on success, or false on failure
*/
bool mce_hybris_ps_set_active(bool state)
{
static bool (*real)(bool) = 0;
RESOLVE;
return !real ? false : real(state);
}
/** INTERNAL Set hybris-plugin -> hybris-module PS event callback
*
* Note: the callback will be called from worker thread context
*
* @param cb callback plugin should use to send events to module side
*/
static void mce_hybris_ps_set_hook(mce_hybris_ps_fn cb)
{
static void (*real)(mce_hybris_ps_fn) = 0;
RESOLVE;
if( real ) real(cb);
}
/** Set proximity sensor event reporting callback
*
* Note: the callback will be called from the same context where
* glib mainloop is running
*
* @param cb callback plugin should use to send events to application code
*
* @return true on success, or false on failure
*/
bool mce_hybris_ps_set_callback(mce_hybris_ps_fn cb)
{
bool res = true;
if( (evepipe_ps_cb = cb) ) {
mce_hybris_ps_set_hook(evepipe_send_ps);
res = evepipe_init();
}
else {
mce_hybris_ps_set_hook(0);
}
return res;
}
/* ------------------------------------------------------------------------- *
* ambient light sensor
* ------------------------------------------------------------------------- */
/** Start using libhybris for ambient light sensor input
*
* @return true if functionality supported, or false if not
*/
bool mce_hybris_als_init(void)
{
bool (*real)(void) = 0;
Sep 12, 2019
Sep 12, 2019
715
716
if( mce_hybris_feature_supported(MCE_CONF_FEATURE_HYBRIS_LIGHT_SENSOR) )
RESOLVE;
Apr 30, 2013
Apr 30, 2013
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
return !real ? false : real();
}
/** Stop using libhybris for ambient light sensor input
*/
void mce_hybris_als_quit(void)
{
static void (*real)(void) = 0;
RESOLVE;
evepipe_als_cb = 0;
if( real ) real();
}
/** Enable/disable ambient light sensor events via libhybris
*
* @param state true for enabling events, false for disabling
*
* @return true on success, or false on failure
*/
bool mce_hybris_als_set_active(bool state)
{
static bool (*real)(bool) = 0;
RESOLVE;
return !real ? false : real(state);
}
/** INTERNAL Set hybris-plugin -> hybris-module PS event callback
*
* Note: the callback will be called from worker thread context
*
* @param cb callback plugin should use to send events to module side
*/
static void mce_hybris_als_set_hook(mce_hybris_als_fn cb)
{
static void (*real)(mce_hybris_als_fn) = 0;
RESOLVE;
if( real ) real(cb);
}
/** Set ambient light sensor event reporting callback
*
* Note: the callback will be called from the same context where
* glib mainloop is running
*
* @param cb callback plugin should use to send events to application code
*
* @return true on success, or false on failure
*/
bool mce_hybris_als_set_callback(mce_hybris_als_fn cb)
{
bool res = true;
if( (evepipe_als_cb = cb) ) {
mce_hybris_als_set_hook(evepipe_send_als);
res = evepipe_init();
}
else {
mce_hybris_als_set_hook(0);
}
return res;
}