1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
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  */
16 
17 package android.hardware.display;
18 
19 import android.Manifest;
20 import android.annotation.IntDef;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SystemApi;
25 import android.annotation.SystemService;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.metrics.LogMaker;
29 import android.os.IBinder;
30 import android.os.RemoteException;
31 import android.os.ServiceManager;
32 import android.os.ServiceManager.ServiceNotFoundException;
33 import android.provider.Settings.Secure;
34 
35 import com.android.internal.R;
36 import com.android.internal.logging.MetricsLogger;
37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
38 
39 import java.lang.annotation.Retention;
40 import java.lang.annotation.RetentionPolicy;
41 import java.time.LocalTime;
42 
43 /**
44  * Manages the display's color transforms and modes.
45  *
46  * @hide
47  */
48 @SystemApi
49 @SystemService(Context.COLOR_DISPLAY_SERVICE)
50 public final class ColorDisplayManager {
51 
52     /**
53      * @hide
54      */
55     @Retention(RetentionPolicy.SOURCE)
56     @IntDef({CAPABILITY_NONE, CAPABILITY_PROTECTED_CONTENT, CAPABILITY_HARDWARE_ACCELERATION_GLOBAL,
57             CAPABILITY_HARDWARE_ACCELERATION_PER_APP})
58     public @interface CapabilityType {}
59 
60     /**
61      * The device does not support color transforms.
62      *
63      * @hide
64      */
65     @SystemApi
66     public static final int CAPABILITY_NONE = 0x0;
67     /**
68      * The device can use GPU composition on protected content (layers whose buffers are protected
69      * in the trusted memory zone).
70      *
71      * @hide
72      */
73     @SystemApi
74     public static final int CAPABILITY_PROTECTED_CONTENT = 0x1;
75     /**
76      * The device's hardware can efficiently apply transforms to the entire display.
77      *
78      * @hide
79      */
80     @SystemApi
81     public static final int CAPABILITY_HARDWARE_ACCELERATION_GLOBAL = 0x2;
82     /**
83      * The device's hardware can efficiently apply transforms to a specific Surface (window) so
84      * that apps can be transformed independently of one another.
85      *
86      * @hide
87      */
88     @SystemApi
89     public static final int CAPABILITY_HARDWARE_ACCELERATION_PER_APP = 0x4;
90 
91     /**
92      * @hide
93      */
94     @Retention(RetentionPolicy.SOURCE)
95     @IntDef({ AUTO_MODE_DISABLED, AUTO_MODE_CUSTOM_TIME, AUTO_MODE_TWILIGHT })
96     public @interface AutoMode {}
97 
98     /**
99      * Auto mode value to prevent Night display from being automatically activated. It can still
100      * be activated manually via {@link #setNightDisplayActivated(boolean)}.
101      *
102      * @see #setNightDisplayAutoMode(int)
103      *
104      * @hide
105      */
106     @SystemApi
107     public static final int AUTO_MODE_DISABLED = 0;
108     /**
109      * Auto mode value to automatically activate Night display at a specific start and end time.
110      *
111      * @see #setNightDisplayAutoMode(int)
112      * @see #setNightDisplayCustomStartTime(LocalTime)
113      * @see #setNightDisplayCustomEndTime(LocalTime)
114      *
115      * @hide
116      */
117     @SystemApi
118     public static final int AUTO_MODE_CUSTOM_TIME = 1;
119     /**
120      * Auto mode value to automatically activate Night display from sunset to sunrise.
121      *
122      * @see #setNightDisplayAutoMode(int)
123      *
124      * @hide
125      */
126     @SystemApi
127     public static final int AUTO_MODE_TWILIGHT = 2;
128 
129     /**
130      * @hide
131      */
132     @Retention(RetentionPolicy.SOURCE)
133     @IntDef({COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC})
134     public @interface ColorMode {}
135 
136     /**
137      * Color mode with natural colors.
138      *
139      * @hide
140      * @see #setColorMode(int)
141      */
142     public static final int COLOR_MODE_NATURAL = 0;
143     /**
144      * Color mode with boosted colors.
145      *
146      * @hide
147      * @see #setColorMode(int)
148      */
149     public static final int COLOR_MODE_BOOSTED = 1;
150     /**
151      * Color mode with saturated colors.
152      *
153      * @hide
154      * @see #setColorMode(int)
155      */
156     public static final int COLOR_MODE_SATURATED = 2;
157     /**
158      * Color mode with automatic colors.
159      *
160      * @hide
161      * @see #setColorMode(int)
162      */
163     public static final int COLOR_MODE_AUTOMATIC = 3;
164 
165     /**
166      * Display color mode range reserved for vendor customizations by the RenderIntent definition in
167      * hardware/interfaces/graphics/common/1.1/types.hal. These are NOT directly related to (but ARE
168      * mutually exclusive with) the {@link ColorMode} constants, but ARE directly related (and ARE
169      * mutually exclusive with) the DISPLAY_COLOR_* constants in DisplayTransformManager.
170      *
171      * @hide
172      */
173     public static final int VENDOR_COLOR_MODE_RANGE_MIN = 256; // 0x100
174     /**
175      * @hide
176      */
177     public static final int VENDOR_COLOR_MODE_RANGE_MAX = 511; // 0x1ff
178 
179     private final ColorDisplayManagerInternal mManager;
180     private MetricsLogger mMetricsLogger;
181 
182     /**
183      * @hide
184      */
ColorDisplayManager()185     public ColorDisplayManager() {
186         mManager = ColorDisplayManagerInternal.getInstance();
187     }
188 
189     /**
190      * (De)activates the night display transform.
191      *
192      * @hide
193      */
194     @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setNightDisplayActivated(boolean activated)195     public boolean setNightDisplayActivated(boolean activated) {
196         return mManager.setNightDisplayActivated(activated);
197     }
198 
199     /**
200      * Returns whether the night display transform is currently active.
201      *
202      * @hide
203      */
isNightDisplayActivated()204     public boolean isNightDisplayActivated() {
205         return mManager.isNightDisplayActivated();
206     }
207 
208     /**
209      * Sets the color temperature of the night display transform.
210      *
211      * @hide
212      */
213     @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setNightDisplayColorTemperature(int temperature)214     public boolean setNightDisplayColorTemperature(int temperature) {
215         return mManager.setNightDisplayColorTemperature(temperature);
216     }
217 
218     /**
219      * Gets the color temperature of the night display transform.
220      *
221      * @hide
222      */
getNightDisplayColorTemperature()223     public int getNightDisplayColorTemperature() {
224         return mManager.getNightDisplayColorTemperature();
225     }
226 
227     /**
228      * Returns the current auto mode value controlling when Night display will be automatically
229      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM_TIME}, or
230      * {@link #AUTO_MODE_TWILIGHT}.
231      *
232      * @hide
233      */
234     @SystemApi
235     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
getNightDisplayAutoMode()236     public @AutoMode int getNightDisplayAutoMode() {
237         return mManager.getNightDisplayAutoMode();
238     }
239 
240     /**
241      * Returns the current auto mode value, without validation, or {@code 1} if the auto mode has
242      * never been set.
243      *
244      * @hide
245      */
getNightDisplayAutoModeRaw()246     public int getNightDisplayAutoModeRaw() {
247         return mManager.getNightDisplayAutoModeRaw();
248     }
249 
250     /**
251      * Sets the current auto mode value controlling when Night display will be automatically
252      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM_TIME}, or
253      * {@link #AUTO_MODE_TWILIGHT}.
254      *
255      * @param autoMode the new auto mode to use
256      * @return {@code true} if new auto mode was set successfully
257      *
258      * @hide
259      */
260     @SystemApi
261     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setNightDisplayAutoMode(@utoMode int autoMode)262     public boolean setNightDisplayAutoMode(@AutoMode int autoMode) {
263         if (autoMode != AUTO_MODE_DISABLED
264                 && autoMode != AUTO_MODE_CUSTOM_TIME
265                 && autoMode != AUTO_MODE_TWILIGHT) {
266             throw new IllegalArgumentException("Invalid autoMode: " + autoMode);
267         }
268         if (mManager.getNightDisplayAutoMode() != autoMode) {
269             getMetricsLogger().write(new LogMaker(
270                     MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CHANGED)
271                     .setType(MetricsEvent.TYPE_ACTION)
272                     .setSubtype(autoMode));
273         }
274         return mManager.setNightDisplayAutoMode(autoMode);
275     }
276 
277     /**
278      * Returns the local time when Night display will be automatically activated when using
279      * {@link ColorDisplayManager#AUTO_MODE_CUSTOM_TIME}.
280      *
281      * @hide
282      */
getNightDisplayCustomStartTime()283     public @NonNull LocalTime getNightDisplayCustomStartTime() {
284         return mManager.getNightDisplayCustomStartTime().getLocalTime();
285     }
286 
287     /**
288      * Sets the local time when Night display will be automatically activated when using
289      * {@link ColorDisplayManager#AUTO_MODE_CUSTOM_TIME}.
290      *
291      * @param startTime the local time to automatically activate Night display
292      * @return {@code true} if the new custom start time was set successfully
293      *
294      * @hide
295      */
296     @SystemApi
297     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setNightDisplayCustomStartTime(@onNull LocalTime startTime)298     public boolean setNightDisplayCustomStartTime(@NonNull LocalTime startTime) {
299         if (startTime == null) {
300             throw new IllegalArgumentException("startTime cannot be null");
301         }
302         getMetricsLogger().write(new LogMaker(
303                 MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
304                 .setType(MetricsEvent.TYPE_ACTION)
305                 .setSubtype(0));
306         return mManager.setNightDisplayCustomStartTime(new Time(startTime));
307     }
308 
309     /**
310      * Returns the local time when Night display will be automatically deactivated when using
311      * {@link #AUTO_MODE_CUSTOM_TIME}.
312      *
313      * @hide
314      */
getNightDisplayCustomEndTime()315     public @NonNull LocalTime getNightDisplayCustomEndTime() {
316         return mManager.getNightDisplayCustomEndTime().getLocalTime();
317     }
318 
319     /**
320      * Sets the local time when Night display will be automatically deactivated when using
321      * {@link #AUTO_MODE_CUSTOM_TIME}.
322      *
323      * @param endTime the local time to automatically deactivate Night display
324      * @return {@code true} if the new custom end time was set successfully
325      *
326      * @hide
327      */
328     @SystemApi
329     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setNightDisplayCustomEndTime(@onNull LocalTime endTime)330     public boolean setNightDisplayCustomEndTime(@NonNull LocalTime endTime) {
331         if (endTime == null) {
332             throw new IllegalArgumentException("endTime cannot be null");
333         }
334         getMetricsLogger().write(new LogMaker(
335                 MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
336                 .setType(MetricsEvent.TYPE_ACTION)
337                 .setSubtype(1));
338         return mManager.setNightDisplayCustomEndTime(new Time(endTime));
339     }
340 
341     /**
342      * Sets the current display color mode.
343      *
344      * @hide
345      */
setColorMode(int colorMode)346     public void setColorMode(int colorMode) {
347         mManager.setColorMode(colorMode);
348     }
349 
350     /**
351      * Gets the current display color mode.
352      *
353      * @hide
354      */
getColorMode()355     public int getColorMode() {
356         return mManager.getColorMode();
357     }
358 
359     /**
360      * Returns whether the device has a wide color gamut display.
361      *
362      * @hide
363      */
364     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
isDeviceColorManaged()365     public boolean isDeviceColorManaged() {
366         return mManager.isDeviceColorManaged();
367     }
368 
369     /**
370      * Set the level of color saturation to apply to the display.
371      *
372      * @param saturationLevel 0-100 (inclusive), where 100 is full saturation
373      * @return whether the saturation level change was applied successfully
374      * @hide
375      */
376     @SystemApi
377     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setSaturationLevel(@ntRangefrom = 0, to = 100) int saturationLevel)378     public boolean setSaturationLevel(@IntRange(from = 0, to = 100) int saturationLevel) {
379         return mManager.setSaturationLevel(saturationLevel);
380     }
381 
382     /**
383      * Gets whether or not a non-default saturation level is currently applied to the display.
384      *
385      * @return {@code true} if the display is not at full saturation
386      * @hide
387      */
388     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
isSaturationActivated()389     public boolean isSaturationActivated() {
390         return mManager.isSaturationActivated();
391     }
392 
393     /**
394      * Set the level of color saturation to apply to a specific app.
395      *
396      * @param packageName the package name of the app whose windows should be desaturated
397      * @param saturationLevel 0-100 (inclusive), where 100 is full saturation
398      * @return whether the saturation level change was applied successfully
399      * @hide
400      */
401     @SystemApi
402     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setAppSaturationLevel(@onNull String packageName, @IntRange(from = 0, to = 100) int saturationLevel)403     public boolean setAppSaturationLevel(@NonNull String packageName,
404             @IntRange(from = 0, to = 100) int saturationLevel) {
405         return mManager.setAppSaturationLevel(packageName, saturationLevel);
406     }
407 
408     /**
409      * Enables or disables display white balance.
410      *
411      * @hide
412      */
413     @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
setDisplayWhiteBalanceEnabled(boolean enabled)414     public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
415         return mManager.setDisplayWhiteBalanceEnabled(enabled);
416     }
417 
418     /**
419      * Returns whether display white balance is currently enabled. Even if enabled, it may or may
420      * not be active, if another transform with higher priority is active.
421      *
422      * @hide
423      */
isDisplayWhiteBalanceEnabled()424     public boolean isDisplayWhiteBalanceEnabled() {
425         return mManager.isDisplayWhiteBalanceEnabled();
426     }
427 
428     /**
429      * Returns {@code true} if Night Display is supported by the device.
430      *
431      * @hide
432      */
isNightDisplayAvailable(Context context)433     public static boolean isNightDisplayAvailable(Context context) {
434         return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable);
435     }
436 
437     /**
438      * Returns the minimum allowed color temperature (in Kelvin) to tint the display when
439      * activated.
440      *
441      * @hide
442      */
getMinimumColorTemperature(Context context)443     public static int getMinimumColorTemperature(Context context) {
444         return context.getResources()
445                 .getInteger(R.integer.config_nightDisplayColorTemperatureMin);
446     }
447 
448     /**
449      * Returns the maximum allowed color temperature (in Kelvin) to tint the display when
450      * activated.
451      *
452      * @hide
453      */
getMaximumColorTemperature(Context context)454     public static int getMaximumColorTemperature(Context context) {
455         return context.getResources()
456                 .getInteger(R.integer.config_nightDisplayColorTemperatureMax);
457     }
458 
459     /**
460      * Returns {@code true} if display white balance is supported by the device.
461      *
462      * @hide
463      */
isDisplayWhiteBalanceAvailable(Context context)464     public static boolean isDisplayWhiteBalanceAvailable(Context context) {
465         return context.getResources().getBoolean(R.bool.config_displayWhiteBalanceAvailable);
466     }
467 
468     /**
469      * Check if the color transforms are color accelerated. Some transforms are experimental only
470      * on non-accelerated platforms due to the performance implications.
471      *
472      * @hide
473      */
isColorTransformAccelerated(Context context)474     public static boolean isColorTransformAccelerated(Context context) {
475         return context.getResources().getBoolean(R.bool.config_setColorTransformAccelerated);
476     }
477 
478     /**
479      * Returns the available software and hardware color transform capabilities of this device.
480      *
481      * @hide
482      */
483     @SystemApi
484     @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
getTransformCapabilities()485     public @CapabilityType int getTransformCapabilities() {
486         return mManager.getTransformCapabilities();
487     }
488 
489     /**
490      * Returns whether accessibility transforms are currently enabled, which determines whether
491      * color modes are currently configurable for this device.
492      *
493      * @hide
494      */
areAccessibilityTransformsEnabled(Context context)495     public static boolean areAccessibilityTransformsEnabled(Context context) {
496         final ContentResolver cr = context.getContentResolver();
497         return Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1
498                 || Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) == 1;
499     }
500 
getMetricsLogger()501     private MetricsLogger getMetricsLogger() {
502         if (mMetricsLogger == null) {
503             mMetricsLogger = new MetricsLogger();
504         }
505         return mMetricsLogger;
506     }
507 
508     private static class ColorDisplayManagerInternal {
509 
510         private static ColorDisplayManagerInternal sInstance;
511 
512         private final IColorDisplayManager mCdm;
513 
ColorDisplayManagerInternal(IColorDisplayManager colorDisplayManager)514         private ColorDisplayManagerInternal(IColorDisplayManager colorDisplayManager) {
515             mCdm = colorDisplayManager;
516         }
517 
getInstance()518         public static ColorDisplayManagerInternal getInstance() {
519             synchronized (ColorDisplayManagerInternal.class) {
520                 if (sInstance == null) {
521                     try {
522                         IBinder b = ServiceManager.getServiceOrThrow(Context.COLOR_DISPLAY_SERVICE);
523                         sInstance = new ColorDisplayManagerInternal(
524                                 IColorDisplayManager.Stub.asInterface(b));
525                     } catch (ServiceNotFoundException e) {
526                         throw new IllegalStateException(e);
527                     }
528                 }
529                 return sInstance;
530             }
531         }
532 
isNightDisplayActivated()533         boolean isNightDisplayActivated() {
534             try {
535                 return mCdm.isNightDisplayActivated();
536             } catch (RemoteException e) {
537                 throw e.rethrowFromSystemServer();
538             }
539         }
540 
setNightDisplayActivated(boolean activated)541         boolean setNightDisplayActivated(boolean activated) {
542             try {
543                 return mCdm.setNightDisplayActivated(activated);
544             } catch (RemoteException e) {
545                 throw e.rethrowFromSystemServer();
546             }
547         }
548 
getNightDisplayColorTemperature()549         int getNightDisplayColorTemperature() {
550             try {
551                 return mCdm.getNightDisplayColorTemperature();
552             } catch (RemoteException e) {
553                 throw e.rethrowFromSystemServer();
554             }
555         }
556 
setNightDisplayColorTemperature(int temperature)557         boolean setNightDisplayColorTemperature(int temperature) {
558             try {
559                 return mCdm.setNightDisplayColorTemperature(temperature);
560             } catch (RemoteException e) {
561                 throw e.rethrowFromSystemServer();
562             }
563         }
564 
getNightDisplayAutoMode()565         int getNightDisplayAutoMode() {
566             try {
567                 return mCdm.getNightDisplayAutoMode();
568             } catch (RemoteException e) {
569                 throw e.rethrowFromSystemServer();
570             }
571         }
572 
getNightDisplayAutoModeRaw()573         int getNightDisplayAutoModeRaw() {
574             try {
575                 return mCdm.getNightDisplayAutoModeRaw();
576             } catch (RemoteException e) {
577                 throw e.rethrowFromSystemServer();
578             }
579         }
580 
setNightDisplayAutoMode(int autoMode)581         boolean setNightDisplayAutoMode(int autoMode) {
582             try {
583                 return mCdm.setNightDisplayAutoMode(autoMode);
584             } catch (RemoteException e) {
585                 throw e.rethrowFromSystemServer();
586             }
587         }
588 
getNightDisplayCustomStartTime()589         Time getNightDisplayCustomStartTime() {
590             try {
591                 return mCdm.getNightDisplayCustomStartTime();
592             } catch (RemoteException e) {
593                 throw e.rethrowFromSystemServer();
594             }
595         }
596 
setNightDisplayCustomStartTime(Time startTime)597         boolean setNightDisplayCustomStartTime(Time startTime) {
598             try {
599                 return mCdm.setNightDisplayCustomStartTime(startTime);
600             } catch (RemoteException e) {
601                 throw e.rethrowFromSystemServer();
602             }
603         }
604 
getNightDisplayCustomEndTime()605         Time getNightDisplayCustomEndTime() {
606             try {
607                 return mCdm.getNightDisplayCustomEndTime();
608             } catch (RemoteException e) {
609                 throw e.rethrowFromSystemServer();
610             }
611         }
612 
setNightDisplayCustomEndTime(Time endTime)613         boolean setNightDisplayCustomEndTime(Time endTime) {
614             try {
615                 return mCdm.setNightDisplayCustomEndTime(endTime);
616             } catch (RemoteException e) {
617                 throw e.rethrowFromSystemServer();
618             }
619         }
620 
isDeviceColorManaged()621         boolean isDeviceColorManaged() {
622             try {
623                 return mCdm.isDeviceColorManaged();
624             } catch (RemoteException e) {
625                 throw e.rethrowFromSystemServer();
626             }
627         }
628 
setSaturationLevel(int saturationLevel)629         boolean setSaturationLevel(int saturationLevel) {
630             try {
631                 return mCdm.setSaturationLevel(saturationLevel);
632             } catch (RemoteException e) {
633                 throw e.rethrowFromSystemServer();
634             }
635         }
636 
isSaturationActivated()637         boolean isSaturationActivated() {
638             try {
639                 return mCdm.isSaturationActivated();
640             } catch (RemoteException e) {
641                 throw e.rethrowFromSystemServer();
642             }
643         }
644 
setAppSaturationLevel(String packageName, int saturationLevel)645         boolean setAppSaturationLevel(String packageName, int saturationLevel) {
646             try {
647                 return mCdm.setAppSaturationLevel(packageName, saturationLevel);
648             } catch (RemoteException e) {
649                 throw e.rethrowFromSystemServer();
650             }
651         }
652 
isDisplayWhiteBalanceEnabled()653         boolean isDisplayWhiteBalanceEnabled() {
654             try {
655                 return mCdm.isDisplayWhiteBalanceEnabled();
656             } catch (RemoteException e) {
657                 throw e.rethrowFromSystemServer();
658             }
659         }
660 
setDisplayWhiteBalanceEnabled(boolean enabled)661         boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
662             try {
663                 return mCdm.setDisplayWhiteBalanceEnabled(enabled);
664             } catch (RemoteException e) {
665                 throw e.rethrowFromSystemServer();
666             }
667         }
668 
getColorMode()669         int getColorMode() {
670             try {
671                 return mCdm.getColorMode();
672             } catch (RemoteException e) {
673                 throw e.rethrowFromSystemServer();
674             }
675         }
676 
setColorMode(int colorMode)677         void setColorMode(int colorMode) {
678             try {
679                 mCdm.setColorMode(colorMode);
680             } catch (RemoteException e) {
681                 throw e.rethrowFromSystemServer();
682             }
683         }
684 
getTransformCapabilities()685         int getTransformCapabilities() {
686             try {
687                 return mCdm.getTransformCapabilities();
688             } catch (RemoteException e) {
689                 throw e.rethrowFromSystemServer();
690             }
691         }
692     }
693 }
694