• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
Res_png_9patchRes_png_9patch104     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     uint32_t flags;
399 
400     // Index from header of the string data.
401     uint32_t stringsStart;
402 
403     // Index from header of the style data.
404     uint32_t stylesStart;
405 };
406 
407 /**
408  * This structure defines a span of style information associated with
409  * a string in the pool.
410  */
411 struct ResStringPool_span
412 {
413     enum {
414         END = 0xFFFFFFFF
415     };
416 
417     // This is the name of the span -- that is, the name of the XML
418     // tag that defined it.  The special value END (0xFFFFFFFF) indicates
419     // the end of an array of spans.
420     ResStringPool_ref name;
421 
422     // The range of characters in the string that this span applies to.
423     uint32_t firstChar, lastChar;
424 };
425 
426 /**
427  * Convenience class for accessing data in a ResStringPool resource.
428  */
429 class ResStringPool
430 {
431 public:
432     ResStringPool();
433     ResStringPool(const void* data, size_t size, bool copyData=false);
434     ~ResStringPool();
435 
436     status_t setTo(const void* data, size_t size, bool copyData=false);
437 
438     status_t getError() const;
439 
440     void uninit();
441 
stringAt(const ResStringPool_ref & ref,size_t * outLen)442     inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
443         return stringAt(ref.index, outLen);
444     }
445     const char16_t* stringAt(size_t idx, size_t* outLen) const;
446 
447     const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
448     const ResStringPool_span* styleAt(size_t idx) const;
449 
450     ssize_t indexOfString(const char16_t* str, size_t strLen) const;
451 
452     size_t size() const;
453 
454 private:
455     status_t                    mError;
456     void*                       mOwnedData;
457     const ResStringPool_header* mHeader;
458     size_t                      mSize;
459     const uint32_t*             mEntries;
460     const uint32_t*             mEntryStyles;
461     const char16_t*             mStrings;
462     uint32_t                    mStringPoolSize;    // number of uint16_t
463     const uint32_t*             mStyles;
464     uint32_t                    mStylePoolSize;    // number of uint32_t
465 };
466 
467 /** ********************************************************************
468  *  XML Tree
469  *
470  *  Binary representation of an XML document.  This is designed to
471  *  express everything in an XML document, in a form that is much
472  *  easier to parse on the device.
473  *
474  *********************************************************************** */
475 
476 /**
477  * XML tree header.  This appears at the front of an XML tree,
478  * describing its content.  It is followed by a flat array of
479  * ResXMLTree_node structures; the hierarchy of the XML document
480  * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
481  * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
482  */
483 struct ResXMLTree_header
484 {
485     struct ResChunk_header header;
486 };
487 
488 /**
489  * Basic XML tree node.  A single item in the XML document.  Extended info
490  * about the node can be found after header.headerSize.
491  */
492 struct ResXMLTree_node
493 {
494     struct ResChunk_header header;
495 
496     // Line number in original source file at which this element appeared.
497     uint32_t lineNumber;
498 
499     // Optional XML comment that was associated with this element; -1 if none.
500     struct ResStringPool_ref comment;
501 };
502 
503 /**
504  * Extended XML tree node for CDATA tags -- includes the CDATA string.
505  * Appears header.headerSize bytes after a ResXMLTree_node.
506  */
507 struct ResXMLTree_cdataExt
508 {
509     // The raw CDATA character data.
510     struct ResStringPool_ref data;
511 
512     // The typed value of the character data if this is a CDATA node.
513     struct Res_value typedData;
514 };
515 
516 /**
517  * Extended XML tree node for namespace start/end nodes.
518  * Appears header.headerSize bytes after a ResXMLTree_node.
519  */
520 struct ResXMLTree_namespaceExt
521 {
522     // The prefix of the namespace.
523     struct ResStringPool_ref prefix;
524 
525     // The URI of the namespace.
526     struct ResStringPool_ref uri;
527 };
528 
529 /**
530  * Extended XML tree node for element start/end nodes.
531  * Appears header.headerSize bytes after a ResXMLTree_node.
532  */
533 struct ResXMLTree_endElementExt
534 {
535     // String of the full namespace of this element.
536     struct ResStringPool_ref ns;
537 
538     // String name of this node if it is an ELEMENT; the raw
539     // character data if this is a CDATA node.
540     struct ResStringPool_ref name;
541 };
542 
543 /**
544  * Extended XML tree node for start tags -- includes attribute
545  * information.
546  * Appears header.headerSize bytes after a ResXMLTree_node.
547  */
548 struct ResXMLTree_attrExt
549 {
550     // String of the full namespace of this element.
551     struct ResStringPool_ref ns;
552 
553     // String name of this node if it is an ELEMENT; the raw
554     // character data if this is a CDATA node.
555     struct ResStringPool_ref name;
556 
557     // Byte offset from the start of this structure where the attributes start.
558     uint16_t attributeStart;
559 
560     // Size of the ResXMLTree_attribute structures that follow.
561     uint16_t attributeSize;
562 
563     // Number of attributes associated with an ELEMENT.  These are
564     // available as an array of ResXMLTree_attribute structures
565     // immediately following this node.
566     uint16_t attributeCount;
567 
568     // Index (1-based) of the "id" attribute. 0 if none.
569     uint16_t idIndex;
570 
571     // Index (1-based) of the "class" attribute. 0 if none.
572     uint16_t classIndex;
573 
574     // Index (1-based) of the "style" attribute. 0 if none.
575     uint16_t styleIndex;
576 };
577 
578 struct ResXMLTree_attribute
579 {
580     // Namespace of this attribute.
581     struct ResStringPool_ref ns;
582 
583     // Name of this attribute.
584     struct ResStringPool_ref name;
585 
586     // The original raw string value of this attribute.
587     struct ResStringPool_ref rawValue;
588 
589     // Processesd typed value of this attribute.
590     struct Res_value typedValue;
591 };
592 
593 class ResXMLTree;
594 
595 class ResXMLParser
596 {
597 public:
598     ResXMLParser(const ResXMLTree& tree);
599 
600     enum event_code_t {
601         BAD_DOCUMENT = -1,
602         START_DOCUMENT = 0,
603         END_DOCUMENT = 1,
604 
605         FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE,
606 
607         START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
608         END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
609         START_TAG = RES_XML_START_ELEMENT_TYPE,
610         END_TAG = RES_XML_END_ELEMENT_TYPE,
611         TEXT = RES_XML_CDATA_TYPE
612     };
613 
614     struct ResXMLPosition
615     {
616         event_code_t                eventCode;
617         const ResXMLTree_node*      curNode;
618         const void*                 curExt;
619     };
620 
621     void restart();
622 
623     event_code_t getEventType() const;
624     // Note, unlike XmlPullParser, the first call to next() will return
625     // START_TAG of the first element.
626     event_code_t next();
627 
628     // These are available for all nodes:
629     int32_t getCommentID() const;
630     const uint16_t* getComment(size_t* outLen) const;
631     uint32_t getLineNumber() const;
632 
633     // This is available for TEXT:
634     int32_t getTextID() const;
635     const uint16_t* getText(size_t* outLen) const;
636     ssize_t getTextValue(Res_value* outValue) const;
637 
638     // These are available for START_NAMESPACE and END_NAMESPACE:
639     int32_t getNamespacePrefixID() const;
640     const uint16_t* getNamespacePrefix(size_t* outLen) const;
641     int32_t getNamespaceUriID() const;
642     const uint16_t* getNamespaceUri(size_t* outLen) const;
643 
644     // These are available for START_TAG and END_TAG:
645     int32_t getElementNamespaceID() const;
646     const uint16_t* getElementNamespace(size_t* outLen) const;
647     int32_t getElementNameID() const;
648     const uint16_t* getElementName(size_t* outLen) const;
649 
650     // Remaining methods are for retrieving information about attributes
651     // associated with a START_TAG:
652 
653     size_t getAttributeCount() const;
654 
655     // Returns -1 if no namespace, -2 if idx out of range.
656     int32_t getAttributeNamespaceID(size_t idx) const;
657     const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
658 
659     int32_t getAttributeNameID(size_t idx) const;
660     const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
661     uint32_t getAttributeNameResID(size_t idx) const;
662 
663     int32_t getAttributeValueStringID(size_t idx) const;
664     const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
665 
666     int32_t getAttributeDataType(size_t idx) const;
667     int32_t getAttributeData(size_t idx) const;
668     ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
669 
670     ssize_t indexOfAttribute(const char* ns, const char* attr) const;
671     ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
672                              const char16_t* attr, size_t attrLen) const;
673 
674     ssize_t indexOfID() const;
675     ssize_t indexOfClass() const;
676     ssize_t indexOfStyle() const;
677 
678     void getPosition(ResXMLPosition* pos) const;
679     void setPosition(const ResXMLPosition& pos);
680 
681 private:
682     friend class ResXMLTree;
683 
684     event_code_t nextNode();
685 
686     const ResXMLTree&           mTree;
687     event_code_t                mEventCode;
688     const ResXMLTree_node*      mCurNode;
689     const void*                 mCurExt;
690 };
691 
692 /**
693  * Convenience class for accessing data in a ResXMLTree resource.
694  */
695 class ResXMLTree : public ResXMLParser
696 {
697 public:
698     ResXMLTree();
699     ResXMLTree(const void* data, size_t size, bool copyData=false);
700     ~ResXMLTree();
701 
702     status_t setTo(const void* data, size_t size, bool copyData=false);
703 
704     status_t getError() const;
705 
706     void uninit();
707 
708     const ResStringPool& getStrings() const;
709 
710 private:
711     friend class ResXMLParser;
712 
713     status_t validateNode(const ResXMLTree_node* node) const;
714 
715     status_t                    mError;
716     void*                       mOwnedData;
717     const ResXMLTree_header*    mHeader;
718     size_t                      mSize;
719     const uint8_t*              mDataEnd;
720     ResStringPool               mStrings;
721     const uint32_t*             mResIds;
722     size_t                      mNumResIds;
723     const ResXMLTree_node*      mRootNode;
724     const void*                 mRootExt;
725     event_code_t                mRootCode;
726 };
727 
728 /** ********************************************************************
729  *  RESOURCE TABLE
730  *
731  *********************************************************************** */
732 
733 /**
734  * Header for a resource table.  Its data contains a series of
735  * additional chunks:
736  *   * A ResStringPool_header containing all table values.
737  *   * One or more ResTable_package chunks.
738  *
739  * Specific entries within a resource table can be uniquely identified
740  * with a single integer as defined by the ResTable_ref structure.
741  */
742 struct ResTable_header
743 {
744     struct ResChunk_header header;
745 
746     // The number of ResTable_package structures.
747     uint32_t packageCount;
748 };
749 
750 /**
751  * A collection of resource data types within a package.  Followed by
752  * one or more ResTable_type and ResTable_typeSpec structures containing the
753  * entry values for each resource type.
754  */
755 struct ResTable_package
756 {
757     struct ResChunk_header header;
758 
759     // If this is a base package, its ID.  Package IDs start
760     // at 1 (corresponding to the value of the package bits in a
761     // resource identifier).  0 means this is not a base package.
762     uint32_t id;
763 
764     // Actual name of this package, \0-terminated.
765     char16_t name[128];
766 
767     // Offset to a ResStringPool_header defining the resource
768     // type symbol table.  If zero, this package is inheriting from
769     // another base package (overriding specific values in it).
770     uint32_t typeStrings;
771 
772     // Last index into typeStrings that is for public use by others.
773     uint32_t lastPublicType;
774 
775     // Offset to a ResStringPool_header defining the resource
776     // key symbol table.  If zero, this package is inheriting from
777     // another base package (overriding specific values in it).
778     uint32_t keyStrings;
779 
780     // Last index into keyStrings that is for public use by others.
781     uint32_t lastPublicKey;
782 };
783 
784 /**
785  * Describes a particular resource configuration.
786  */
787 struct ResTable_config
788 {
789     // Number of bytes in this structure.
790     uint32_t size;
791 
792     union {
793         struct {
794             // Mobile country code (from SIM).  0 means "any".
795             uint16_t mcc;
796             // Mobile network code (from SIM).  0 means "any".
797             uint16_t mnc;
798         };
799         uint32_t imsi;
800     };
801 
802     union {
803         struct {
804             // \0\0 means "any".  Otherwise, en, fr, etc.
805             char language[2];
806 
807             // \0\0 means "any".  Otherwise, US, CA, etc.
808             char country[2];
809         };
810         uint32_t locale;
811     };
812 
813     enum {
814         ORIENTATION_ANY  = 0x0000,
815         ORIENTATION_PORT = 0x0001,
816         ORIENTATION_LAND = 0x0002,
817         ORIENTATION_SQUARE = 0x0003,
818     };
819 
820     enum {
821         TOUCHSCREEN_ANY  = 0x0000,
822         TOUCHSCREEN_NOTOUCH  = 0x0001,
823         TOUCHSCREEN_STYLUS  = 0x0002,
824         TOUCHSCREEN_FINGER  = 0x0003,
825     };
826 
827     enum {
828         DENSITY_DEFAULT = 0,
829         DENSITY_LOW = 120,
830         DENSITY_MEDIUM = 160,
831         DENSITY_HIGH = 240,
832         DENSITY_NONE = 0xffff
833     };
834 
835     union {
836         struct {
837             uint8_t orientation;
838             uint8_t touchscreen;
839             uint16_t density;
840         };
841         uint32_t screenType;
842     };
843 
844     enum {
845         KEYBOARD_ANY  = 0x0000,
846         KEYBOARD_NOKEYS  = 0x0001,
847         KEYBOARD_QWERTY  = 0x0002,
848         KEYBOARD_12KEY  = 0x0003,
849     };
850 
851     enum {
852         NAVIGATION_ANY  = 0x0000,
853         NAVIGATION_NONAV  = 0x0001,
854         NAVIGATION_DPAD  = 0x0002,
855         NAVIGATION_TRACKBALL  = 0x0003,
856         NAVIGATION_WHEEL  = 0x0004,
857     };
858 
859     enum {
860         MASK_KEYSHIDDEN = 0x0003,
861         KEYSHIDDEN_ANY = 0x0000,
862         KEYSHIDDEN_NO = 0x0001,
863         KEYSHIDDEN_YES = 0x0002,
864         KEYSHIDDEN_SOFT = 0x0003,
865     };
866 
867     enum {
868         MASK_NAVHIDDEN = 0x000c,
869         NAVHIDDEN_ANY = 0x0000,
870         NAVHIDDEN_NO = 0x0004,
871         NAVHIDDEN_YES = 0x0008,
872     };
873 
874     union {
875         struct {
876             uint8_t keyboard;
877             uint8_t navigation;
878             uint8_t inputFlags;
879             uint8_t inputPad0;
880         };
881         uint32_t input;
882     };
883 
884     enum {
885         SCREENWIDTH_ANY = 0
886     };
887 
888     enum {
889         SCREENHEIGHT_ANY = 0
890     };
891 
892     union {
893         struct {
894             uint16_t screenWidth;
895             uint16_t screenHeight;
896         };
897         uint32_t screenSize;
898     };
899 
900     enum {
901         SDKVERSION_ANY = 0
902     };
903 
904     enum {
905         MINORVERSION_ANY = 0
906     };
907 
908     union {
909         struct {
910             uint16_t sdkVersion;
911             // For now minorVersion must always be 0!!!  Its meaning
912             // is currently undefined.
913             uint16_t minorVersion;
914         };
915         uint32_t version;
916     };
917 
918     enum {
919         // screenLayout bits for screen size class.
920         MASK_SCREENSIZE = 0x0f,
921         SCREENSIZE_ANY  = 0x00,
922         SCREENSIZE_SMALL = 0x01,
923         SCREENSIZE_NORMAL = 0x02,
924         SCREENSIZE_LARGE = 0x03,
925 
926         // screenLayout bits for wide/long screen variation.
927         MASK_SCREENLONG = 0x30,
928         SCREENLONG_ANY = 0x00,
929         SCREENLONG_NO = 0x10,
930         SCREENLONG_YES = 0x20,
931     };
932 
933     union {
934         struct {
935             uint8_t screenLayout;
936             uint8_t screenConfigPad0;
937             uint8_t screenConfigPad1;
938             uint8_t screenConfigPad2;
939         };
940         uint32_t screenConfig;
941     };
942 
copyFromDeviceNoSwapResTable_config943     inline void copyFromDeviceNoSwap(const ResTable_config& o) {
944         const size_t size = dtohl(o.size);
945         if (size >= sizeof(ResTable_config)) {
946             *this = o;
947         } else {
948             memcpy(this, &o, size);
949             memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
950         }
951     }
952 
copyFromDtoHResTable_config953     inline void copyFromDtoH(const ResTable_config& o) {
954         copyFromDeviceNoSwap(o);
955         size = sizeof(ResTable_config);
956         mcc = dtohs(mcc);
957         mnc = dtohs(mnc);
958         density = dtohs(density);
959         screenWidth = dtohs(screenWidth);
960         screenHeight = dtohs(screenHeight);
961         sdkVersion = dtohs(sdkVersion);
962         minorVersion = dtohs(minorVersion);
963     }
964 
swapHtoDResTable_config965     inline void swapHtoD() {
966         size = htodl(size);
967         mcc = htods(mcc);
968         mnc = htods(mnc);
969         density = htods(density);
970         screenWidth = htods(screenWidth);
971         screenHeight = htods(screenHeight);
972         sdkVersion = htods(sdkVersion);
973         minorVersion = htods(minorVersion);
974     }
975 
compareResTable_config976     inline int compare(const ResTable_config& o) const {
977         int32_t diff = (int32_t)(imsi - o.imsi);
978         if (diff != 0) return diff;
979         diff = (int32_t)(locale - o.locale);
980         if (diff != 0) return diff;
981         diff = (int32_t)(screenType - o.screenType);
982         if (diff != 0) return diff;
983         diff = (int32_t)(input - o.input);
984         if (diff != 0) return diff;
985         diff = (int32_t)(screenSize - o.screenSize);
986         if (diff != 0) return diff;
987         diff = (int32_t)(version - o.version);
988         if (diff != 0) return diff;
989         diff = (int32_t)(screenLayout - o.screenLayout);
990         return (int)diff;
991     }
992 
993     // Flags indicating a set of config values.  These flag constants must
994     // match the corresponding ones in android.content.pm.ActivityInfo and
995     // attrs_manifest.xml.
996     enum {
997         CONFIG_MCC = 0x0001,
998         CONFIG_MNC = 0x0002,
999         CONFIG_LOCALE = 0x0004,
1000         CONFIG_TOUCHSCREEN = 0x0008,
1001         CONFIG_KEYBOARD = 0x0010,
1002         CONFIG_KEYBOARD_HIDDEN = 0x0020,
1003         CONFIG_NAVIGATION = 0x0040,
1004         CONFIG_ORIENTATION = 0x0080,
1005         CONFIG_DENSITY = 0x0100,
1006         CONFIG_SCREEN_SIZE = 0x0200,
1007         CONFIG_VERSION = 0x0400,
1008         CONFIG_SCREEN_LAYOUT = 0x0800
1009     };
1010 
1011     // Compare two configuration, returning CONFIG_* flags set for each value
1012     // that is different.
diffResTable_config1013     inline int diff(const ResTable_config& o) const {
1014         int diffs = 0;
1015         if (mcc != o.mcc) diffs |= CONFIG_MCC;
1016         if (mnc != o.mnc) diffs |= CONFIG_MNC;
1017         if (locale != o.locale) diffs |= CONFIG_LOCALE;
1018         if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
1019         if (density != o.density) diffs |= CONFIG_DENSITY;
1020         if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
1021         if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
1022                 diffs |= CONFIG_KEYBOARD_HIDDEN;
1023         if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
1024         if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
1025         if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
1026         if (version != o.version) diffs |= CONFIG_VERSION;
1027         if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
1028         return diffs;
1029     }
1030 
1031     // Return true if 'this' is more specific than 'o'.
1032     inline bool
isMoreSpecificThanResTable_config1033     isMoreSpecificThan(const ResTable_config& o) const {
1034         // The order of the following tests defines the importance of one
1035         // configuration parameter over another.  Those tests first are more
1036         // important, trumping any values in those following them.
1037         if (imsi || o.imsi) {
1038             if (mcc != o.mcc) {
1039                 if (!mcc) return false;
1040                 if (!o.mcc) return true;
1041             }
1042 
1043             if (mnc != o.mnc) {
1044                 if (!mnc) return false;
1045                 if (!o.mnc) return true;
1046             }
1047         }
1048 
1049         if (locale || o.locale) {
1050             if (language[0] != o.language[0]) {
1051                 if (!language[0]) return false;
1052                 if (!o.language[0]) return true;
1053             }
1054 
1055             if (country[0] != o.country[0]) {
1056                 if (!country[0]) return false;
1057                 if (!o.country[0]) return true;
1058             }
1059         }
1060 
1061         if (screenConfig || o.screenConfig) {
1062             if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
1063                 if (!(screenLayout & MASK_SCREENSIZE)) return false;
1064                 if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
1065             }
1066             if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
1067                 if (!(screenLayout & MASK_SCREENLONG)) return false;
1068                 if (!(o.screenLayout & MASK_SCREENLONG)) return true;
1069             }
1070         }
1071 
1072         if (screenType || o.screenType) {
1073             if (orientation != o.orientation) {
1074                 if (!orientation) return false;
1075                 if (!o.orientation) return true;
1076             }
1077 
1078             // density is never 'more specific'
1079             // as the default just equals 160
1080 
1081             if (touchscreen != o.touchscreen) {
1082                 if (!touchscreen) return false;
1083                 if (!o.touchscreen) return true;
1084             }
1085         }
1086 
1087         if (input || o.input) {
1088             if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
1089                 if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
1090                 if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
1091             }
1092 
1093             if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
1094                 if (!(inputFlags & MASK_NAVHIDDEN)) return false;
1095                 if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
1096             }
1097 
1098             if (keyboard != o.keyboard) {
1099                 if (!keyboard) return false;
1100                 if (!o.keyboard) return true;
1101             }
1102 
1103             if (navigation != o.navigation) {
1104                 if (!navigation) return false;
1105                 if (!o.navigation) return true;
1106             }
1107         }
1108 
1109         if (screenSize || o.screenSize) {
1110             if (screenWidth != o.screenWidth) {
1111                 if (!screenWidth) return false;
1112                 if (!o.screenWidth) return true;
1113             }
1114 
1115             if (screenHeight != o.screenHeight) {
1116                 if (!screenHeight) return false;
1117                 if (!o.screenHeight) return true;
1118             }
1119         }
1120 
1121         if (version || o.version) {
1122             if (sdkVersion != o.sdkVersion) {
1123                 if (!sdkVersion) return false;
1124                 if (!o.sdkVersion) return true;
1125             }
1126 
1127             if (minorVersion != o.minorVersion) {
1128                 if (!minorVersion) return false;
1129                 if (!o.minorVersion) return true;
1130             }
1131         }
1132         return false;
1133     }
1134 
1135     // Return true if 'this' is a better match than 'o' for the 'requested'
1136     // configuration.  This assumes that match() has already been used to
1137     // remove any configurations that don't match the requested configuration
1138     // at all; if they are not first filtered, non-matching results can be
1139     // considered better than matching ones.
1140     // The general rule per attribute: if the request cares about an attribute
1141     // (it normally does), if the two (this and o) are equal it's a tie.  If
1142     // they are not equal then one must be generic because only generic and
1143     // '==requested' will pass the match() call.  So if this is not generic,
1144     // it wins.  If this IS generic, o wins (return false).
1145     inline bool
isBetterThanResTable_config1146     isBetterThan(const ResTable_config& o,
1147             const ResTable_config* requested) const {
1148         if (requested) {
1149             if (imsi || o.imsi) {
1150                 if ((mcc != o.mcc) && requested->mcc) {
1151                     return (mcc);
1152                 }
1153 
1154                 if ((mnc != o.mnc) && requested->mnc) {
1155                     return (mnc);
1156                 }
1157             }
1158 
1159             if (locale || o.locale) {
1160                 if ((language[0] != o.language[0]) && requested->language[0]) {
1161                     return (language[0]);
1162                 }
1163 
1164                 if ((country[0] != o.country[0]) && requested->country[0]) {
1165                     return (country[0]);
1166                 }
1167             }
1168 
1169             if (screenConfig || o.screenConfig) {
1170                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
1171                         && (requested->screenLayout & MASK_SCREENSIZE)) {
1172                     return (screenLayout & MASK_SCREENSIZE);
1173                 }
1174                 if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
1175                         && (requested->screenLayout & MASK_SCREENLONG)) {
1176                     return (screenLayout & MASK_SCREENLONG);
1177                 }
1178             }
1179 
1180             if (screenType || o.screenType) {
1181                 if ((orientation != o.orientation) && requested->orientation) {
1182                     return (orientation);
1183                 }
1184 
1185                 if (density != o.density) {
1186                     // density is tough.  Any density is potentially useful
1187                     // because the system will scale it.  Scaling down
1188                     // is generally better than scaling up.
1189                     // Default density counts as 160dpi (the system default)
1190                     // TODO - remove 160 constants
1191                     int h = (density?density:160);
1192                     int l = (o.density?o.density:160);
1193                     bool bImBigger = true;
1194                     if (l > h) {
1195                         int t = h;
1196                         h = l;
1197                         l = t;
1198                         bImBigger = false;
1199                     }
1200 
1201                     int reqValue = (requested->density?requested->density:160);
1202                     if (reqValue >= h) {
1203                         // requested value higher than both l and h, give h
1204                         return bImBigger;
1205                     }
1206                     if (l >= reqValue) {
1207                         // requested value lower than both l and h, give l
1208                         return !bImBigger;
1209                     }
1210                     // saying that scaling down is 2x better than up
1211                     if (((2 * l) - reqValue) * h > reqValue * reqValue) {
1212                         return !bImBigger;
1213                     } else {
1214                         return bImBigger;
1215                     }
1216                 }
1217 
1218                 if ((touchscreen != o.touchscreen) && requested->touchscreen) {
1219                     return (touchscreen);
1220                 }
1221             }
1222 
1223             if (input || o.input) {
1224                 const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
1225                 const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
1226                 if (keysHidden != oKeysHidden) {
1227                     const int reqKeysHidden =
1228                             requested->inputFlags & MASK_KEYSHIDDEN;
1229                     if (reqKeysHidden) {
1230 
1231                         if (!keysHidden) return false;
1232                         if (!oKeysHidden) return true;
1233                         // For compatibility, we count KEYSHIDDEN_NO as being
1234                         // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
1235                         // these by making an exact match more specific.
1236                         if (reqKeysHidden == keysHidden) return true;
1237                         if (reqKeysHidden == oKeysHidden) return false;
1238                     }
1239                 }
1240 
1241                 const int navHidden = inputFlags & MASK_NAVHIDDEN;
1242                 const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
1243                 if (navHidden != oNavHidden) {
1244                     const int reqNavHidden =
1245                             requested->inputFlags & MASK_NAVHIDDEN;
1246                     if (reqNavHidden) {
1247 
1248                         if (!navHidden) return false;
1249                         if (!oNavHidden) return true;
1250                     }
1251                 }
1252 
1253                 if ((keyboard != o.keyboard) && requested->keyboard) {
1254                     return (keyboard);
1255                 }
1256 
1257                 if ((navigation != o.navigation) && requested->navigation) {
1258                     return (navigation);
1259                 }
1260             }
1261 
1262             if (screenSize || o.screenSize) {
1263                 if ((screenWidth != o.screenWidth) && requested->screenWidth) {
1264                     return (screenWidth);
1265                 }
1266 
1267                 if ((screenHeight != o.screenHeight) &&
1268                         requested->screenHeight) {
1269                     return (screenHeight);
1270                 }
1271             }
1272 
1273             if (version || o.version) {
1274                 if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
1275                     return (sdkVersion > o.sdkVersion);
1276                 }
1277 
1278                 if ((minorVersion != o.minorVersion) &&
1279                         requested->minorVersion) {
1280                     return (minorVersion);
1281                 }
1282             }
1283 
1284             return false;
1285         }
1286         return isMoreSpecificThan(o);
1287     }
1288 
1289     // Return true if 'this' can be considered a match for the parameters in
1290     // 'settings'.
1291     // Note this is asymetric.  A default piece of data will match every request
1292     // but a request for the default should not match odd specifics
1293     // (ie, request with no mcc should not match a particular mcc's data)
1294     // settings is the requested settings
matchResTable_config1295     inline bool match(const ResTable_config& settings) const {
1296         if (imsi != 0) {
1297             if ((settings.mcc != 0 && mcc != 0
1298                  && mcc != settings.mcc) ||
1299                 (settings.mcc == 0 && mcc != 0)) {
1300                 return false;
1301             }
1302             if ((settings.mnc != 0 && mnc != 0
1303                  && mnc != settings.mnc) ||
1304                 (settings.mnc == 0 && mnc != 0)) {
1305                 return false;
1306             }
1307         }
1308         if (locale != 0) {
1309             if (settings.language[0] != 0 && language[0] != 0
1310                 && (language[0] != settings.language[0]
1311                     || language[1] != settings.language[1])) {
1312                 return false;
1313             }
1314             if (settings.country[0] != 0 && country[0] != 0
1315                 && (country[0] != settings.country[0]
1316                     || country[1] != settings.country[1])) {
1317                 return false;
1318             }
1319         }
1320         if (screenConfig != 0) {
1321             const int screenSize = screenLayout&MASK_SCREENSIZE;
1322             const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
1323             if (setScreenSize != 0 && screenSize != 0
1324                     && screenSize != setScreenSize) {
1325                 return false;
1326             }
1327 
1328             const int screenLong = screenLayout&MASK_SCREENLONG;
1329             const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
1330             if (setScreenLong != 0 && screenLong != 0
1331                     && screenLong != setScreenLong) {
1332                 return false;
1333             }
1334         }
1335         if (screenType != 0) {
1336             if (settings.orientation != 0 && orientation != 0
1337                 && orientation != settings.orientation) {
1338                 return false;
1339             }
1340             // density always matches - we can scale it.  See isBetterThan
1341             if (settings.touchscreen != 0 && touchscreen != 0
1342                 && touchscreen != settings.touchscreen) {
1343                 return false;
1344             }
1345         }
1346         if (input != 0) {
1347             const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
1348             const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
1349             if (setKeysHidden != 0 && keysHidden != 0
1350                 && keysHidden != setKeysHidden) {
1351                 // For compatibility, we count a request for KEYSHIDDEN_NO as also
1352                 // matching the more recent KEYSHIDDEN_SOFT.  Basically
1353                 // KEYSHIDDEN_NO means there is some kind of keyboard available.
1354                 //LOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
1355                 if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
1356                     //LOGI("No match!");
1357                     return false;
1358                 }
1359             }
1360             const int navHidden = inputFlags&MASK_NAVHIDDEN;
1361             const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
1362             if (setNavHidden != 0 && navHidden != 0
1363                 && navHidden != setNavHidden) {
1364                 return false;
1365             }
1366             if (settings.keyboard != 0 && keyboard != 0
1367                 && keyboard != settings.keyboard) {
1368                 return false;
1369             }
1370             if (settings.navigation != 0 && navigation != 0
1371                 && navigation != settings.navigation) {
1372                 return false;
1373             }
1374         }
1375         if (screenSize != 0) {
1376             if (settings.screenWidth != 0 && screenWidth != 0
1377                 && screenWidth != settings.screenWidth) {
1378                 return false;
1379             }
1380             if (settings.screenHeight != 0 && screenHeight != 0
1381                 && screenHeight != settings.screenHeight) {
1382                 return false;
1383             }
1384         }
1385         if (version != 0) {
1386             if (settings.sdkVersion != 0 && sdkVersion != 0
1387                 && sdkVersion > settings.sdkVersion) {
1388                 return false;
1389             }
1390             if (settings.minorVersion != 0 && minorVersion != 0
1391                 && minorVersion != settings.minorVersion) {
1392                 return false;
1393             }
1394         }
1395         return true;
1396     }
1397 
getLocaleResTable_config1398     void getLocale(char str[6]) const {
1399         memset(str, 0, 6);
1400         if (language[0]) {
1401             str[0] = language[0];
1402             str[1] = language[1];
1403             if (country[0]) {
1404                 str[2] = '_';
1405                 str[3] = country[0];
1406                 str[4] = country[1];
1407             }
1408         }
1409     }
1410 
toStringResTable_config1411     String8 toString() const {
1412         char buf[200];
1413         sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
1414                 "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d sz=%d long=%d vers=%d.%d",
1415                 mcc, mnc,
1416                 language[0] ? language[0] : '-', language[1] ? language[1] : '-',
1417                 country[0] ? country[0] : '-', country[1] ? country[1] : '-',
1418                 orientation, touchscreen, density, keyboard, navigation, inputFlags,
1419                 screenWidth, screenHeight,
1420                 screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
1421                 sdkVersion, minorVersion);
1422         return String8(buf);
1423     }
1424 };
1425 
1426 /**
1427  * A specification of the resources defined by a particular type.
1428  *
1429  * There should be one of these chunks for each resource type.
1430  *
1431  * This structure is followed by an array of integers providing the set of
1432  * configuation change flags (ResTable_config::CONFIG_*) that have multiple
1433  * resources for that configuration.  In addition, the high bit is set if that
1434  * resource has been made public.
1435  */
1436 struct ResTable_typeSpec
1437 {
1438     struct ResChunk_header header;
1439 
1440     // The type identifier this chunk is holding.  Type IDs start
1441     // at 1 (corresponding to the value of the type bits in a
1442     // resource identifier).  0 is invalid.
1443     uint8_t id;
1444 
1445     // Must be 0.
1446     uint8_t res0;
1447     // Must be 0.
1448     uint16_t res1;
1449 
1450     // Number of uint32_t entry configuration masks that follow.
1451     uint32_t entryCount;
1452 
1453     enum {
1454         // Additional flag indicating an entry is public.
1455         SPEC_PUBLIC = 0x40000000
1456     };
1457 };
1458 
1459 /**
1460  * A collection of resource entries for a particular resource data
1461  * type. Followed by an array of uint32_t defining the resource
1462  * values, corresponding to the array of type strings in the
1463  * ResTable_package::typeStrings string block. Each of these hold an
1464  * index from entriesStart; a value of NO_ENTRY means that entry is
1465  * not defined.
1466  *
1467  * There may be multiple of these chunks for a particular resource type,
1468  * supply different configuration variations for the resource values of
1469  * that type.
1470  *
1471  * It would be nice to have an additional ordered index of entries, so
1472  * we can do a binary search if trying to find a resource by string name.
1473  */
1474 struct ResTable_type
1475 {
1476     struct ResChunk_header header;
1477 
1478     enum {
1479         NO_ENTRY = 0xFFFFFFFF
1480     };
1481 
1482     // The type identifier this chunk is holding.  Type IDs start
1483     // at 1 (corresponding to the value of the type bits in a
1484     // resource identifier).  0 is invalid.
1485     uint8_t id;
1486 
1487     // Must be 0.
1488     uint8_t res0;
1489     // Must be 0.
1490     uint16_t res1;
1491 
1492     // Number of uint32_t entry indices that follow.
1493     uint32_t entryCount;
1494 
1495     // Offset from header where ResTable_entry data starts.
1496     uint32_t entriesStart;
1497 
1498     // Configuration this collection of entries is designed for.
1499     ResTable_config config;
1500 };
1501 
1502 /**
1503  * This is the beginning of information about an entry in the resource
1504  * table.  It holds the reference to the name of this entry, and is
1505  * immediately followed by one of:
1506  *   * A Res_value structure, if FLAG_COMPLEX is -not- set.
1507  *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.
1508  *     These supply a set of name/value mappings of data.
1509  */
1510 struct ResTable_entry
1511 {
1512     // Number of bytes in this structure.
1513     uint16_t size;
1514 
1515     enum {
1516         // If set, this is a complex entry, holding a set of name/value
1517         // mappings.  It is followed by an array of ResTable_map structures.
1518         FLAG_COMPLEX = 0x0001,
1519         // If set, this resource has been declared public, so libraries
1520         // are allowed to reference it.
1521         FLAG_PUBLIC = 0x0002
1522     };
1523     uint16_t flags;
1524 
1525     // Reference into ResTable_package::keyStrings identifying this entry.
1526     struct ResStringPool_ref key;
1527 };
1528 
1529 /**
1530  * Extended form of a ResTable_entry for map entries, defining a parent map
1531  * resource from which to inherit values.
1532  */
1533 struct ResTable_map_entry : public ResTable_entry
1534 {
1535     // Resource identifier of the parent mapping, or 0 if there is none.
1536     ResTable_ref parent;
1537     // Number of name/value pairs that follow for FLAG_COMPLEX.
1538     uint32_t count;
1539 };
1540 
1541 /**
1542  * A single name/value mapping that is part of a complex resource
1543  * entry.
1544  */
1545 struct ResTable_map
1546 {
1547     // The resource identifier defining this mapping's name.  For attribute
1548     // resources, 'name' can be one of the following special resource types
1549     // to supply meta-data about the attribute; for all other resource types
1550     // it must be an attribute resource.
1551     ResTable_ref name;
1552 
1553     // Special values for 'name' when defining attribute resources.
1554     enum {
1555         // This entry holds the attribute's type code.
1556         ATTR_TYPE = Res_MAKEINTERNAL(0),
1557 
1558         // For integral attributes, this is the minimum value it can hold.
1559         ATTR_MIN = Res_MAKEINTERNAL(1),
1560 
1561         // For integral attributes, this is the maximum value it can hold.
1562         ATTR_MAX = Res_MAKEINTERNAL(2),
1563 
1564         // Localization of this resource is can be encouraged or required with
1565         // an aapt flag if this is set
1566         ATTR_L10N = Res_MAKEINTERNAL(3),
1567 
1568         // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
1569         ATTR_OTHER = Res_MAKEINTERNAL(4),
1570         ATTR_ZERO = Res_MAKEINTERNAL(5),
1571         ATTR_ONE = Res_MAKEINTERNAL(6),
1572         ATTR_TWO = Res_MAKEINTERNAL(7),
1573         ATTR_FEW = Res_MAKEINTERNAL(8),
1574         ATTR_MANY = Res_MAKEINTERNAL(9)
1575 
1576     };
1577 
1578     // Bit mask of allowed types, for use with ATTR_TYPE.
1579     enum {
1580         // No type has been defined for this attribute, use generic
1581         // type handling.  The low 16 bits are for types that can be
1582         // handled generically; the upper 16 require additional information
1583         // in the bag so can not be handled generically for TYPE_ANY.
1584         TYPE_ANY = 0x0000FFFF,
1585 
1586         // Attribute holds a references to another resource.
1587         TYPE_REFERENCE = 1<<0,
1588 
1589         // Attribute holds a generic string.
1590         TYPE_STRING = 1<<1,
1591 
1592         // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
1593         // optionally specify a constrained range of possible integer values.
1594         TYPE_INTEGER = 1<<2,
1595 
1596         // Attribute holds a boolean integer.
1597         TYPE_BOOLEAN = 1<<3,
1598 
1599         // Attribute holds a color value.
1600         TYPE_COLOR = 1<<4,
1601 
1602         // Attribute holds a floating point value.
1603         TYPE_FLOAT = 1<<5,
1604 
1605         // Attribute holds a dimension value, such as "20px".
1606         TYPE_DIMENSION = 1<<6,
1607 
1608         // Attribute holds a fraction value, such as "20%".
1609         TYPE_FRACTION = 1<<7,
1610 
1611         // Attribute holds an enumeration.  The enumeration values are
1612         // supplied as additional entries in the map.
1613         TYPE_ENUM = 1<<16,
1614 
1615         // Attribute holds a bitmaks of flags.  The flag bit values are
1616         // supplied as additional entries in the map.
1617         TYPE_FLAGS = 1<<17
1618     };
1619 
1620     // Enum of localization modes, for use with ATTR_L10N.
1621     enum {
1622         L10N_NOT_REQUIRED = 0,
1623         L10N_SUGGESTED    = 1
1624     };
1625 
1626     // This mapping's value.
1627     Res_value value;
1628 };
1629 
1630 /**
1631  * Convenience class for accessing data in a ResTable resource.
1632  */
1633 class ResTable
1634 {
1635 public:
1636     ResTable();
1637     ResTable(const void* data, size_t size, void* cookie,
1638              bool copyData=false);
1639     ~ResTable();
1640 
1641     status_t add(const void* data, size_t size, void* cookie,
1642                  bool copyData=false);
1643     status_t add(Asset* asset, void* cookie,
1644                  bool copyData=false);
1645     status_t add(ResTable* src);
1646 
1647     status_t getError() const;
1648 
1649     void uninit();
1650 
1651     struct resource_name
1652     {
1653         const char16_t* package;
1654         size_t packageLen;
1655         const char16_t* type;
1656         size_t typeLen;
1657         const char16_t* name;
1658         size_t nameLen;
1659     };
1660 
1661     bool getResourceName(uint32_t resID, resource_name* outName) const;
1662 
1663     /**
1664      * Retrieve the value of a resource.  If the resource is found, returns a
1665      * value >= 0 indicating the table it is in (for use with
1666      * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
1667      * not found, returns a negative error code.
1668      *
1669      * Note that this function does not do reference traversal.  If you want
1670      * to follow references to other resources to get the "real" value to
1671      * use, you need to call resolveReference() after this function.
1672      *
1673      * @param resID The desired resoruce identifier.
1674      * @param outValue Filled in with the resource data that was found.
1675      *
1676      * @return ssize_t Either a >= 0 table index or a negative error code.
1677      */
1678     ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
1679             uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const;
1680 
1681     inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
1682             uint32_t* outSpecFlags=NULL) const {
1683         return getResource(res.ident, outValue, false, outSpecFlags, NULL);
1684     }
1685 
1686     ssize_t resolveReference(Res_value* inOutValue,
1687                              ssize_t blockIndex,
1688                              uint32_t* outLastRef = NULL,
1689                              uint32_t* inoutTypeSpecFlags = NULL,
1690                              ResTable_config* outConfig = NULL) const;
1691 
1692     enum {
1693         TMP_BUFFER_SIZE = 16
1694     };
1695     const char16_t* valueToString(const Res_value* value, size_t stringBlock,
1696                                   char16_t tmpBuffer[TMP_BUFFER_SIZE],
1697                                   size_t* outLen);
1698 
1699     struct bag_entry {
1700         ssize_t stringBlock;
1701         ResTable_map map;
1702     };
1703 
1704     /**
1705      * Retrieve the bag of a resource.  If the resoruce is found, returns the
1706      * number of bags it contains and 'outBag' points to an array of their
1707      * values.  If not found, a negative error code is returned.
1708      *
1709      * Note that this function -does- do reference traversal of the bag data.
1710      *
1711      * @param resID The desired resource identifier.
1712      * @param outBag Filled inm with a pointer to the bag mappings.
1713      *
1714      * @return ssize_t Either a >= 0 bag count of negative error code.
1715      */
1716     ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
1717 
1718     void unlockBag(const bag_entry* bag) const;
1719 
1720     void lock() const;
1721 
1722     ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
1723             uint32_t* outTypeSpecFlags=NULL) const;
1724 
1725     void unlock() const;
1726 
1727     class Theme {
1728     public:
1729         Theme(const ResTable& table);
1730         ~Theme();
1731 
getResTable()1732         inline const ResTable& getResTable() const { return mTable; }
1733 
1734         status_t applyStyle(uint32_t resID, bool force=false);
1735         status_t setTo(const Theme& other);
1736 
1737         /**
1738          * Retrieve a value in the theme.  If the theme defines this
1739          * value, returns a value >= 0 indicating the table it is in
1740          * (for use with getTableStringBlock() and getTableCookie) and
1741          * fills in 'outValue'.  If not found, returns a negative error
1742          * code.
1743          *
1744          * Note that this function does not do reference traversal.  If you want
1745          * to follow references to other resources to get the "real" value to
1746          * use, you need to call resolveReference() after this function.
1747          *
1748          * @param resID A resource identifier naming the desired theme
1749          *              attribute.
1750          * @param outValue Filled in with the theme value that was
1751          *                 found.
1752          *
1753          * @return ssize_t Either a >= 0 table index or a negative error code.
1754          */
1755         ssize_t getAttribute(uint32_t resID, Res_value* outValue,
1756                 uint32_t* outTypeSpecFlags = NULL) const;
1757 
1758         /**
1759          * This is like ResTable::resolveReference(), but also takes
1760          * care of resolving attribute references to the theme.
1761          */
1762         ssize_t resolveAttributeReference(Res_value* inOutValue,
1763                 ssize_t blockIndex, uint32_t* outLastRef = NULL,
1764                 uint32_t* inoutTypeSpecFlags = NULL,
1765                 ResTable_config* inoutConfig = NULL) const;
1766 
1767         void dumpToLog() const;
1768 
1769     private:
1770         Theme(const Theme&);
1771         Theme& operator=(const Theme&);
1772 
1773         struct theme_entry {
1774             ssize_t stringBlock;
1775             uint32_t typeSpecFlags;
1776             Res_value value;
1777         };
1778         struct type_info {
1779             size_t numEntries;
1780             theme_entry* entries;
1781         };
1782         struct package_info {
1783             size_t numTypes;
1784             type_info types[];
1785         };
1786 
1787         void free_package(package_info* pi);
1788         package_info* copy_package(package_info* pi);
1789 
1790         const ResTable& mTable;
1791         package_info*   mPackages[Res_MAXPACKAGE];
1792     };
1793 
1794     void setParameters(const ResTable_config* params);
1795     void getParameters(ResTable_config* params) const;
1796 
1797     // Retrieve an identifier (which can be passed to getResource)
1798     // for a given resource name.  The 'name' can be fully qualified
1799     // (<package>:<type>.<basename>) or the package or type components
1800     // can be dropped if default values are supplied here.
1801     //
1802     // Returns 0 if no such resource was found, else a valid resource ID.
1803     uint32_t identifierForName(const char16_t* name, size_t nameLen,
1804                                const char16_t* type = 0, size_t typeLen = 0,
1805                                const char16_t* defPackage = 0,
1806                                size_t defPackageLen = 0,
1807                                uint32_t* outTypeSpecFlags = NULL) const;
1808 
1809     static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
1810                                   String16* outPackage,
1811                                   String16* outType,
1812                                   String16* outName,
1813                                   const String16* defType = NULL,
1814                                   const String16* defPackage = NULL,
1815                                   const char** outErrorMsg = NULL);
1816 
1817     static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
1818     static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
1819 
1820     // Used with stringToValue.
1821     class Accessor
1822     {
1823     public:
~Accessor()1824         inline virtual ~Accessor() { }
1825 
1826         virtual uint32_t getCustomResource(const String16& package,
1827                                            const String16& type,
1828                                            const String16& name) const = 0;
1829         virtual uint32_t getCustomResourceWithCreation(const String16& package,
1830                                                        const String16& type,
1831                                                        const String16& name,
1832                                                        const bool createIfNeeded = false) = 0;
1833         virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
1834         virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
1835         virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
1836         virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
1837         virtual bool getAttributeEnum(uint32_t attrID,
1838                                       const char16_t* name, size_t nameLen,
1839                                       Res_value* outValue) = 0;
1840         virtual bool getAttributeFlags(uint32_t attrID,
1841                                        const char16_t* name, size_t nameLen,
1842                                        Res_value* outValue) = 0;
1843         virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
1844         virtual bool getLocalizationSetting() = 0;
1845         virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
1846     };
1847 
1848     // Convert a string to a resource value.  Handles standard "@res",
1849     // "#color", "123", and "0x1bd" types; performs escaping of strings.
1850     // The resulting value is placed in 'outValue'; if it is a string type,
1851     // 'outString' receives the string.  If 'attrID' is supplied, the value is
1852     // type checked against this attribute and it is used to perform enum
1853     // evaluation.  If 'acccessor' is supplied, it will be used to attempt to
1854     // resolve resources that do not exist in this ResTable.  If 'attrType' is
1855     // supplied, the value will be type checked for this format if 'attrID'
1856     // is not supplied or found.
1857     bool stringToValue(Res_value* outValue, String16* outString,
1858                        const char16_t* s, size_t len,
1859                        bool preserveSpaces, bool coerceType,
1860                        uint32_t attrID = 0,
1861                        const String16* defType = NULL,
1862                        const String16* defPackage = NULL,
1863                        Accessor* accessor = NULL,
1864                        void* accessorCookie = NULL,
1865                        uint32_t attrType = ResTable_map::TYPE_ANY,
1866                        bool enforcePrivate = true) const;
1867 
1868     // Perform processing of escapes and quotes in a string.
1869     static bool collectString(String16* outString,
1870                               const char16_t* s, size_t len,
1871                               bool preserveSpaces,
1872                               const char** outErrorMsg = NULL,
1873                               bool append = false);
1874 
1875     size_t getBasePackageCount() const;
1876     const char16_t* getBasePackageName(size_t idx) const;
1877     uint32_t getBasePackageId(size_t idx) const;
1878 
1879     size_t getTableCount() const;
1880     const ResStringPool* getTableStringBlock(size_t index) const;
1881     void* getTableCookie(size_t index) const;
1882 
1883     // Return the configurations (ResTable_config) that we know about
1884     void getConfigurations(Vector<ResTable_config>* configs) const;
1885 
1886     void getLocales(Vector<String8>* locales) const;
1887 
1888 #ifndef HAVE_ANDROID_OS
1889     void print(bool inclValues) const;
1890 #endif
1891 
1892 private:
1893     struct Header;
1894     struct Type;
1895     struct Package;
1896     struct PackageGroup;
1897     struct bag_set;
1898 
1899     status_t add(const void* data, size_t size, void* cookie,
1900                  Asset* asset, bool copyData);
1901 
1902     ssize_t getResourcePackageIndex(uint32_t resID) const;
1903     ssize_t getEntry(
1904         const Package* package, int typeIndex, int entryIndex,
1905         const ResTable_config* config,
1906         const ResTable_type** outType, const ResTable_entry** outEntry,
1907         const Type** outTypeClass) const;
1908     status_t parsePackage(
1909         const ResTable_package* const pkg, const Header* const header);
1910 
1911     void print_value(const Package* pkg, const Res_value& value) const;
1912 
1913     mutable Mutex               mLock;
1914 
1915     status_t                    mError;
1916 
1917     ResTable_config             mParams;
1918 
1919     // Array of all resource tables.
1920     Vector<Header*>             mHeaders;
1921 
1922     // Array of packages in all resource tables.
1923     Vector<PackageGroup*>       mPackageGroups;
1924 
1925     // Mapping from resource package IDs to indices into the internal
1926     // package array.
1927     uint8_t                     mPackageMap[256];
1928 };
1929 
1930 }   // namespace android
1931 
1932 #endif // _LIBS_UTILS_RESOURCE_TYPES_H
1933