Just An Application

September 22, 2011

Android Internals: Resources – Part Ten: Complex Resource Entry Examples

Filed under: Android, Android Internals, Android Resources — Tags: , , — Simon Lewis @ 3:51 am

Complex Resource entries are used to represent array, attribute, plurals, and style Resources.

Terminology

To try and reduce the confusion resulting from the naming issues described here in what follows I am simply going to refer to instances of
struct ResTable_map as members.

1.0 Arrays

As the following examples show the distinction between array, integer-array, and string-array Resources only exists at the XML source level. Their binary
representations are identical which is why they are all stored in a single Type chunk.

1.1 Array

This array Resource definition

    <array name="example_array">
        <item>@array/example_integer_array</item>
        <item>@array/example_string_array</item>
    </array>

results in this complex Resource entry

    ...

    00000a10 10 00       // entry[0] size
    00000a12 01 00       // entry[0] flags
    00000a14 09 00 00 00 // entry[0] key [example_array]
    00000a18 00 00 00 00 // parent
    00000a1c 02 00 00 00 // count
    
    00000a20 00 00 00 02 // name
    00000a24 08 00       // size
    00000a26 00          // 0
    00000a27 01          // dataType
    00000a28 01 00 04 7f // data
    00000a2c 01 00 00 02 // name
    00000a30 08 00       // size
    00000a32 00          // 0
    00000a33 01          // dataType
    00000a34 02 00 04 7f // data

    ...

Each member represents an element of the array.

The name field of each member is the result of applying the macro Res_MAKEARRAY to the index of the element that it represents.

Res_MAKEARRAY() is defined as follows

    #define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))

(see frameworks/base/include/ResourceTypes.h line 216)

Each member has a data type of Res_value.TYPE_REFERENCE and the data is a Resource id.

1.2 Integer Array

This integer array Resource definition

    <integer-array name="example_integer_array">
        <item>1</item>
        <item>3</item>
        <item>5</item>
        <item>7</item>
        <item>11</item>
        <item>13</item>
        <item>17</item>
    </integer-array>

results in this complex Resource entry

    ...

    00000a38 10 00       // entry[1] size
    00000a3a 01 00       // entry[1] flags
    00000a3c 0a 00 00 00 // entry[1] key [example_integer_array]
    00000a40 00 00 00 00 // parent
    00000a44 07 00 00 00 // count

    00000a48 00 00 00 02 // name
    00000a4c 08 00       // size
    00000a4e 00          // 0
    00000a4f 10          // dataType
    00000a50 01 00 00 00 // data
    00000a54 01 00 00 02 // name
    00000a58 08 00       // size
    00000a5a 00          // 0
    00000a5b 10          // dataType
    00000a5c 03 00 00 00 // data
    00000a60 02 00 00 02 // name
    00000a64 08 00       // size
    00000a66 00          // 0
    00000a67 10          // dataType
    00000a68 05 00 00 00 // data
    00000a6c 03 00 00 02 // name
    00000a70 08 00       // size
    00000a72 00          // 0
    00000a73 10          // dataType
    00000a74 07 00 00 00 // data
    00000a78 04 00 00 02 // name
    00000a7c 08 00       // size
    00000a7e 00          // 0
    00000a7f 10          // dataType
    00000a80 0b 00 00 00 // data
    00000a84 05 00 00 02 // name
    00000a88 08 00       // size
    00000a8a 00          // 0
    00000a8b 10          // dataType
    00000a8c 0d 00 00 00 // data
    00000a90 06 00 00 02 // name
    00000a94 08 00       // size
    00000a96 00          // 0
    00000a97 10          // dataType
    00000a98 11 00 00 00 // data

    ...

The only difference between this example and the preceding one is that the data type of each member is Res_value.TYPE_INTEGER and the data is an integer.

1.3 String Array

This string array Resource definition

    <string-array name="example_string_array">
        <item>Viking</item>
        <item>North Utsire</item>
        <item>South Utsire</item>
        <item>Forties</item>
        <item>Cromarty</item>
        <item>Forth</item>
        <item>Tyne</item>
    </string-array>

