Search code examples
androidcolorsdisplaysamsung-galaxy

How to determine current AMOLED screen mode?


Many Android devices with AMOLED screens display all images with oversaturated colors by default. E.g. Samsung Galaxy phones have the "Adaptive" screen mode, which forces windows of all apps to be displayed as if they were rendered in the native screen color space, which is wider than Display-P3.

OTOH, not all such devices support EGL_EXT_gl_colorspace_display_p3, regardless of screen mode, so I can't be sure whether the device my app is running on even has a wide-gamut screen, even less determine whether this mode is the default.

So, how can I actually determine whether current screen mode is sRGB or some wide-gamut mode? I'm targeting one specific device model, Samsung Galaxy A320F/DS (AKA "A3 (2017)"), so platform-specific ways are also OK.


Solution

  • There are several layers where colors can be manipulated.

    • SurfaceFlinger. This component is common to all Android systems. One can pass a custom color matrix to it (see the source code of the handler of this request) via e.g. the following command executed as the root user:
    service call SurfaceFlinger 1015 i32 1 \
    f 0 f 0 f 1 f 0 \
    f 0 f 1 f 0 f 0 \
    f 1 f 0 f 0 f 0 \
    f 0 f 0 f 0 f 1
    

    The above example command sets a matrix that will, acting on RGBA vectors, swap red and blue channels. To reset the custom matrix to default (identity) you can simply do

    service call SurfaceFlinger 1015 i32 0
    

    You might be able to do all this from a Java/JNI app without root privileges, simply asking for some permission, I didn't research this.

    • mDNIe, which stands for mobile Digital Natural Image engine. It's a Samsung-specific system that acts on a lower level than SurfaceFlinger. Namely, it affects Always On Display, on which SurfaceFlinger's custom color matrix doesn't have any effect.
      Current screen mode can be seen in the /sys/class/mdnie/mdnie/mode file, which appears to have the following mapping of values on Galaxy A320F/DS:
      • 0 — AMOLED cinema (apparently aims at Display-P3),
      • 1 — AMOLED photo (apparently aims at Adobe RGB),
      • 2 — Basic (aims at sRGB),
      • 3 — (don't know its purpose, but the value is accepted if written to mode)
      • 4 — Adaptive display (the widest, apparently native screen color space).
      • 5 — (don't know its purpose, but the value is accepted if written to mode)

    Moreover, the colors are also affected by the CoolWarm slider as well as Advanced options RGB per-channel adjustments. Changes to the former are somehow reflected in mdnie_ldu and sensorRGB files in the same directory, while the latter directly corresponds to whiteRGB file.

    Also, Blue light filter feature state is reflected in the night_mode file (it also influences mdnie_ldu and sensorRGB files mentioned above).

    Of the files described above, only mode is readable to a non-root user on SM-A320F/DS. On SM-G950FD (AKA "S8") nothing is accessible without root.