blob: d31ce9b5e70db4b4687632820daa403d85496fd1 [file] [log] [blame]
Steve Kondik5ee87cb2015-08-16 22:33:30 -07001/*
Matt Wagantalleb82dbf2016-02-02 11:32:18 -08002 * Copyright (C) 2015-2016 The CyanogenMod Project
Steve Kondik5ee87cb2015-08-16 22:33:30 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package cyanogenmod.hardware;
17
18import android.content.Context;
19import android.os.IBinder;
20import android.os.RemoteException;
21import android.os.ServiceManager;
22import android.util.Log;
Steve Kondik86cae922016-07-18 02:36:42 -070023import android.util.Range;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070024
25import cyanogenmod.app.CMContextConstants;
26
Steve Kondik7cef6f62015-08-31 18:43:51 -070027import java.io.UnsupportedEncodingException;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070028import java.lang.IllegalArgumentException;
Steve Kondik7cef6f62015-08-31 18:43:51 -070029import java.nio.ByteBuffer;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070030import java.util.Arrays;
31import java.util.List;
32
33/**
34 * Manages access to CyanogenMod hardware extensions
35 *
Adnan Begovic99b8c5d2015-09-02 10:18:12 -070036 * <p>
37 * This manager requires the HARDWARE_ABSTRACTION_ACCESS permission.
38 * <p>
Steve Kondik5ee87cb2015-08-16 22:33:30 -070039 * To get the instance of this class, utilize CMHardwareManager#getInstance(Context context)
Steve Kondik5ee87cb2015-08-16 22:33:30 -070040 */
41public final class CMHardwareManager {
42 private static final String TAG = "CMHardwareManager";
43
Adnan Begovic19b267d2016-03-13 14:36:58 -080044 private static ICMHardwareService sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070045
46 private Context mContext;
47 /**
48 * Adaptive backlight support (this refers to technologies like NVIDIA SmartDimmer,
49 * QCOM CABL or Samsung CABC)
50 */
51 public static final int FEATURE_ADAPTIVE_BACKLIGHT = 0x1;
52
53 /**
54 * Color enhancement support
55 */
56 public static final int FEATURE_COLOR_ENHANCEMENT = 0x2;
57
58 /**
59 * Display RGB color calibration
60 */
61 public static final int FEATURE_DISPLAY_COLOR_CALIBRATION = 0x4;
62
63 /**
64 * Display gamma calibration
65 */
66 public static final int FEATURE_DISPLAY_GAMMA_CALIBRATION = 0x8;
67
68 /**
69 * High touch sensitivity for touch panels
70 */
71 public static final int FEATURE_HIGH_TOUCH_SENSITIVITY = 0x10;
72
73 /**
74 * Hardware navigation key disablement
75 */
76 public static final int FEATURE_KEY_DISABLE = 0x20;
77
78 /**
79 * Long term orbits (LTO)
80 */
81 public static final int FEATURE_LONG_TERM_ORBITS = 0x40;
82
83 /**
84 * Serial number other than ro.serialno
85 */
86 public static final int FEATURE_SERIAL_NUMBER = 0x80;
87
88 /**
89 * Increased display readability in bright light
90 */
91 public static final int FEATURE_SUNLIGHT_ENHANCEMENT = 0x100;
92
93 /**
94 * Double-tap the touch panel to wake up the device
95 */
96 public static final int FEATURE_TAP_TO_WAKE = 0x200;
97
98 /**
99 * Variable vibrator intensity
100 */
101 public static final int FEATURE_VIBRATOR = 0x400;
102
103 /**
104 * Touchscreen hovering
105 */
106 public static final int FEATURE_TOUCH_HOVERING = 0x800;
107
Steve Kondike18f6d82015-08-17 15:31:46 -0700108 /**
109 * Auto contrast
110 */
111 public static final int FEATURE_AUTO_CONTRAST = 0x1000;
112
113 /**
114 * Display modes
115 */
116 public static final int FEATURE_DISPLAY_MODES = 0x2000;
117
Steve Kondik7cef6f62015-08-31 18:43:51 -0700118 /**
119 * Persistent storage
120 */
121 public static final int FEATURE_PERSISTENT_STORAGE = 0x4000;
122
Danesh M2acf3ea2015-09-21 17:49:42 -0700123 /**
124 * Thermal change monitor
125 */
126 public static final int FEATURE_THERMAL_MONITOR = 0x8000;
127
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800128 /**
129 * Unique device ID
130 */
131 public static final int FEATURE_UNIQUE_DEVICE_ID = 0x10000;
132
Steve Kondik86cae922016-07-18 02:36:42 -0700133 /**
134 * Color balance
135 */
136 public static final int FEATURE_COLOR_BALANCE = 0x20000;
137
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700138 private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
139 FEATURE_ADAPTIVE_BACKLIGHT,
140 FEATURE_COLOR_ENHANCEMENT,
141 FEATURE_HIGH_TOUCH_SENSITIVITY,
142 FEATURE_KEY_DISABLE,
143 FEATURE_SUNLIGHT_ENHANCEMENT,
144 FEATURE_TAP_TO_WAKE,
145 FEATURE_TOUCH_HOVERING,
Danesh M2acf3ea2015-09-21 17:49:42 -0700146 FEATURE_AUTO_CONTRAST,
147 FEATURE_THERMAL_MONITOR
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700148 );
149
150 private static CMHardwareManager sCMHardwareManagerInstance;
151
152 /**
153 * @hide to prevent subclassing from outside of the framework
154 */
155 private CMHardwareManager(Context context) {
156 Context appContext = context.getApplicationContext();
157 if (appContext != null) {
158 mContext = appContext;
159 } else {
160 mContext = context;
161 }
Adnan Begovic19b267d2016-03-13 14:36:58 -0800162 sService = getService();
Adnan Begovica335ba32016-03-14 08:13:57 -0700163
164 if (context.getPackageManager().hasSystemFeature(
165 CMContextConstants.Features.HARDWARE_ABSTRACTION) && !checkService()) {
Adnan Begovicb51572d2016-04-26 16:57:38 -0700166 Log.wtf(TAG, "Unable to get CMHardwareService. The service either" +
Adnan Begovica335ba32016-03-14 08:13:57 -0700167 " crashed, was not started, or the interface has been called to early in" +
168 " SystemServer init");
169 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700170 }
171
172 /**
173 * Get or create an instance of the {@link cyanogenmod.hardware.CMHardwareManager}
174 * @param context
175 * @return {@link CMHardwareManager}
176 */
177 public static CMHardwareManager getInstance(Context context) {
178 if (sCMHardwareManagerInstance == null) {
179 sCMHardwareManagerInstance = new CMHardwareManager(context);
180 }
181 return sCMHardwareManagerInstance;
182 }
183
184 /** @hide */
Adnan Begovic19b267d2016-03-13 14:36:58 -0800185 public static ICMHardwareService getService() {
186 if (sService != null) {
187 return sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700188 }
189 IBinder b = ServiceManager.getService(CMContextConstants.CM_HARDWARE_SERVICE);
190 if (b != null) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800191 sService = ICMHardwareService.Stub.asInterface(b);
192 return sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700193 }
194 return null;
195 }
196
197 /**
198 * @return the supported features bitmask
199 */
200 public int getSupportedFeatures() {
201 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200202 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800203 return sService.getSupportedFeatures();
BadDaemon40a46bd2015-08-31 21:34:08 +0200204 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700205 } catch (RemoteException e) {
206 }
207 return 0;
208 }
209
210 /**
211 * Determine if a CM Hardware feature is supported on this device
212 *
213 * @param feature The CM Hardware feature to query
214 *
215 * @return true if the feature is supported, false otherwise.
216 */
217 public boolean isSupported(int feature) {
218 return feature == (getSupportedFeatures() & feature);
219 }
220
221 /**
222 * Determine if the given feature is enabled or disabled.
223 *
224 * Only used for features which have simple enable/disable controls.
225 *
226 * @param feature the CM Hardware feature to query
227 *
228 * @return true if the feature is enabled, false otherwise.
229 */
230 public boolean get(int feature) {
231 if (!BOOLEAN_FEATURES.contains(feature)) {
232 throw new IllegalArgumentException(feature + " is not a boolean");
233 }
234
235 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200236 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800237 return sService.get(feature);
BadDaemon40a46bd2015-08-31 21:34:08 +0200238 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700239 } catch (RemoteException e) {
240 }
241 return false;
242 }
243
244 /**
245 * Enable or disable the given feature
246 *
247 * Only used for features which have simple enable/disable controls.
248 *
249 * @param feature the CM Hardware feature to set
250 * @param enable true to enable, false to disale
251 *
252 * @return true if the feature is enabled, false otherwise.
253 */
254 public boolean set(int feature, boolean enable) {
255 if (!BOOLEAN_FEATURES.contains(feature)) {
256 throw new IllegalArgumentException(feature + " is not a boolean");
257 }
258
259 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200260 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800261 return sService.set(feature, enable);
BadDaemon40a46bd2015-08-31 21:34:08 +0200262 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700263 } catch (RemoteException e) {
264 }
265 return false;
266 }
267
268 private int getArrayValue(int[] arr, int idx, int defaultValue) {
269 if (arr == null || arr.length <= idx) {
270 return defaultValue;
271 }
272
273 return arr[idx];
274 }
275
276 /**
277 * {@hide}
278 */
279 public static final int VIBRATOR_INTENSITY_INDEX = 0;
280 /**
281 * {@hide}
282 */
283 public static final int VIBRATOR_DEFAULT_INDEX = 1;
284 /**
285 * {@hide}
286 */
287 public static final int VIBRATOR_MIN_INDEX = 2;
288 /**
289 * {@hide}
290 */
291 public static final int VIBRATOR_MAX_INDEX = 3;
292 /**
293 * {@hide}
294 */
295 public static final int VIBRATOR_WARNING_INDEX = 4;
296
297 private int[] getVibratorIntensityArray() {
298 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200299 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800300 return sService.getVibratorIntensity();
BadDaemon40a46bd2015-08-31 21:34:08 +0200301 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700302 } catch (RemoteException e) {
303 }
304 return null;
305 }
306
307 /**
308 * @return The current vibrator intensity.
309 */
310 public int getVibratorIntensity() {
311 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_INTENSITY_INDEX, 0);
312 }
313
314 /**
315 * @return The default vibrator intensity.
316 */
317 public int getVibratorDefaultIntensity() {
318 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_DEFAULT_INDEX, 0);
319 }
320
321 /**
322 * @return The minimum vibrator intensity.
323 */
324 public int getVibratorMinIntensity() {
325 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MIN_INDEX, 0);
326 }
327
328 /**
329 * @return The maximum vibrator intensity.
330 */
331 public int getVibratorMaxIntensity() {
332 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MAX_INDEX, 0);
333 }
334
335 /**
336 * @return The warning threshold vibrator intensity.
337 */
338 public int getVibratorWarningIntensity() {
339 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_WARNING_INDEX, 0);
340 }
341
342 /**
343 * Set the current vibrator intensity
344 *
345 * @param intensity the intensity to set, between {@link #getVibratorMinIntensity()} and
346 * {@link #getVibratorMaxIntensity()} inclusive.
347 *
348 * @return true on success, false otherwise.
349 */
350 public boolean setVibratorIntensity(int intensity) {
351 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200352 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800353 return sService.setVibratorIntensity(intensity);
BadDaemon40a46bd2015-08-31 21:34:08 +0200354 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700355 } catch (RemoteException e) {
356 }
357 return false;
358 }
359
360 /**
361 * {@hide}
362 */
363 public static final int COLOR_CALIBRATION_RED_INDEX = 0;
364 /**
365 * {@hide}
366 */
367 public static final int COLOR_CALIBRATION_GREEN_INDEX = 1;
368 /**
369 * {@hide}
370 */
371 public static final int COLOR_CALIBRATION_BLUE_INDEX = 2;
372 /**
373 * {@hide}
374 */
375 public static final int COLOR_CALIBRATION_DEFAULT_INDEX = 3;
376 /**
377 * {@hide}
378 */
379 public static final int COLOR_CALIBRATION_MIN_INDEX = 4;
380 /**
381 * {@hide}
382 */
383 public static final int COLOR_CALIBRATION_MAX_INDEX = 5;
384
385 private int[] getDisplayColorCalibrationArray() {
386 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200387 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800388 return sService.getDisplayColorCalibration();
BadDaemon40a46bd2015-08-31 21:34:08 +0200389 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700390 } catch (RemoteException e) {
391 }
392 return null;
393 }
394
395 /**
396 * @return the current RGB calibration, where int[0] = R, int[1] = G, int[2] = B.
397 */
398 public int[] getDisplayColorCalibration() {
399 int[] arr = getDisplayColorCalibrationArray();
400 if (arr == null || arr.length < 3) {
401 return null;
402 }
403 return Arrays.copyOf(arr, 3);
404 }
405
406 /**
407 * @return the default value for all colors
408 */
409 public int getDisplayColorCalibrationDefault() {
410 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_DEFAULT_INDEX, 0);
411 }
412
413 /**
414 * @return The minimum value for all colors
415 */
416 public int getDisplayColorCalibrationMin() {
417 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MIN_INDEX, 0);
418 }
419
420 /**
421 * @return The minimum value for all colors
422 */
423 public int getDisplayColorCalibrationMax() {
424 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MAX_INDEX, 0);
425 }
426
427 /**
428 * Set the display color calibration to the given rgb triplet
429 *
430 * @param rgb RGB color calibration. Each value must be between
Scott Mertzaa11b332016-06-13 12:21:07 -0700431 * {@link #getDisplayColorCalibrationMin()} and {@link #getDisplayColorCalibrationMax()},
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700432 * inclusive.
433 *
434 * @return true on success, false otherwise.
435 */
436 public boolean setDisplayColorCalibration(int[] rgb) {
437 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200438 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800439 return sService.setDisplayColorCalibration(rgb);
BadDaemon40a46bd2015-08-31 21:34:08 +0200440 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700441 } catch (RemoteException e) {
442 }
443 return false;
444 }
445
446 /**
Steve Kondik7cef6f62015-08-31 18:43:51 -0700447 * Write a string to persistent storage, which persists thru factory reset
448 *
Scott Mertz62579b12016-01-22 14:36:19 -0800449 * @param key String identifier for this item. Must not exceed 64 characters.
450 * @param value The UTF-8 encoded string to store of at least 1 character. null deletes the key/value pair.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700451 * @return true on success
452 */
453 public boolean writePersistentString(String key, String value) {
454 try {
455 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700456 return sService.writePersistentBytes(key,
Steve Kondik7cef6f62015-08-31 18:43:51 -0700457 value == null ? null : value.getBytes("UTF-8"));
458 }
459 } catch (RemoteException e) {
460 } catch (UnsupportedEncodingException e) {
461 Log.e(TAG, e.getMessage(), e);
462 }
463 return false;
464 }
465
466 /**
467 * Write an integer to persistent storage, which persists thru factory reset
468 *
Scott Mertz62579b12016-01-22 14:36:19 -0800469 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700470 * @param value The integer to store
471 * @return true on success
472 */
473 public boolean writePersistentInt(String key, int value) {
474 try {
475 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700476 return sService.writePersistentBytes(key,
Steve Kondik7cef6f62015-08-31 18:43:51 -0700477 ByteBuffer.allocate(4).putInt(value).array());
478 }
479 } catch (RemoteException e) {
480 }
481 return false;
482 }
483
484 /**
485 * Write a byte array to persistent storage, which persists thru factory reset
486 *
Scott Mertz62579b12016-01-22 14:36:19 -0800487 * @param key String identifier for this item. Must not exceed 64 characters.
488 * @param value The byte array to store, must be 1-4096 bytes. null deletes the key/value pair.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700489 * @return true on success
490 */
491 public boolean writePersistentBytes(String key, byte[] value) {
492 try {
493 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700494 return sService.writePersistentBytes(key, value);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700495 }
496 } catch (RemoteException e) {
497 }
498 return false;
499 }
500
501 /**
502 * Read a string from persistent storage
503 *
Scott Mertz62579b12016-01-22 14:36:19 -0800504 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700505 * @return the stored UTF-8 encoded string, null if not found
506 */
507 public String readPersistentString(String key) {
508 try {
509 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700510 byte[] bytes = sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700511 if (bytes != null) {
512 return new String(bytes, "UTF-8");
513 }
514 }
515 } catch (RemoteException e) {
516 } catch (UnsupportedEncodingException e) {
517 Log.e(TAG, e.getMessage(), e);
518 }
519 return null;
520 }
521
522 /**
523 * Read an integer from persistent storage
524 *
Scott Mertz62579b12016-01-22 14:36:19 -0800525 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700526 * @return the stored integer, zero if not found
527 */
528 public int readPersistentInt(String key) {
529 try {
530 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700531 byte[] bytes = sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700532 if (bytes != null) {
533 return ByteBuffer.wrap(bytes).getInt();
534 }
535 }
536 } catch (RemoteException e) {
537 }
538 return 0;
539 }
540
541 /**
542 * Read a byte array from persistent storage
543 *
Scott Mertz62579b12016-01-22 14:36:19 -0800544 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700545 * @return the stored byte array, null if not found
546 */
547 public byte[] readPersistentBytes(String key) {
548 try {
549 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700550 return sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700551 }
552 } catch (RemoteException e) {
553 }
554 return null;
555 }
556
557 /** Delete an object from persistent storage
558 *
559 * @param key String identifier for this item
560 * @return true if an item was deleted
561 */
562 public boolean deletePersistentObject(String key) {
563 try {
564 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700565 return sService.writePersistentBytes(key, null);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700566 }
567 } catch (RemoteException e) {
568 }
569 return false;
570 }
571
572 /**
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700573 * {@hide}
574 */
575 public static final int GAMMA_CALIBRATION_RED_INDEX = 0;
576 /**
577 * {@hide}
578 */
579 public static final int GAMMA_CALIBRATION_GREEN_INDEX = 1;
580 /**
581 * {@hide}
582 */
583 public static final int GAMMA_CALIBRATION_BLUE_INDEX = 2;
584 /**
585 * {@hide}
586 */
587 public static final int GAMMA_CALIBRATION_MIN_INDEX = 3;
588 /**
589 * {@hide}
590 */
591 public static final int GAMMA_CALIBRATION_MAX_INDEX = 4;
592
593 private int[] getDisplayGammaCalibrationArray(int idx) {
594 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200595 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800596 return sService.getDisplayGammaCalibration(idx);
BadDaemon40a46bd2015-08-31 21:34:08 +0200597 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700598 } catch (RemoteException e) {
599 }
600 return null;
601 }
602
603 /**
604 * @return the number of RGB controls the device supports
605 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700606 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700607 public int getNumGammaControls() {
608 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200609 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800610 return sService.getNumGammaControls();
BadDaemon40a46bd2015-08-31 21:34:08 +0200611 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700612 } catch (RemoteException e) {
613 }
614 return 0;
615 }
616
617 /**
Scott Mertzaa11b332016-06-13 12:21:07 -0700618 * @param idx the control to query
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700619 *
620 * @return the current RGB gamma calibration for the given control
621 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700622 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700623 public int[] getDisplayGammaCalibration(int idx) {
624 int[] arr = getDisplayGammaCalibrationArray(idx);
625 if (arr == null || arr.length < 3) {
626 return null;
627 }
628 return Arrays.copyOf(arr, 3);
629 }
630
631 /**
632 * @return the minimum value for all colors
633 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700634 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700635 public int getDisplayGammaCalibrationMin() {
636 return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MIN_INDEX, 0);
637 }
638
639 /**
640 * @return the maximum value for all colors
641 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700642 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700643 public int getDisplayGammaCalibrationMax() {
644 return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MAX_INDEX, 0);
645 }
646
647 /**
648 * Set the display gamma calibration for a specific control
649 *
650 * @param idx the control to set
651 * @param rgb RGB color calibration. Each value must be between
Scott Mertzaa11b332016-06-13 12:21:07 -0700652 * {@link #getDisplayGammaCalibrationMin()} and {@link #getDisplayGammaCalibrationMax()},
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700653 * inclusive.
654 *
655 * @return true on success, false otherwise.
656 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700657 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700658 public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
659 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200660 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800661 return sService.setDisplayGammaCalibration(idx, rgb);
BadDaemon40a46bd2015-08-31 21:34:08 +0200662 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700663 } catch (RemoteException e) {
664 }
665 return false;
666 }
667
668 /**
669 * @return the source location of LTO data, or null on failure
670 */
671 public String getLtoSource() {
672 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200673 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800674 return sService.getLtoSource();
BadDaemon40a46bd2015-08-31 21:34:08 +0200675 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700676 } catch (RemoteException e) {
677 }
678 return null;
679 }
680
681 /**
682 * @return the destination location of LTO data, or null on failure
683 */
684 public String getLtoDestination() {
685 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200686 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800687 return sService.getLtoDestination();
BadDaemon40a46bd2015-08-31 21:34:08 +0200688 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700689 } catch (RemoteException e) {
690 }
691 return null;
692 }
693
694 /**
695 * @return the interval, in milliseconds, to trigger LTO data download
696 */
697 public long getLtoDownloadInterval() {
698 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200699 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800700 return sService.getLtoDownloadInterval();
BadDaemon40a46bd2015-08-31 21:34:08 +0200701 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700702 } catch (RemoteException e) {
703 }
704 return 0;
705 }
706
707 /**
708 * @return the serial number to display instead of ro.serialno, or null on failure
709 */
710 public String getSerialNumber() {
711 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200712 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800713 return sService.getSerialNumber();
BadDaemon40a46bd2015-08-31 21:34:08 +0200714 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700715 } catch (RemoteException e) {
716 }
717 return null;
718 }
719
720 /**
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800721 * @return an id that's both unique and deterministic for the device
722 */
723 public String getUniqueDeviceId() {
724 try {
725 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800726 return sService.getUniqueDeviceId();
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800727 }
728 } catch (RemoteException e) {
729 }
730 return null;
731 }
732
733 /**
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700734 * @return true if adaptive backlight should be enabled when sunlight enhancement
735 * is enabled.
736 */
737 public boolean requireAdaptiveBacklightForSunlightEnhancement() {
738 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200739 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800740 return sService.requireAdaptiveBacklightForSunlightEnhancement();
BadDaemon40a46bd2015-08-31 21:34:08 +0200741 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700742 } catch (RemoteException e) {
743 }
744 return false;
745 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700746
747 /**
Steve Kondik968127f2015-12-08 04:12:45 -0800748 * @return true if this implementation does it's own lux metering
749 */
750 public boolean isSunlightEnhancementSelfManaged() {
751 try {
752 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800753 return sService.isSunlightEnhancementSelfManaged();
Steve Kondik968127f2015-12-08 04:12:45 -0800754 }
755 } catch (RemoteException e) {
756 }
757 return false;
758 }
759
760 /**
Steve Kondike18f6d82015-08-17 15:31:46 -0700761 * @return a list of available display modes on the devices
762 */
763 public DisplayMode[] getDisplayModes() {
764 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200765 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800766 return sService.getDisplayModes();
BadDaemon40a46bd2015-08-31 21:34:08 +0200767 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700768 } catch (RemoteException e) {
769 }
770 return null;
771 }
772
773 /**
774 * @return the currently active display mode
775 */
776 public DisplayMode getCurrentDisplayMode() {
777 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200778 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800779 return sService.getCurrentDisplayMode();
BadDaemon40a46bd2015-08-31 21:34:08 +0200780 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700781 } catch (RemoteException e) {
782 }
783 return null;
784 }
785
786 /**
787 * @return the default display mode to be set on boot
788 */
789 public DisplayMode getDefaultDisplayMode() {
790 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200791 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800792 return sService.getDefaultDisplayMode();
BadDaemon40a46bd2015-08-31 21:34:08 +0200793 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700794 } catch (RemoteException e) {
795 }
796 return null;
797 }
798
799 /**
800 * @return true if setting the mode was successful
801 */
Steve Kondikba4db5a2015-08-20 01:52:29 -0700802 public boolean setDisplayMode(DisplayMode mode, boolean makeDefault) {
Steve Kondike18f6d82015-08-17 15:31:46 -0700803 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200804 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800805 return sService.setDisplayMode(mode, makeDefault);
BadDaemon40a46bd2015-08-31 21:34:08 +0200806 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700807 } catch (RemoteException e) {
808 }
809 return false;
810 }
BadDaemon40a46bd2015-08-31 21:34:08 +0200811
Steve Kondik86cae922016-07-18 02:36:42 -0700812 public Range<Integer> getColorBalanceRange() {
813 int min = 0;
814 int max = 0;
815 try {
816 if (checkService()) {
817 min = sService.getColorBalanceMin();
818 max = sService.getColorBalanceMax();
819 }
820 } catch (RemoteException e) {
821 }
822 return new Range<Integer>(min, max);
823 }
824
825 public int getColorBalance() {
826 try {
827 if (checkService()) {
828 return sService.getColorBalance();
829 }
830 } catch (RemoteException e) {
831 }
832 return 0;
833 }
834
835 public boolean setColorBalance(int value) {
836 try {
837 if (checkService()) {
838 return sService.setColorBalance(value);
839 }
840 } catch (RemoteException e) {
841 }
842 return false;
843 }
844
BadDaemon40a46bd2015-08-31 21:34:08 +0200845 /**
846 * @return true if service is valid
847 */
848 private boolean checkService() {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800849 if (sService == null) {
850 Log.w(TAG, "not connected to CMHardwareManagerService");
851 return false;
BadDaemon40a46bd2015-08-31 21:34:08 +0200852 }
853 return true;
854 }
Danesh M2acf3ea2015-09-21 17:49:42 -0700855
856 /**
857 * @return current thermal {@link cyanogenmod.hardware.ThermalListenerCallback.State}
858 */
859 public int getThermalState() {
860 try {
861 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800862 return sService.getThermalState();
Danesh M2acf3ea2015-09-21 17:49:42 -0700863 }
864 } catch (RemoteException e) {
865 }
866 return ThermalListenerCallback.State.STATE_UNKNOWN;
867 }
868
869 /**
870 * Register a callback to be notified of thermal state changes
871 * @return boolean indicating whether register succeeded or failed
872 */
873 public boolean registerThermalListener(ThermalListenerCallback thermalCallback) {
874 try {
875 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800876 return sService.registerThermalListener(thermalCallback);
Danesh M2acf3ea2015-09-21 17:49:42 -0700877 }
878 } catch (RemoteException e) {
879 }
880 return false;
881 }
882
883 /**
884 * Unregister a callback previously registered to be notified of thermal state changes
885 * @return boolean indicating whether un-registering succeeded or failed
886 */
887 public boolean unRegisterThermalListener(ThermalListenerCallback thermalCallback) {
888 try {
889 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800890 return sService.unRegisterThermalListener(thermalCallback);
Danesh M2acf3ea2015-09-21 17:49:42 -0700891 }
892 } catch (RemoteException e) {
893 }
894 return false;
895 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700896}