results in this complex Resource entry

    ...

    00000a9c 10 00       // entry[2] size
    00000a9e 01 00       // entry[2] flags
    00000aa0 0b 00 00 00 // entry[2] key [example_string_array]
    00000aa4 00 00 00 00 // parent
    00000aa8 07 00 00 00 // count

    00000aac 00 00 00 02 // name
    00000ab0 08 00       // size
    00000ab2 00          // 0
    00000ab3 03          // dataType
    00000ab4 07 00 00 00 // data
    00000ab8 01 00 00 02 // name
    00000abc 08 00       // size
    00000abe 00          // 0
    00000abf 03          // dataType
    00000ac0 08 00 00 00 // data
    00000ac4 02 00 00 02 // name
    00000ac8 08 00       // size
    00000aca 00          // 0
    00000acb 03          // dataType
    00000acc 09 00 00 00 // data
    00000ad0 03 00 00 02 // name
    00000ad4 08 00       // size
    00000ad6 00          // 0
    00000ad7 03          // dataType
    00000ad8 0a 00 00 00 // data
    00000adc 04 00 00 02 // name
    00000ae0 08 00       // size
    00000ae2 00          // 0
    00000ae3 03          // dataType
    00000ae4 0b 00 00 00 // data
    00000ae8 05 00 00 02 // name
    00000aec 08 00       // size
    00000aee 00          // 0
    00000aef 03          // dataType
    00000af0 0c 00 00 00 // data
    00000af4 06 00 00 02 // name
    00000af8 08 00       // size
    00000afa 00          // 0
    00000afb 03          // dataType
    00000afc 0d 00 00 00 // data

    ...

The only difference between this example and the preceding one is that the data type of each member is Res_value.TYPE_STRING and the data is an index
into the StringPool chunk of the containing Table chunk.

2.0 Attributes

2.1 Attribute Types

Attribute types are defined by the following anonymous enum which nested in the definition of struct ResTable_map (see frameworks/base/include/ResourceTypes.h lines 1675-1714)

    enum {
        // No type has been defined for this attribute, use generic
        // type handling.  The low 16 bits are for types that can be
        // handled generically; the upper 16 require additional information
        // in the bag so can not be handled generically for TYPE_ANY.
        TYPE_ANY = 0x0000FFFF,

        // Attribute holds a references to another resource.
        TYPE_REFERENCE = 1<<0,

        // Attribute holds a generic string.
        TYPE_STRING = 1<<1,

        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
        // optionally specify a constrained range of possible integer values.
        TYPE_INTEGER = 1<<2,

        // Attribute holds a boolean integer.
        TYPE_BOOLEAN = 1<<3,

        // Attribute holds a color value.
        TYPE_COLOR = 1<<4,

        // Attribute holds a floating point value.
        TYPE_FLOAT = 1<<5,

        // Attribute holds a dimension value, such as "20px".
        TYPE_DIMENSION = 1<<6,

        // Attribute holds a fraction value, such as "20%".
        TYPE_FRACTION = 1<<7,

        // Attribute holds an enumeration.  The enumeration values are
        // supplied as additional entries in the map.
        TYPE_ENUM = 1<<16,

        // Attribute holds a bitmaks of flags.  The flag bit values are
        // supplied as additional entries in the map.
        TYPE_FLAGS = 1<<17
    };

2.2 Boolean Attribute

This attribute Resource definition

    <attr name="example_boolean_attribute" format="boolean"/>

results in this complex Resource entry

    ...
 
    0000073c 10 00       // entry[0] size
    0000073e 01 00       // entry[0] flags
    00000740 00 00 00 00 // entry[0] key [example_boolean_attribute]
    00000744 00 00 00 00 // parent
    00000748 01 00 00 00 // count

    0000074c 00 00 00 01 // name
    00000750 08 00       // size
    00000752 00          // 0
    00000753 10          // dataType
    00000754 08 00 00 00 // data
	
    ...

The entry has a single member which specifies the type of the attribute.

2.3 Enum Attribute

This attribute Resource definition

    <attr name="example_enum_attribute">
        <enum name="Humber" value="0"/>
        <enum name="Thames" value="1"/>
        <enum name="Dover"  value="2"/>
        <enum name="Wight"  value="3"/>
    </attr>

results in this complex Resource entry

    ...
 
    00000758 10 00       // entry[1] size
    0000075a 01 00       // entry[1] flags
    0000075c 01 00 00 00 // entry[1] key [example_enum_attribute]
    00000760 00 00 00 00 // parent
    00000764 05 00 00 00 // count

    00000768 00 00 00 01 // name
    0000076c 08 00       // size
    0000076e 00          // 0
    0000076f 10          // dataType
    00000770 00 00 01 00 // data
    00000774 00 00 05 7f // name
    00000778 08 00       // size
    0000077a 00          // 0
    0000077b 10          // dataType
    0000077c 00 00 00 00 // data
    00000780 01 00 05 7f // name
    00000784 08 00       // size
    00000786 00          // 0
    00000787 10          // dataType
    00000788 01 00 00 00 // data
    0000078c 02 00 05 7f // name
    00000790 08 00       // size
    00000792 00          // 0
    00000793 10          // dataType
    00000794 02 00 00 00 // data
    00000798 03 00 05 7f // name
    0000079c 08 00       // size
    0000079e 00          // 0
    0000079f 10          // dataType
    000007a0 03 00 00 00 // data

    ...

There are five members.

The first specifies the attribute type

The other four specify the enum members.

