Search This Blog

May 17, 2011

Android SystemProperties

Change value in Android console, code read value and switch branch.

In console
$ setprop rw.SECOND_DISPLAY_CONNECTED 0
In CPP code
property_get("rw.SECOND_DISPLAY_CONNECTED", value, "");
In Java code
import android.os.SystemProperties;
...
int value= SystemProperties.getInt("rw.SECOND_DISPLAY_CONNECTED",0);
The SystemProperties definition in "~/myandroid/frameworks/base/core/java/android/os/SystemProperties.java"
public class SystemProperties
{
    public static final int PROP_NAME_MAX = 31;
    public static final int PROP_VALUE_MAX = 91;

    private static native String native_get(String key);
    private static native String native_get(String key, String def);
    private static native int native_get_int(String key, int def);
    private static native long native_get_long(String key, long def);
    private static native boolean native_get_boolean(String key, boolean def);
    private static native void native_set(String key, String def);

    /**
     * Get the value for the given key.
     * @return an empty string if the key isn't found
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static String get(String key) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get(key);
    }

    /**
     * Get the value for the given key.
     * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static String get(String key, String def) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get(key, def);
    }

    /**
     * Get the value for the given key, and return as an integer.
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as an integer, or def if the key isn't found or
     *         cannot be parsed
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static int getInt(String key, int def) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get_int(key, def);
    }

    /**
     * Get the value for the given key, and return as a long.
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as a long, or def if the key isn't found or
     *         cannot be parsed
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static long getLong(String key, long def) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get_long(key, def);
    }

    /**
     * Get the value for the given key, returned as a boolean.
     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
     * (case insensitive).
     * If the key does not exist, or has any other value, then the default
     * result is returned.
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as a boolean, or def if the key isn't found or is
     *         not able to be parsed as a boolean.
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static boolean getBoolean(String key, boolean def) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get_boolean(key, def);
    }

    /**
     * Set the value for the given key.
     * @throws IllegalArgumentException if the key exceeds 32 characters
     * @throws IllegalArgumentException if the value exceeds 92 characters
     */
    public static void set(String key, String val) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        if (val != null && val.length() > PROP_VALUE_MAX) {
            throw new IllegalArgumentException("val.length > " +
                PROP_VALUE_MAX);
        }
        native_set(key, val);
    }
}
From the code above, we can know when we call SystemProperties.getInt(), it will excute "int native_get_int(String key, int def)" .

May 6, 2011

Extended display identification data(EDID)

1. EDID background

    we have product, need to connect difference monitor over VGA display port. In order to guarantee to set factory default  resolution of that monitor, we need to get video timing information for monitor by DDC interface(usually I2C bus). The information also call  Extended display identification data (EDID), (EDID) is a data structure provided by a digital display to describe its capabilities to a video source (e.g.graphics card, Set-top box). It is what enables a modern personal computer to know what kinds of monitors are connected to it. EDID is defined by a standard published by the Video Electronics Standards Association (VESA). The EDID includes manufacturer name and serial number, product type, phosphoror filter type, timings supported by the display, display size, luminance data and (for digital displays only) pixel mapping data.

2.EDID 1.3 data format

   EDID has 128 bytes, detail information please refer http://en.wikipedia.org/wiki/Extended_display_identification_data. We only focus on those video timing relate information.
   Usually EDID raw data like below(Sample monitor DELL 1907FP)
