Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2005 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 //
     18 // Definitions of resource data structures.
     19 //
     20 #ifndef _LIBS_UTILS_RESOURCE_TYPES_H
     21 #define _LIBS_UTILS_RESOURCE_TYPES_H
     22 
     23 #include <utils/Asset.h>
     24 #include <utils/ByteOrder.h>
     25 #include <utils/Errors.h>
     26 #include <utils/String16.h>
     27 #include <utils/Vector.h>
     28 
     29 #include <utils/threads.h>
     30 
     31 #include <stdint.h>
     32 #include <sys/types.h>
     33 
     34 namespace android {
     35 
     36 /** ********************************************************************
     37  *  PNG Extensions
     38  *
     39  *  New private chunks that may be placed in PNG images.
     40  *
     41  *********************************************************************** */
     42 
     43 /**
     44  * This chunk specifies how to split an image into segments for
     45  * scaling.
     46  *
     47  * There are J horizontal and K vertical segments.  These segments divide
     48  * the image into J*K regions as follows (where J=4 and K=3):
     49  *
     50  *      F0   S0    F1     S1
     51  *   +-----+----+------+-------+
     52  * S2|  0  |  1 |  2   |   3   |
     53  *   +-----+----+------+-------+
     54  *   |     |    |      |       |
     55  *   |     |    |      |       |
     56  * F2|  4  |  5 |  6   |   7   |
     57  *   |     |    |      |       |
     58  *   |     |    |      |       |
     59  *   +-----+----+------+-------+
     60  * S3|  8  |  9 |  10  |   11  |
     61  *   +-----+----+------+-------+
     62  *
     63  * Each horizontal and vertical segment is considered to by either
     64  * stretchable (marked by the Sx labels) or fixed (marked by the Fy
     65  * labels), in the horizontal or vertical axis, respectively. In the
     66  * above example, the first is horizontal segment (F0) is fixed, the
     67  * next is stretchable and then they continue to alternate. Note that
     68  * the segment list for each axis can begin or end with a stretchable
     69  * or fixed segment.
     70  *
     71  * The relative sizes of the stretchy segments indicates the relative
     72  * amount of stretchiness of the regions bordered by the segments.  For
     73  * example, regions 3, 7 and 11 above will take up more horizontal space
     74  * than regions 1, 5 and 9 since the horizontal segment associated with
     75  * the first set of regions is larger than the other set of regions.  The
     76  * ratios of the amount of horizontal (or vertical) space taken by any
     77  * two stretchable slices is exactly the ratio of their corresponding
     78  * segment lengths.
     79  *
     80  * xDivs and yDivs point to arrays of horizontal and vertical pixel
     81  * indices.  The first pair of Divs (in either array) indicate the
     82  * starting and ending points of the first stretchable segment in that
     83  * axis. The next pair specifies the next stretchable segment, etc. So
     84  * in the above example xDiv[0] and xDiv[1] specify the horizontal
     85  * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and
     86  * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
     87  * the leftmost slices always start at x=0 and the rightmost slices
     88  * always end at the end of the image. So, for example, the regions 0,
     89  * 4 and 8 (which are fixed along the X axis) start at x value 0 and
     90  * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
     91  * xDiv[2].
     92  *
     93  * The array pointed to by the colors field lists contains hints for
     94  * each of the regions.  They are ordered according left-to-right and
     95  * top-to-bottom as indicated above. For each segment that is a solid
     96  * color the array entry will contain that color value; otherwise it
     97  * will contain NO_COLOR.  Segments that are completely transparent
     98  * will always have the value TRANSPARENT_COLOR.
     99  *
    100  * The PNG chunk type is "npTc".
    101  */
    102 struct Res_png_9patch
    103 {
    104     Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
    105                        yDivs(NULL), colors(NULL) { }
    106 
    107     int8_t wasDeserialized;
    108     int8_t numXDivs;
    109     int8_t numYDivs;
    110     int8_t numColors;
    111 
    112     // These tell where the next section of a patch starts.
    113     // For example, the first patch includes the pixels from
    114     // 0 to xDivs[0]-1 and the second patch includes the pixels
    115     // from xDivs[0] to xDivs[1]-1.
    116     // Note: allocation/free of these pointers is left to the caller.
    117     int32_t* xDivs;
    118     int32_t* yDivs;
    119 
    120     int32_t paddingLeft, paddingRight;
    121     int32_t paddingTop, paddingBottom;
    122 
    123     enum {
    124         // The 9 patch segment is not a solid color.
    125         NO_COLOR = 0x00000001,
    126 
    127         // The 9 patch segment is completely transparent.
    128         TRANSPARENT_COLOR = 0x00000000
    129     };
    130     // Note: allocation/free of this pointer is left to the caller.
    131     uint32_t* colors;
    132 
    133     // Convert data from device representation to PNG file representation.
    134     void deviceToFile();
    135     // Convert data from PNG file representation to device representation.
    136     void fileToDevice();
    137     // Serialize/Marshall the patch data into a newly malloc-ed block
    138     void* serialize();
    139     // Serialize/Marshall the patch data
    140     void serialize(void* outData);
    141     // Deserialize/Unmarshall the patch data
    142     static Res_png_9patch* deserialize(const void* data);
    143     // Compute the size of the serialized data structure
    144     size_t serializedSize();
    145 };
    146 
    147 /** ********************************************************************
    148  *  Base Types
    149  *
    150  *  These are standard types that are shared between multiple specific
    151  *  resource types.
    152  *
    153  *********************************************************************** */
    154 
    155 /**
    156  * Header that appears at the front of every data chunk in a resource.
    157  */
    158 struct ResChunk_header
    159 {
    160     // Type identifier for this chunk.  The meaning of this value depends
    161     // on the containing chunk.
    162     uint16_t type;
    163 
    164     // Size of the chunk header (in bytes).  Adding this value to
    165     // the address of the chunk allows you to find its associated data
    166     // (if any).
    167     uint16_t headerSize;
    168 
    169     // Total size of this chunk (in bytes).  This is the chunkSize plus
    170     // the size of any data associated with the chunk.  Adding this value
    171     // to the chunk allows you to completely skip its contents (including
    172     // any child chunks).  If this value is the same as chunkSize, there is
    173     // no data associated with the chunk.
    174     uint32_t size;
    175 };
    176 
    177 enum {
    178     RES_NULL_TYPE               = 0x0000,
    179     RES_STRING_POOL_TYPE        = 0x0001,
    180     RES_TABLE_TYPE              = 0x0002,
    181     RES_XML_TYPE                = 0x0003,
    182 
    183     // Chunk types in RES_XML_TYPE
    184     RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
    185     RES_XML_START_NAMESPACE_TYPE= 0x0100,
    186     RES_XML_END_NAMESPACE_TYPE  = 0x0101,
    187     RES_XML_START_ELEMENT_TYPE  = 0x0102,
    188     RES_XML_END_ELEMENT_TYPE    = 0x0103,
    189     RES_XML_CDATA_TYPE          = 0x0104,
    190     RES_XML_LAST_CHUNK_TYPE     = 0x017f,
    191     // This contains a uint32_t array mapping strings in the string
    192     // pool back to resource identifiers.  It is optional.
    193     RES_XML_RESOURCE_MAP_TYPE   = 0x0180,
    194 
    195     // Chunk types in RES_TABLE_TYPE
    196     RES_TABLE_PACKAGE_TYPE      = 0x0200,
    197     RES_TABLE_TYPE_TYPE         = 0x0201,
    198     RES_TABLE_TYPE_SPEC_TYPE    = 0x0202
    199 };
    200 
    201 /**
    202  * Macros for building/splitting resource identifiers.
    203  */
    204 #define Res_VALIDID(resid) (resid != 0)
    205 #define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)
    206 #define Res_MAKEID(package, type, entry) \
    207     (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))
    208 #define Res_GETPACKAGE(id) ((id>>24)-1)
    209 #define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
    210 #define Res_GETENTRY(id) (id&0xFFFF)
    211 
    212 #define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)
    213 #define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
    214 #define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
    215 
    216 #define Res_MAXPACKAGE 255
    217 
    218 /**
    219  * Representation of a value in a resource, supplying type
    220  * information.
    221  */
    222 struct Res_value
    223 {
    224     // Number of bytes in this structure.
    225     uint16_t size;
    226 
    227     // Always set to 0.
    228     uint8_t res0;
    229 
    230     // Type of the data value.
    231     enum {
    232         // Contains no data.
    233         TYPE_NULL = 0x00,
    234         // The 'data' holds a ResTable_ref, a reference to another resource
    235         // table entry.
    236         TYPE_REFERENCE = 0x01,
    237         // The 'data' holds an attribute resource identifier.
    238         TYPE_ATTRIBUTE = 0x02,
    239         // The 'data' holds an index into the containing resource table's
    240         // global value string pool.
    241         TYPE_STRING = 0x03,
    242         // The 'data' holds a single-precision floating point number.
    243         TYPE_FLOAT = 0x04,
    244         // The 'data' holds a complex number encoding a dimension value,
    245         // such as "100in".
    246         TYPE_DIMENSION = 0x05,
    247         // The 'data' holds a complex number encoding a fraction of a
    248         // container.
    249         TYPE_FRACTION = 0x06,
    250 
    251         // Beginning of integer flavors...
    252         TYPE_FIRST_INT = 0x10,
    253 
    254         // The 'data' is a raw integer value of the form n..n.
    255         TYPE_INT_DEC = 0x10,
    256         // The 'data' is a raw integer value of the form 0xn..n.
    257         TYPE_INT_HEX = 0x11,
    258         // The 'data' is either 0 or 1, for input "false" or "true" respectively.
    259         TYPE_INT_BOOLEAN = 0x12,
    260 
    261         // Beginning of color integer flavors...
    262         TYPE_FIRST_COLOR_INT = 0x1c,
    263 
    264         // The 'data' is a raw integer value of the form #aarrggbb.
    265         TYPE_INT_COLOR_ARGB8 = 0x1c,
    266         // The 'data' is a raw integer value of the form #rrggbb.
    267         TYPE_INT_COLOR_RGB8 = 0x1d,
    268         // The 'data' is a raw integer value of the form #argb.
    269         TYPE_INT_COLOR_ARGB4 = 0x1e,
    270         // The 'data' is a raw integer value of the form #rgb.
    271         TYPE_INT_COLOR_RGB4 = 0x1f,
    272 
    273         // ...end of integer flavors.
    274         TYPE_LAST_COLOR_INT = 0x1f,
    275 
    276         // ...end of integer flavors.
    277         TYPE_LAST_INT = 0x1f
    278     };
    279     uint8_t dataType;
    280 
    281     // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
    282     enum {
    283         // Where the unit type information is.  This gives us 16 possible
    284         // types, as defined below.
    285         COMPLEX_UNIT_SHIFT = 0,
    286         COMPLEX_UNIT_MASK = 0xf,
    287 
    288         // TYPE_DIMENSION: Value is raw pixels.
    289         COMPLEX_UNIT_PX = 0,
    290         // TYPE_DIMENSION: Value is Device Independent Pixels.
    291         COMPLEX_UNIT_DIP = 1,
    292         // TYPE_DIMENSION: Value is a Scaled device independent Pixels.
    293         COMPLEX_UNIT_SP = 2,
    294         // TYPE_DIMENSION: Value is in points.
    295         COMPLEX_UNIT_PT = 3,
    296         // TYPE_DIMENSION: Value is in inches.
    297         COMPLEX_UNIT_IN = 4,
    298         // TYPE_DIMENSION: Value is in millimeters.
    299         COMPLEX_UNIT_MM = 5,
    300 
    301         // TYPE_FRACTION: A basic fraction of the overall size.
    302         COMPLEX_UNIT_FRACTION = 0,
    303         // TYPE_FRACTION: A fraction of the parent size.
    304         COMPLEX_UNIT_FRACTION_PARENT = 1,
    305 
    306         // Where the radix information is, telling where the decimal place
    307         // appears in the mantissa.  This give us 4 possible fixed point
    308         // representations as defined below.
    309         COMPLEX_RADIX_SHIFT = 4,
    310         COMPLEX_RADIX_MASK = 0x3,
    311 
    312         // The mantissa is an integral number -- i.e., 0xnnnnnn.0
    313         COMPLEX_RADIX_23p0 = 0,
    314         // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
    315         COMPLEX_RADIX_16p7 = 1,
    316         // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
    317         COMPLEX_RADIX_8p15 = 2,
    318         // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
    319         COMPLEX_RADIX_0p23 = 3,
    320 
    321         // Where the actual value is.  This gives us 23 bits of
    322         // precision.  The top bit is the sign.
    323         COMPLEX_MANTISSA_SHIFT = 8,
    324         COMPLEX_MANTISSA_MASK = 0xffffff
    325     };
    326 
    327     // The data for this item, as interpreted according to dataType.
    328     uint32_t data;
    329 
    330     void copyFrom_dtoh(const Res_value& src);
    331 };
    332 
    333 /**
    334  *  This is a reference to a unique entry (a ResTable_entry structure)
    335  *  in a resource table.  The value is structured as: 0xpptteeee,
    336  *  where pp is the package index, tt is the type index in that
    337  *  package, and eeee is the entry index in that type.  The package
    338  *  and type values start at 1 for the first item, to help catch cases
    339  *  where they have not been supplied.
    340  */
    341 struct ResTable_ref
    342 {
    343     uint32_t ident;
    344 };
    345 
    346 /**
    347  * Reference to a string in a string pool.
    348  */
    349 struct ResStringPool_ref
    350 {
    351     // Index into the string pool table (uint32_t-offset from the indices
    352     // immediately after ResStringPool_header) at which to find the location
    353     // of the string data in the pool.
    354     uint32_t index;
    355 };
    356 
    357 /** ********************************************************************
    358  *  String Pool
    359  *
    360  *  A set of strings that can be references by others through a
    361  *  ResStringPool_ref.
    362  *
    363  *********************************************************************** */
    364 
    365 /**
    366  * Definition for a pool of strings.  The data of this chunk is an
    367  * array of uint32_t providing indices into the pool, relative to
    368  * stringsStart.  At stringsStart are all of the UTF-16 strings
    369  * concatenated together; each starts with a uint16_t of the string's
    370  * length and each ends with a 0x0000 terminator.  If a string is >
    371  * 32767 characters, the high bit of the length is set meaning to take
    372  * those 15 bits as a high word and it will be followed by another
    373  * uint16_t containing the low word.
    374  *
    375  * If styleCount is not zero, then immediately following the array of
    376  * uint32_t indices into the string table is another array of indices
    377  * into a style table starting at stylesStart.  Each entry in the
    378  * style table is an array of ResStringPool_span structures.
    379  */
    380 struct ResStringPool_header
    381 {
    382     struct ResChunk_header header;
    383 
    384     // Number of strings in this pool (number of uint32_t indices that follow
    385     // in the data).
    386     uint32_t stringCount;
    387 
    388     // Number of style span arrays in the pool (number of uint32_t indices
    389     // follow the string indices).
    390     uint32_t styleCount;
    391 
    392     // Flags.
    393     enum {
    394         // If set, the string index is sorted by the string values (based
    395         // on strcmp16()).
    396         SORTED_FLAG = 1<<0,
    397 
    398         // String pool is encoded in UTF-8
    399         UTF8_FLAG = 1<<8
    400     };
    401     uint32_t flags;
    402 
    403     // Index from header of the string data.
    404     uint32_t stringsStart;
    405 
    406     // Index from header of the style data.
    407     uint32_t stylesStart;
    408 };
    409 
    410 /**
    411  * This structure defines a span of style information associated with
    412  * a string in the pool.
    413  */
    414 struct ResStringPool_span
    415 {
    416     enum {
    417         END = 0xFFFFFFFF
    418     };
    419 
    420     // This is the name of the span -- that is, the name of the XML
    421     // tag that defined it.  The special value END (0xFFFFFFFF) indicates
    422     // the end of an array of spans.
    423     ResStringPool_ref name;
    424 
    425     // The range of characters in the string that this span applies to.
    426     uint32_t firstChar, lastChar;
    427 };
    428 
    429 /**
    430  * Convenience class for accessing data in a ResStringPool resource.
    431  */
    432 class ResStringPool
    433 {
    434 public:
    435     ResStringPool();
    436     ResStringPool(const void* data, size_t size, bool copyData=false);
    437     ~ResStringPool();
    438 
    439     status_t setTo(const void* data, size_t size, bool copyData=false);
    440 
    441     status_t getError() const;
    442 
    443     void uninit();
    444 
    445     inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
    446         return stringAt(ref.index, outLen);
    447     }
    448     const char16_t* stringAt(size_t idx, size_t* outLen) const;
    449 
    450     const char* string8At(size_t idx, size_t* outLen) const;
    451 
    452     const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
    453     const ResStringPool_span* styleAt(size_t idx) const;
    454 
    455     ssize_t indexOfString(const char16_t* str, size_t strLen) const;
    456 
    457     size_t size() const;
    458 
    459 #ifndef HAVE_ANDROID_OS
    460     bool isUTF8() const;
    461 #endif
    462 
    463 private:
    464     status_t                    mError;
    465     void*                       mOwnedData;
    466     const ResStringPool_header* mHeader;
    467     size_t                      mSize;
    468     mutable Mutex               mDecodeLock;
    469     const uint32_t*             mEntries;
    470     const uint32_t*             mEntryStyles;
    471     const void*                 mStrings;
    472     char16_t**                  mCache;
    473     uint32_t                    mStringPoolSize;    // number of uint16_t
    474     const uint32_t*             mStyles;
    475     uint32_t                    mStylePoolSize;    // number of uint32_t
    476 };
    477 
    478 /** ********************************************************************
    479  *  XML Tree
    480  *
    481  *  Binary representation of an XML document.  This is designed to
    482  *  express everything in an XML document, in a form that is much
    483  *  easier to parse on the device.
    484  *
    485  *********************************************************************** */
    486 
    487 /**
    488  * XML tree header.  This appears at the front of an XML tree,
    489  * describing its content.  It is followed by a flat array of
    490  * ResXMLTree_node structures; the hierarchy of the XML document
    491  * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
    492  * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
    493  */
    494 struct ResXMLTree_header
    495 {
    496     struct ResChunk_header header;
    497 };
    498 
    499 /**
    500  * Basic XML tree node.  A single item in the XML document.  Extended info
    501  * about the node can be found after header.headerSize.
    502  */
    503 struct ResXMLTree_node
    504 {
    505     struct ResChunk_header header;
    506 
    507     // Line number in original source file at which this element appeared.
    508     uint32_t lineNumber;
    509 
    510     // Optional XML comment that was associated with this element; -1 if none.
    511     struct ResStringPool_ref comment;
    512 };
    513 
    514 /**
    515  * Extended XML tree node for CDATA tags -- includes the CDATA string.
    516  * Appears header.headerSize bytes after a ResXMLTree_node.
    517  */
    518 struct ResXMLTree_cdataExt
    519 {
    520     // The raw CDATA character data.
    521     struct ResStringPool_ref data;
    522 
    523     // The typed value of the character data if this is a CDATA node.
    524     struct Res_value typedData;
    525 };
    526 
    527 /**
    528  * Extended XML tree node for namespace start/end nodes.
    529  * Appears header.headerSize bytes after a ResXMLTree_node.
    530  */
    531 struct ResXMLTree_namespaceExt
    532 {
    533     // The prefix of the namespace.
    534     struct ResStringPool_ref prefix;
    535 
    536     // The URI of the namespace.
    537     struct ResStringPool_ref uri;
    538 };
    539 
    540 /**
    541  * Extended XML tree node for element start/end nodes.
    542  * Appears header.headerSize bytes after a ResXMLTree_node.
    543  */
    544 struct ResXMLTree_endElementExt
    545 {
    546     // String of the full namespace of this element.
    547     struct ResStringPool_ref ns;
    548 
    549     // String name of this node if it is an ELEMENT; the raw
    550     // character data if this is a CDATA node.
    551     struct ResStringPool_ref name;
    552 };
    553 
    554 /**
    555  * Extended XML tree node for start tags -- includes attribute
    556  * information.
    557  * Appears header.headerSize bytes after a ResXMLTree_node.
    558  */
    559 struct ResXMLTree_attrExt
    560 {
    561     // String of the full namespace of this element.
    562     struct ResStringPool_ref ns;
    563 
    564     // String name of this node if it is an ELEMENT; the raw
    565     // character data if this is a CDATA node.
    566     struct ResStringPool_ref name;
    567 
    568     // Byte offset from the start of this structure where the attributes start.
    569     uint16_t attributeStart;
    570 
    571     // Size of the ResXMLTree_attribute structures that follow.
    572     uint16_t attributeSize;
    573 
    574     // Number of attributes associated with an ELEMENT.  These are
    575     // available as an array of ResXMLTree_attribute structures
    576     // immediately following this node.
    577     uint16_t attributeCount;
    578 
    579     // Index (1-based) of the "id" attribute. 0 if none.
    580     uint16_t idIndex;
    581 
    582     // Index (1-based) of the "class" attribute. 0 if none.
    583     uint16_t classIndex;
    584 
    585     // Index (1-based) of the "style" attribute. 0 if none.
    586     uint16_t styleIndex;
    587 };
    588 
    589 struct ResXMLTree_attribute
    590 {
    591     // Namespace of this attribute.
    592     struct ResStringPool_ref ns;
    593 
    594     // Name of this attribute.
    595     struct ResStringPool_ref name;
    596 
    597     // The original raw string value of this attribute.
    598     struct ResStringPool_ref rawValue;
    599 
    600     // Processesd typed value of this attribute.
    601     struct Res_value typedValue;
    602 };
    603 
    604 class ResXMLTree;
    605 
    606 class ResXMLParser
    607 {
    608 public:
    609     ResXMLParser(const ResXMLTree& tree);
    610 
    611     enum event_code_t {
    612         BAD_DOCUMENT = -1,
    613         START_DOCUMENT = 0,
    614         END_DOCUMENT = 1,
    615 
    616         FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE,
    617 
    618         START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
    619         END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
    620         START_TAG = RES_XML_START_ELEMENT_TYPE,
    621         END_TAG = RES_XML_END_ELEMENT_TYPE,
    622         TEXT = RES_XML_CDATA_TYPE
    623     };
    624 
    625     struct ResXMLPosition
    626     {
    627         event_code_t                eventCode;
    628         const ResXMLTree_node*      curNode;
    629         const void*                 curExt;
    630     };
    631 
    632     void restart();
    633 
    634     const ResStringPool& getStrings() const;
    635 
    636     event_code_t getEventType() const;
    637     // Note, unlike XmlPullParser, the first call to next() will return
    638     // START_TAG of the first element.
    639     event_code_t next();
    640 
    641     // These are available for all nodes:
    642     int32_t getCommentID() const;
    643     const uint16_t* getComment(size_t* outLen) const;
    644     uint32_t getLineNumber() const;
    645 
    646     // This is available for TEXT:
    647     int32_t getTextID() const;
    648     const uint16_t* getText(size_t* outLen) const;
    649     ssize_t getTextValue(Res_value* outValue) const;
    650 
    651     // These are available for START_NAMESPACE and END_NAMESPACE:
    652     int32_t getNamespacePrefixID() const;
    653     const uint16_t* getNamespacePrefix(size_t* outLen) const;
    654     int32_t getNamespaceUriID() const;
    655     const uint16_t* getNamespaceUri(size_t* outLen) const;
    656 
    657     // These are available for START_TAG and END_TAG:
    658     int32_t getElementNamespaceID() const;
    659     const uint16_t* getElementNamespace(size_t* outLen) const;
    660     int32_t getElementNameID() const;
    661     const uint16_t* getElementName(size_t* outLen) const;
    662 
    663     // Remaining methods are for retrieving information about attributes
    664     // associated with a START_TAG:
    665 
    666     size_t getAttributeCount() const;
    667 
    668     // Returns -1 if no namespace, -2 if idx out of range.
    669     int32_t getAttributeNamespaceID(size_t idx) const;
    670     const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
    671 
    672     int32_t getAttributeNameID(size_t idx) const;
    673     const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
    674     uint32_t getAttributeNameResID(size_t idx) const;
    675 
    676     int32_t getAttributeValueStringID(size_t idx) const;
    677     const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
    678 
    679     int32_t getAttributeDataType(size_t idx) const;
    680     int32_t getAttributeData(size_t idx) const;
    681     ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
    682 
    683     ssize_t indexOfAttribute(const char* ns, const char* attr) const;
    684     ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
    685                              const char16_t* attr, size_t attrLen) const;
    686 
    687     ssize_t indexOfID() const;
    688     ssize_t indexOfClass() const;
    689     ssize_t indexOfStyle() const;
    690 
    691     void getPosition(ResXMLPosition* pos) const;
    692     void setPosition(const ResXMLPosition& pos);
    693 
    694 private:
    695     friend class ResXMLTree;
    696 
    697     event_code_t nextNode();
    698 
    699     const ResXMLTree&           mTree;
    700     event_code_t                mEventCode;
    701     const ResXMLTree_node*      mCurNode;
    702     const void*                 mCurExt;
    703 };
    704 
    705 /**
    706  * Convenience class for accessing data in a ResXMLTree resource.
    707  */
    708 class ResXMLTree : public ResXMLParser
    709 {
    710 public:
    711     ResXMLTree();
    712     ResXMLTree(const void* data, size_t size, bool copyData=false);
    713     ~ResXMLTree();
    714 
    715     status_t setTo(const void* data, size_t size, bool copyData=false);
    716 
    717     status_t getError() const;
    718 
    719     void uninit();
    720 
    721 private:
    722     friend class ResXMLParser;
    723 
    724     status_t validateNode(const ResXMLTree_node* node) const;
    725 
    726     status_t                    mError;
    727     void*                       mOwnedData;
    728     const ResXMLTree_header*    mHeader;
    729     size_t                      mSize;
    730     const uint8_t*              mDataEnd;
    731     ResStringPool               mStrings;
    732     const uint32_t*             mResIds;
    733     size_t                      mNumResIds;
    734     const ResXMLTree_node*      mRootNode;
    735     const void*                 mRootExt;
    736     event_code_t                mRootCode;
    737 };
    738 
    739 /** ********************************************************************
    740  *  RESOURCE TABLE
    741  *
    742  *********************************************************************** */
    743 
    744 /**
    745  * Header for a resource table.  Its data contains a series of
    746  * additional chunks:
    747  *   * A ResStringPool_header containing all table values.
    748  *   * One or more ResTable_package chunks.
    749  *
    750  * Specific entries within a resource table can be uniquely identified
    751  * with a single integer as defined by the ResTable_ref structure.
    752  */
    753 struct ResTable_header
    754 {
    755     struct ResChunk_header header;
    756 
    757     // The number of ResTable_package structures.
    758     uint32_t packageCount;
    759 };
    760 
    761 /**
    762  * A collection of resource data types within a package.  Followed by
    763  * one or more ResTable_type and ResTable_typeSpec structures containing the
    764  * entry values for each resource type.
    765  */
    766 struct ResTable_package
    767 {
    768     struct ResChunk_header header;
    769 
    770     // If this is a base package, its ID.  Package IDs start
    771     // at 1 (corresponding to the value of the package bits in a
    772     // resource identifier).  0 means this is not a base package.
    773     uint32_t id;
    774 
    775     // Actual name of this package, \0-terminated.
    776     char16_t name[128];
    777 
    778     // Offset to a ResStringPool_header defining the resource
    779     // type symbol table.  If zero, this package is inheriting from
    780     // another base package (overriding specific values in it).
    781     uint32_t typeStrings;
    782 
    783     // Last index into typeStrings that is for public use by others.
    784     uint32_t lastPublicType;
    785 
    786     // Offset to a ResStringPool_header defining the resource
    787     // key symbol table.  If zero, this package is inheriting from
    788     // another base package (overriding specific values in it).
    789     uint32_t keyStrings;
    790 
    791     // Last index into keyStrings that is for public use by others.
    792     uint32_t lastPublicKey;
    793 };
    794 
    795 /**
    796  * Describes a particular resource configuration.
    797  */
    798 struct ResTable_config
    799 {
    800     // Number of bytes in this structure.
    801     uint32_t size;
    802 
    803     union {
    804         struct {
    805             // Mobile country code (from SIM).  0 means "any".
    806             uint16_t mcc;
    807             // Mobile network code (from SIM).  0 means "any".
    808             uint16_t mnc;
    809         };
    810         uint32_t imsi;
    811     };
    812 
    813     union {
    814         struct {
    815             // \0\0 means "any".  Otherwise, en, fr, etc.
    816             char language[2];
    817 
    818             // \0\0 means "any".  Otherwise, US, CA, etc.
    819             char country[2];
    820         };
    821         uint32_t locale;
    822     };
    823 
    824     enum {
    825         ORIENTATION_ANY  = 0x0000,
    826         ORIENTATION_PORT = 0x0001,
    827         ORIENTATION_LAND = 0x0002,
    828         ORIENTATION_SQUARE = 0x0003,
    829     };
    830 
    831     enum {
    832         TOUCHSCREEN_ANY  = 0x0000,
    833         TOUCHSCREEN_NOTOUCH  = 0x0001,
    834         TOUCHSCREEN_STYLUS  = 0x0002,
    835         TOUCHSCREEN_FINGER  = 0x0003,
    836     };
    837 
    838     enum {
    839         DENSITY_DEFAULT = 0,
    840         DENSITY_LOW = 120,
    841         DENSITY_MEDIUM = 160,
    842         DENSITY_HIGH = 240,
    843         DENSITY_NONE = 0xffff
    844     };
    845 
    846     union {
    847         struct {
    848             uint8_t orientation;
    849             uint8_t touchscreen;
    850             uint16_t density;
    851         };
    852         uint32_t screenType;
    853     };
    854 
    855     enum {
    856         KEYBOARD_ANY  = 0x0000,
    857         KEYBOARD_NOKEYS  = 0x0001,
    858         KEYBOARD_QWERTY  = 0x0002,
    859         KEYBOARD_12KEY  = 0x0003,
    860     };
    861 
    862     enum {
    863         NAVIGATION_ANY  = 0x0000,
    864         NAVIGATION_NONAV  = 0x0001,
    865         NAVIGATION_DPAD  = 0x0002,
    866         NAVIGATION_TRACKBALL  = 0x0003,
    867         NAVIGATION_WHEEL  = 0x0004,
    868     };
    869 
    870     enum {
    871         MASK_KEYSHIDDEN = 0x0003,
    872         KEYSHIDDEN_ANY = 0x0000,
    873         KEYSHIDDEN_NO = 0x0001,
    874         KEYSHIDDEN_YES = 0x0002,
    875         KEYSHIDDEN_SOFT = 0x0003,
    876     };
    877 
    878     enum {
    879         MASK_NAVHIDDEN = 0x000c,
    880         NAVHIDDEN_ANY = 0x0000,
    881         NAVHIDDEN_NO = 0x0004,
    882         NAVHIDDEN_YES = 0x0008,
    883     };
    884 
    885     union {
    886         struct {
    887             uint8_t keyboard;
    888             uint8_t navigation;
    889             uint8_t inputFlags;
    890             uint8_t inputPad0;
    891         };
    892         uint32_t input;
    893     };
    894 
    895     enum {
    896         SCREENWIDTH_ANY = 0
    897     };
    898 
    899     enum {
    900         SCREENHEIGHT_ANY = 0
    901     };
    902 
    903     union {
    904         struct {
    905             uint16_t screenWidth;
    906             uint16_t screenHeight;
    907         };
    908         uint32_t screenSize;
    909     };
    910 
    911     enum {
    912         SDKVERSION_ANY = 0
    913     };
    914 
    915     enum {
    916         MINORVERSION_ANY = 0
    917     };
    918 
    919     union {
    920         struct {
    921             uint16_t sdkVersion;
    922             // For now minorVersion must always be 0!!!  Its meaning
    923             // is currently undefined.
    924             uint16_t minorVersion;
    925         };
    926         uint32_t version;
    927     };
    928 
    929     enum {
    930         // screenLayout bits for screen size class.
    931         MASK_SCREENSIZE = 0x0f,
    932         SCREENSIZE_ANY  = 0x00,
    933         SCREENSIZE_SMALL = 0x01,
    934         SCREENSIZE_NORMAL = 0x02,
    935         SCREENSIZE_LARGE = 0x03,
    936 
    937         // screenLayout bits for wide/long screen variation.
    938         MASK_SCREENLONG = 0x30,
    939         SCREENLONG_ANY = 0x00,
    940         SCREENLONG_NO = 0x10,
    941         SCREENLONG_YES = 0x20,
    942     };
    943 
    944     enum {
    945         // uiMode bits for the mode type.
    946         MASK_UI_MODE_TYPE = 0x0f,
    947         UI_MODE_TYPE_ANY = 0x00,
    948         UI_MODE_TYPE_NORMAL = 0x01,
    949         UI_MODE_TYPE_DESK = 0x02,
    950         UI_MODE_TYPE_CAR = 0x03,
    951 
    952         // uiMode bits for the night switch.
    953         MASK_UI_MODE_NIGHT = 0x30,
    954         UI_MODE_NIGHT_ANY = 0x00,
    955         UI_MODE_NIGHT_NO = 0x10,
    956         UI_MODE_NIGHT_YES = 0x20,
    957     };
    958 
    959     union {
    960         struct {
    961             uint8_t screenLayout;
    962             uint8_t uiMode;
    963             uint8_t screenConfigPad1;
    964             uint8_t screenConfigPad2;
    965         };
    966         uint32_t screenConfig;
    967     };
    968 
    969     inline void copyFromDeviceNoSwap(const ResTable_config& o) {
    970         const size_t size = dtohl(o.size);
    971         if (size >= sizeof(ResTable_config)) {
    972             *this = o;
    973         } else {
    974             memcpy(this, &o, size);
    975             memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
    976         }
    977     }
    978 
    979     inline void copyFromDtoH(const ResTable_config& o) {
    980         copyFromDeviceNoSwap(o);
    981         size = sizeof(ResTable_config);
    982         mcc = dtohs(mcc);
    983         mnc = dtohs(mnc);
    984         density = dtohs(density);
    985         screenWidth = dtohs(screenWidth);
    986         screenHeight = dtohs(screenHeight);
    987         sdkVersion = dtohs(sdkVersion);
    988         minorVersion = dtohs(minorVersion);
    989     }
    990 
    991     inline void swapHtoD() {
    992         size = htodl(size);
    993         mcc = htods(mcc);
    994         mnc = htods(mnc);
    995         density = htods(density);
    996         screenWidth = htods(screenWidth);
    997         screenHeight = htods(screenHeight);
    998         sdkVersion = htods(sdkVersion);
    999         minorVersion = htods(minorVersion);
   1000     }
   1001 
   1002     inline int compare(const ResTable_config& o) const {
   1003         int32_t diff = (int32_t)(imsi - o.imsi);
   1004         if (diff != 0) return diff;
   1005         diff = (int32_t)(locale - o.locale);
   1006         if (diff != 0) return diff;
   1007         diff = (int32_t)(screenType - o.screenType);
   1008         if (diff != 0) return diff;
   1009         diff = (int32_t)(input - o.input);
   1010         if (diff != 0) return diff;
   1011         diff = (int32_t)(screenSize - o.screenSize);
   1012         if (diff != 0) return diff;
   1013         diff = (int32_t)(version - o.version);
   1014         if (diff != 0) return diff;
   1015         diff = (int32_t)(screenLayout - o.screenLayout);
   1016         if (diff != 0) return diff;
   1017         diff = (int32_t)(uiMode - o.uiMode);
   1018         return (int)diff;
   1019     }
   1020 
   1021     // Flags indicating a set of config values.  These flag constants must
   1022     // match the corresponding ones in android.content.pm.ActivityInfo and
   1023     // attrs_manifest.xml.
   1024     enum {
   1025         CONFIG_MCC = 0x0001,
   1026         CONFIG_MNC = 0x0002,
   1027         CONFIG_LOCALE = 0x0004,
   1028         CONFIG_TOUCHSCREEN = 0x0008,
   1029         CONFIG_KEYBOARD = 0x0010,
   1030         CONFIG_KEYBOARD_HIDDEN = 0x0020,
   1031         CONFIG_NAVIGATION = 0x0040,
   1032         CONFIG_ORIENTATION = 0x0080,
   1033         CONFIG_DENSITY = 0x0100,
   1034         CONFIG_SCREEN_SIZE = 0x0200,
   1035         CONFIG_VERSION = 0x0400,
   1036         CONFIG_SCREEN_LAYOUT = 0x0800,
   1037         CONFIG_UI_MODE = 0x1000
   1038     };
   1039 
   1040     // Compare two configuration, returning CONFIG_* flags set for each value
   1041     // that is different.
   1042     inline int diff(const ResTable_config& o) const {
   1043         int diffs = 0;
   1044         if (mcc != o.mcc) diffs |= CONFIG_MCC;
   1045         if (mnc != o.mnc) diffs |= CONFIG_MNC;
   1046         if (locale != o.locale) diffs |= CONFIG_LOCALE;
   1047         if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
   1048         if (density != o.density) diffs |= CONFIG_DENSITY;
   1049         if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
   1050         if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
   1051                 diffs |= CONFIG_KEYBOARD_HIDDEN;
   1052         if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
   1053         if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
   1054         if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
   1055         if (version != o.version) diffs |= CONFIG_VERSION;
   1056         if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
   1057         if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
   1058         return diffs;
   1059     }
   1060 
   1061     // Return true if 'this' is more specific than 'o'.
   1062     inline bool
   1063     isMoreSpecificThan(const ResTable_config& o) const {
   1064         // The order of the following tests defines the importance of one
   1065         // configuration parameter over another.  Those tests first are more
   1066         // important, trumping any values in those following them.
   1067         if (imsi || o.imsi) {
   1068             if (mcc != o.mcc) {
   1069                 if (!mcc) return false;
   1070                 if (!o.mcc) return true;
   1071             }
   1072 
   1073             if (mnc != o.mnc) {
   1074                 if (!mnc) return false;
   1075                 if (!o.mnc) return true;
   1076             }
   1077         }
   1078 
   1079         if (locale || o.locale) {
   1080             if (language[0] != o.language[0]) {
   1081                 if (!language[0]) return false;
   1082                 if (!o.language[0]) return true;
   1083             }
   1084 
   1085             if (country[0] != o.country[0]) {
   1086                 if (!country[0]) return false;
   1087                 if (!o.country[0]) return true;
   1088             }
   1089         }
   1090 
   1091         if (screenLayout || o.screenLayout) {
   1092             if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
   1093                 if (!(screenLayout & MASK_SCREENSIZE)) return false;
   1094                 if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
   1095             }
   1096             if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
   1097                 if (!(screenLayout & MASK_SCREENLONG)) return false;
   1098                 if (!(o.screenLayout & MASK_SCREENLONG)) return true;
   1099             }
   1100         }
   1101 
   1102         if (orientation != o.orientation) {
   1103             if (!orientation) return false;
   1104             if (!o.orientation) return true;
   1105         }
   1106 
   1107         if (uiMode || o.uiMode) {
   1108             if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
   1109                 if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
   1110                 if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
   1111             }
   1112             if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
   1113                 if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
   1114                 if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
   1115             }
   1116         }
   1117 
   1118         // density is never 'more specific'
   1119         // as the default just equals 160
   1120 
   1121         if (touchscreen != o.touchscreen) {
   1122             if (!touchscreen) return false;
   1123             if (!o.touchscreen) return true;
   1124         }
   1125 
   1126         if (input || o.input) {
   1127             if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
   1128                 if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
   1129                 if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
   1130             }
   1131 
   1132             if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
   1133                 if (!(inputFlags & MASK_NAVHIDDEN)) return false;
   1134                 if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
   1135             }
   1136 
   1137             if (keyboard != o.keyboard) {
   1138                 if (!keyboard) return false;
   1139                 if (!o.keyboard) return true;
   1140             }
   1141 
   1142             if (navigation != o.navigation) {
   1143                 if (!navigation) return false;
   1144                 if (!o.navigation) return true;
   1145             }
   1146         }
   1147 
   1148         if (screenSize || o.screenSize) {
   1149             if (screenWidth != o.screenWidth) {
   1150                 if (!screenWidth) return false;
   1151                 if (!o.screenWidth) return true;
   1152             }
   1153 
   1154             if (screenHeight != o.screenHeight) {
   1155                 if (!screenHeight) return false;
   1156                 if (!o.screenHeight) return true;
   1157             }
   1158         }
   1159 
   1160         if (version || o.version) {
   1161             if (sdkVersion != o.sdkVersion) {
   1162                 if (!sdkVersion) return false;
   1163                 if (!o.sdkVersion) return true;
   1164             }
   1165 
   1166             if (minorVersion != o.minorVersion) {
   1167                 if (!minorVersion) return false;
   1168                 if (!o.minorVersion) return true;
   1169             }
   1170         }
   1171         return false;
   1172     }
   1173 
   1174     // Return true if 'this' is a better match than 'o' for the 'requested'
   1175     // configuration.  This assumes that match() has already been used to
   1176     // remove any configurations that don't match the requested configuration
   1177     // at all; if they are not first filtered, non-matching results can be
   1178     // considered better than matching ones.
   1179     // The general rule per attribute: if the request cares about an attribute
   1180     // (it normally does), if the two (this and o) are equal it's a tie.  If
   1181     // they are not equal then one must be generic because only generic and
   1182     // '==requested' will pass the match() call.  So if this is not generic,
   1183     // it wins.  If this IS generic, o wins (return false).
   1184     inline bool
   1185     isBetterThan(const ResTable_config& o,
   1186             const ResTable_config* requested) const {
   1187         if (requested) {
   1188             if (imsi || o.imsi) {
   1189                 if ((mcc != o.mcc) && requested->mcc) {
   1190                     return (mcc);
   1191                 }
   1192 
   1193                 if ((mnc != o.mnc) && requested->mnc) {
   1194                     return (mnc);
   1195                 }
   1196             }
   1197 
   1198             if (locale || o.locale) {
   1199                 if ((language[0] != o.language[0]) && requested->language[0]) {
   1200                     return (language[0]);
   1201                 }
   1202 
   1203                 if ((country[0] != o.country[0]) && requested->country[0]) {
   1204                     return (country[0]);
   1205                 }
   1206             }
   1207 
   1208             if (screenLayout || o.screenLayout) {
   1209                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
   1210                         && (requested->screenLayout & MASK_SCREENSIZE)) {
   1211                     return (screenLayout & MASK_SCREENSIZE);
   1212                 }
   1213                 if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
   1214                         && (requested->screenLayout & MASK_SCREENLONG)) {
   1215                     return (screenLayout & MASK_SCREENLONG);
   1216                 }
   1217             }
   1218 
   1219             if ((orientation != o.orientation) && requested->orientation) {
   1220                 return (orientation);
   1221             }
   1222 
   1223             if (uiMode || o.uiMode) {
   1224                 if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
   1225                         && (requested->uiMode & MASK_UI_MODE_TYPE)) {
   1226                     return (uiMode & MASK_UI_MODE_TYPE);
   1227                 }
   1228                 if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
   1229                         && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
   1230                     return (uiMode & MASK_UI_MODE_NIGHT);
   1231                 }
   1232             }
   1233 
   1234             if (screenType || o.screenType) {
   1235                 if (density != o.density) {
   1236                     // density is tough.  Any density is potentially useful
   1237                     // because the system will scale it.  Scaling down
   1238                     // is generally better than scaling up.
   1239                     // Default density counts as 160dpi (the system default)
   1240                     // TODO - remove 160 constants
   1241                     int h = (density?density:160);
   1242                     int l = (o.density?o.density:160);
   1243                     bool bImBigger = true;
   1244                     if (l > h) {
   1245                         int t = h;
   1246                         h = l;
   1247                         l = t;
   1248                         bImBigger = false;
   1249                     }
   1250 
   1251                     int reqValue = (requested->density?requested->density:160);
   1252                     if (reqValue >= h) {
   1253                         // requested value higher than both l and h, give h
   1254                         return bImBigger;
   1255                     }
   1256                     if (l >= reqValue) {
   1257                         // requested value lower than both l and h, give l
   1258                         return !bImBigger;
   1259                     }
   1260                     // saying that scaling down is 2x better than up
   1261                     if (((2 * l) - reqValue) * h > reqValue * reqValue) {
   1262                         return !bImBigger;
   1263                     } else {
   1264                         return bImBigger;
   1265                     }
   1266                 }
   1267 
   1268                 if ((touchscreen != o.touchscreen) && requested->touchscreen) {
   1269                     return (touchscreen);
   1270                 }
   1271             }
   1272 
   1273             if (input || o.input) {
   1274                 const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
   1275                 const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
   1276                 if (keysHidden != oKeysHidden) {
   1277                     const int reqKeysHidden =
   1278                             requested->inputFlags & MASK_KEYSHIDDEN;
   1279                     if (reqKeysHidden) {
   1280 
   1281                         if (!keysHidden) return false;
   1282                         if (!oKeysHidden) return true;
   1283                         // For compatibility, we count KEYSHIDDEN_NO as being
   1284                         // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
   1285                         // these by making an exact match more specific.
   1286                         if (reqKeysHidden == keysHidden) return true;
   1287                         if (reqKeysHidden == oKeysHidden) return false;
   1288                     }
   1289                 }
   1290 
   1291                 const int navHidden = inputFlags & MASK_NAVHIDDEN;
   1292                 const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
   1293                 if (navHidden != oNavHidden) {
   1294                     const int reqNavHidden =
   1295                             requested->inputFlags & MASK_NAVHIDDEN;
   1296                     if (reqNavHidden) {
   1297 
   1298                         if (!navHidden) return false;
   1299                         if (!oNavHidden) return true;
   1300                     }
   1301                 }
   1302 
   1303                 if ((keyboard != o.keyboard) && requested->keyboard) {
   1304                     return (keyboard);
   1305                 }
   1306 
   1307                 if ((navigation != o.navigation) && requested->navigation) {
   1308                     return (navigation);
   1309                 }
   1310             }
   1311 
   1312             if (screenSize || o.screenSize) {
   1313                 if ((screenWidth != o.screenWidth) && requested->screenWidth) {
   1314                     return (screenWidth);
   1315                 }
   1316 
   1317                 if ((screenHeight != o.screenHeight) &&
   1318                         requested->screenHeight) {
   1319                     return (screenHeight);
   1320                 }
   1321             }
   1322 
   1323             if (version || o.version) {
   1324                 if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
   1325                     return (sdkVersion > o.sdkVersion);
   1326                 }
   1327 
   1328                 if ((minorVersion != o.minorVersion) &&
   1329                         requested->minorVersion) {
   1330                     return (minorVersion);
   1331                 }
   1332             }
   1333 
   1334             return false;
   1335         }
   1336         return isMoreSpecificThan(o);
   1337     }
   1338 
   1339     // Return true if 'this' can be considered a match for the parameters in
   1340     // 'settings'.
   1341     // Note this is asymetric.  A default piece of data will match every request
   1342     // but a request for the default should not match odd specifics
   1343     // (ie, request with no mcc should not match a particular mcc's data)
   1344     // settings is the requested settings
   1345     inline bool match(const ResTable_config& settings) const {
   1346         if (imsi != 0) {
   1347             if ((settings.mcc != 0 && mcc != 0
   1348                  && mcc != settings.mcc) ||
   1349                 (settings.mcc == 0 && mcc != 0)) {
   1350                 return false;
   1351             }
   1352             if ((settings.mnc != 0 && mnc != 0
   1353                  && mnc != settings.mnc) ||
   1354                 (settings.mnc == 0 && mnc != 0)) {
   1355                 return false;
   1356             }
   1357         }
   1358         if (locale != 0) {
   1359             if (settings.language[0] != 0 && language[0] != 0
   1360                 && (language[0] != settings.language[0]
   1361                     || language[1] != settings.language[1])) {
   1362                 return false;
   1363             }
   1364             if (settings.country[0] != 0 && country[0] != 0
   1365                 && (country[0] != settings.country[0]
   1366                     || country[1] != settings.country[1])) {
   1367                 return false;
   1368             }
   1369         }
   1370         if (screenConfig != 0) {
   1371             const int screenSize = screenLayout&MASK_SCREENSIZE;
   1372             const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
   1373             if (setScreenSize != 0 && screenSize != 0
   1374                     && screenSize != setScreenSize) {
   1375                 return false;
   1376             }
   1377 
   1378             const int screenLong = screenLayout&MASK_SCREENLONG;
   1379             const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
   1380             if (setScreenLong != 0 && screenLong != 0
   1381                     && screenLong != setScreenLong) {
   1382                 return false;
   1383             }
   1384 
   1385             const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
   1386             const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
   1387             if (setUiModeType != 0 && uiModeType != 0
   1388                     && uiModeType != setUiModeType) {
   1389                 return false;
   1390             }
   1391 
   1392             const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
   1393             const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
   1394             if (setUiModeNight != 0 && uiModeNight != 0
   1395                     && uiModeNight != setUiModeNight) {
   1396                 return false;
   1397             }
   1398         }
   1399         if (screenType != 0) {
   1400             if (settings.orientation != 0 && orientation != 0
   1401                 && orientation != settings.orientation) {
   1402                 return false;
   1403             }
   1404             // density always matches - we can scale it.  See isBetterThan
   1405             if (settings.touchscreen != 0 && touchscreen != 0
   1406                 && touchscreen != settings.touchscreen) {
   1407                 return false;
   1408             }
   1409         }
   1410         if (input != 0) {
   1411             const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
   1412             const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
   1413             if (setKeysHidden != 0 && keysHidden != 0
   1414                 && keysHidden != setKeysHidden) {
   1415                 // For compatibility, we count a request for KEYSHIDDEN_NO as also
   1416                 // matching the more recent KEYSHIDDEN_SOFT.  Basically
   1417                 // KEYSHIDDEN_NO means there is some kind of keyboard available.
   1418                 //LOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
   1419                 if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
   1420                     //LOGI("No match!");
   1421                     return false;
   1422                 }
   1423             }
   1424             const int navHidden = inputFlags&MASK_NAVHIDDEN;
   1425             const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
   1426             if (setNavHidden != 0 && navHidden != 0
   1427                 && navHidden != setNavHidden) {
   1428                 return false;
   1429             }
   1430             if (settings.keyboard != 0 && keyboard != 0
   1431                 && keyboard != settings.keyboard) {
   1432                 return false;
   1433             }
   1434             if (settings.navigation != 0 && navigation != 0
   1435                 && navigation != settings.navigation) {
   1436                 return false;
   1437             }
   1438         }
   1439         if (screenSize != 0) {
   1440             if (settings.screenWidth != 0 && screenWidth != 0
   1441                 && screenWidth != settings.screenWidth) {
   1442                 return false;
   1443             }
   1444             if (settings.screenHeight != 0 && screenHeight != 0
   1445                 && screenHeight != settings.screenHeight) {
   1446                 return false;
   1447             }
   1448         }
   1449         if (version != 0) {
   1450             if (settings.sdkVersion != 0 && sdkVersion != 0
   1451                 && sdkVersion > settings.sdkVersion) {
   1452                 return false;
   1453             }
   1454             if (settings.minorVersion != 0 && minorVersion != 0
   1455                 && minorVersion != settings.minorVersion) {
   1456                 return false;
   1457             }
   1458         }
   1459         return true;
   1460     }
   1461 
   1462     void getLocale(char str[6]) const {
   1463         memset(str, 0, 6);
   1464         if (language[0]) {
   1465             str[0] = language[0];
   1466             str[1] = language[1];
   1467             if (country[0]) {
   1468                 str[2] = '_';
   1469                 str[3] = country[0];
   1470                 str[4] = country[1];
   1471             }
   1472         }
   1473     }
   1474 
   1475     String8 toString() const {
   1476         char buf[200];
   1477         sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
   1478                 "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d sz=%d long=%d "
   1479                 "ui=%d night=%d vers=%d.%d",
   1480                 mcc, mnc,
   1481                 language[0] ? language[0] : '-', language[1] ? language[1] : '-',
   1482                 country[0] ? country[0] : '-', country[1] ? country[1] : '-',
   1483                 orientation, touchscreen, density, keyboard, navigation, inputFlags,
   1484                 screenWidth, screenHeight,
   1485                 screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
   1486                 uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
   1487                 sdkVersion, minorVersion);
   1488         return String8(buf);
   1489     }
   1490 };
   1491 
   1492 /**
   1493  * A specification of the resources defined by a particular type.
   1494  *
   1495  * There should be one of these chunks for each resource type.
   1496  *
   1497  * This structure is followed by an array of integers providing the set of
   1498  * configuation change flags (ResTable_config::CONFIG_*) that have multiple
   1499  * resources for that configuration.  In addition, the high bit is set if that
   1500  * resource has been made public.
   1501  */
   1502 struct ResTable_typeSpec
   1503 {
   1504     struct ResChunk_header header;
   1505 
   1506     // The type identifier this chunk is holding.  Type IDs start
   1507     // at 1 (corresponding to the value of the type bits in a
   1508     // resource identifier).  0 is invalid.
   1509     uint8_t id;
   1510 
   1511     // Must be 0.
   1512     uint8_t res0;
   1513     // Must be 0.
   1514     uint16_t res1;
   1515 
   1516     // Number of uint32_t entry configuration masks that follow.
   1517     uint32_t entryCount;
   1518 
   1519     enum {
   1520         // Additional flag indicating an entry is public.
   1521         SPEC_PUBLIC = 0x40000000
   1522     };
   1523 };
   1524 
   1525 /**
   1526  * A collection of resource entries for a particular resource data
   1527  * type. Followed by an array of uint32_t defining the resource
   1528  * values, corresponding to the array of type strings in the
   1529  * ResTable_package::typeStrings string block. Each of these hold an
   1530  * index from entriesStart; a value of NO_ENTRY means that entry is
   1531  * not defined.
   1532  *
   1533  * There may be multiple of these chunks for a particular resource type,
   1534  * supply different configuration variations for the resource values of
   1535  * that type.
   1536  *
   1537  * It would be nice to have an additional ordered index of entries, so
   1538  * we can do a binary search if trying to find a resource by string name.
   1539  */
   1540 struct ResTable_type
   1541 {
   1542     struct ResChunk_header header;
   1543 
   1544     enum {
   1545         NO_ENTRY = 0xFFFFFFFF
   1546     };
   1547 
   1548     // The type identifier this chunk is holding.  Type IDs start
   1549     // at 1 (corresponding to the value of the type bits in a
   1550     // resource identifier).  0 is invalid.
   1551     uint8_t id;
   1552 
   1553     // Must be 0.
   1554     uint8_t res0;
   1555     // Must be 0.
   1556     uint16_t res1;
   1557 
   1558     // Number of uint32_t entry indices that follow.
   1559     uint32_t entryCount;
   1560 
   1561     // Offset from header where ResTable_entry data starts.
   1562     uint32_t entriesStart;
   1563 
   1564     // Configuration this collection of entries is designed for.
   1565     ResTable_config config;
   1566 };
   1567 
   1568 /**
   1569  * This is the beginning of information about an entry in the resource
   1570  * table.  It holds the reference to the name of this entry, and is
   1571  * immediately followed by one of:
   1572  *   * A Res_value structure, if FLAG_COMPLEX is -not- set.
   1573  *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.
   1574  *     These supply a set of name/value mappings of data.
   1575  */
   1576 struct ResTable_entry
   1577 {
   1578     // Number of bytes in this structure.
   1579     uint16_t size;
   1580 
   1581     enum {
   1582         // If set, this is a complex entry, holding a set of name/value
   1583         // mappings.  It is followed by an array of ResTable_map structures.
   1584         FLAG_COMPLEX = 0x0001,
   1585         // If set, this resource has been declared public, so libraries
   1586         // are allowed to reference it.
   1587         FLAG_PUBLIC = 0x0002
   1588     };
   1589     uint16_t flags;
   1590 
   1591     // Reference into ResTable_package::keyStrings identifying this entry.
   1592     struct ResStringPool_ref key;
   1593 };
   1594 
   1595 /**
   1596  * Extended form of a ResTable_entry for map entries, defining a parent map
   1597  * resource from which to inherit values.
   1598  */
   1599 struct ResTable_map_entry : public ResTable_entry
   1600 {
   1601     // Resource identifier of the parent mapping, or 0 if there is none.
   1602     ResTable_ref parent;
   1603     // Number of name/value pairs that follow for FLAG_COMPLEX.
   1604     uint32_t count;
   1605 };
   1606 
   1607 /**
   1608  * A single name/value mapping that is part of a complex resource
   1609  * entry.
   1610  */
   1611 struct ResTable_map
   1612 {
   1613     // The resource identifier defining this mapping's name.  For attribute
   1614     // resources, 'name' can be one of the following special resource types
   1615     // to supply meta-data about the attribute; for all other resource types
   1616     // it must be an attribute resource.
   1617     ResTable_ref name;
   1618 
   1619     // Special values for 'name' when defining attribute resources.
   1620     enum {
   1621         // This entry holds the attribute's type code.
   1622         ATTR_TYPE = Res_MAKEINTERNAL(0),
   1623 
   1624         // For integral attributes, this is the minimum value it can hold.
   1625         ATTR_MIN = Res_MAKEINTERNAL(1),
   1626 
   1627         // For integral attributes, this is the maximum value it can hold.
   1628         ATTR_MAX = Res_MAKEINTERNAL(2),
   1629 
   1630         // Localization of this resource is can be encouraged or required with
   1631         // an aapt flag if this is set
   1632         ATTR_L10N = Res_MAKEINTERNAL(3),
   1633 
   1634         // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
   1635         ATTR_OTHER = Res_MAKEINTERNAL(4),
   1636         ATTR_ZERO = Res_MAKEINTERNAL(5),
   1637         ATTR_ONE = Res_MAKEINTERNAL(6),
   1638         ATTR_TWO = Res_MAKEINTERNAL(7),
   1639         ATTR_FEW = Res_MAKEINTERNAL(8),
   1640         ATTR_MANY = Res_MAKEINTERNAL(9)
   1641 
   1642     };
   1643 
   1644     // Bit mask of allowed types, for use with ATTR_TYPE.
   1645     enum {
   1646         // No type has been defined for this attribute, use generic
   1647         // type handling.  The low 16 bits are for types that can be
   1648         // handled generically; the upper 16 require additional information
   1649         // in the bag so can not be handled generically for TYPE_ANY.
   1650         TYPE_ANY = 0x0000FFFF,
   1651 
   1652         // Attribute holds a references to another resource.
   1653         TYPE_REFERENCE = 1<<0,
   1654 
   1655         // Attribute holds a generic string.
   1656         TYPE_STRING = 1<<1,
   1657 
   1658         // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
   1659         // optionally specify a constrained range of possible integer values.
   1660         TYPE_INTEGER = 1<<2,
   1661 
   1662         // Attribute holds a boolean integer.
   1663         TYPE_BOOLEAN = 1<<3,
   1664 
   1665         // Attribute holds a color value.
   1666         TYPE_COLOR = 1<<4,
   1667 
   1668         // Attribute holds a floating point value.
   1669         TYPE_FLOAT = 1<<5,
   1670 
   1671         // Attribute holds a dimension value, such as "20px".
   1672         TYPE_DIMENSION = 1<<6,
   1673 
   1674         // Attribute holds a fraction value, such as "20%".
   1675         TYPE_FRACTION = 1<<7,
   1676 
   1677         // Attribute holds an enumeration.  The enumeration values are
   1678         // supplied as additional entries in the map.
   1679         TYPE_ENUM = 1<<16,
   1680 
   1681         // Attribute holds a bitmaks of flags.  The flag bit values are
   1682         // supplied as additional entries in the map.
   1683         TYPE_FLAGS = 1<<17
   1684     };
   1685 
   1686     // Enum of localization modes, for use with ATTR_L10N.
   1687     enum {
   1688         L10N_NOT_REQUIRED = 0,
   1689         L10N_SUGGESTED    = 1
   1690     };
   1691 
   1692     // This mapping's value.
   1693     Res_value value;
   1694 };
   1695 
   1696 /**
   1697  * Convenience class for accessing data in a ResTable resource.
   1698  */
   1699 class ResTable
   1700 {
   1701 public:
   1702     ResTable();
   1703     ResTable(const void* data, size_t size, void* cookie,
   1704              bool copyData=false);
   1705     ~ResTable();
   1706 
   1707     status_t add(const void* data, size_t size, void* cookie,
   1708                  bool copyData=false);
   1709     status_t add(Asset* asset, void* cookie,
   1710                  bool copyData=false);
   1711     status_t add(ResTable* src);
   1712 
   1713     status_t getError() const;
   1714 
   1715     void uninit();
   1716 
   1717     struct resource_name
   1718     {
   1719         const char16_t* package;
   1720         size_t packageLen;
   1721         const char16_t* type;
   1722         size_t typeLen;
   1723         const char16_t* name;
   1724         size_t nameLen;
   1725     };
   1726 
   1727     bool getResourceName(uint32_t resID, resource_name* outName) const;
   1728 
   1729     /**
   1730      * Retrieve the value of a resource.  If the resource is found, returns a
   1731      * value >= 0 indicating the table it is in (for use with
   1732      * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
   1733      * not found, returns a negative error code.
   1734      *
   1735      * Note that this function does not do reference traversal.  If you want
   1736      * to follow references to other resources to get the "real" value to
   1737      * use, you need to call resolveReference() after this function.
   1738      *
   1739      * @param resID The desired resoruce identifier.
   1740      * @param outValue Filled in with the resource data that was found.
   1741      *
   1742      * @return ssize_t Either a >= 0 table index or a negative error code.
   1743      */
   1744     ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
   1745             uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const;
   1746 
   1747     inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
   1748             uint32_t* outSpecFlags=NULL) const {
   1749         return getResource(res.ident, outValue, false, outSpecFlags, NULL);
   1750     }
   1751 
   1752     ssize_t resolveReference(Res_value* inOutValue,
   1753                              ssize_t blockIndex,
   1754                              uint32_t* outLastRef = NULL,
   1755                              uint32_t* inoutTypeSpecFlags = NULL,
   1756                              ResTable_config* outConfig = NULL) const;
   1757 
   1758     enum {
   1759         TMP_BUFFER_SIZE = 16
   1760     };
   1761     const char16_t* valueToString(const Res_value* value, size_t stringBlock,
   1762                                   char16_t tmpBuffer[TMP_BUFFER_SIZE],
   1763                                   size_t* outLen);
   1764 
   1765     struct bag_entry {
   1766         ssize_t stringBlock;
   1767         ResTable_map map;
   1768     };
   1769 
   1770     /**
   1771      * Retrieve the bag of a resource.  If the resoruce is found, returns the
   1772      * number of bags it contains and 'outBag' points to an array of their
   1773      * values.  If not found, a negative error code is returned.
   1774      *
   1775      * Note that this function -does- do reference traversal of the bag data.
   1776      *
   1777      * @param resID The desired resource identifier.
   1778      * @param outBag Filled inm with a pointer to the bag mappings.
   1779      *
   1780      * @return ssize_t Either a >= 0 bag count of negative error code.
   1781      */
   1782     ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
   1783 
   1784     void unlockBag(const bag_entry* bag) const;
   1785 
   1786     void lock() const;
   1787 
   1788     ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
   1789             uint32_t* outTypeSpecFlags=NULL) const;
   1790 
   1791     void unlock() const;
   1792 
   1793     class Theme {
   1794     public:
   1795         Theme(const ResTable& table);
   1796         ~Theme();
   1797 
   1798         inline const ResTable& getResTable() const { return mTable; }
   1799 
   1800         status_t applyStyle(uint32_t resID, bool force=false);
   1801         status_t setTo(const Theme& other);
   1802 
   1803         /**
   1804          * Retrieve a value in the theme.  If the theme defines this
   1805          * value, returns a value >= 0 indicating the table it is in
   1806          * (for use with getTableStringBlock() and getTableCookie) and
   1807          * fills in 'outValue'.  If not found, returns a negative error
   1808          * code.
   1809          *
   1810          * Note that this function does not do reference traversal.  If you want
   1811          * to follow references to other resources to get the "real" value to
   1812          * use, you need to call resolveReference() after this function.
   1813          *
   1814          * @param resID A resource identifier naming the desired theme
   1815          *              attribute.
   1816          * @param outValue Filled in with the theme value that was
   1817          *                 found.
   1818          *
   1819          * @return ssize_t Either a >= 0 table index or a negative error code.
   1820          */
   1821         ssize_t getAttribute(uint32_t resID, Res_value* outValue,
   1822                 uint32_t* outTypeSpecFlags = NULL) const;
   1823 
   1824         /**
   1825          * This is like ResTable::resolveReference(), but also takes
   1826          * care of resolving attribute references to the theme.
   1827          */
   1828         ssize_t resolveAttributeReference(Res_value* inOutValue,
   1829                 ssize_t blockIndex, uint32_t* outLastRef = NULL,
   1830                 uint32_t* inoutTypeSpecFlags = NULL,
   1831                 ResTable_config* inoutConfig = NULL) const;
   1832 
   1833         void dumpToLog() const;
   1834 
   1835     private:
   1836         Theme(const Theme&);
   1837         Theme& operator=(const Theme&);
   1838 
   1839         struct theme_entry {
   1840             ssize_t stringBlock;
   1841             uint32_t typeSpecFlags;
   1842             Res_value value;
   1843         };
   1844         struct type_info {
   1845             size_t numEntries;
   1846             theme_entry* entries;
   1847         };
   1848         struct package_info {
   1849             size_t numTypes;
   1850             type_info types[];
   1851         };
   1852 
   1853         void free_package(package_info* pi);
   1854         package_info* copy_package(package_info* pi);
   1855 
   1856         const ResTable& mTable;
   1857         package_info*   mPackages[Res_MAXPACKAGE];
   1858     };
   1859 
   1860     void setParameters(const ResTable_config* params);
   1861     void getParameters(ResTable_config* params) const;
   1862 
   1863     // Retrieve an identifier (which can be passed to getResource)
   1864     // for a given resource name.  The 'name' can be fully qualified
   1865     // (<package>:<type>.<basename>) or the package or type components
   1866     // can be dropped if default values are supplied here.
   1867     //
   1868     // Returns 0 if no such resource was found, else a valid resource ID.
   1869     uint32_t identifierForName(const char16_t* name, size_t nameLen,
   1870                                const char16_t* type = 0, size_t typeLen = 0,
   1871                                const char16_t* defPackage = 0,
   1872                                size_t defPackageLen = 0,
   1873                                uint32_t* outTypeSpecFlags = NULL) const;
   1874 
   1875     static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
   1876                                   String16* outPackage,
   1877                                   String16* outType,
   1878                                   String16* outName,
   1879                                   const String16* defType = NULL,
   1880                                   const String16* defPackage = NULL,
   1881                                   const char** outErrorMsg = NULL);
   1882 
   1883     static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
   1884     static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
   1885 
   1886     // Used with stringToValue.
   1887     class Accessor
   1888     {
   1889     public:
   1890         inline virtual ~Accessor() { }
   1891 
   1892         virtual uint32_t getCustomResource(const String16& package,
   1893                                            const String16& type,
   1894                                            const String16& name) const = 0;
   1895         virtual uint32_t getCustomResourceWithCreation(const String16& package,
   1896                                                        const String16& type,
   1897                                                        const String16& name,
   1898                                                        const bool createIfNeeded = false) = 0;
   1899         virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
   1900         virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
   1901         virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
   1902         virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
   1903         virtual bool getAttributeEnum(uint32_t attrID,
   1904                                       const char16_t* name, size_t nameLen,
   1905                                       Res_value* outValue) = 0;
   1906         virtual bool getAttributeFlags(uint32_t attrID,
   1907                                        const char16_t* name, size_t nameLen,
   1908                                        Res_value* outValue) = 0;
   1909         virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
   1910         virtual bool getLocalizationSetting() = 0;
   1911         virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
   1912     };
   1913 
   1914     // Convert a string to a resource value.  Handles standard "@res",
   1915     // "#color", "123", and "0x1bd" types; performs escaping of strings.
   1916     // The resulting value is placed in 'outValue'; if it is a string type,
   1917     // 'outString' receives the string.  If 'attrID' is supplied, the value is
   1918     // type checked against this attribute and it is used to perform enum
   1919     // evaluation.  If 'acccessor' is supplied, it will be used to attempt to
   1920     // resolve resources that do not exist in this ResTable.  If 'attrType' is
   1921     // supplied, the value will be type checked for this format if 'attrID'
   1922     // is not supplied or found.
   1923     bool stringToValue(Res_value* outValue, String16* outString,
   1924                        const char16_t* s, size_t len,
   1925                        bool preserveSpaces, bool coerceType,
   1926                        uint32_t attrID = 0,
   1927                        const String16* defType = NULL,
   1928                        const String16* defPackage = NULL,
   1929                        Accessor* accessor = NULL,
   1930                        void* accessorCookie = NULL,
   1931                        uint32_t attrType = ResTable_map::TYPE_ANY,
   1932                        bool enforcePrivate = true) const;
   1933 
   1934     // Perform processing of escapes and quotes in a string.
   1935     static bool collectString(String16* outString,
   1936                               const char16_t* s, size_t len,
   1937                               bool preserveSpaces,
   1938                               const char** outErrorMsg = NULL,
   1939                               bool append = false);
   1940 
   1941     size_t getBasePackageCount() const;
   1942     const char16_t* getBasePackageName(size_t idx) const;
   1943     uint32_t getBasePackageId(size_t idx) const;
   1944 
   1945     size_t getTableCount() const;
   1946     const ResStringPool* getTableStringBlock(size_t index) const;
   1947     void* getTableCookie(size_t index) const;
   1948 
   1949     // Return the configurations (ResTable_config) that we know about
   1950     void getConfigurations(Vector<ResTable_config>* configs) const;
   1951 
   1952     void getLocales(Vector<String8>* locales) const;
   1953 
   1954 #ifndef HAVE_ANDROID_OS
   1955     void print(bool inclValues) const;
   1956 #endif
   1957 
   1958 private:
   1959     struct Header;
   1960     struct Type;
   1961     struct Package;
   1962     struct PackageGroup;
   1963     struct bag_set;
   1964 
   1965     status_t add(const void* data, size_t size, void* cookie,
   1966                  Asset* asset, bool copyData);
   1967 
   1968     ssize_t getResourcePackageIndex(uint32_t resID) const;
   1969     ssize_t getEntry(
   1970         const Package* package, int typeIndex, int entryIndex,
   1971         const ResTable_config* config,
   1972         const ResTable_type** outType, const ResTable_entry** outEntry,
   1973         const Type** outTypeClass) const;
   1974     status_t parsePackage(
   1975         const ResTable_package* const pkg, const Header* const header);
   1976 
   1977     void print_value(const Package* pkg, const Res_value& value) const;
   1978 
   1979     mutable Mutex               mLock;
   1980 
   1981     status_t                    mError;
   1982 
   1983     ResTable_config             mParams;
   1984 
   1985     // Array of all resource tables.
   1986     Vector<Header*>             mHeaders;
   1987 
   1988     // Array of packages in all resource tables.
   1989     Vector<PackageGroup*>       mPackageGroups;
   1990 
   1991     // Mapping from resource package IDs to indices into the internal
   1992     // package array.
   1993     uint8_t                     mPackageMap[256];
   1994 };
   1995 
   1996 }   // namespace android
   1997 
   1998 #endif // _LIBS_UTILS_RESOURCE_TYPES_H
   1999