In each case

  • the name is the Resource id of the id Resource corresponding to the name attribute in the original XML, for example, Humber == 0x7f050000,

  • the data type is 0x10 (Res_value.TYPE_INTEGER) and

  • the data value is the value defined by the value attribute in the original XML.

2.4 Flags Attribute

This attribute Resource definition

    <attr name="exmple_flag_attribute">
        <flag name="Up"    value="0"/>
        <flag name="Down"  value="1"/>
        <flag name="Left"  value="2"/>
        <flag name="Right" value="3"/>
    </attr>

results in this complex Resource entry

    ...
 
    000007a4 10 00       // entry[2] size
    000007a6 01 00       // entry[2] flags
    000007a8 02 00 00 00 // entry[2] key [exmple_flag_attribute]
    000007ac 00 00 00 00 // parent
    000007b0 05 00 00 00 // count

    000007b4 00 00 00 01 // name
    000007b8 08 00       // size
    000007ba 00          // 0
    000007bb 10          // dataType
    000007bc 00 00 02 00 // data
    000007c0 04 00 05 7f // name
    000007c4 08 00       // size
    000007c6 00          // 0
    000007c7 10          // dataType
    000007c8 00 00 00 00 // data
    000007cc 05 00 05 7f // name
    000007d0 08 00       // size
    000007d2 00          // 0
    000007d3 10          // dataType
    000007d4 01 00 00 00 // data
    000007d8 06 00 05 7f // name
    000007dc 08 00       // size
    000007de 00          // 0
    000007df 10          // dataType
    000007e0 02 00 00 00 // data
    000007e4 07 00 05 7f // name
    000007e8 08 00       // size
    000007ea 00          // 0
    000007eb 10          // dataType
    000007ec 03 00 00 00 // data

    ...

There are five members.

The first specifies the attribute type

The other four specify the flags.

In each case

  • the name is the Resource id corresponding to the name attribute in the original XML, for example, Up == 0x7f050004,

  • the data type is 0x10 (Res_value.TYPE_INTEGER) and

  • the data value is the value defined by the value attribute in the original XML.

2.5 Integer Attribute

    <attr 
        name   = "example_integer_attribute" 
        format = "integer" 
        min    = "2" 
        max    = "7"/>
    ...
 
    000007f0 10 00       // entry[3] size
    000007f2 01 00       // entry[3] flags
    000007f4 03 00 00 00 // entry[3] key [example_integer_attribute]
    000007f8 00 00 00 00 // parent
    000007fc 03 00 00 00 // count

    00000800 00 00 00 01 // name
    00000804 08 00       // size
    00000806 00          // 0
    00000807 10          // dataType
    00000808 04 00 00 00 // data
    0000080c 01 00 00 01 // name
    00000810 08 00       // size
    00000812 00          // 0
    00000813 10          // dataType
    00000814 02 00 00 00 // data
    00000818 02 00 00 01 // name
    0000081c 08 00       // size
    0000081e 00          // 0
    0000081f 10          // dataType
    00000820 07 00 00 00 // data
	
    ...

The first specifies the attribute type

The second specifies the mimimum value

The second specifies the maximum value

3.0 Plurals

This plurals Resource definition

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <plurals name="plurals_example">
            <item quantity="one">once</item>
            <item quantity="two">twice</item>
            <item quantity="other">lots</item>
        </plurals>
    </resources>

results in this complex Resource entry

    ...

    00000f24 10 00       // entry[0] size
    00000f26 01 00       // entry[0] flags
    00000f28 24 00 00 00 // entry[0] key [plurals_example]
    00000f2c 00 00 00 00 // parent
    00000f30 03 00 00 00 // count

    00000f34 04 00 00 01 // name
    00000f38 08 00       // size
    00000f3a 00          // 0
    00000f3b 03          // dataType
    00000f3c 0f 00 00 00 // data
    00000f40 06 00 00 01 // name
    00000f44 08 00       // size
    00000f46 00          // 0
    00000f47 03          // dataType
    00000f48 0e 00 00 00 // data
    00000f4c 07 00 00 01 // name
    00000f50 08 00       // size
    00000f52 00          // 0
    00000f53 03          // dataType
    00000f54 10 00 00 00 // data
	
    ...

The three members correspond to the three items.

The names

  • 0x01000004

  • 0x01000006

  • 0x01000007

are the three constants

The data type of each member is Res_value.TYPE_STRING and the value is an index into the containing Table chunk’s StringPool chunk.