0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x10 0xAC 0x14 0x40 0x32 0x36 0x33 0x42
0x0A 0x10 0x01 0x03 0x0E 0x26 0x1E 0x78 0xEE 0x68 0x75 0xA2 0x5A 0x49 0x9F 0x23
0x13 0x50 0x54 0xA5 0x4B 0x00 0x71 0x4F 0x81 0x80 0x01 0x01 0x01 0x01 0x01 0x01
0x01 0x01 0x01 0x01 0x01 0x01 0x30 0x2A 0x00 0x98 0x51 0x00 0x2A 0x40 0x30 0x70
0x13 0x00 0x78 0x2D 0x11 0x00 0x00 0x1E 0x00 0x00 0x00 0xFF 0x00 0x43 0x39 0x37
0x35 0x39 0x36 0x33 0x37 0x42 0x33 0x36 0x32 0x0A 0x00 0x00 0x00 0xFC 0x00 0x44
0x45 0x4C 0x4C 0x20 0x31 0x39 0x30 0x37 0x46 0x50 0x0A 0x20 0x00 0x00 0x00 0xFD
0x00 0x38 0x4C 0x1E 0x51 0x0E 0x00 0x0A 0x20 0x20 0x20 0x20 0x20 0x20 0x00 0x7A
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  We care about ”Descriptor Blocks“, There are four "Descritor Blocks" from byte 54(Byte 0 is first byte), 18 bytes per block,we call them DTD. DTD is in first Descriptor Block in normal way, but it can be in any of the four. We read first two bytes of the block, we can judge it is DTD if they are nonzero, some monitor manufacturer may have more than one DTD, that need us to choose which one is most suitable.
Let’s decode DTD
0x30 0x2A 0x00 0x98 0x51 0x00 0x2A 0x40 0x30 0x70 0x13 0x00 0x78 0x2D 0x11 0x00 0x00 0x1E
byte0,1 is pixle clock, unit 10Khz,MSB in byte1, LSB in byte 0,
0x2A30=10800, that is 10800x10Khz=108Mhz.
byte2 and byte4 upper 4 bites is Horizontal active,
0x500 = 1280 pixel
byte5 and byte7 upper 4 bits is Vertical active
0x400 = 1024 pixel
byte3 and byte4 lower 4 bits is Horizontal banking
0x198= 408 pixel
byte6 and byte7 lower 4 bits is Vertical banking
0x2a=42 pixel
byte8 and byte11(bit7-6) is Horizontal sync offset
0x30 = 48
byte9 and byte11(bit5-4) is Horizontal sync pulse width
0x70 = 112
byte10 upper 4 bits and byte11(bit3-2) is Vertical sync offset
0x1 = 1
byte10 lower 4 bits and byte11(bit1-0) is Vertical sync pulse width
0x3 = 3
byte17  Interlaced or not (bit 7)
           Stereo or not (bit 6-5) ("00" means not)
           Separate Sync or not (bit 4-3)
           Vertical Sync positive or not (bit 2)
           Horizontal Sync positive or not (bit 1)
           Stereo Mode (bit 0) (unused if 6-5 are 00)
0x1E means HSync and VSync are positive.
And we need get refresh rate from EDID Standard timing identification(byte38-53)
0x81 0x80 0x01 0x01 0x01 0x01
First byte: Horizontal resolution. Multiply by 8, then add 248 for actual value
0x81 * 8 +248 = 1280
Second byte:
bit 7-6
Aspect ratio. Actual vertical resolution depends on horizontal resolution.
00=16:10, 01=4:3, 10=5:4, 11=16:9 (00=1:1 prior to v1.3)
10b means 5:4
bit 5-0
Vertical frequency. Add 60 to get actual value.
0 + 60 = 60Hz
Now we got timing parameters
General timing
Screen refresh rate 60Hz
Pixel frequency 108Mhz
Horizontal timing (line)
Visible area= 1280 pixels
HSync width = 112 pixels
Front porch = 48 pixels
Back porch = 408-112-48 = 248 pixels
Vertical timing(line)
Visible area = 1024 pixels
VSync width = 3 pixels
Front porch = 1
Back porch = 42 - 1- 3 = 38 pixels
We can get below information by decoding full EDID  structure
========================================
Display Information (EDID)
========================================
  EDID Version 1.3
  Manufacturer: DEL
  Model: 4014
  Serial#: 1110652466
  Year: 2006 Week 10
  Serial Number: C9759637B362
  Monitor Name: DELL 1907FP
  Display Characteristics:
     Monitor Operating Limits: From EDID
          H: 30-81KHz V: 56-76Hz DCLK: 140MHz
     Analog Display Input: Input Voltage - 0.700V/0.300V
     Sync: Separate Composite Sync on Green
     Max H-size in cm: 38
     Max V-size in cm: 30
     Gamma: 2.20
     DPMS: Active yes, Suspend yes, Standby yes
     RGB Color Display
     Chroma
        RedX:     0.634 RedY:     0.354
        GreenX:   0.287 GreenY:   0.621
        BlueX:    0.138 BlueY:    0.077
        WhiteX:   0.313 WhiteY:   0.329
     Default color format is primary
     First DETAILED Timing is preferred
  Detailed Timings
     108 MHz 1280 1328 1440 1688 1024 1025 1028 1066 +HSync +VSync
  Supported VESA Modes
     720x400@70Hz
     640x480@60Hz
     640x480@75Hz
     800x600@60Hz
     800x600@75Hz
     1024x768@60Hz
     1024x768@75Hz
     1280x1024@75Hz
     Manufacturer's mask: 0
  Standard Timings
     1152x864@75Hz
     1280x1024@60Hz
========================================

3. How to setup other resolution timing that not in EDID?

   In Linux, we can use “cvt” command to calculate timing setting for one resolutionn.
$ cvt 1280 1024 60
# 1280 is horizontal size , 1024 is vertical size, 60 is refresh rate.
#  we will get mode line like below
108 MHz 1280 1328 1440 1688 1024 1025 1028 1066 +HSync +VSync
I have checked some latest monitor in market. Most of them are not VESA timing, but suitable for themselves. Except one "KTC" monitor, I have tried to use its EDID timing to setup, however, the display shift right about 100 pixels. It is very unprofessional!
( Also we can have quick refer another interesting web site http://tinyvga.com/vga-timing. )