ResourceTable.cpp revision 081d1b4cf602fdd7302b597e6bf902cb415bc3a8
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Build resource files from raw assets. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 9de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#include "AaptUtil.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceIdCache.h" 13dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski#include "SdkConstants.h" 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski#include <algorithm> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <androidfw/ResourceTypes.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/ByteOrder.h> 1882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski#include <utils/TypeHelpers.h> 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdarg.h> 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 212412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe// SSIZE: mingw does not have signed size_t == ssize_t. 222412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary. 23b12f2410c7bdbf90bd8a77b897846ee2763e3037Elliott Hughes#if !defined(_WIN32) 242412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define SSIZE(x) x 252412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define STATUST(x) x 262412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe#else 272412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define SSIZE(x) (signed size_t)x 282412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define STATUST(x) (status_t)x 292412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe#endif 302412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe 312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe// Set to true for noisy debug output. 322412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampestatic const bool kIsDebug = false; 332412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe 342412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe#if PRINT_STRING_METRICS 352412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampestatic const bool kPrintStringMetrics = true; 362412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe#else 372412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampestatic const bool kPrintStringMetrics = false; 382412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe#endif 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 409b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskistatic const char* kAttrPrivateType = "^attr-private"; 419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 43e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 44e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 53a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 54e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, target, table, options); 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 57e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 58e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 59e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& outTarget, 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options); 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 74e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 75e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<XMLNode>& root, 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(true, NULL); 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(false, NULL); 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_UTF8) != 0) { 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->setUTF8(true); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 9107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (table->processBundleFormat(bundle, resourceName, target, root) != NO_ERROR) { 9207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 9307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 945b9847ca3fbcd0bb2528dd2b4c0b789e2d501684Adam Lesinski 9507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski bool hasErrors = false; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->assignResourceIds(assets, table); 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if ((options&XML_COMPILE_PARSE_VALUES) != 0) { 10407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski status_t err = root->parseValues(assets, table); 10507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (err != NO_ERROR) { 10607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski hasErrors = true; 10707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 113e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 114e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) { 115e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return UNKNOWN_ERROR; 116e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 11787332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe 1182412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 1192412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Input XML Resource:\n"); 1202412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe root->print(); 1212412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 12207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski status_t err = root->flatten(target, 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_COMMENTS) != 0, 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_RAW_VALUES) != 0); 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1292412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 1302412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Output XML Resource:\n"); 1312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe ResXMLTree tree; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(target->getData(), target->getSize()); 1332412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printXMLBlock(&tree); 1342412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski target->setCompressionMethod(ZipEntry::kCompressDeflated); 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct flag_entry 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* name; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t nameLen; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value; 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* description; 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t referenceArray[] = 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' }; 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t stringArray[] = 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 's', 't', 'r', 'i', 'n', 'g' }; 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t integerArray[] = 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'i', 'n', 't', 'e', 'g', 'e', 'r' }; 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t booleanArray[] = 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'b', 'o', 'o', 'l', 'e', 'a', 'n' }; 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t colorArray[] = 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'c', 'o', 'l', 'o', 'r' }; 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t floatArray[] = 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'o', 'a', 't' }; 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t dimensionArray[] = 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' }; 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t fractionArray[] = 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' }; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t enumArray[] = 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'e', 'n', 'u', 'm' }; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t flagsArray[] = 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'a', 'g', 's' }; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry gFormatFlags[] = { 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE, 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n" 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."}, 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING, 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." }, 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER, 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "an integer value, such as \"<code>100</code>\"." }, 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN, 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." }, 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR, 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n" 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." }, 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT, 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a floating point value, such as \"<code>1.2</code>\"."}, 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION, 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n" 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n" 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "in (inches), mm (millimeters)." }, 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION, 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n" 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n" 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "some parent container." }, 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL }, 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL }, 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' }; 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry l10nRequiredFlags[] = { 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL }, 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t nulStr[] = { 0 }; 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic uint32_t parse_flags(const char16_t* str, size_t len, 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags, bool* outError = NULL) 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(*str)) { 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(str[len-1])) { 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + len; 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value = 0; 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* div = str; 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (div < end && *div != '|') { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski div++; 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* cur = flags; 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (cur->name) { 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) { 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value |= cur->value; 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cur++; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!cur->name) { 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = true; 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = div < end ? div+1 : div; 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = false; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 mayOrMust(int type, int flags) 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&(~flags)) == 0) { 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>Must"); 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>May"); 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg, 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& typeName, const String16& ident, int type, 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags) 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hadType = false; 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (flags->name) { 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&flags->value) != 0 && flags->description != NULL) { 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 fullMsg(mayOrMust(type, flags->value)); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(" be ")); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(flags->description)); 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, fullMsg); 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hadType = true; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags++; 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) { 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("<p>This may also be a reference to a resource (in the form\n" 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n" 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "theme attribute (in the form\n" 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n" 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "containing a value of this type.")); 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct PendingAttribute 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage; 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos sourcePos; 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool appendComment; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t type; 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment; 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors; 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool added; 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute(String16 _package, const sp<AaptFile>& in, 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, bool _appendComment) 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : myPackage(_package) 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , sourcePos(in->getPrintableSource(), block.getLineNumber()) 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , appendComment(_appendComment) 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , type(ResTable_map::TYPE_ANY) 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , hasErrors(false) 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , added(false) 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t createIfNeeded(ResourceTable* outTable) 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (added || hasErrors) { 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski added = true; 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 311afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if (!outTable->makeAttribute(myPackage, ident, sourcePos, type, comment, appendComment)) { 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 315afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return NO_ERROR; 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t compileAttribute(const sp<AaptFile>& in, 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable, 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outIdent = NULL, 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inStyleable = false) 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute attr(myPackage, in, block, inStyleable); 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 flag16("flag"); 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.ident = String16(block.getAttributeStringValue(identIdx, &len)); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outIdent) { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outIdent = attr.ident; 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("A 'name' attribute is required for <attr>\n"); 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.comment = String16( 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == 0) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeStr).string()); 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!inStyleable) { 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute definitions outside of styleables always define the 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // attribute as a generic value. 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minIdx = block.indexOfAttribute(NULL, "min"); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minIdx >= 0) { 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(minIdx, &len)); 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^min"), String16(val), NULL, NULL); 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxIdx >= 0) { 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^max"), String16(val), NULL, NULL); 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) { 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n"); 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization"); 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (l10nIdx >= 0) { 412f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* str = block.getAttributeStringValue(l10nIdx, &len); 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool error; 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error) { 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string()); 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[11]; 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", l10n_required); 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^l10n"), String16(buf), NULL, NULL); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 enumOrFlagsComment; 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t localType = 0; 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_ENUM; 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_FLAGS; 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == ResTable_map::TYPE_ANY) { 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // No type was explicitly stated, so supplying enum tags 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // implicitly creates an enum or flag. 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = 0; 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) { 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Wasn't originally specified as an enum, so update its type. 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type |= localType; 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", attr.type); 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, attr16, attr.ident, String16(""), 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), String16(numberStr), NULL, NULL, true); 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) { 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localType == ResTable_map::TYPE_ENUM) { 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<enum> attribute can not be used inside a flags format\n"); 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<flag> attribute can not be used inside a enum format\n"); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'name' attribute is required for <enum> or <flag>\n"); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value; 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t valueIdx = block.indexOfAttribute(NULL, "value"); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (valueIdx >= 0) { 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value = String16(block.getAttributeStringValue(valueIdx, &len)); 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'value' attribute is required for <enum> or <flag>\n"); 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <enum> or <flag> 'value' attribute must be a number," 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " not \"%s\"\n", 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(value).string()); 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (enumOrFlagsComment.size() == 0) { 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(mayOrMust(attr.type, 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM) 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? String16(" be one of the following constant values.") 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : String16(" be one or more (separated by '|') of the following constant values.")); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</p>\n<table>\n" 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>")); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n<tr><td><code>")); 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(itemIdent); 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</code></td><td>")); 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(value); 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td><td>")); 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getComment(&len)) { 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16(block.getComment(&len))); 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td></tr>")); 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, attr.ident, String16(""), 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent, value, NULL, NULL, false, true); 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </enum> is expected\n", 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </flag> is expected\n", 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && attr.added) { 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags); 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && enumOrFlagsComment.size() > 0) { 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n</table>")); 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment); 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool localeIsDefined(const ResTable_config& config) 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return config.locale == 0; 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddBag(Bundle* bundle, 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& parentIdent, 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& itemIdent, 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 5912412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe const String16& /* product */, 592a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 598a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block, item16, &str, &spans, isFormatted, 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pseudolocalize); 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 6072412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe 6082412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 6092412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d " 6102412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe " pid=%s, bag=%s, id=%s: %s\n", 6112412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.language[0], config.language[1], 6122412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.country[0], config.country[1], 6132412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.orientation, config.density, 6142412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(parentIdent).string(), 6152412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(ident).string(), 6162412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(itemIdent).string(), 6172412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(str).string()); 6182412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, parentIdent, itemIdent, str, 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &spans, &config, overwrite, false, curFormat); 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns true if needle is one of the elements in the comma-separated list 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * haystack, false otherwise. 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isInProductList(const String16& needle, const String16& haystack) { 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *needle2 = needle.string(); 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *haystack2 = haystack.string(); 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t needlesize = needle.size(); 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0') { 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncmp16(haystack2, needle2, needlesize) == 0) { 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') { 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0' && *haystack2 != ',') { 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*haystack2 == ',') { 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 6538ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski/* 6548ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * A simple container that holds a resource type and name. It is ordered first by type then 6558ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * by name. 6568ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 6578ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinskistruct type_ident_pair_t { 6588ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 type; 6598ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 ident; 6608ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6618ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t() { }; 6628ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { } 6638ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { } 6648ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski inline bool operator < (const type_ident_pair_t& o) const { 6658ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski int cmp = compare_type(type, o.type); 6668ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (cmp < 0) { 6678ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return true; 6688ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else if (cmp > 0) { 6698ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return false; 6708ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else { 6718ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return strictly_order_type(ident, o.ident); 6728ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6738ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6748ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski}; 6758ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6768ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddEntry(Bundle* bundle, 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curTag, 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled, 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 689a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 6918ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool>* skippedResourceNames, 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), block, 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag, &str, curIsStyled ? &spans : NULL, 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isFormatted, pseudolocalize); 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a product type was specified on the command line 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and also in the string, and the two are not the same, 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * return without adding the string. 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *bundleProduct = bundle->getProduct(); 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct == NULL) { 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundleProduct = ""; 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (product.size() != 0) { 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the command-line-specified product is empty, only "default" 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * matches. Other variants are skipped. This is so generation 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * of the R.java file when the product is not known is predictable. 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct[0] == '\0') { 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(String16("default").string(), product.string()) != 0) { 7268ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski /* 7278ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * This string has a product other than 'default'. Do not add it, 7288ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * but record it so that if we do not see the same string with 7298ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * product 'default' or no product, then report an error. 7308ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 7318ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski skippedResourceNames->replaceValueFor( 7328ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(curType, ident), true); 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The command-line product is not empty. 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the product for this string is on the command-line list, 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it matches. "default" also matches, but only if nothing 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * else has matched already. 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isInProductList(product, String16(bundleProduct))) { 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(String16("default").string(), product.string()) == 0 && 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 7542412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 7552412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n", 7562412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.language[0], config.language[1], 7572412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.country[0], config.country[1], 7582412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.orientation, config.density, 7592412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(ident).string(), String8(str).string()); 7602412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, str, &spans, &config, 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski false, curFormat, overwrite); 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileResourceFile(Bundle* bundle, 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& defParams, 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(in, &block, false, true); 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Top-level tag. 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 resources16("resources"); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Identifier declaration tags. 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 declare_styleable16("declare-styleable"); 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation organizational tags. 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string16("string"); 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 drawable16("drawable"); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 color16("color"); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bool16("bool"); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer16("integer"); 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 dimen16("dimen"); 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 fraction16("fraction"); 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 plurals16("plurals"); 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 array16("array"); 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string_array16("string-array"); 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer_array16("integer-array"); 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public16("public"); 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public_padding16("public-padding"); 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 private_symbols16("private-symbols"); 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 java_symbol16("java-symbol"); 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 add_resource16("add-resource"); 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 skip16("skip"); 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 eat_comment16("eat-comment"); 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation tags. 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bag16("bag"); 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // plural values 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 other16("other"); 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOther16("^other"); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 zero16("zero"); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityZero16("^zero"); 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 one16("one"); 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOne16("^one"); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 two16("two"); 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityTwo16("^two"); 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 few16("few"); 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityFew16("^few"); 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 many16("many"); 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityMany16("^many"); 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // useful attribute names and special values 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 name16("name"); 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 translatable16("translatable"); 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 formatted16("formatted"); 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 false16("false"); 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage(assets->getPackage()); 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool fileIsTranslatable = true; 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) { 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileIsTranslatable = false; 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t> nextPublicId(0); 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8488ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // Stores the resource names that were skipped. Typically this happens when 8498ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // AAPT is invoked without a product specified and a resource has no 8508ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // 'default' product attribute. 8518ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool> skippedResourceNames; 8528ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = block.next(); 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (code == ResXMLTree::START_NAMESPACE); 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "No start tag found\n"); 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config curParams(defParams); 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config pseudoParams(curParams); 873a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[0] = 'e'; 874a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[1] = 'n'; 875a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[0] = 'X'; 876a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[1] = 'A'; 877a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 878a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ResTable_config pseudoBidiParams(curParams); 879a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[0] = 'a'; 880a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[1] = 'r'; 881a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[0] = 'X'; 882a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[1] = 'B'; 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 88447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // We should skip resources for pseudolocales if they were 88547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // already added automatically. This is a fix for a transition period when 88647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // manually pseudolocalized resources may be expected. 88747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // TODO: remove this check after next SDK version release. 88847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED && 88947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoParams.locale) || 89047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk (bundle->getPseudolocalize() & PSEUDO_BIDI && 89147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoBidiParams.locale)) { 89247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk SourcePos(in->getPrintableSource(), 0).warning( 89347843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk "Resource file %s is skipped as pseudolocalization" 89447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk " was done automatically.", 89547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk in->getPrintableSource().string()); 89647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk return NO_ERROR; 89747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk } 89847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* curTag = NULL; 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curType; 9035892248580859620db90d5ef2e3c2f48531933faAdrian Roos String16 curName; 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat = ResTable_map::TYPE_ANY; 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBag = false; 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBagReplaceOnOverwrite = false; 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled = false; 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsPseudolocalizable = false; 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsFormatted = fileIsTranslatable; 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool localHasErrors = false; 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t ident = 0; 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "id"); 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* identStr = block.getAttributeStringValue(identIdx, &len); 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value identValue; 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(identStr, len, &identValue)) { 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'id' attribute is not an integer: %s\n", 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(identIdx, &len)).string()); 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = identValue.data; 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'id' attribute supplied <public>," 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = nextPublicId.valueFor(type); 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, name, ident); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(name), srcPos); 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public-padding>\n"); 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public-padding>\n"); 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t start = 0; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t startIdx = block.indexOfAttribute(NULL, "start"); 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (startIdx >= 0) { 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* startStr = block.getAttributeStringValue(startIdx, &len); 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value startValue; 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(startStr, len, &startValue)) { 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'start' attribute is not an integer: %s\n", 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(startIdx, &len)).string()); 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = startValue.data; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'start' attribute supplied <public-padding>," 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = nextPublicId.valueFor(type); 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t end = 0; 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t endIdx = block.indexOfAttribute(NULL, "end"); 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (endIdx >= 0) { 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* endStr = block.getAttributeStringValue(endIdx, &len); 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value endValue; 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(endStr, len, &endValue)) { 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'end' attribute is not an integer: %s\n", 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(endIdx, &len)).string()); 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski end = endValue.data; 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'end' attribute supplied <public-padding>\n"); 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (end >= start) { 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, end+1); 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Padding start '%ul' is after end '%ul'\n", 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start, end); 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (uint32_t curIdent=start; curIdent<=end; curIdent++) { 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localHasErrors) { 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curName(name); 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[64]; 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", (int)(end-curIdent+1)); 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName.append(String16(buf)); 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(srcPos, myPackage, type, curName, 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("padding"), NULL, &curParams, false, 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_STRING, overwrite); 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName, curIdent); 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(curName), srcPos); 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(curName), comment, srcPos); 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 pkg; 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkgIdx < 0) { 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'package' attribute is required for <private-symbols>\n"); 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = String16(block.getAttributeStringValue(pkgIdx, &len)); 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 112678713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 112778713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski "<private-symbols> is deprecated. Use the command line flag " 112878713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski "--private-symbols instead.\n"); 112978713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski if (assets->havePrivateSymbols()) { 113078713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 113178713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski "private symbol package already specified. Ignoring...\n"); 113278713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski } else { 113378713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski assets->setSymbolsPrivatePackage(String8(pkg)); 113478713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski } 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R")); 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolJavaSymbol(String8(name), srcPos); 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName; 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <add-resource>\n"); 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeName = String16(block.getAttributeStringValue(typeIdx, &len)); 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <add-resource>\n"); 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->canAddEntry(srcPos, myPackage, typeName, name); 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx < 0) { 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <declare-styleable>\n"); 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8("styleable"), srcPos); 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleSymbols = symbols; 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(ident), srcPos); 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols == NULL) { 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleSymbols->appendComment(String8(ident), comment, srcPos); 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = NULL; 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true); 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->addSymbol(String8(itemIdent), 0, srcPos); 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(itemIdent), comment, srcPos); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </attr> is expected\n", 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, NULL); 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &item16; 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 13205892248580859620db90d5ef2e3c2f48531933faAdrian Roos ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 13215892248580859620db90d5ef2e3c2f48531933faAdrian Roos if (nameIdx >= 0) { 13225892248580859620db90d5ef2e3c2f48531933faAdrian Roos curName = String16(block.getAttributeStringValue(nameIdx, &len)); 13235892248580859620db90d5ef2e3c2f48531933faAdrian Roos } 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <item> 'format' attribute value \"%s\" not valid\n", 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <item>\n"); 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note the existence and locale of every string we process 134591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath char rawLocale[RESTABLE_MAX_LOCALE_LEN]; 134691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath curParams.getBcp47Locale(rawLocale); 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 locale(rawLocale); 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 translatable; 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatted; 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1355f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* attr = block.getAttributeName(i, &length); 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(attr, name16.string()) == 0) { 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.setTo(block.getAttributeStringValue(i, &length)); 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, translatable16.string()) == 0) { 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski translatable.setTo(block.getAttributeStringValue(i, &length)); 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, formatted16.string()) == 0) { 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatted.setTo(block.getAttributeStringValue(i, &length)); 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name.size() > 0) { 13665892248580859620db90d5ef2e3c2f48531933faAdrian Roos if (locale.size() == 0) { 13675892248580859620db90d5ef2e3c2f48531933faAdrian Roos outTable->addDefaultLocalization(name); 13685892248580859620db90d5ef2e3c2f48531933faAdrian Roos } 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (translatable == false16) { 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Untranslatable strings must only exist in the default [empty] locale 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (locale.size() > 0) { 1373a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 1374a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski "string '%s' marked untranslatable but exists in locale '%s'\n", 1375a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(name).string(), 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski locale.string()); 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // hasErrors = localHasErrors = true; 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Intentionally empty block: 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Don't add untranslatable strings to the localization table; that 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // way if we later see localizations of them, they'll be flagged as 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // having no default translation. 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1386a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski outTable->addLocalization( 1387a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski name, 1388a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locale, 1389a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber())); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatted == false16) { 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string16; 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = string16; 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 140184410b054c7db0b6685a0f15cb2d1ffcb264f6c9Igor Viarheichyk curIsPseudolocalizable = fileIsTranslatable && (translatable != false16); 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &drawable16; 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = drawable16; 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &color16; 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = color16; 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bool16; 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = bool16; 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer16; 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = integer16; 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &dimen16; 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = dimen16; 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &fraction16; 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = fraction16; 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bag16; 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <bag>\n"); 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &style16; 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = style16; 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &plurals16; 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = plurals16; 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1445a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = fileIsTranslatable; 1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { 1447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &array16; 1448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <array> 'format' attribute value \"%s\" not valid\n", 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check whether these strings need valid formats. 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (simplified form of what string16 does above) 1467a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bool isTranslatable = false; 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 14699a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath 14709a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // Pseudolocalizable by default, unless this string array isn't 14719a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // translatable. 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1474f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* attr = block.getAttributeName(i, &length); 1475a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (strcmp16(attr, formatted16.string()) == 0) { 1476f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* value = block.getAttributeStringValue(i, &length); 14779a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath if (strcmp16(value, false16.string()) == 0) { 1478a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted = false; 14799a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath } 1480a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } else if (strcmp16(attr, translatable16.string()) == 0) { 1481f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* value = block.getAttributeStringValue(i, &length); 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(value, false16.string()) == 0) { 1483a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin isTranslatable = false; 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string_array16; 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1493a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = isTranslatable && fileIsTranslatable; 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer_array16; 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag %s where item is expected\n", 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <%s>\n", 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 product; 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski identIdx = block.indexOfAttribute(NULL, "product"); 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski product = String16(block.getAttributeStringValue(identIdx, &len)); 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsBag) { 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Figure out the parent of this bag... 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 parentIdent; 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent"); 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (parentIdentIdx >= 0) { 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len)); 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t sep = ident.findLast('.'); 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sep >= 0) { 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent.setTo(ident, sep); 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->startBag(SourcePos(in->getPrintableSource(), 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getLineNumber()), myPackage, curType, ident, 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent, &curParams, 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overwrite, curIsBagReplaceOnOverwrite); 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t elmIndex = 0; 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char elmIndexStr[14]; 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), item16.string()) != 0) { 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <%s>, only <item>\n", 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curType == array16) { 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(elmIndexStr, "^index_%d", (int)elmIndex++); 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(elmIndexStr); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (curType == plurals16) { 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity"); 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len)); 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (quantity16 == other16) { 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOther16; 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == zero16) { 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityZero16; 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == one16) { 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOne16; 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == two16) { 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityTwo16; 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == few16) { 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityFew16; 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == many16) { 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityMany16; 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Illegal 'quantity' attribute is <item> inside <plurals>\n"); 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'quantity' attribute is required for <item> inside <plurals>\n"); 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <item>\n"); 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident, parentIdent, itemIdent, curFormat, curIsFormatted, 1615a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, outTable); 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1618a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1620a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1621a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1622a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1623a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, 1624a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1625a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_ACCENTED, 1626a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1627a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1628a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1629a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1630a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1631a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage, 1632a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1633a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_BIDI, 1634a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1635a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1637a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { 1643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </%s> is expected\n", 1645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *curTag, curIsStyled, curFormat, curIsFormatted, 1658a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable); 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (err == NO_ERROR) { 16645892248580859620db90d5ef2e3c2f48531933faAdrian Roos if (curType == string16 && !curParams.language[0] && !curParams.country[0]) { 16655892248580859620db90d5ef2e3c2f48531933faAdrian Roos outTable->addDefaultLocalization(curName); 16665892248580859620db90d5ef2e3c2f48531933faAdrian Roos } 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1668a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1670a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1671a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1672a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1673a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, 1674a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ident, *curTag, curIsStyled, curFormat, 1675a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1676a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable); 1677a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1678a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1679a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1680a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1681a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams, 1682a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin myPackage, curType, ident, *curTag, curIsStyled, curFormat, 1683a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1684a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable); 1685a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), 1696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(curType).string(), String8(ident).string(), 1697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 1698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, curType, ident, comment, false); 1702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::END_TAG) { 1705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 1706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); 1708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) { 1712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::TEXT) { 1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isWhitespace(block.getText(&len))) { 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found text \"%s\" where item tag is expected\n", 1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getText(&len)).string()); 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17248ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // For every resource defined, there must be exist one variant with a product attribute 17258ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // set to 'default' (or no product attribute at all). 17268ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // We check to see that for every resource that was ignored because of a mismatched 17278ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // product attribute, some product variant of that resource was processed. 17288ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski for (size_t i = 0; i < skippedResourceNames.size(); i++) { 17298ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (skippedResourceNames[i]) { 17308ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const type_ident_pair_t& p = skippedResourceNames.keyAt(i); 17318ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) { 17328ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const char* bundleProduct = 17338ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski (bundle->getProduct() == NULL) ? "" : bundle->getProduct(); 17348ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "In resource file %s: %s\n", 17358ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski in->getPrintableSource().string(), 17368ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski curParams.toString().string()); 17378ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 17388ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "\t%s '%s' does not match product %s.\n" 17398ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski "\tYou may have forgotten to include a 'default' product variant" 17408ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski " of the resource.\n", 17418ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String8(p.type).string(), String8(p.ident).string(), 17428ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski bundleProduct[0] == 0 ? "default" : bundleProduct); 17438ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return UNKNOWN_ERROR; 17448ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17458ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17468ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17478ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 17482412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1751833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type) 1752833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mAssetsPackage(assetsPackage) 1753833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mPackageType(type) 1754833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mTypeIdOffset(0) 1755833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mNumLocal(0) 1756833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mBundle(bundle) 1757833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski{ 1758833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t packageId = -1; 1759833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski switch (mPackageType) { 1760833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case App: 1761833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case AppFeature: 1762833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x7f; 1763833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1764833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1765833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case System: 1766833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x01; 1767833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1768833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1769833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case SharedLibrary: 1770833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x00; 1771833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1772833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1773833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski default: 1774833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski assert(0); 1775833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1776833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1777833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> package = new Package(mAssetsPackage, packageId); 1778833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mPackages.add(assetsPackage, package); 1779833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mOrderedPackages.add(package); 1780833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1781833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Every resource table always has one first entry, the bag attributes. 1782833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const SourcePos unknown(String8("????"), 0); 1783833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski getType(mAssetsPackage, String16("attr"), unknown); 1784833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski} 1785833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1786833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinskistatic uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) { 1787833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 1788833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 1789833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (packageName == table.getBasePackageName(i)) { 1790833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return table.getLastTypeIdForPackage(i); 1791833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1792833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1793833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets) 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = assets->buildIncludedResources(bundle); 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mAssets = assets; 1804833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage); 1805833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1806833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const String8& featureAfter = bundle->getFeatureAfterPackage(); 1807833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAfter.isEmpty()) { 1808833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski AssetManager featureAssetManager; 1809833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAssetManager.addAssetPath(featureAfter, NULL)) { 1810833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "ERROR: Feature package '%s' not found.\n", 1811833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski featureAfter.string()); 1812833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1815833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const ResTable& featureTable = featureAssetManager.getResources(false); 1816030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert mTypeIdOffset = std::max(mTypeIdOffset, 1817833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski findLargestTypeIdForPackage(featureTable, mAssetsPackage)); 1818833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addPublic(const SourcePos& sourcePos, 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Error declaring public resource %s/%s for included package %s\n", 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(type).string(), String8(name).string(), 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string()); 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos); 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->addPublic(sourcePos, name, ident); 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addEntry(const SourcePos& sourcePos, 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool doSetIndex, 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int32_t format, 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1863833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1864833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1865833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite, 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski params, doSetIndex); 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->setItem(sourcePos, value, style, format, overwrite); 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::startBag(const SourcePos& sourcePos, 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 18872412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe bool replace, bool /* isId */) 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1898833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1899833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1900833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1902833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) { 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool canAdd = false; 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t->getCanAddEntries().indexOf(name) >= 0) { 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski canAdd = true; 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!canAdd) { 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n", 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string()); 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params); 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((result = e->makeItABag(sourcePos)) != NO_ERROR) { 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && replace) { 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e->emptyBag(sourcePos); 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addBag(const SourcePos& sourcePos, 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagKey, 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, const int32_t format) 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding bag left: file=%s, line=%d, type=%s\n", 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.striing(), sourcePos.line, String8(type).string()); 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params); 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool first = e->getBag().indexOfKey(bagKey) < 0; 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format); 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR && first) { 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name) const 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) return true; 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config) const 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(config); 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& ref, 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage) 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasBagOrEntry(package, type, name); 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendComment(const String16& package, 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment, 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendComment(comment, onlyIfEmpty); 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendTypeComment(const String16& package, 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment) 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendTypeComment(comment); 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2100afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinskibool ResourceTable::makeAttribute(const String16& package, 2101afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const String16& name, 2102afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const SourcePos& source, 2103afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski int32_t format, 2104afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const String16& comment, 2105afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski bool shouldAppendComment) { 2106afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const String16 attr16("attr"); 2107afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2108afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // First look for this in the included resources... 2109afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2110afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski .identifierForName(name.string(), name.size(), 2111afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski attr16.string(), attr16.size(), 2112afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski package.string(), package.size()); 2113afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if (rid != 0) { 2114afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski source.error("Attribute \"%s\" has already been defined", String8(name).string()); 2115afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return false; 2116afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } 2117afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2118afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski sp<ResourceTable::Entry> entry = getEntry(package, attr16, name, source, false); 2119afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if (entry == NULL) { 2120afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski source.error("Failed to create entry attr/%s", String8(name).string()); 2121afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return false; 2122afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } 2123afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2124afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if (entry->makeItABag(source) != NO_ERROR) { 2125afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return false; 2126afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } 2127afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2128afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const String16 formatKey16("^type"); 2129afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const String16 formatValue16(String8::format("%d", format)); 2130afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2131afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski ssize_t idx = entry->getBag().indexOfKey(formatKey16); 2132afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if (idx >= 0) { 2133afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // We have already set a format for this attribute, check if they are different. 2134afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // We allow duplicate attribute definitions so long as they are identical. 2135afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // This is to ensure inter-operation with libraries that define the same generic attribute. 2136afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski const Item& formatItem = entry->getBag().valueAt(idx); 2137afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski if ((format & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) || 2138afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski formatItem.value != formatValue16) { 2139afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski source.error("Attribute \"%s\" already defined with incompatible format.\n" 2140afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski "%s:%d: Original attribute defined here.", 2141afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski String8(name).string(), formatItem.sourcePos.file.string(), 2142afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski formatItem.sourcePos.line); 2143afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return false; 2144afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } 2145afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } else { 2146afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski entry->addToBag(source, formatKey16, formatValue16); 2147afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // Increment the number of resources we have. This is used to determine if we should 2148afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski // even generate a resource table. 2149afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski mNumLocal++; 2150afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski } 2151afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski appendComment(package, attr16, name, comment, shouldAppendComment); 2152afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski return true; 2153afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski} 2154afc79be228596c56ea68c0d2fa22d0a8d733be47Adam Lesinski 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::canAddEntry(const SourcePos& pos, 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, pos); 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->canAddEntry(name); 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::size() const { 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPackages.size(); 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::numLocalResources() const { 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal; 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasResources() const { 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal > 0; 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 217627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskisp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 217727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 218027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flatten(bundle, filter, data, isBase); 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err == NO_ERROR ? data : NULL; 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiinline uint32_t ResourceTable::getResId(const sp<Package>& p, 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<Type>& t, 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t nameId) 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return makeResId(p->getAssignedId(), t->getIndex(), nameId); 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& package, 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic); 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) return id; // cache hit 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size(), 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &specFlags); 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyPublic) { 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2213833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, rid); 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2216833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2217833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (p == NULL) return 0; 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 22209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 22219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 22229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (type != String16("attr")) { 22239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return 0; 22249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 22259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski t = p->getTypes().valueFor(String16(kAttrPrivateType)); 22269b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t == NULL) return 0; 22279b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski c = t->getConfigs().valueFor(name); 22289b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) return 0; 22299b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(p, t, ei)); 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& ref, 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage, 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char** outErrorMsg, 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool refOnlyPublic = true; 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef( 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ref.string(), ref.size(), &package, &type, &name, 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outErrorMsg, &refOnlyPublic)) { 22492412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 22502412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanding resource: ref=%s\n", String8(ref).string()); 22512412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanding resource: defType=%s\n", 22522412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe defType ? String8(*defType).string() : "NULL"); 22532412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanding resource: defPackage=%s\n", 22542412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe defPackage ? String8(*defPackage).string() : "NULL"); 22552412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanding resource: ref=%s\n", String8(ref).string()); 22562412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", 22572412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(package).string(), String8(type).string(), 22582412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(name).string()); 22592412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); 22632412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 22642412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", 22652412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(package).string(), String8(type).string(), 22662412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe String8(name).string(), res); 22672412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res == 0) { 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outErrorMsg) 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outErrorMsg = "No resource found that matches the given name"; 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::isValidResourceName(const String16& s) 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = s.string(); 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*p >= 'a' && *p <= 'z') 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*p >= 'A' && *p <= 'Z') 2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *p == '_' 2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (!first && *p >= '0' && *p <= '9')) { 2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& str, 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool preserveSpaces, bool coerceType, 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outStr, void* accessorCookie, 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrType, const String8* configTypeName, 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription* config) 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 finalStr; 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = true; 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style == NULL || style->size() == 0) { 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Text is not styled so it can be any type... let's figure it out. 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = mAssets->getIncludedResources() 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski coerceType, attrID, NULL, &mAssetsPackage, this, 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski accessorCookie, attrType); 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Styled text can only be a string, and while collecting the style 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // information we have already processed that string! 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->size = sizeof(Res_value); 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->res0 = 0; 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = outValue->TYPE_STRING; 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finalStr = str; 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!res) { 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outValue->dataType == outValue->TYPE_STRING) { 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should do better merging styles. 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool) { 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configStr; 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = config->toString(); 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = "(null)"; 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 23342412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 23352412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Adding to pool string style #%zu config %s: %s\n", 23362412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe style != NULL ? style->size() : 0U, 23372412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe configStr.string(), String8(finalStr).string()); 23382412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style != NULL && style->size() > 0) { 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, *style, configTypeName, config); 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, true, configTypeName, config); 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Caller will fill this in later. 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outStr) { 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outStr = finalStr; 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResource( 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) const 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getCustomResource: %s %s %s\n", String8(package).string(), 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(type).string(), String8(name).string()); 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) return 0; 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 23689b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 23699b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (type != String16("attr")) { 23709b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return 0; 23719b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 23729b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski t = p->getTypes().valueFor(String16(kAttrPrivateType)); 23739b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t == NULL) return 0; 23749b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski c = t->getConfigs().valueFor(name); 23759b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) return 0; 23769b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getResId(p, t, ei); 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResourceWithCreation( 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name, 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool createIfNotFound) 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resId = getCustomResource(package, type, name); 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resId != 0 || !createIfNotFound) { 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2391f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (mAssetsPackage != package) { 2392833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.error("creating resource for external package %s: %s/%s.", 2393f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8(package).string(), String8(type).string(), String8(name).string()); 2394833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package == String16("android")) { 2395833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?"); 2396833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2397833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 2398f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 2399f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2400f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String16 value("false"); 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true); 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status == NO_ERROR) { 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resId = getResId(package, type, name); 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return origPackage; 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x\n", attrID); 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x (%s): #%08x\n", attrID, 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(getEntry(attrID)->getName()).string(), value.data); 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outType = value.data; 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin) 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMin #%08x\n", attrID); 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) { 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMin = value.data; 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax) 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMax #%08x\n", attrID); 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) { 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMax = value.data; 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getAttributeL10N(uint32_t attrID) 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeL10N #%08x\n", attrID); 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) { 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResTable_map::L10N_NOT_REQUIRED; 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getLocalizationSetting() 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mBundle->getRequireLocalization(); 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (accessorCookie != NULL && fmt != NULL) { 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie* ac = (AccessorCookie*)accessorCookie; 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retval=0; 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[1024]; 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_list ap; 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_start(ap, fmt); 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retval = vsnprintf(buf, sizeof(buf), fmt, ap); 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_end(ap); 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf, ac->attr.string(), ac->value.string()); 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeKeys( 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, Vector<String16>* outKeys) 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = e->getBag().keyAt(i); 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (key.size() > 0 && key.string()[0] != '^') { 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outKeys->add(key); 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeEnum( 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing %s to %s\n", String8(name, nameLen).string(), 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeFlags( 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = Res_value::TYPE_INT_HEX; 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* end = name + nameLen; 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* pos = name; 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end) { 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* start = pos; 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end && *pos != '|') { 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(start, pos-start); 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value val; 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!got) { 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got value: 0x%08x\n", val.data); 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data |= val.data; 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= N) { 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Didn't find this flag identifier. 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::assignResourceIds() 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t firstError = NO_ERROR; 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First generate all bag attributes and assign indices. 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL || p->getTypes().size() == 0) { 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25809b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mPackageType == System) { 25819b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski p->movePrivateAttrs(); 25829b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 25839b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2584833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // This has no sense for packages being built as AppFeature (aka with a non-zero offset). 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = p->applyPublicTypeOrder(); 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate attributes... 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->generateAttributes(this, p->getName()); 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2618833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski uint32_t typeIdOffset = 0; 2619833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (mPackageType == AppFeature && p->getName() == mAssetsPackage) { 2620833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeIdOffset = mTypeIdOffset; 2621833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2622833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos unknown(String8("????"), 0); 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> attr = p->getType(String16("attr"), unknown); 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26264d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski // Force creation of ID if we are building feature splits. 26274d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski // Auto-generated ID resources won't apply the type ID offset correctly unless 26284d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski // the offset is applied here first. 26294d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski // b/30607637 26304d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski if (mPackageType == AppFeature && p->getName() == mAssetsPackage) { 26314d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski sp<Type> id = p->getType(String16("id"), unknown); 26324d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski } 26334d219da3c43f12ff000e685ae069374b618b30fcAdam Lesinski 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign indices... 263543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 263643a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 264143a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = t->applyPublicEntryOrder(); 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2648833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski t->setIndex(ti + 1 + typeIdOffset); 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t, 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "First type is not attr!"); 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei); 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(ei); 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26629b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign resource IDs to keys in bags... 266443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 26699b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 26739b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 26749b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 26759b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordered config #%d: %p\n", ci, c.get()); 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->assignResourceIds(this, p->getName()); 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return firstError; 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26945892248580859620db90d5ef2e3c2f48531933faAdrian Roosstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols, 26955892248580859620db90d5ef2e3c2f48531933faAdrian Roos bool skipSymbolsWithoutDefaultLocalization) { 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 26975892248580859620db90d5ef2e3c2f48531933faAdrian Roos const String8 defaultLocale; 26985892248580859620db90d5ef2e3c2f48531933faAdrian Roos const String16 stringType("string"); 2699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 27169b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 27189b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<AaptSymbols> typeSymbols; 27199b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t->getName() == String16(kAttrPrivateType)) { 27209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski typeSymbols = outSymbols->addNestedSymbol(String8("attr"), t->getPos()); 27219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } else { 27229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); 27239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 27249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 27253fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski if (typeSymbols == NULL) { 27263fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski return UNKNOWN_ERROR; 27273fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski } 27283fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = getResId(p, t, ci); 2735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid == 0) { 2736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2738833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) { 27395892248580859620db90d5ef2e3c2f48531933faAdrian Roos 27405892248580859620db90d5ef2e3c2f48531933faAdrian Roos if (skipSymbolsWithoutDefaultLocalization && 27415892248580859620db90d5ef2e3c2f48531933faAdrian Roos t->getName() == stringType) { 27425892248580859620db90d5ef2e3c2f48531933faAdrian Roos 27435892248580859620db90d5ef2e3c2f48531933faAdrian Roos // Don't generate symbols for strings without a default localization. 27445892248580859620db90d5ef2e3c2f48531933faAdrian Roos if (mHasDefaultLocalization.find(c->getName()) 27455892248580859620db90d5ef2e3c2f48531933faAdrian Roos == mHasDefaultLocalization.end()) { 27465892248580859620db90d5ef2e3c2f48531933faAdrian Roos // printf("Skip symbol [%08x] %s\n", rid, 27475892248580859620db90d5ef2e3c2f48531933faAdrian Roos // String8(c->getName()).string()); 27485892248580859620db90d5ef2e3c2f48531933faAdrian Roos continue; 27495892248580859620db90d5ef2e3c2f48531933faAdrian Roos } 27505892248580859620db90d5ef2e3c2f48531933faAdrian Roos } 27515892248580859620db90d5ef2e3c2f48531933faAdrian Roos 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos()); 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(c->getComment()); 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); 27568ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski //printf("Type symbol [%08x] %s comment: %s\n", rid, 27578ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // String8(c->getName()).string(), String8(comment).string()); 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = c->getTypeComment(); 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendTypeComment(String8(c->getName()), comment); 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2769a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src) 2770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2771a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski mLocalizations[name][locale] = src; 2772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27745892248580859620db90d5ef2e3c2f48531933faAdrian Roosvoid 27755892248580859620db90d5ef2e3c2f48531933faAdrian RoosResourceTable::addDefaultLocalization(const String16& name) 27765892248580859620db90d5ef2e3c2f48531933faAdrian Roos{ 27775892248580859620db90d5ef2e3c2f48531933faAdrian Roos mHasDefaultLocalization.insert(name); 27785892248580859620db90d5ef2e3c2f48531933faAdrian Roos} 27795892248580859620db90d5ef2e3c2f48531933faAdrian Roos 2780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*! 2782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Flag various sorts of localization problems. '+' indicates checks already implemented; 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * '-' indicates checks that will be implemented in the future. 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized string for which no default-locale version exists => warning 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A string for which no version in an explicitly-requested locale exists => warning 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized translation of an translateable="false" string => warning 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - A localized string not provided in every locale used by the table 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::validateLocalizations(void) 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 defaultLocale; 2795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For all strings... 2797030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert for (const auto& nameIter : mLocalizations) { 2798030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert const std::map<String8, SourcePos>& configSrcMap = nameIter.second; 2799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Look for strings with no default localization 2801a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.count(defaultLocale) == 0) { 2802a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' has no default translation.", 2803030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert String8(nameIter.first).string()); 2804a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (mBundle->getVerbose()) { 2805030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert for (const auto& locale : configSrcMap) { 2806030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert locale.second.printf("locale %s found", locale.first.string()); 2807a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // !!! TODO: throw an error here in some circumstances 2810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check that all requested localizations are present for this string 2813fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) { 2814fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* allConfigs = mBundle->getConfigurations().string(); 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* start = allConfigs; 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* comma; 2817030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert 2818030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert std::set<String8> missingConfigs; 2819a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski AaptLocaleValue locale; 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 config; 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comma = strchr(start, ','); 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comma != NULL) { 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start, comma - start); 2825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = comma + 1; 2826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start); 2828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2830a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!locale.initFromFilterString(config)) { 2831a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski continue; 2832a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2833a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2834a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // don't bother with the pseudolocale "en_XA" or "ar_XB" 2835a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (config != "en_XA" && config != "ar_XB") { 2836a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(config) == configSrcMap.end()) { 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // okay, no specific localization found. it's possible that we are 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // requiring a specific regional localization [e.g. de_DE] but there is an 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // available string in the generic language localization [e.g. de]; 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // consider that string to have fulfilled the localization requirement. 2841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 region(config.string(), 2); 2842a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(region) == configSrcMap.end() && 2843a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configSrcMap.count(defaultLocale) == 0) { 2844a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski missingConfigs.insert(config); 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2848a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } while (comma != NULL); 2849a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2850a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!missingConfigs.empty()) { 2851a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8 configStr; 2852030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert for (const auto& iter : missingConfigs) { 2853030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert configStr.appendFormat(" %s", iter.string()); 2854a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2855a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' is missing %u required localizations:%s", 2856030f536009b56dbcc23d284541e51562bd9a6ed3Dan Albert String8(nameIter.first).string(), 2857a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski (unsigned int)missingConfigs.size(), 2858a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.string()); 2859a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 286627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskistatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 286727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const sp<AaptFile>& dest, 286827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription nullConfig; 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const static String16 mipmap16("mipmap"); 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool useUTF8 = !bundle->getUTF16StringsOption(); 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2879de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // The libraries this table references. 2880de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski Vector<sp<Package> > libraryPackages; 28816022debdbcc4498736580640c6287b57872617a2Adam Lesinski const ResTable& table = mAssets->getIncludedResources(); 28826022debdbcc4498736580640c6287b57872617a2Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 28836022debdbcc4498736580640c6287b57872617a2Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 28846022debdbcc4498736580640c6287b57872617a2Adam Lesinski size_t packageId = table.getBasePackageId(i); 28856022debdbcc4498736580640c6287b57872617a2Adam Lesinski String16 packageName(table.getBasePackageName(i)); 28866022debdbcc4498736580640c6287b57872617a2Adam Lesinski if (packageId > 0x01 && packageId != 0x7f && 28876022debdbcc4498736580640c6287b57872617a2Adam Lesinski packageName != String16("android")) { 28886022debdbcc4498736580640c6287b57872617a2Adam Lesinski libraryPackages.add(sp<Package>(new Package(packageName, packageId))); 28896022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 28906022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 2891de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through all data, collecting all values (strings, 2893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // references, etc). 2894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool valueStrings(useUTF8); 2895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Entry> > allEntries; 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool typeStrings(useUTF8); 2903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool keyStrings(useUTF8); 2904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2905833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t stringsAdded = 0; 2906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(String16("<empty>"), false); 2911833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2914833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2915833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski while (stringsAdded < t->getIndex() - 1) { 2916833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeStrings.add(String16("<empty>"), false); 2917833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2918833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2919833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 typeName(t->getName()); 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(typeName, false); 2922833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a hack to tweak the sorting order of the final strings, 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to put stuff that is generally not language-specific first. 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configTypeName(typeName); 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (configTypeName == "drawable" || configTypeName == "layout" 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "color" || configTypeName == "anim" 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "interpolator" || configTypeName == "animator" 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "xml" || configTypeName == "menu" 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "mipmap" || configTypeName == "raw") { 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "1complex"; 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "2value"; 2935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // mipmaps don't get filtered, so they will 293827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // allways end up in the base. Make sure they 293927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // don't end up in a split. 294027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (typeName == mipmap16 && !isBase) { 294127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 294227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 294327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = c->getEntries().keyAt(ei); 2955fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 2956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setNameIndex(keyStrings.add(e->getName(), true)); 2963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this entry has no values for other configs, 2965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and is the default config, then it is special. Otherwise 2966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we want to add it with the config info. 2967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription* valueConfig = NULL; 2968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != 1 || config == nullConfig) { 2969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueConfig = &config; 2970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->prepareFlatten(&valueStrings, this, 2973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &configTypeName, &config); 2974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries.add(e); 2978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setTypeStrings(typeStrings.createStringBlock()); 2983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setKeyStrings(keyStrings.createStringBlock()); 2984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 2987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now we want to sort the value strings for better locality. This will 2988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // cause the positions of the strings to change, so we need to go back 2989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // through out resource entries and update them accordingly. Only need 2990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to do this if actually writing the output file. 2991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueStrings.sortByConfig(); 2992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<allEntries.size(); pi++) { 2993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries[pi]->remapStringValue(&valueStrings); 2994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strAmt = 0; 2998de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now build the array of package chunks. 3000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<AaptFile> > flatPackages; 3001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 3002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 3003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 3004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 3005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getTypeStrings().size(); 3009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t baseSize = sizeof(ResTable_package); 3011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Start the package data. 3013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 3014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_package* header = (ResTable_package*)data->editData(baseSize); 3015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (header == NULL) { 3016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_package\n"); 3017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(header, 0, sizeof(*header)); 3020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.type = htods(RES_TABLE_PACKAGE_TYPE); 3021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.headerSize = htods(sizeof(*header)); 3022833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski header->id = htodl(static_cast<uint32_t>(p->getAssignedId())); 3023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy16_htod(header->name, p->getName().string()); 3024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the string blocks. 3026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStringsStart = data->getSize(); 3027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> strFile = p->getTypeStringsData(); 3028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = data->writeData(strFile->getData(), strFile->getSize()); 30292412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kPrintStringMetrics) { 30302412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe fprintf(stderr, "**** type strings: %zd\n", SSIZE(amt)); 30312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 3033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t keyStringsStart = data->getSize(); 3037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strFile = p->getKeyStringsData(); 3038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt = data->writeData(strFile->getData(), strFile->getSize()); 30392412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kPrintStringMetrics) { 30402412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe fprintf(stderr, "**** key strings: %zd\n", SSIZE(amt)); 30412412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 3043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 304727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (isBase) { 304827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flattenLibraryTable(data, libraryPackages); 304927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (err != NO_ERROR) { 305027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski fprintf(stderr, "ERROR: failed to write library table\n"); 305127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski return err; 305227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 3053de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3054de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the type chunks inside of this package. 3056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 3057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve them in the same order as the type string block. 3058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName(p->getTypeStrings().stringAt(ti, &len)); 3060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(typeName); 3061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), 3062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Type name %s not found", 3063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeName).string()); 3064833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (t == NULL) { 3065833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski continue; 3066833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 306827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool skipEntireType = (typeName == mipmap16 && !isBase); 3069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; 3071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Until a non-NO_ENTRY value has been written for a resource, 3073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that resource is invalid; validResources[i] represents 3074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the item at t->getOrderedConfigs().itemAt(i). 3075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> validResources; 3076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.insertAt(false, 0, N); 3077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First write the typeSpec chunk, containing information about 3079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // each resource entry in this type. 3080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 3081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N; 3082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecStart = data->getSize(); 3083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_typeSpec* tsHeader = (ResTable_typeSpec*) 3084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart); 3085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tsHeader == NULL) { 3086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n"); 3087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tsHeader, 0, sizeof(*tsHeader)); 3090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE); 3091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.headerSize = htods(sizeof(*tsHeader)); 3092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.size = htodl(typeSpecSize); 3093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->id = ti+1; 3094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->entryCount = htodl(N); 3095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* typeSpecFlags = (uint32_t*) 3097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 3098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeSpecStart + sizeof(ResTable_typeSpec)); 3099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(typeSpecFlags, 0, sizeof(uint32_t)*N); 3100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 3102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 31039b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (cl == NULL) { 31049b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 31059b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 31069b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 3107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cl->getPublic()) { 3108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); 3109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 311027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 311127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 311227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 311327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 311427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 3115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t CN = cl->getEntries().size(); 3116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<CN; ci++) { 3117fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(ci))) { 3118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t cj=ci+1; cj<CN; cj++) { 3121fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(cj))) { 3122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl( 3125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj))); 3126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 313127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 313227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 313327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 313427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 3135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We need to write one type chunk for each configuration for 3136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // which we have entries in this type. 3137e97908d32ee8ea80138d085260a0eac93841c722Adam Lesinski SortedVector<ConfigDescription> uniqueConfigs; 3138e97908d32ee8ea80138d085260a0eac93841c722Adam Lesinski if (t != NULL) { 3139e97908d32ee8ea80138d085260a0eac93841c722Adam Lesinski uniqueConfigs = t->getUniqueConfigs(); 3140e97908d32ee8ea80138d085260a0eac93841c722Adam Lesinski } 3141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; 3143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3144e97908d32ee8ea80138d085260a0eac93841c722Adam Lesinski const size_t NC = uniqueConfigs.size(); 3145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<NC; ci++) { 31469b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const ConfigDescription& config = uniqueConfigs[ci]; 3147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 31482412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 31492412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Writing config %zu config: imsi:%d/%d lang:%c%c cnt:%c%c " 31502412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 31512412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe "sw%ddp w%ddp h%ddp layout:%d\n", 31522412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe ti + 1, 31532412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.mcc, config.mnc, 31542412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.language[0] ? config.language[0] : '-', 31552412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.language[1] ? config.language[1] : '-', 31562412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.country[0] ? config.country[0] : '-', 31572412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.country[1] ? config.country[1] : '-', 31582412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.orientation, 31592412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.uiMode, 31602412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.touchscreen, 31612412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.density, 31622412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.keyboard, 31632412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.inputFlags, 31642412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.navigation, 31652412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.screenWidth, 31662412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.screenHeight, 31672412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.smallestScreenWidthDp, 31682412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.screenWidthDp, 31692412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.screenHeightDp, 31702412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config.screenLayout); 31712412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3173fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 3174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStart = data->getSize(); 3178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_type* tHeader = (ResTable_type*) 3180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart); 3181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tHeader == NULL) { 3182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_type\n"); 3183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tHeader, 0, sizeof(*tHeader)); 3187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.type = htods(RES_TABLE_TYPE_TYPE); 3188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.headerSize = htods(sizeof(*tHeader)); 3189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->id = ti+1; 3190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entryCount = htodl(N); 3191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entriesStart = htodl(typeSize); 3192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config = config; 31932412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 31942412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Writing type %zu config: imsi:%d/%d lang:%c%c cnt:%c%c " 31952412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 31962412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe "sw%ddp w%ddp h%ddp layout:%d\n", 31972412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe ti + 1, 31982412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.mcc, tHeader->config.mnc, 31992412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.language[0] ? tHeader->config.language[0] : '-', 32002412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.language[1] ? tHeader->config.language[1] : '-', 32012412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.country[0] ? tHeader->config.country[0] : '-', 32022412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.country[1] ? tHeader->config.country[1] : '-', 32032412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.orientation, 32042412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.uiMode, 32052412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.touchscreen, 32062412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.density, 32072412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.keyboard, 32082412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.inputFlags, 32092412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.navigation, 32102412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.screenWidth, 32112412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.screenHeight, 32122412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.smallestScreenWidthDp, 32132412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.screenWidthDp, 32142412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.screenHeightDp, 32152412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe tHeader->config.screenLayout); 32162412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.swapHtoD(); 3218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the entries inside of this type. 3220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 3221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 32229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Entry> e = NULL; 32239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (cl != NULL) { 32249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski e = cl->getEntries().valueFor(config); 32259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 3226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set the offset for this entry in its type. 3228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* index = (uint32_t*) 3229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 3230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeStart + sizeof(ResTable_type)); 3231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 3232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(data->getSize()-typeStart-typeSize); 3233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create the entry. 3235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = e->flatten(bundle, data, cl->getPublic()); 3236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.editItemAt(ei) = true; 3240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(ResTable_type::NO_ENTRY); 3242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the type information. 3246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader = (ResTable_type*) 3247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) + typeStart); 3248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.size = htodl(data->getSize()-typeStart); 3249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3251833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // If we're building splits, then each invocation of the flattening 3252833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // step will have 'missing' entries. Don't warn/error for this case. 3253833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getSplitConfigurations().isEmpty()) { 3254833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski bool missing_entry = false; 3255833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ? 3256833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski "error" : "warning"; 3257833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; ++i) { 3258833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!validResources[i]) { 3259833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); 32609b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c != NULL) { 326101f185633c1c12017731336e7f926fe398c69781Colin Cross fprintf(stderr, "%s: no entries written for %s/%s (0x%08zx)\n", log_prefix, 32629b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski String8(typeName).string(), String8(c->getName()).string(), 32639b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Res_MAKEID(p->getAssignedId() - 1, ti, i)); 32649b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 3265833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski missing_entry = true; 3266833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3267833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3268833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getErrorOnMissingConfigEntry() && missing_entry) { 3269833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "Error: Missing entries, quit!\n"); 3270833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NOT_ENOUGH_DATA; 3271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3272cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang } 3273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the package information. 3276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header = (ResTable_package*)data->editData(); 3277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(data->getSize()); 3278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->typeStrings = htodl(typeStringsStart); 3279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicType = htodl(p->getTypeStrings().size()); 3280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->keyStrings = htodl(keyStringsStart); 3281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicKey = htodl(p->getKeyStrings().size()); 3282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages.add(data); 3284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // And now write out the final chunks. 3287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dataStart = dest->getSize(); 3288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 3290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // blah 3291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header header; 3292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.type = htods(RES_TABLE_TYPE); 3294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.headerSize = htods(sizeof(header)); 3295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.packageCount = htodl(flatPackages.size()); 3296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dest->writeData(&header, sizeof(header)); 3297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_header\n"); 3299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strStart = dest->getSize(); 3304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = valueStrings.writeStringBlock(dest); 3305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = (dest->getSize()-strStart); 3310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 33112412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kPrintStringMetrics) { 33122412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe fprintf(stderr, "**** value strings: %zd\n", SSIZE(amt)); 33132412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe fprintf(stderr, "**** total strings: %zd\n", SSIZE(strAmt)); 33142412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3315de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<flatPackages.size(); pi++) { 3317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = dest->writeData(flatPackages[pi]->getData(), 3318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages[pi]->getSize()); 3319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n"); 3321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header* header = (ResTable_header*) 3326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)dest->getData()) + dataStart); 3327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(dest->getSize() - dataStart); 3328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 33292412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kPrintStringMetrics) { 33302412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe fprintf(stderr, "**** total resource table size: %zu / %zu%% strings\n", 33312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe dest->getSize(), (size_t)(strAmt*100)/dest->getSize()); 33322412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3337de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskistatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) { 3338de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write out the library table if necessary 3339de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (libs.size() > 0) { 334087332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe if (kIsDebug) { 334187332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe fprintf(stderr, "Writing library reference table\n"); 334287332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe } 3343de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3344de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t libStart = dest->getSize(); 3345de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t count = libs.size(); 33466022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange( 33476022debdbcc4498736580640c6287b57872617a2Adam Lesinski libStart, sizeof(ResTable_lib_header)); 3348de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3349de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(libHeader, 0, sizeof(*libHeader)); 3350de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE); 3351de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.headerSize = htods(sizeof(*libHeader)); 3352de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count)); 3353de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->count = htodl(count); 3354de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3355de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write the library entries 3356de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski for (size_t i = 0; i < count; i++) { 3357de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t entryStart = dest->getSize(); 3358de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski sp<Package> libPackage = libs[i]; 335987332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe if (kIsDebug) { 336087332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe fprintf(stderr, " Entry %s -> 0x%02x\n", 3361de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski String8(libPackage->getName()).string(), 336287332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe (uint8_t)libPackage->getAssignedId()); 336387332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe } 3364de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 33656022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange( 33666022debdbcc4498736580640c6287b57872617a2Adam Lesinski entryStart, sizeof(ResTable_lib_entry)); 3367de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(entry, 0, sizeof(*entry)); 3368de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski entry->packageId = htodl(libPackage->getAssignedId()); 3369de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski strcpy16_htod(entry->packageName, libPackage->getName().string()); 3370de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3371de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3372de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return NO_ERROR; 3373de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 3374de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) 3376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<!-- This file contains <public> resource definitions for all\n" 3379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " resources that were generated from the source data. -->\n" 3380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<resources>\n"); 3382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, true); 3384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, false); 3385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "</resources>\n"); 3389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub) 3392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didHeader = false; 3394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> pkg = mPackages.valueFor(package); 3396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 3397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NT = pkg->getOrderedTypes().size(); 3398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NT; i++) { 3399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = pkg->getOrderedTypes().itemAt(i); 3400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didType = false; 3405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getOrderedConfigs().size(); 3407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NC; j++) { 3408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(j); 3409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c->getPublic() != pub) { 3414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didType) { 3418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n"); 3419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didType = true; 3420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didHeader) { 3422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 3423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PUBLIC SECTION. These resources have been declared public.\n"); 3424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," Changes to these definitions will break binary compatibility. -->\n\n"); 3425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PRIVATE SECTION. These resources have not been declared public.\n"); 3427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," You can make them public my moving these lines into a file in res/values. -->\n\n"); 3428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didHeader = true; 3430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!pub) { 3432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NE = c->getEntries().size(); 3433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<NE; k++) { 3434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); 3435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos.file != "") { 3436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- Declared at %s:%d -->\n", 3437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.file.string(), pos.line); 3438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", 3442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(c->getName()).string(), 3444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(pkg, t, c->getEntryIndex())); 3445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3450282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::Item::Item(const SourcePos& _sourcePos, 3451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool _isId, 3452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& _value, 3453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* _style, 3454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t _format) 3455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : sourcePos(_sourcePos) 3456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , isId(_isId) 3457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , value(_value) 3458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , format(_format) 3459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , bagKeyId(0) 3460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , evaluating(false) 3461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_style) { 3463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style = *_style; 3464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 346782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam LesinskiResourceTable::Entry::Entry(const Entry& entry) 346882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski : RefBase() 346982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mName(entry.mName) 347082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParent(entry.mParent) 347182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mType(entry.mType) 347282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItem(entry.mItem) 347382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItemFormat(entry.mItemFormat) 347482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mBag(entry.mBag) 347582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mNameIndex(entry.mNameIndex) 347682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParentId(entry.mParentId) 347782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mPos(entry.mPos) {} 347882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3479978ab9d92934b79409638cf220de3002fea8d505Adam LesinskiResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) { 3480978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mName = entry.mName; 3481978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mParent = entry.mParent; 3482978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mType = entry.mType; 3483978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mItem = entry.mItem; 3484978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mItemFormat = entry.mItemFormat; 3485978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mBag = entry.mBag; 3486978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mNameIndex = entry.mNameIndex; 3487978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mParentId = entry.mParentId; 3488978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mPos = entry.mPos; 3489978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski return *this; 3490978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski} 3491978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski 3492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) 3493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_UNKNOWN) { 3498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_BAG; 3499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined as a single item.\n" 3502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, 3509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 3510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t format, 3512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 3513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, false, value, style); 3515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 351743a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski if (mBag.size() == 0) { 351843a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.", 351943a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string()); 352043a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } else { 352143a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const Item& item(mBag.valueAt(0)); 352243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.\n" 352343a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski "%s:%d: Originally defined here.\n", 352443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string(), 352543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 352643a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } 3527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { 3530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined.\n" 3531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_ITEM; 3538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem = item; 3539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItemFormat = format; 3540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, 3544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key, const String16& value, 3545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, int32_t format) 3547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, isId, value, style, format); 3554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX NOTE: there is an error if you try to have a bag with two keys, 3556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one an attr and one an id, with the same name. Not something we 3557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // currently ever have to worry about. 3558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t origKey = mBag.indexOfKey(key); 3559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (origKey >= 0) { 3560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!replace) { 3561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& item(mBag.valueAt(origKey)); 3562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s already has bag item %s.\n" 3563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(key).string(), 3565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 3566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Replacing %s with %s\n", 3569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mBag.valueFor(key).value).string(), String8(value).string()); 3570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.replaceValueFor(key, item); 3571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.add(key, item); 3574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 357782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::Entry::removeFromBag(const String16& key) { 357882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mType != Entry::TYPE_BAG) { 357982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 358082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 358182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 358282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mBag.removeItem(key) >= 0) { 358382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 358482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 358582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return UNKNOWN_ERROR; 358682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 358782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos) 3589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.clear(); 3596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table, 3600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.isId) { 3609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->hasBagOrEntry(key, &id16, &package)) { 3610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value("false"); 361187332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe if (kIsDebug) { 361287332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe fprintf(stderr, "Generating %s:id/%s\n", 361387332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe String8(package).string(), 361487332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe String8(key).string()); 361587332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe } 3616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, 3617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id16, key, value); 3618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!table->hasBagOrEntry(key, &attr16, &package)) { 3623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 1 3625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", 3626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// String8(key).string()); 3627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// const Item& item(mBag.valueAt(i)); 3628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "Referenced from file %s line %d\n", 3629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// item.sourcePos.file.string(), item.sourcePos.line); 3630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// return UNKNOWN_ERROR; 3631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 3632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 3633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", ResTable_map::TYPE_ANY); 3634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addBag(SourcePos("<generated>", 0), package, 3635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, key, String16(""), 3636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 3637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 3638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 3642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, 36482412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe const String16& /* package */) 3649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 3651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* errorMsg; 3654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 3655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = 0; 3658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParent.size() > 0) { 3659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); 3660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParentId == 0) { 3661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error retrieving parent for item: %s '%s'.\n", 3662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorMsg, String8(mParent).string()); 3663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.bagKeyId = table->getResId(key, 3671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.isId ? &id16 : &attr16, NULL, &errorMsg); 3672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); 3673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 3674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, 3675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(it.isId ? id16 : attr16).string(), 3676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(key).string()); 3677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 36812412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 3682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table, 3685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8* configTypeName, const ConfigDescription* config) 3686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value)); 3690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, 0, 3692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, mItemFormat, 3693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(key), String8(it.value)); 3702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, it.bagKeyId, 3704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, it.format, 3705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::remapStringValue(StringPool* strings) 3718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37402412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampessize_t ResourceTable::Entry::flatten(Bundle* /* bundle */, const sp<AaptFile>& data, bool isPublic) 3741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t amt = 0; 3743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_entry header; 3744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.size = htods(sizeof(header)); 37462412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe const type ty = mType; 37472412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (ty == TYPE_BAG) { 37482412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe header.flags |= htods(header.FLAG_COMPLEX); 3749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 37502412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (isPublic) { 37512412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe header.flags |= htods(header.FLAG_PUBLIC); 37522412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 37532412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe header.key.index = htodl(mNameIndex); 3754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty != TYPE_BAG) { 3755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&header, sizeof(header)); 3756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mItem; 3762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value par; 3763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&par, 0, sizeof(par)); 3764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.size = htods(it.parsedValue.size); 3765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.dataType = it.parsedValue.dataType; 3766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.res0 = it.parsedValue.res0; 3767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.data = htodl(it.parsedValue.data); 3768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", 3770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), it.parsedValue.dataType, 3771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data, par.res0); 3772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&par, it.parsedValue.size); 3774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += it.parsedValue.size; 3779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mBag.size(); 3781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create correct ordering of items. 3783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<uint32_t, const Item*> items; 3784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items.add(it.bagKeyId, &it); 3787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = items.size(); 3789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map_entry mapHeader; 3791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(&mapHeader, &header, sizeof(header)); 3792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.size = htods(sizeof(mapHeader)); 3793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.parent.ident = htodl(mParentId); 3794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.count = htodl(N); 3795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&mapHeader, sizeof(mapHeader)); 3796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = *items.valueAt(i); 3803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map map; 3804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.name.ident = htodl(it.bagKeyId); 3805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.size = htods(it.parsedValue.size); 3806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.dataType = it.parsedValue.dataType; 3807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.res0 = it.parsedValue.res0; 3808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.data = htodl(it.parsedValue.data); 3809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&map, sizeof(map)); 3810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += sizeof(map); 3815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendComment(const String16& comment, 3821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 3822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyIfEmpty && mComment.size() > 0) { 3827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mComment.size() > 0) { 3830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(String16("\n")); 3831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(comment); 3833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendTypeComment(const String16& comment) 3836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mTypeComment.size() > 0) { 3841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(String16("\n")); 3842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(comment); 3844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, 3847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 3848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 3849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t entryIdx = Res_GETENTRY(ident); 3852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryIdx < 0) { 3853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", 3854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), ident); 3855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t typeIdx = Res_GETTYPE(ident); 3860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 3861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdx++; 3862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublicIndex > 0 && mPublicIndex != typeIdx) { 3863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting type codes for its" 3864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " public identifiers (0x%x vs 0x%x).\n", 3865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), 3866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex, typeIdx); 3867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex = typeIdx; 3870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFirstPublicSourcePos == NULL) { 3873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFirstPublicSourcePos = new SourcePos(sourcePos); 3874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublic.indexOfKey(name) < 0) { 3877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublic.add(name, Public(sourcePos, String16(), ident)); 3878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Public& p = mPublic.editValueFor(name); 3880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p.ident != ident) { 3881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting public identifiers" 3882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " (0x%08x vs 0x%08x).\n" 3883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), p.ident, ident, 3885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.file.string(), p.sourcePos.line); 3886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::Type::canAddEntry(const String16& name) 3894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanAddEntries.add(name); 3896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, 3899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 3901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex, 3902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 3903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool autoAddOverlay) 3904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pos = -1; 3906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = mConfigs.valueFor(entry); 3907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) { 3909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource at %s appears in overlay but not" 3910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " in the base package; use <add-resource> to add.\n", 3911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(entry).string()); 3912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c = new ConfigList(entry, sourcePos); 3915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mConfigs.add(entry, c); 3916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos = (int)mOrderedConfigs.size(); 3917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.add(c); 3918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(pos); 3920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 3924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 3925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 3927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 39282412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 39292412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (config != NULL) { 39302412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " 3931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 39322412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe "sw%ddp w%ddp h%ddp layout:%d\n", 3933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line, 3934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->mcc, config->mnc, 3935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[0] ? config->language[0] : '-', 3936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[1] ? config->language[1] : '-', 3937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[0] ? config->country[0] : '-', 3938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[1] ? config->country[1] : '-', 3939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->orientation, 3940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->touchscreen, 3941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->density, 3942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->keyboard, 3943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->inputFlags, 3944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->navigation, 3945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidth, 3946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeight, 3947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->smallestScreenWidthDp, 3948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidthDp, 3949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeightDp, 39502412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe config->screenLayout); 39512412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } else { 39522412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("New entry at %s:%d: NULL config\n", 39532412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe sourcePos.file.string(), sourcePos.line); 39542412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 3955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e = new Entry(entry, sourcePos); 3957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->addEntry(cdesc, e); 3958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 3959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 3961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) { 3962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedConfigs[pos] == c) { 3963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= (int)mOrderedConfigs.size()) { 3967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry"); 3968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setEntryIndex(pos); 3972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 3974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 3977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 39799b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskisp<ResourceTable::ConfigList> ResourceTable::Type::removeEntry(const String16& entry) { 39809b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski ssize_t idx = mConfigs.indexOfKey(entry); 39819b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (idx < 0) { 39829b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return NULL; 39839b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 39849b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 39859b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<ConfigList> removed = mConfigs.valueAt(idx); 39869b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mConfigs.removeItemsAt(idx); 39879b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 39889b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Vector<sp<ConfigList> >::iterator iter = std::find( 39899b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.begin(), mOrderedConfigs.end(), removed); 39909b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (iter != mOrderedConfigs.end()) { 39919b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.erase(iter); 39929b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 39939b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 39949b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mPublic.removeItem(entry); 39959b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return removed; 39969b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 39979b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 39989b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam LesinskiSortedVector<ConfigDescription> ResourceTable::Type::getUniqueConfigs() const { 39999b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski SortedVector<ConfigDescription> unique; 40009b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t entryCount = mOrderedConfigs.size(); 40019b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < entryCount; i++) { 40029b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mOrderedConfigs[i] == NULL) { 40039b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 40049b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 40059b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configs = 40069b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs[i]->getEntries(); 40079b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t configCount = configs.size(); 40089b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t j = 0; j < configCount; j++) { 40099b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski unique.add(configs.keyAt(j)); 40109b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 40119b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 40129b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return unique; 40139b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 40149b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 4015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::applyPublicEntryOrder() 4016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedConfigs.size(); 4018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<ConfigList> > origOrder(mOrderedConfigs); 4019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasError = false; 4020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(NULL, i); 4024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NP = mPublic.size(); 4027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordering %d configs from %d public defs\n", N, NP); 4028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 4029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j=0; j<NP; j++) { 4030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name = mPublic.keyAt(j); 4031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Public& p = mPublic.valueAt(j); 4032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = Res_GETENTRY(p.ident); 4033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", 4034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mName).string(), String8(name).string(), p.ident, N); 4035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool found = false; 4036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 4038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); 4039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getName() == name) { 4040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx >= (int32_t)mOrderedConfigs.size()) { 40419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.resize(idx + 1); 40429b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 40439b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 40449b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mOrderedConfigs.itemAt(idx) == NULL) { 4045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublic(true); 4046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublicSourcePos(p.sourcePos); 4047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, idx); 4048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 4049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 4050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski found = true; 4051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> oe = mOrderedConfigs.itemAt(idx); 4054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Multiple entry names declared for public entry" 4056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x in type %s (%s vs %s).\n" 4057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 4058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx+1, String8(mName).string(), 4059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(oe->getName()).string(), 4060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), 4061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().file.string(), 4062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().line); 4063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 4064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!found) { 4069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public symbol %s/%s declared here is not defined.", 4070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string()); 4071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 4072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size()); 4076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != origOrder.size()) { 4078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Internal error: remaining private symbol count mismatch\n"); 4079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = origOrder.size(); 4080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j = 0; 4083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 40849b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<ConfigList>& e = origOrder.itemAt(i); 4085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining entries. 4086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedConfigs.itemAt(j) != NULL) { 4087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 4088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, j); 4090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 4091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 40932412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasError ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 4094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4096833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::Package::Package(const String16& name, size_t packageId) 4097833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mName(name), mPackageId(packageId), 4098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeStringsMapping(0xffffffff), 4099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mKeyStringsMapping(0xffffffff) 4100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type, 4104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = mTypes.valueFor(type); 4108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 4109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = new Type(type, sourcePos); 4110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypes.add(type, t); 4111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(t); 4112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 4113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For some reason the type's index is set to one plus the index 4114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the mOrderedTypes list, rather than just the index. 4115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->setIndex(mOrderedTypes.size()); 4116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t; 4119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data) 4122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping); 4124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 4125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Type string data is corrupt!\n"); 412657079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 4127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 412857079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 412957079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 413057079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 413157079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mTypeStringsData = data; 413257079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 4133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data) 4136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping); 4138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 4139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Key string data is corrupt!\n"); 414057079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 4141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 414257079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 414357079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 414457079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 414557079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mKeyStringsData = data; 414657079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 4147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data, 4150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResStringPool* strings, 4151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t>* mappings) 4152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data->getData() == NULL) { 4154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 4155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = strings->setTo(data->getData(), data->getSize()); 4158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 4159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = strings->size(); 4160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 4162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mappings->add(String16(strings->stringAt(i, &len)), i); 4163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 4166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::applyPublicTypeOrder() 4169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedTypes.size(); 4171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Type> > origOrder(mOrderedTypes); 4172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(NULL, i); 4176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 4180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = t->getPublicIndex(); 4181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx > 0) { 4182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx--; 4183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (idx >= (int32_t)mOrderedTypes.size()) { 4184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(); 4185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedTypes.itemAt(idx) != NULL) { 4187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> ot = mOrderedTypes.itemAt(idx); 4188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->getFirstPublicSourcePos().error("Multiple type names declared for public type" 4189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x (%s vs %s).\n" 4190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 4191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx, String8(ot->getName()).string(), 4192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 4193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().file.string(), 4194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().line); 4195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 4196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, idx); 4198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 4199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i--; 4200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 4201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j=0; 4205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 42069b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<Type>& t = origOrder.itemAt(i); 4207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining types. 4208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedTypes.itemAt(j) != NULL) { 4209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 4210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, j); 4212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 4215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 42179b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskivoid ResourceTable::Package::movePrivateAttrs() { 42189b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Type> attr = mTypes.valueFor(String16("attr")); 42199b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (attr == NULL) { 42209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Nothing to do. 42219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return; 42229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Vector<sp<ConfigList> > privateAttrs; 42259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42269b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski bool hasPublic = false; 42279b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const Vector<sp<ConfigList> >& configs = attr->getOrderedConfigs(); 42289b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t configCount = configs.size(); 42299b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < configCount; i++) { 42309b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (configs[i] == NULL) { 42319b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 42329b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42339b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42349b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (attr->isPublic(configs[i]->getName())) { 42359b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski hasPublic = true; 42369b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } else { 42379b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski privateAttrs.add(configs[i]); 42389b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42399b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42409b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Only if we have public attributes do we create a separate type for 42429b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // private attributes. 42439b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (!hasPublic) { 42449b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return; 42459b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42469b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42479b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Create a new type for private attributes. 42489b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Type> privateAttrType = getType(String16(kAttrPrivateType), SourcePos()); 42499b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42509b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t privateAttrCount = privateAttrs.size(); 42519b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < privateAttrCount; i++) { 42529b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const sp<ConfigList>& cl = privateAttrs[i]; 42539b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42549b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Remove the private attributes from their current type. 42559b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski attr->removeEntry(cl->getName()); 42569b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42579b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Add it to the new type. 42589b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = cl->getEntries(); 42599b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t entryCount = entries.size(); 42609b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t j = 0; j < entryCount; j++) { 42619b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const sp<Entry>& oldEntry = entries[j]; 42629b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Entry> entry = privateAttrType->getEntry( 42639b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski cl->getName(), oldEntry->getPos(), &entries.keyAt(j)); 42649b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski *entry = *oldEntry; 42659b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42669b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42679b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Move the symbols to the new type. 42689b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 42699b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 42709b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 42719b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 4272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) 4273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4274833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package != mAssetsPackage) { 4275833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NULL; 4276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4277833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return mPackages.valueFor(package); 4278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::getType(const String16& package, 4281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = getPackage(package); 4286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return p->getType(type, sourcePos, doSetIndex); 4290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, 4293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 4295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 4297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 4298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos, doSetIndex); 4301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 4302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay()); 4305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4307e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskisp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package, 4308e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& type, const String16& name) const 4309e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski{ 4310e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t packageCount = mOrderedPackages.size(); 4311e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 4312e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Package>& p = mOrderedPackages[pi]; 4313e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (p == NULL || p->getName() != package) { 4314e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4315e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4316e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4317e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<Type> >& types = p->getOrderedTypes(); 4318e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t typeCount = types.size(); 4319e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 4320e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Type>& t = types[ti]; 4321e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (t == NULL || t->getName() != type) { 4322e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4323e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4324e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4325e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs(); 4326e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t configCount = configs.size(); 4327e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 4328e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<ConfigList>& cl = configs[ci]; 4329e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (cl == NULL || cl->getName() != name) { 4330e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4331e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4332e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4333e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return cl; 4334e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4335e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4336e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4337e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NULL; 4338e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4339e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, 4341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config) const 4342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4343833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski size_t pid = Res_GETPACKAGE(resID)+1; 4344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 4345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p; 4346833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; i++) { 4347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> check = mOrderedPackages[i]; 4348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (check->getAssignedId() == pid) { 4349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = check; 4350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Package not found for resource #%08x\n", resID); 4356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int tid = Res_GETTYPE(resID); 4360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) { 4361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Type not found for resource #%08x\n", resID); 4362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes()[tid]; 4365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int eid = Res_GETENTRY(resID); 4367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) { 4368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs()[eid]; 4373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 4379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 4380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 4381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID); 4383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 4387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const 4390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 4393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = e->getBag().valueAt(i); 4399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 4400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n", 4401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == attrID) { 4405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ⁢ 4406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getItemValue( 4413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resID, uint32_t attrID, Res_value* outValue) 4414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item* item = getItem(resID, attrID); 4416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = false; 4418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item != NULL) { 4419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item->evaluating) { 4420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&e->getBag().valueAt(i) == item) { 4425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n", 4429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 4432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = true; 4434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId); 44352412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 4437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", 4438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID, String8(getEntry(resID)->getName()).string(), 4439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType, outValue->data); 4440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x]: failed\n", 4442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID); 4443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 44442412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 4445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = false; 4446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 4448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 444982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 445082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 445128994d8d181c286b39811441ce78399576c2d315Adam Lesinski * Returns the SDK version at which the attribute was 445228994d8d181c286b39811441ce78399576c2d315Adam Lesinski * made public, or -1 if the resource ID is not an attribute 445328994d8d181c286b39811441ce78399576c2d315Adam Lesinski * or is not public. 445482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 445528994d8d181c286b39811441ce78399576c2d315Adam Lesinskiint ResourceTable::getPublicAttributeSdkLevel(uint32_t attrId) const { 445628994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (Res_GETPACKAGE(attrId) + 1 != 0x01 || Res_GETTYPE(attrId) + 1 != 0x01) { 445728994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 445882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 445982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 446082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski uint32_t specFlags; 446182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (!mAssets->getIncludedResources().getResourceFlags(attrId, &specFlags)) { 446228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 446328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 446428994d8d181c286b39811441ce78399576c2d315Adam Lesinski 446528994d8d181c286b39811441ce78399576c2d315Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 446628994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 446728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 446828994d8d181c286b39811441ce78399576c2d315Adam Lesinski 446928994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t entryId = Res_GETENTRY(attrId); 447028994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (entryId <= 0x021c) { 447128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 1; 447228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x021d) { 447328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 2; 447428994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0269) { 447528994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_CUPCAKE; 447628994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x028d) { 447728994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_DONUT; 447828994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02ad) { 447928994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR; 448028994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02b3) { 448128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR_0_1; 448228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02b5) { 448328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR_MR1; 448428994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02bd) { 448528994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_FROYO; 448628994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02cb) { 448728994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_GINGERBREAD; 448828994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0361) { 448928994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB; 449028994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0366) { 449128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB_MR1; 449228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03a6) { 449328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB_MR2; 449428994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03ae) { 449528994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN; 449628994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03cc) { 449728994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN_MR1; 449828994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03da) { 449928994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN_MR2; 450028994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03f1) { 450128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_KITKAT; 450228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03f6) { 450328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_KITKAT_WATCH; 450428994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x04ce) { 450528994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_LOLLIPOP; 450628994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else { 450728994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Anything else is marked as defined in 450828994d8d181c286b39811441ce78399576c2d315Adam Lesinski // SDK_LOLLIPOP_MR1 since after this 450928994d8d181c286b39811441ce78399576c2d315Adam Lesinski // version no attribute compat work 451028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // needs to be done. 451128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_LOLLIPOP_MR1; 451282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 451382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 451482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 451528994d8d181c286b39811441ce78399576c2d315Adam Lesinski/** 451628994d8d181c286b39811441ce78399576c2d315Adam Lesinski * First check the Manifest, then check the command line flag. 451728994d8d181c286b39811441ce78399576c2d315Adam Lesinski */ 451828994d8d181c286b39811441ce78399576c2d315Adam Lesinskistatic int getMinSdkVersion(const Bundle* bundle) { 451928994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (bundle->getManifestMinSdkVersion() != NULL && strlen(bundle->getManifestMinSdkVersion()) > 0) { 452028994d8d181c286b39811441ce78399576c2d315Adam Lesinski return atoi(bundle->getManifestMinSdkVersion()); 452128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) { 452228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return atoi(bundle->getMinSdkVersion()); 4523e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 452428994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 0; 4525e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4526e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4527beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinskibool ResourceTable::shouldGenerateVersionedResource( 4528beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski const sp<ResourceTable::ConfigList>& configList, 4529beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski const ConfigDescription& sourceConfig, 4530beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski const int sdkVersionToGenerate) { 4531f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski assert(sdkVersionToGenerate > sourceConfig.sdkVersion); 4532526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski assert(configList != NULL); 4533f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries 4534f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski = configList->getEntries(); 4535f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski ssize_t idx = entries.indexOfKey(sourceConfig); 4536f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski 4537f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski // The source config came from this list, so it should be here. 4538f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski assert(idx >= 0); 4539f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski 4540beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // The next configuration either only varies in sdkVersion, or it is completely different 4541beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // and therefore incompatible. If it is incompatible, we must generate the versioned resource. 4542f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski 4543beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // NOTE: The ordering of configurations takes sdkVersion as higher precedence than other 4544beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // qualifiers, so we need to iterate through the entire list to be sure there 4545beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // are no higher sdk level versions of this resource. 4546f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski ConfigDescription tempConfig(sourceConfig); 4547beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski for (size_t i = static_cast<size_t>(idx) + 1; i < entries.size(); i++) { 4548beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski const ConfigDescription& nextConfig = entries.keyAt(i); 4549beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski tempConfig.sdkVersion = nextConfig.sdkVersion; 4550beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski if (tempConfig == nextConfig) { 4551beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // The two configs are the same, check the sdk version. 4552beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski return sdkVersionToGenerate < nextConfig.sdkVersion; 4553beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski } 4554f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski } 4555beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski 4556beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski // No match was found, so we should generate the versioned resource. 4557beb9e33bfb79847c25aac98e39f3ea620a953ef7Adam Lesinski return true; 4558f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski} 4559f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski 456082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 456182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Modifies the entries in the resource table to account for compatibility 456282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * issues with older versions of Android. 456382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 456482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * This primarily handles the issue of private/public attribute clashes 456582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * in framework resources. 456682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 456782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * AAPT has traditionally assigned resource IDs to public attributes, 456882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * and then followed those public definitions with private attributes. 456982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 457082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 457182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 457282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 457382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 457482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 457582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/secret 457682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/shhh 457782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 457882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Each release, when attributes are added, they take the place of the private 457982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attributes and the private attributes are shifted down again. 458082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 458182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 458282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 458382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 458482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/shinyNewAttr 458582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/highlyValuedFeature 458682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 458782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 458882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010238 | attr/secret 458982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010239 | attr/shhh 459082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 459182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Platform code may look for private attributes set in a theme. If an app 459282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * compiled against a newer version of the platform uses a new public 459382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute that happens to have the same ID as the private attribute 459482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * the older platform is expecting, then the behavior is undefined. 459582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 459682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * We get around this by detecting any newly defined attributes (in L), 459782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * copy the resource into a -v21 qualified resource, and delete the 459882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute from the original resource. This ensures that older platforms 459982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * don't see the new attribute, but when running on L+ platforms, the 460082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute will be respected. 460182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 460282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle) { 460328994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int minSdk = getMinSdkVersion(bundle); 460428994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (minSdk >= SDK_LOLLIPOP_MR1) { 460528994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Lollipop MR1 and up handles public attributes differently, no 460628994d8d181c286b39811441ce78399576c2d315Adam Lesinski // need to do any compat modifications. 4607e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 460882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 460982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 461082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const String16 attr16("attr"); 461182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 461282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t packageCount = mOrderedPackages.size(); 461382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 461482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 461582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (p == NULL || p->getTypes().size() == 0) { 461682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Empty, skip! 461782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 461882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 461982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 462082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 462182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 462282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 462382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (t == NULL) { 462482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 462582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 462682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 462782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t configCount = t->getOrderedConfigs().size(); 462882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 462982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 463082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (c == NULL) { 463182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 463282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 463382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 463482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski Vector<key_value_pair_t<ConfigDescription, sp<Entry> > > entriesToAdd; 463582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = 463682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski c->getEntries(); 463782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entryCount = entries.size(); 463882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ei = 0; ei < entryCount; ei++) { 46399b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<Entry>& e = entries.valueAt(ei); 464082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (e == NULL || e->getType() != Entry::TYPE_BAG) { 464182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 464282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 464382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 464482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const ConfigDescription& config = entries.keyAt(ei); 464528994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (config.sdkVersion >= SDK_LOLLIPOP_MR1) { 464682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 464782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 464882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 464928994d8d181c286b39811441ce78399576c2d315Adam Lesinski KeyedVector<int, Vector<String16> > attributesToRemove; 465082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const KeyedVector<String16, Item>& bag = e->getBag(); 465182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t bagCount = bag.size(); 465282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t bi = 0; bi < bagCount; bi++) { 465382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const uint32_t attrId = getResId(bag.keyAt(bi), &attr16); 465428994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = getPublicAttributeSdkLevel(attrId); 465528994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) { 465628994d8d181c286b39811441ce78399576c2d315Adam Lesinski AaptUtil::appendValue(attributesToRemove, sdkLevel, bag.keyAt(bi)); 465782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 465882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 465982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 466082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (attributesToRemove.isEmpty()) { 466182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 466282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 466382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 466428994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t sdkCount = attributesToRemove.size(); 466528994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t i = 0; i < sdkCount; i++) { 466628994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = attributesToRemove.keyAt(i); 466728994d8d181c286b39811441ce78399576c2d315Adam Lesinski 4668f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski if (!shouldGenerateVersionedResource(c, config, sdkLevel)) { 4669f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski // There is a style that will override this generated one. 4670f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski continue; 4671f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski } 4672f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski 467328994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Duplicate the entry under the same configuration 467428994d8d181c286b39811441ce78399576c2d315Adam Lesinski // but with sdkVersion == sdkLevel. 467528994d8d181c286b39811441ce78399576c2d315Adam Lesinski ConfigDescription newConfig(config); 467628994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion = sdkLevel; 467728994d8d181c286b39811441ce78399576c2d315Adam Lesinski 467828994d8d181c286b39811441ce78399576c2d315Adam Lesinski sp<Entry> newEntry = new Entry(*e); 467928994d8d181c286b39811441ce78399576c2d315Adam Lesinski 468028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Remove all items that have a higher SDK level than 468128994d8d181c286b39811441ce78399576c2d315Adam Lesinski // the one we are synthesizing. 468228994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t j = 0; j < sdkCount; j++) { 468328994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (j == i) { 468428994d8d181c286b39811441ce78399576c2d315Adam Lesinski continue; 468528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 468628994d8d181c286b39811441ce78399576c2d315Adam Lesinski 468728994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (attributesToRemove.keyAt(j) > sdkLevel) { 468828994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t attrCount = attributesToRemove[j].size(); 468928994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t k = 0; k < attrCount; k++) { 469028994d8d181c286b39811441ce78399576c2d315Adam Lesinski newEntry->removeFromBag(attributesToRemove[j][k]); 469128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 469228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 469328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 469428994d8d181c286b39811441ce78399576c2d315Adam Lesinski 469528994d8d181c286b39811441ce78399576c2d315Adam Lesinski entriesToAdd.add(key_value_pair_t<ConfigDescription, sp<Entry> >( 469628994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig, newEntry)); 469728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 469882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 469982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Remove the attribute from the original. 470082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < attributesToRemove.size(); i++) { 470128994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t j = 0; j < attributesToRemove[i].size(); j++) { 470228994d8d181c286b39811441ce78399576c2d315Adam Lesinski e->removeFromBag(attributesToRemove[i][j]); 470328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 470482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 470582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 470682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 470782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entriesToAddCount = entriesToAdd.size(); 470882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < entriesToAddCount; i++) { 4709f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski assert(entries.indexOfKey(entriesToAdd[i].key) < 0); 471082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 4711f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski if (bundle->getVerbose()) { 4712f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski entriesToAdd[i].value->getPos() 4713f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski .printf("using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 471428994d8d181c286b39811441ce78399576c2d315Adam Lesinski entriesToAdd[i].key.sdkVersion, 4715f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(p->getName()).string(), 4716f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(t->getName()).string(), 4717f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(entriesToAdd[i].value->getName()).string(), 4718f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski entriesToAdd[i].key.toString().string()); 4719f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski } 472082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 4721978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski sp<Entry> newEntry = t->getEntry(c->getName(), 4722978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski entriesToAdd[i].value->getPos(), 4723978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski &entriesToAdd[i].key); 4724978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski 4725978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski *newEntry = *entriesToAdd[i].value; 472682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 472782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 472882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 472982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 473082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 473182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 4732e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4733e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle, 4734e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 4735e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptFile>& target, 4736e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<XMLNode>& root) { 47376e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski const String16 vector16("vector"); 47386e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski const String16 animatedVector16("animated-vector"); 47396e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski 474028994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int minSdk = getMinSdkVersion(bundle); 474128994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (minSdk >= SDK_LOLLIPOP_MR1) { 474228994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Lollipop MR1 and up handles public attributes differently, no 474328994d8d181c286b39811441ce78399576c2d315Adam Lesinski // need to do any compat modifications. 4744e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4745e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4746e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 474728994d8d181c286b39811441ce78399576c2d315Adam Lesinski const ConfigDescription config(target->getGroupEntry().toParams()); 474828994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (target->getResourceType() == "" || config.sdkVersion >= SDK_LOLLIPOP_MR1) { 47496e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski // Skip resources that have no type (AndroidManifest.xml) or are already version qualified 47506e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski // with v21 or higher. 4751e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4752e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4753e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4754ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski sp<XMLNode> newRoot = NULL; 4755f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski int sdkVersionToGenerate = SDK_LOLLIPOP_MR1; 4756e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4757e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski Vector<sp<XMLNode> > nodesToVisit; 4758e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(root); 4759e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski while (!nodesToVisit.isEmpty()) { 4760e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<XMLNode> node = nodesToVisit.top(); 4761e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.pop(); 4762e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 47636e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski if (bundle->getNoVersionVectors() && (node->getElementName() == vector16 || 47646e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski node->getElementName() == animatedVector16)) { 47656e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski // We were told not to version vector tags, so skip the children here. 47666e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski continue; 47676e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski } 47686e46056abc1c2803ed7f195bab169bbb1cacec6bAdam Lesinski 4769e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes(); 4770ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski for (size_t i = 0; i < attrs.size(); i++) { 4771e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const XMLNode::attribute_entry& attr = attrs[i]; 477228994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = getPublicAttributeSdkLevel(attr.nameResId); 477328994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) { 4774ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (newRoot == NULL) { 4775ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski newRoot = root->clone(); 4776ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski } 4777ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski 477828994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Find the smallest sdk version that we need to synthesize for 477928994d8d181c286b39811441ce78399576c2d315Adam Lesinski // and do that one. Subsequent versions will be processed on 478028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // the next pass. 4781f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate); 478228994d8d181c286b39811441ce78399576c2d315Adam Lesinski 4783ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (bundle->getVerbose()) { 4784ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski SourcePos(node->getFilename(), node->getStartLineNumber()).printf( 4785ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski "removing attribute %s%s%s from <%s>", 4786ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(attr.ns).string(), 4787ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski (attr.ns.size() == 0 ? "" : ":"), 4788ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(attr.name).string(), 4789ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(node->getElementName()).string()); 4790ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski } 4791ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski node->removeAttribute(i); 4792ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski i--; 4793e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4794e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4795e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4796e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule a visit to the children. 4797e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<XMLNode> >& children = node->getChildren(); 4798e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t childCount = children.size(); 4799e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t i = 0; i < childCount; i++) { 4800e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(children[i]); 4801e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4802e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4803e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4804ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (newRoot == NULL) { 4805e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4806e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4807e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4808e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Look to see if we already have an overriding v21 configuration. 4809e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), 4810e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), resourceName); 4811f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) { 4812e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // We don't have an overriding entry for v21, so we must duplicate this one. 4813f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski ConfigDescription newConfig(config); 4814f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski newConfig.sdkVersion = sdkVersionToGenerate; 4815e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), 4816e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski AaptGroupEntry(newConfig), target->getResourceType()); 481707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8 resPath = String8::format("res/%s/%s.xml", 4818e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newFile->getGroupEntry().toDirName(target->getResourceType()).string(), 481907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8(resourceName).string()); 4820e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resPath.convertToResPath(); 4821e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4822e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Add a resource table entry. 4823f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski if (bundle->getVerbose()) { 4824f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski SourcePos(target->getSourceFile(), -1).printf( 4825f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski "using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 482628994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion, 4827f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski mAssets->getPackage().string(), 4828f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski newFile->getResourceType().string(), 4829f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(resourceName).string(), 4830f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski newConfig.toString().string()); 4831f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski } 4832e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4833e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski addEntry(SourcePos(), 4834e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(mAssets->getPackage()), 4835e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), 4836e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resourceName, 4837e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(resPath), 4838e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski NULL, 4839e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski &newConfig); 4840e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4841e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule this to be compiled. 4842e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski CompileResourceWorkItem item; 4843e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resourceName = resourceName; 4844e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resPath = resPath; 4845e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.file = newFile; 484607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski item.xmlRoot = newRoot; 484707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski item.needsCompiling = false; // This step occurs after we parse/assign, so we don't need 484807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // to do it again. 4849e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski mWorkQueue.push(item); 4850e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4851e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4852e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4853de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4854f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinskivoid ResourceTable::getDensityVaryingResources( 4855f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { 4856de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const ConfigDescription nullConfig; 4857de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4858de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t packageCount = mOrderedPackages.size(); 4859de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t p = 0; p < packageCount; p++) { 4860de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes(); 4861de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t typeCount = types.size(); 4862de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t t = 0; t < typeCount; t++) { 4863081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski const sp<Type>& type = types[t]; 4864081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski if (type == NULL) { 4865081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski continue; 4866081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski } 4867081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski 4868081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski const Vector<sp<ConfigList> >& configs = type->getOrderedConfigs(); 4869de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t configCount = configs.size(); 4870de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t c = 0; c < configCount; c++) { 4871081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski const sp<ConfigList>& configList = configs[c]; 4872081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski if (configList == NULL) { 4873081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski continue; 4874081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski } 4875081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski 4876f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries 4877081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski = configList->getEntries(); 4878de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t configEntryCount = configEntries.size(); 4879de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t ce = 0; ce < configEntryCount; ce++) { 4880081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski const sp<Entry>& entry = configEntries.valueAt(ce); 4881081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski if (entry == NULL) { 4882081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski continue; 4883081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski } 4884081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski 4885de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const ConfigDescription& config = configEntries.keyAt(ce); 4886de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (AaptConfig::isDensityOnly(config)) { 4887de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // This configuration only varies with regards to density. 4888f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski const Symbol symbol( 4889f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski mOrderedPackages[p]->getName(), 4890081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski type->getName(), 4891081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski configList->getName(), 4892f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski getResId(mOrderedPackages[p], types[t], 4893081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski configList->getEntryIndex())); 4894081d1b4cf602fdd7302b597e6bf902cb415bc3a8Adam Lesinski 4895de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4896f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski AaptUtil::appendValue(resources, symbol, 4897f45d2fad2ecd3cb3c4aeee3014763e01b59eab09Adam Lesinski SymbolDefinition(symbol, config, entry->getPos())); 4898de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4899de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4900de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4901de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4902de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4903de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski} 490407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 490507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinskistatic String16 buildNamespace(const String16& package) { 490607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return String16("http://schemas.android.com/apk/res/") + package; 490707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski} 490807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 490907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinskistatic sp<XMLNode> findOnlyChildElement(const sp<XMLNode>& parent) { 491007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const Vector<sp<XMLNode> >& children = parent->getChildren(); 491107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski sp<XMLNode> onlyChild; 491207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 491307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (children[i]->getType() != XMLNode::TYPE_CDATA) { 491407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (onlyChild != NULL) { 491507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return NULL; 491607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 491707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski onlyChild = children[i]; 491807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 491907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 492007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return onlyChild; 492107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski} 492207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 492307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski/** 492407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * Detects use of the `bundle' format and extracts nested resources into their own top level 492507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * resources. The bundle format looks like this: 492607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * 492707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <!-- res/drawable/bundle.xml --> 492807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <animated-vector xmlns:aapt="http://schemas.android.com/aapt"> 492907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <aapt:attr name="android:drawable"> 493007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <vector android:width="60dp" 493107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:height="60dp"> 493207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <path android:name="v" 493307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:fillColor="#000000" 493407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:pathData="M300,70 l 0,-70 70,..." /> 493507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * </vector> 493607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * </aapt:attr> 493707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * </animated-vector> 493807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * 493907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * When AAPT sees the <aapt:attr> tag, it will extract its single element and its children 494007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * into a new high-level resource, assigning it a name and ID. Then value of the `name` 494107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * attribute must be a resource attribute. That resource attribute is inserted into the parent 494207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * with the reference to the extracted resource as the value. 494307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * 494407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <!-- res/drawable/bundle.xml --> 494507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <animated-vector android:drawable="@drawable/bundle_1.xml"> 494607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * </animated-vector> 494707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * 494807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <!-- res/drawable/bundle_1.xml --> 494907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <vector android:width="60dp" 495007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:height="60dp"> 495107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * <path android:name="v" 495207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:fillColor="#000000" 495307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * android:pathData="M300,70 l 0,-70 70,..." /> 495407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski * </vector> 495507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski */ 495607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinskistatus_t ResourceTable::processBundleFormat(const Bundle* bundle, 495707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16& resourceName, 495807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<AaptFile>& target, 495907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<XMLNode>& root) { 496007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski Vector<sp<XMLNode> > namespaces; 496107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (root->getType() == XMLNode::TYPE_NAMESPACE) { 496207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski namespaces.push(root); 496307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 496407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return processBundleFormatImpl(bundle, resourceName, target, root, &namespaces); 496507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski} 496607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 496707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinskistatus_t ResourceTable::processBundleFormatImpl(const Bundle* bundle, 496807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16& resourceName, 496907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<AaptFile>& target, 497007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<XMLNode>& parent, 497107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski Vector<sp<XMLNode> >* namespaces) { 497207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16 kAaptNamespaceUri16("http://schemas.android.com/aapt"); 497307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16 kName16("name"); 497407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16 kAttr16("attr"); 497507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const String16 kAssetPackage16(mAssets->getPackage()); 497607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 497707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski Vector<sp<XMLNode> >& children = parent->getChildren(); 497807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 497907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<XMLNode>& child = children[i]; 498007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 498107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (child->getType() == XMLNode::TYPE_CDATA) { 498207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski continue; 498307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } else if (child->getType() == XMLNode::TYPE_NAMESPACE) { 498407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski namespaces->push(child); 498507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 498607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 498707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (child->getElementNamespace() != kAaptNamespaceUri16 || 498807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski child->getElementName() != kAttr16) { 498907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski status_t result = processBundleFormatImpl(bundle, resourceName, target, child, 499007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski namespaces); 499107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (result != NO_ERROR) { 499207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return result; 499307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 499407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 499507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (child->getType() == XMLNode::TYPE_NAMESPACE) { 499607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski namespaces->pop(); 499707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 499807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski continue; 499907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 500007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 500107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // This is the <aapt:attr> tag. Look for the 'name' attribute. 500207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski SourcePos source(child->getFilename(), child->getStartLineNumber()); 500307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 500407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski sp<XMLNode> nestedRoot = findOnlyChildElement(child); 500507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (nestedRoot == NULL) { 500607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source.error("<%s:%s> must have exactly one child element", 500707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8(child->getElementNamespace()).string(), 500807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8(child->getElementName()).string()); 500907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 501007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 501107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 501207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Find the special attribute 'parent-attr'. This attribute's value contains 501307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // the resource attribute for which this element should be assigned in the parent. 501407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const XMLNode::attribute_entry* attr = child->getAttribute(String16(), kName16); 501507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (attr == NULL) { 501607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source.error("inline resource definition must specify an attribute via 'name'"); 501707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 501807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 501907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 502007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Parse the attribute name. 502107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const char* errorMsg = NULL; 502207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String16 attrPackage, attrType, attrName; 502307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski bool result = ResTable::expandResourceRef(attr->string.string(), 502407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski attr->string.size(), 502507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski &attrPackage, &attrType, &attrName, 502607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski &kAttr16, &kAssetPackage16, 502707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski &errorMsg, NULL); 502807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (!result) { 502907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source.error("invalid attribute name for 'name': %s", errorMsg); 503007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 503107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 503207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 503307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (attrType != kAttr16) { 503407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // The value of the 'name' attribute must be an attribute reference. 503507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source.error("value of 'name' must be an attribute reference."); 503607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 503707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 503807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 503907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Generate a name for this nested resource and try to add it to the table. 504007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // We do this in a loop because the name may be taken, in which case we will 504107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // increment a suffix until we succeed. 504207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8 nestedResourceName; 504307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8 nestedResourcePath; 504407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski int suffix = 1; 504507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski while (true) { 504607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // This child element will be extracted into its own resource file. 504707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Generate a name and path for it from its parent. 504807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedResourceName = String8::format("%s_%d", 504907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8(resourceName).string(), suffix++); 505007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedResourcePath = String8::format("res/%s/%s.xml", 505107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski target->getGroupEntry().toDirName(target->getResourceType()) 505207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski .string(), 505307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedResourceName.string()); 505407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 505507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Lookup or create the entry for this name. 505607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski sp<Entry> entry = getEntry(kAssetPackage16, 505707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String16(target->getResourceType()), 505807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String16(nestedResourceName), 505907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source, 506007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski false, 506107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski &target->getGroupEntry().toParams(), 506207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski true); 506307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (entry == NULL) { 506407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 506507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 506607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 506707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (entry->getType() == Entry::TYPE_UNKNOWN) { 506807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // The value for this resource has never been set, 506907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // meaning we're good! 507007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski entry->setItem(source, String16(nestedResourcePath)); 507107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski break; 507207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 507307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 507407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // We failed (name already exists), so try with a different name 507507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // (increment the suffix). 507607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 507707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 507807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (bundle->getVerbose()) { 507907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski source.printf("generating nested resource %s:%s/%s", 508007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski mAssets->getPackage().string(), target->getResourceType().string(), 508107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedResourceName.string()); 508207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 508307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 508407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Build the attribute reference and assign it to the parent. 508507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String16 nestedResourceRef = String16(String8::format("@%s:%s/%s", 508607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski mAssets->getPackage().string(), target->getResourceType().string(), 508707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedResourceName.string())); 508807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 508907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String16 attrNs = buildNamespace(attrPackage); 509007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (parent->getAttribute(attrNs, attrName) != NULL) { 509107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski SourcePos(parent->getFilename(), parent->getStartLineNumber()) 509207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski .error("parent of nested resource already defines attribute '%s:%s'", 509307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski String8(attrPackage).string(), String8(attrName).string()); 509407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return UNKNOWN_ERROR; 509507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 509607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 509707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Add the reference to the inline resource. 509807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski parent->addAttribute(attrNs, attrName, nestedResourceRef); 509907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 510007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Remove the <aapt:attr> child element from here. 510107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski children.removeAt(i); 510207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski i--; 510307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 510407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Append all namespace declarations that we've seen on this branch in the XML tree 510507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // to this resource. 510607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // We do this because the order of namespace declarations and prefix usage is determined 510707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // by the developer and we do not want to override any decisions. Be conservative. 510807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski for (size_t nsIndex = namespaces->size(); nsIndex > 0; nsIndex--) { 510907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski const sp<XMLNode>& ns = namespaces->itemAt(nsIndex - 1); 511007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski sp<XMLNode> newNs = XMLNode::newNamespace(ns->getFilename(), ns->getNamespacePrefix(), 511107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski ns->getNamespaceUri()); 511207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski newNs->addChild(nestedRoot); 511307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski nestedRoot = newNs; 511407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 511507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 511607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski // Schedule compilation of the nested resource. 511707dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski CompileResourceWorkItem workItem; 511807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.resPath = nestedResourcePath; 511907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.resourceName = String16(nestedResourceName); 512007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.xmlRoot = nestedRoot; 512107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.file = new AaptFile(target->getSourceFile(), target->getGroupEntry(), 512207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski target->getResourceType()); 512307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski mWorkQueue.push(workItem); 512407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 512507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski return NO_ERROR; 512607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski} 5127