4.0 Styles

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name = "Text">
        </style>
        <style name="CustomText" parent="Text">
            <item name="android:textSize">20sp</item>
            <item name="android:textColor">#008</item>
        </style>
    </resources>
    ...

    00001018 00 00 00 00 // entry_index[0]
    0000101c 10 00 00 00 // entry_index[1]
    00001020 10 00       // entry[0] size
    00001022 01 00       // entry[0] flags
    00001024 27 00 00 00 // entry[0] key [Text]
    00001028 00 00 00 00 // parent
    0000102c 00 00 00 00 // count

    00001030 10 00       // entry[1] size
    00001032 01 00       // entry[1] flags
    00001034 28 00 00 00 // entry[1] key [CustomText]
    00001038 00 00 0d 7f // parent
    0000103c 02 00 00 00 // count

    00001040 95 00 01 01 // name
    00001044 08 00       // size
    00001046 00          // 0
    00001047 05          // dataType
    00001048 02 14 00 00 // data
    0000104c 98 00 01 01 // name
    00001050 08 00       // size
    00001052 00          // 0
    00001053 1f          // dataType
    00001054 88 00 00 ff // data

    ...

The first style which is defined simply to act as a parent for the second is empty and is represented by an empty Complex Resource entry.

The second style which inherits from the first is represented by a Complex Resource entry with two members.

The parent field specifies the Resource id of the parent style.

The name of each member is the Resource id specified by the name attribute in the original XML definition.

The value of each member represents the value specified by the corresponding item in the original XML definition.

5.0 Ids

Complex Resource entries are also used to represent id Resources in some circumstances.

Defining the enum and flags attributes above results in an additional id Typespec/Type chunk pair.

The Type chunk looks like this

    ...

    00000b38 05          // id
    00000b39 00          // 0
    00000b3a 00 00       // 0
    00000b3c 08 00 00 00 // entryCount
    00000b40 54 00 00 00 // entriesStart (address 00000b84)
    00000b44 20 00 00 00 // config: size
    00000b48 00 00 00 00 // config: imsi
    00000b4c 00 00 00 00 // config: locale
    00000b50 00 00 00 00 // config: screenType
    00000b54 00 00 00 00 // config: input
    00000b58 00 00 00 00 // config: screenSize
    00000b5c 00 00 00 00 // config: version
    00000b60 00 00 00 00 // config: screenConfig
    ++++++++++++++++++++

    00000b64 00 00 00 00 // entry_index[0]
    00000b68 10 00 00 00 // entry_index[1]
    00000b6c 20 00 00 00 // entry_index[2]
    00000b70 30 00 00 00 // entry_index[3]
    00000b74 40 00 00 00 // entry_index[4]
    00000b78 50 00 00 00 // entry_index[5]
    00000b7c 60 00 00 00 // entry_index[6]
    00000b80 70 00 00 00 // entry_index[7]
    00000b84 10 00       // entry[0] size
    00000b86 01 00       // entry[0] flags
    00000b88 0c 00 00 00 // entry[0] key [Humber]
    00000b8c 00 00 00 00 // parent
    00000b90 00 00 00 00 // count
    00000b94 10 00       // entry[1] size
    00000b96 01 00       // entry[1] flags
    00000b98 0d 00 00 00 // entry[1] key [Thames]
    00000b9c 00 00 00 00 // parent
    00000ba0 00 00 00 00 // count
    00000ba4 10 00       // entry[2] size
    00000ba6 01 00       // entry[2] flags
    00000ba8 0e 00 00 00 // entry[2] key [Dover]
    00000bac 00 00 00 00 // parent
    00000bb0 00 00 00 00 // count
    00000bb4 10 00       // entry[3] size
    00000bb6 01 00       // entry[3] flags
    00000bb8 0f 00 00 00 // entry[3] key [Wight]
    00000bbc 00 00 00 00 // parent
    00000bc0 00 00 00 00 // count
    00000bc4 10 00       // entry[4] size
    00000bc6 01 00       // entry[4] flags
    00000bc8 10 00 00 00 // entry[4] key [Up]
    00000bcc 00 00 00 00 // parent
    00000bd0 00 00 00 00 // count
    00000bd4 10 00       // entry[5] size
    00000bd6 01 00       // entry[5] flags
    00000bd8 11 00 00 00 // entry[5] key [Down]
    00000bdc 00 00 00 00 // parent
    00000be0 00 00 00 00 // count
    00000be4 10 00       // entry[6] size
    00000be6 01 00       // entry[6] flags
    00000be8 12 00 00 00 // entry[6] key [Left]
    00000bec 00 00 00 00 // parent
    00000bf0 00 00 00 00 // count
    00000bf4 10 00       // entry[7] size
    00000bf6 01 00       // entry[7] flags
    00000bf8 13 00 00 00 // entry[7] key [Right]
    00000bfc 00 00 00 00 // parent
    00000c00 00 00 00 00 // count
    ==================== [End of TYPE]

    ...

As you can see there are eight empty Complex Resource entries, one for each defined enum member and flag.

Note that this is not the only way that id Resources are represented. They can also be represented as Simple Resource entries with a boolean value of false.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: