blob: 5f60443add5f8d2ce9ea0d71486aa3368137e4d3 [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;
Steve Kondik87590f02016-07-20 11:20:02 -070026import cyanogenmod.hardware.HSIC;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070027
Steve Kondik7cef6f62015-08-31 18:43:51 -070028import java.io.UnsupportedEncodingException;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070029import java.lang.IllegalArgumentException;
Steve Kondik7cef6f62015-08-31 18:43:51 -070030import java.nio.ByteBuffer;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070031import java.util.Arrays;
32import java.util.List;
33
34/**
35 * Manages access to CyanogenMod hardware extensions
36 *
Adnan Begovic99b8c5d2015-09-02 10:18:12 -070037 * <p>
38 * This manager requires the HARDWARE_ABSTRACTION_ACCESS permission.
39 * <p>
Steve Kondik5ee87cb2015-08-16 22:33:30 -070040 * To get the instance of this class, utilize CMHardwareManager#getInstance(Context context)
Steve Kondik5ee87cb2015-08-16 22:33:30 -070041 */
42public final class CMHardwareManager {
43 private static final String TAG = "CMHardwareManager";
44
Adnan Begovic19b267d2016-03-13 14:36:58 -080045 private static ICMHardwareService sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -070046
47 private Context mContext;
48 /**
49 * Adaptive backlight support (this refers to technologies like NVIDIA SmartDimmer,
50 * QCOM CABL or Samsung CABC)
51 */
52 public static final int FEATURE_ADAPTIVE_BACKLIGHT = 0x1;
53
54 /**
55 * Color enhancement support
56 */
57 public static final int FEATURE_COLOR_ENHANCEMENT = 0x2;
58
59 /**
60 * Display RGB color calibration
61 */
62 public static final int FEATURE_DISPLAY_COLOR_CALIBRATION = 0x4;
63
64 /**
65 * Display gamma calibration
66 */
67 public static final int FEATURE_DISPLAY_GAMMA_CALIBRATION = 0x8;
68
69 /**
70 * High touch sensitivity for touch panels
71 */
72 public static final int FEATURE_HIGH_TOUCH_SENSITIVITY = 0x10;
73
74 /**
75 * Hardware navigation key disablement
76 */
77 public static final int FEATURE_KEY_DISABLE = 0x20;
78
79 /**
80 * Long term orbits (LTO)
81 */
82 public static final int FEATURE_LONG_TERM_ORBITS = 0x40;
83
84 /**
85 * Serial number other than ro.serialno
86 */
87 public static final int FEATURE_SERIAL_NUMBER = 0x80;
88
89 /**
90 * Increased display readability in bright light
91 */
92 public static final int FEATURE_SUNLIGHT_ENHANCEMENT = 0x100;
93
94 /**
95 * Double-tap the touch panel to wake up the device
96 */
97 public static final int FEATURE_TAP_TO_WAKE = 0x200;
98
99 /**
100 * Variable vibrator intensity
101 */
102 public static final int FEATURE_VIBRATOR = 0x400;
103
104 /**
105 * Touchscreen hovering
106 */
107 public static final int FEATURE_TOUCH_HOVERING = 0x800;
108
Steve Kondike18f6d82015-08-17 15:31:46 -0700109 /**
110 * Auto contrast
111 */
112 public static final int FEATURE_AUTO_CONTRAST = 0x1000;
113
114 /**
115 * Display modes
116 */
117 public static final int FEATURE_DISPLAY_MODES = 0x2000;
118
Steve Kondik7cef6f62015-08-31 18:43:51 -0700119 /**
120 * Persistent storage
121 */
122 public static final int FEATURE_PERSISTENT_STORAGE = 0x4000;
123
Danesh M2acf3ea2015-09-21 17:49:42 -0700124 /**
125 * Thermal change monitor
126 */
127 public static final int FEATURE_THERMAL_MONITOR = 0x8000;
128
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800129 /**
130 * Unique device ID
131 */
132 public static final int FEATURE_UNIQUE_DEVICE_ID = 0x10000;
133
Steve Kondik86cae922016-07-18 02:36:42 -0700134 /**
135 * Color balance
136 */
137 public static final int FEATURE_COLOR_BALANCE = 0x20000;
138
Steve Kondik87590f02016-07-20 11:20:02 -0700139 /**
140 * HSIC picture adjustment
141 */
142 public static final int FEATURE_PICTURE_ADJUSTMENT = 0x40000;
143
144
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700145 private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
146 FEATURE_ADAPTIVE_BACKLIGHT,
147 FEATURE_COLOR_ENHANCEMENT,
148 FEATURE_HIGH_TOUCH_SENSITIVITY,
149 FEATURE_KEY_DISABLE,
150 FEATURE_SUNLIGHT_ENHANCEMENT,
151 FEATURE_TAP_TO_WAKE,
152 FEATURE_TOUCH_HOVERING,
Danesh M2acf3ea2015-09-21 17:49:42 -0700153 FEATURE_AUTO_CONTRAST,
154 FEATURE_THERMAL_MONITOR
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700155 );
156
157 private static CMHardwareManager sCMHardwareManagerInstance;
158
159 /**
160 * @hide to prevent subclassing from outside of the framework
161 */
162 private CMHardwareManager(Context context) {
163 Context appContext = context.getApplicationContext();
164 if (appContext != null) {
165 mContext = appContext;
166 } else {
167 mContext = context;
168 }
Adnan Begovic19b267d2016-03-13 14:36:58 -0800169 sService = getService();
Adnan Begovica335ba32016-03-14 08:13:57 -0700170
171 if (context.getPackageManager().hasSystemFeature(
172 CMContextConstants.Features.HARDWARE_ABSTRACTION) && !checkService()) {
Adnan Begovicb51572d2016-04-26 16:57:38 -0700173 Log.wtf(TAG, "Unable to get CMHardwareService. The service either" +
Adnan Begovica335ba32016-03-14 08:13:57 -0700174 " crashed, was not started, or the interface has been called to early in" +
175 " SystemServer init");
176 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700177 }
178
179 /**
180 * Get or create an instance of the {@link cyanogenmod.hardware.CMHardwareManager}
181 * @param context
182 * @return {@link CMHardwareManager}
183 */
184 public static CMHardwareManager getInstance(Context context) {
185 if (sCMHardwareManagerInstance == null) {
186 sCMHardwareManagerInstance = new CMHardwareManager(context);
187 }
188 return sCMHardwareManagerInstance;
189 }
190
191 /** @hide */
Adnan Begovic19b267d2016-03-13 14:36:58 -0800192 public static ICMHardwareService getService() {
193 if (sService != null) {
194 return sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700195 }
196 IBinder b = ServiceManager.getService(CMContextConstants.CM_HARDWARE_SERVICE);
197 if (b != null) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800198 sService = ICMHardwareService.Stub.asInterface(b);
199 return sService;
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700200 }
201 return null;
202 }
203
204 /**
205 * @return the supported features bitmask
206 */
207 public int getSupportedFeatures() {
208 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200209 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800210 return sService.getSupportedFeatures();
BadDaemon40a46bd2015-08-31 21:34:08 +0200211 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700212 } catch (RemoteException e) {
213 }
214 return 0;
215 }
216
217 /**
218 * Determine if a CM Hardware feature is supported on this device
219 *
220 * @param feature The CM Hardware feature to query
221 *
222 * @return true if the feature is supported, false otherwise.
223 */
224 public boolean isSupported(int feature) {
225 return feature == (getSupportedFeatures() & feature);
226 }
227
228 /**
229 * Determine if the given feature is enabled or disabled.
230 *
231 * Only used for features which have simple enable/disable controls.
232 *
233 * @param feature the CM Hardware feature to query
234 *
235 * @return true if the feature is enabled, false otherwise.
236 */
237 public boolean get(int feature) {
238 if (!BOOLEAN_FEATURES.contains(feature)) {
239 throw new IllegalArgumentException(feature + " is not a boolean");
240 }
241
242 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200243 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800244 return sService.get(feature);
BadDaemon40a46bd2015-08-31 21:34:08 +0200245 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700246 } catch (RemoteException e) {
247 }
248 return false;
249 }
250
251 /**
252 * Enable or disable the given feature
253 *
254 * Only used for features which have simple enable/disable controls.
255 *
256 * @param feature the CM Hardware feature to set
257 * @param enable true to enable, false to disale
258 *
259 * @return true if the feature is enabled, false otherwise.
260 */
261 public boolean set(int feature, boolean enable) {
262 if (!BOOLEAN_FEATURES.contains(feature)) {
263 throw new IllegalArgumentException(feature + " is not a boolean");
264 }
265
266 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200267 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800268 return sService.set(feature, enable);
BadDaemon40a46bd2015-08-31 21:34:08 +0200269 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700270 } catch (RemoteException e) {
271 }
272 return false;
273 }
274
275 private int getArrayValue(int[] arr, int idx, int defaultValue) {
276 if (arr == null || arr.length <= idx) {
277 return defaultValue;
278 }
279
280 return arr[idx];
281 }
282
283 /**
284 * {@hide}
285 */
286 public static final int VIBRATOR_INTENSITY_INDEX = 0;
287 /**
288 * {@hide}
289 */
290 public static final int VIBRATOR_DEFAULT_INDEX = 1;
291 /**
292 * {@hide}
293 */
294 public static final int VIBRATOR_MIN_INDEX = 2;
295 /**
296 * {@hide}
297 */
298 public static final int VIBRATOR_MAX_INDEX = 3;
299 /**
300 * {@hide}
301 */
302 public static final int VIBRATOR_WARNING_INDEX = 4;
303
304 private int[] getVibratorIntensityArray() {
305 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200306 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800307 return sService.getVibratorIntensity();
BadDaemon40a46bd2015-08-31 21:34:08 +0200308 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700309 } catch (RemoteException e) {
310 }
311 return null;
312 }
313
314 /**
315 * @return The current vibrator intensity.
316 */
317 public int getVibratorIntensity() {
318 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_INTENSITY_INDEX, 0);
319 }
320
321 /**
322 * @return The default vibrator intensity.
323 */
324 public int getVibratorDefaultIntensity() {
325 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_DEFAULT_INDEX, 0);
326 }
327
328 /**
329 * @return The minimum vibrator intensity.
330 */
331 public int getVibratorMinIntensity() {
332 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MIN_INDEX, 0);
333 }
334
335 /**
336 * @return The maximum vibrator intensity.
337 */
338 public int getVibratorMaxIntensity() {
339 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MAX_INDEX, 0);
340 }
341
342 /**
343 * @return The warning threshold vibrator intensity.
344 */
345 public int getVibratorWarningIntensity() {
346 return getArrayValue(getVibratorIntensityArray(), VIBRATOR_WARNING_INDEX, 0);
347 }
348
349 /**
350 * Set the current vibrator intensity
351 *
352 * @param intensity the intensity to set, between {@link #getVibratorMinIntensity()} and
353 * {@link #getVibratorMaxIntensity()} inclusive.
354 *
355 * @return true on success, false otherwise.
356 */
357 public boolean setVibratorIntensity(int intensity) {
358 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200359 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800360 return sService.setVibratorIntensity(intensity);
BadDaemon40a46bd2015-08-31 21:34:08 +0200361 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700362 } catch (RemoteException e) {
363 }
364 return false;
365 }
366
367 /**
368 * {@hide}
369 */
370 public static final int COLOR_CALIBRATION_RED_INDEX = 0;
371 /**
372 * {@hide}
373 */
374 public static final int COLOR_CALIBRATION_GREEN_INDEX = 1;
375 /**
376 * {@hide}
377 */
378 public static final int COLOR_CALIBRATION_BLUE_INDEX = 2;
379 /**
380 * {@hide}
381 */
382 public static final int COLOR_CALIBRATION_DEFAULT_INDEX = 3;
383 /**
384 * {@hide}
385 */
386 public static final int COLOR_CALIBRATION_MIN_INDEX = 4;
387 /**
388 * {@hide}
389 */
390 public static final int COLOR_CALIBRATION_MAX_INDEX = 5;
391
392 private int[] getDisplayColorCalibrationArray() {
393 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200394 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800395 return sService.getDisplayColorCalibration();
BadDaemon40a46bd2015-08-31 21:34:08 +0200396 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700397 } catch (RemoteException e) {
398 }
399 return null;
400 }
401
402 /**
403 * @return the current RGB calibration, where int[0] = R, int[1] = G, int[2] = B.
404 */
405 public int[] getDisplayColorCalibration() {
406 int[] arr = getDisplayColorCalibrationArray();
407 if (arr == null || arr.length < 3) {
408 return null;
409 }
410 return Arrays.copyOf(arr, 3);
411 }
412
413 /**
414 * @return the default value for all colors
415 */
416 public int getDisplayColorCalibrationDefault() {
417 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_DEFAULT_INDEX, 0);
418 }
419
420 /**
421 * @return The minimum value for all colors
422 */
423 public int getDisplayColorCalibrationMin() {
424 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MIN_INDEX, 0);
425 }
426
427 /**
428 * @return The minimum value for all colors
429 */
430 public int getDisplayColorCalibrationMax() {
431 return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MAX_INDEX, 0);
432 }
433
434 /**
435 * Set the display color calibration to the given rgb triplet
436 *
437 * @param rgb RGB color calibration. Each value must be between
Scott Mertzaa11b332016-06-13 12:21:07 -0700438 * {@link #getDisplayColorCalibrationMin()} and {@link #getDisplayColorCalibrationMax()},
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700439 * inclusive.
440 *
441 * @return true on success, false otherwise.
442 */
443 public boolean setDisplayColorCalibration(int[] rgb) {
444 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200445 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800446 return sService.setDisplayColorCalibration(rgb);
BadDaemon40a46bd2015-08-31 21:34:08 +0200447 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700448 } catch (RemoteException e) {
449 }
450 return false;
451 }
452
453 /**
Steve Kondik7cef6f62015-08-31 18:43:51 -0700454 * Write a string to persistent storage, which persists thru factory reset
455 *
Scott Mertz62579b12016-01-22 14:36:19 -0800456 * @param key String identifier for this item. Must not exceed 64 characters.
457 * @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 -0700458 * @return true on success
459 */
460 public boolean writePersistentString(String key, String value) {
461 try {
462 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700463 return sService.writePersistentBytes(key,
Steve Kondik7cef6f62015-08-31 18:43:51 -0700464 value == null ? null : value.getBytes("UTF-8"));
465 }
466 } catch (RemoteException e) {
467 } catch (UnsupportedEncodingException e) {
468 Log.e(TAG, e.getMessage(), e);
469 }
470 return false;
471 }
472
473 /**
474 * Write an integer to persistent storage, which persists thru factory reset
475 *
Scott Mertz62579b12016-01-22 14:36:19 -0800476 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700477 * @param value The integer to store
478 * @return true on success
479 */
480 public boolean writePersistentInt(String key, int value) {
481 try {
482 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700483 return sService.writePersistentBytes(key,
Steve Kondik7cef6f62015-08-31 18:43:51 -0700484 ByteBuffer.allocate(4).putInt(value).array());
485 }
486 } catch (RemoteException e) {
487 }
488 return false;
489 }
490
491 /**
492 * Write a byte array to persistent storage, which persists thru factory reset
493 *
Scott Mertz62579b12016-01-22 14:36:19 -0800494 * @param key String identifier for this item. Must not exceed 64 characters.
495 * @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 -0700496 * @return true on success
497 */
498 public boolean writePersistentBytes(String key, byte[] value) {
499 try {
500 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700501 return sService.writePersistentBytes(key, value);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700502 }
503 } catch (RemoteException e) {
504 }
505 return false;
506 }
507
508 /**
509 * Read a string from persistent storage
510 *
Scott Mertz62579b12016-01-22 14:36:19 -0800511 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700512 * @return the stored UTF-8 encoded string, null if not found
513 */
514 public String readPersistentString(String key) {
515 try {
516 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700517 byte[] bytes = sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700518 if (bytes != null) {
519 return new String(bytes, "UTF-8");
520 }
521 }
522 } catch (RemoteException e) {
523 } catch (UnsupportedEncodingException e) {
524 Log.e(TAG, e.getMessage(), e);
525 }
526 return null;
527 }
528
529 /**
530 * Read an integer from persistent storage
531 *
Scott Mertz62579b12016-01-22 14:36:19 -0800532 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700533 * @return the stored integer, zero if not found
534 */
535 public int readPersistentInt(String key) {
536 try {
537 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700538 byte[] bytes = sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700539 if (bytes != null) {
540 return ByteBuffer.wrap(bytes).getInt();
541 }
542 }
543 } catch (RemoteException e) {
544 }
545 return 0;
546 }
547
548 /**
549 * Read a byte array from persistent storage
550 *
Scott Mertz62579b12016-01-22 14:36:19 -0800551 * @param key String identifier for this item. Must not exceed 64 characters.
Steve Kondik7cef6f62015-08-31 18:43:51 -0700552 * @return the stored byte array, null if not found
553 */
554 public byte[] readPersistentBytes(String key) {
555 try {
556 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700557 return sService.readPersistentBytes(key);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700558 }
559 } catch (RemoteException e) {
560 }
561 return null;
562 }
563
564 /** Delete an object from persistent storage
565 *
566 * @param key String identifier for this item
567 * @return true if an item was deleted
568 */
569 public boolean deletePersistentObject(String key) {
570 try {
571 if (checkService()) {
Adnan Begovica335ba32016-03-14 08:13:57 -0700572 return sService.writePersistentBytes(key, null);
Steve Kondik7cef6f62015-08-31 18:43:51 -0700573 }
574 } catch (RemoteException e) {
575 }
576 return false;
577 }
578
579 /**
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700580 * {@hide}
581 */
582 public static final int GAMMA_CALIBRATION_RED_INDEX = 0;
583 /**
584 * {@hide}
585 */
586 public static final int GAMMA_CALIBRATION_GREEN_INDEX = 1;
587 /**
588 * {@hide}
589 */
590 public static final int GAMMA_CALIBRATION_BLUE_INDEX = 2;
591 /**
592 * {@hide}
593 */
594 public static final int GAMMA_CALIBRATION_MIN_INDEX = 3;
595 /**
596 * {@hide}
597 */
598 public static final int GAMMA_CALIBRATION_MAX_INDEX = 4;
599
600 private int[] getDisplayGammaCalibrationArray(int idx) {
601 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200602 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800603 return sService.getDisplayGammaCalibration(idx);
BadDaemon40a46bd2015-08-31 21:34:08 +0200604 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700605 } catch (RemoteException e) {
606 }
607 return null;
608 }
609
610 /**
611 * @return the number of RGB controls the device supports
612 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700613 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700614 public int getNumGammaControls() {
615 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200616 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800617 return sService.getNumGammaControls();
BadDaemon40a46bd2015-08-31 21:34:08 +0200618 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700619 } catch (RemoteException e) {
620 }
621 return 0;
622 }
623
624 /**
Scott Mertzaa11b332016-06-13 12:21:07 -0700625 * @param idx the control to query
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700626 *
627 * @return the current RGB gamma calibration for the given control
628 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700629 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700630 public int[] getDisplayGammaCalibration(int idx) {
631 int[] arr = getDisplayGammaCalibrationArray(idx);
632 if (arr == null || arr.length < 3) {
633 return null;
634 }
635 return Arrays.copyOf(arr, 3);
636 }
637
638 /**
639 * @return the minimum value for all colors
640 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700641 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700642 public int getDisplayGammaCalibrationMin() {
643 return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MIN_INDEX, 0);
644 }
645
646 /**
647 * @return the maximum value for all colors
648 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700649 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700650 public int getDisplayGammaCalibrationMax() {
651 return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MAX_INDEX, 0);
652 }
653
654 /**
655 * Set the display gamma calibration for a specific control
656 *
657 * @param idx the control to set
658 * @param rgb RGB color calibration. Each value must be between
Scott Mertzaa11b332016-06-13 12:21:07 -0700659 * {@link #getDisplayGammaCalibrationMin()} and {@link #getDisplayGammaCalibrationMax()},
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700660 * inclusive.
661 *
662 * @return true on success, false otherwise.
663 */
Steve Kondike18f6d82015-08-17 15:31:46 -0700664 @Deprecated
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700665 public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
666 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200667 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800668 return sService.setDisplayGammaCalibration(idx, rgb);
BadDaemon40a46bd2015-08-31 21:34:08 +0200669 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700670 } catch (RemoteException e) {
671 }
672 return false;
673 }
674
675 /**
676 * @return the source location of LTO data, or null on failure
677 */
678 public String getLtoSource() {
679 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200680 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800681 return sService.getLtoSource();
BadDaemon40a46bd2015-08-31 21:34:08 +0200682 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700683 } catch (RemoteException e) {
684 }
685 return null;
686 }
687
688 /**
689 * @return the destination location of LTO data, or null on failure
690 */
691 public String getLtoDestination() {
692 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200693 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800694 return sService.getLtoDestination();
BadDaemon40a46bd2015-08-31 21:34:08 +0200695 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700696 } catch (RemoteException e) {
697 }
698 return null;
699 }
700
701 /**
702 * @return the interval, in milliseconds, to trigger LTO data download
703 */
704 public long getLtoDownloadInterval() {
705 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200706 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800707 return sService.getLtoDownloadInterval();
BadDaemon40a46bd2015-08-31 21:34:08 +0200708 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700709 } catch (RemoteException e) {
710 }
711 return 0;
712 }
713
714 /**
715 * @return the serial number to display instead of ro.serialno, or null on failure
716 */
717 public String getSerialNumber() {
718 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200719 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800720 return sService.getSerialNumber();
BadDaemon40a46bd2015-08-31 21:34:08 +0200721 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700722 } catch (RemoteException e) {
723 }
724 return null;
725 }
726
727 /**
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800728 * @return an id that's both unique and deterministic for the device
729 */
730 public String getUniqueDeviceId() {
731 try {
732 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800733 return sService.getUniqueDeviceId();
Matt Wagantalleb82dbf2016-02-02 11:32:18 -0800734 }
735 } catch (RemoteException e) {
736 }
737 return null;
738 }
739
740 /**
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700741 * @return true if adaptive backlight should be enabled when sunlight enhancement
742 * is enabled.
743 */
744 public boolean requireAdaptiveBacklightForSunlightEnhancement() {
745 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200746 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800747 return sService.requireAdaptiveBacklightForSunlightEnhancement();
BadDaemon40a46bd2015-08-31 21:34:08 +0200748 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700749 } catch (RemoteException e) {
750 }
751 return false;
752 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700753
754 /**
Steve Kondik968127f2015-12-08 04:12:45 -0800755 * @return true if this implementation does it's own lux metering
756 */
757 public boolean isSunlightEnhancementSelfManaged() {
758 try {
759 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800760 return sService.isSunlightEnhancementSelfManaged();
Steve Kondik968127f2015-12-08 04:12:45 -0800761 }
762 } catch (RemoteException e) {
763 }
764 return false;
765 }
766
767 /**
Steve Kondike18f6d82015-08-17 15:31:46 -0700768 * @return a list of available display modes on the devices
769 */
770 public DisplayMode[] getDisplayModes() {
771 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200772 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800773 return sService.getDisplayModes();
BadDaemon40a46bd2015-08-31 21:34:08 +0200774 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700775 } catch (RemoteException e) {
776 }
777 return null;
778 }
779
780 /**
781 * @return the currently active display mode
782 */
783 public DisplayMode getCurrentDisplayMode() {
784 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200785 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800786 return sService.getCurrentDisplayMode();
BadDaemon40a46bd2015-08-31 21:34:08 +0200787 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700788 } catch (RemoteException e) {
789 }
790 return null;
791 }
792
793 /**
794 * @return the default display mode to be set on boot
795 */
796 public DisplayMode getDefaultDisplayMode() {
797 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200798 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800799 return sService.getDefaultDisplayMode();
BadDaemon40a46bd2015-08-31 21:34:08 +0200800 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700801 } catch (RemoteException e) {
802 }
803 return null;
804 }
805
806 /**
807 * @return true if setting the mode was successful
808 */
Steve Kondikba4db5a2015-08-20 01:52:29 -0700809 public boolean setDisplayMode(DisplayMode mode, boolean makeDefault) {
Steve Kondike18f6d82015-08-17 15:31:46 -0700810 try {
BadDaemon40a46bd2015-08-31 21:34:08 +0200811 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800812 return sService.setDisplayMode(mode, makeDefault);
BadDaemon40a46bd2015-08-31 21:34:08 +0200813 }
Steve Kondike18f6d82015-08-17 15:31:46 -0700814 } catch (RemoteException e) {
815 }
816 return false;
817 }
BadDaemon40a46bd2015-08-31 21:34:08 +0200818
Steve Kondik87590f02016-07-20 11:20:02 -0700819 /**
820 * @return the available range for color temperature adjustments
821 */
Steve Kondik86cae922016-07-18 02:36:42 -0700822 public Range<Integer> getColorBalanceRange() {
823 int min = 0;
824 int max = 0;
825 try {
826 if (checkService()) {
827 min = sService.getColorBalanceMin();
828 max = sService.getColorBalanceMax();
829 }
830 } catch (RemoteException e) {
831 }
832 return new Range<Integer>(min, max);
833 }
834
Steve Kondik87590f02016-07-20 11:20:02 -0700835 /**
836 * @return the current color balance value
837 */
Steve Kondik86cae922016-07-18 02:36:42 -0700838 public int getColorBalance() {
839 try {
840 if (checkService()) {
841 return sService.getColorBalance();
842 }
843 } catch (RemoteException e) {
844 }
845 return 0;
846 }
847
Steve Kondik87590f02016-07-20 11:20:02 -0700848 /**
849 * Sets the desired color balance. Must fall within the range obtained from
850 * getColorBalanceRange()
851 *
852 * @param value
853 * @return true if success
854 */
Steve Kondik86cae922016-07-18 02:36:42 -0700855 public boolean setColorBalance(int value) {
856 try {
857 if (checkService()) {
858 return sService.setColorBalance(value);
859 }
860 } catch (RemoteException e) {
861 }
862 return false;
863 }
864
BadDaemon40a46bd2015-08-31 21:34:08 +0200865 /**
Steve Kondik87590f02016-07-20 11:20:02 -0700866 * Gets the current picture adjustment values
867 *
868 * @return HSIC object with current settings
869 */
870 public HSIC getPictureAdjustment() {
871 try {
872 if (checkService()) {
873 return sService.getPictureAdjustment();
874 }
875 } catch (RemoteException e) {
876 }
877 return null;
878 }
879
880 /**
881 * Gets the default picture adjustment for the current mode
882 *
883 * @return HSIC object with default settings
884 */
885 public HSIC getDefaultPictureAdjustment() {
886 try {
887 if (checkService()) {
888 return sService.getDefaultPictureAdjustment();
889 }
890 } catch (RemoteException e) {
891 }
892 return null;
893 }
894
895 /**
896 * Sets the desired hue/saturation/intensity/contrast
897 *
898 * @param hsic
899 * @return true if success
900 */
901 public boolean setPictureAdjustment(final HSIC hsic) {
902 try {
903 if (checkService()) {
904 return sService.setPictureAdjustment(hsic);
905 }
906 } catch (RemoteException e) {
907 }
908 return false;
909 }
910
911 /**
912 * Get a list of ranges valid for picture adjustment.
913 *
914 * @return range list
915 */
916 public List<Range<Float>> getPictureAdjustmentRanges() {
917 try {
918 if (checkService()) {
919 float[] ranges = sService.getPictureAdjustmentRanges();
920 if (ranges.length > 7) {
921 return Arrays.asList(new Range<Float>(ranges[0], ranges[1]),
922 new Range<Float>(ranges[2], ranges[3]),
923 new Range<Float>(ranges[4], ranges[5]),
924 new Range<Float>(ranges[6], ranges[7]),
925 (ranges.length > 9 ?
926 new Range<Float>(ranges[8], ranges[9]) :
927 new Range<Float>(0.0f, 0.0f)));
928 }
929 }
930 } catch (RemoteException e) {
931 }
932 return null;
933 }
934
935 /**
BadDaemon40a46bd2015-08-31 21:34:08 +0200936 * @return true if service is valid
937 */
938 private boolean checkService() {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800939 if (sService == null) {
940 Log.w(TAG, "not connected to CMHardwareManagerService");
941 return false;
BadDaemon40a46bd2015-08-31 21:34:08 +0200942 }
943 return true;
944 }
Danesh M2acf3ea2015-09-21 17:49:42 -0700945
946 /**
947 * @return current thermal {@link cyanogenmod.hardware.ThermalListenerCallback.State}
948 */
949 public int getThermalState() {
950 try {
951 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800952 return sService.getThermalState();
Danesh M2acf3ea2015-09-21 17:49:42 -0700953 }
954 } catch (RemoteException e) {
955 }
956 return ThermalListenerCallback.State.STATE_UNKNOWN;
957 }
958
959 /**
960 * Register a callback to be notified of thermal state changes
961 * @return boolean indicating whether register succeeded or failed
962 */
963 public boolean registerThermalListener(ThermalListenerCallback thermalCallback) {
964 try {
965 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800966 return sService.registerThermalListener(thermalCallback);
Danesh M2acf3ea2015-09-21 17:49:42 -0700967 }
968 } catch (RemoteException e) {
969 }
970 return false;
971 }
972
973 /**
974 * Unregister a callback previously registered to be notified of thermal state changes
975 * @return boolean indicating whether un-registering succeeded or failed
976 */
977 public boolean unRegisterThermalListener(ThermalListenerCallback thermalCallback) {
978 try {
979 if (checkService()) {
Adnan Begovic19b267d2016-03-13 14:36:58 -0800980 return sService.unRegisterThermalListener(thermalCallback);
Danesh M2acf3ea2015-09-21 17:49:42 -0700981 }
982 } catch (RemoteException e) {
983 }
984 return false;
985 }
Steve Kondik5ee87cb2015-08-16 22:33:30 -0700986}