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 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskistatic const char* kAttrPrivateType = "^attr-private"; 249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 25e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 26e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 27e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 36a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 37e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, target, table, options); 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 40e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 41e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 42e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& outTarget, 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 56e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 57e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 58e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<XMLNode>& root, 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(true, NULL); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(false, NULL); 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_UTF8) != 0) { 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->setUTF8(true); 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->assignResourceIds(assets, table); 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->parseValues(assets, table); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 91e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 92e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) { 93e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return UNKNOWN_ERROR; 94e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Input XML Resource:\n")); 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(root->print()); 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = root->flatten(target, 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_COMMENTS) != 0, 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_RAW_VALUES) != 0); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Output XML Resource:\n")); 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(ResXMLTree tree; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(target->getData(), target->getSize()); 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree)); 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski target->setCompressionMethod(ZipEntry::kCompressDeflated); 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#undef NOISY 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct flag_entry 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* name; 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t nameLen; 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value; 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* description; 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t referenceArray[] = 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' }; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t stringArray[] = 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 's', 't', 'r', 'i', 'n', 'g' }; 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t integerArray[] = 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'i', 'n', 't', 'e', 'g', 'e', 'r' }; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t booleanArray[] = 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'b', 'o', 'o', 'l', 'e', 'a', 'n' }; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t colorArray[] = 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'c', 'o', 'l', 'o', 'r' }; 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t floatArray[] = 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'o', 'a', 't' }; 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t dimensionArray[] = 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' }; 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t fractionArray[] = 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' }; 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t enumArray[] = 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'e', 'n', 'u', 'm' }; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t flagsArray[] = 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'a', 'g', 's' }; 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry gFormatFlags[] = { 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE, 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n" 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."}, 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING, 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." }, 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER, 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "an integer value, such as \"<code>100</code>\"." }, 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN, 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." }, 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR, 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n" 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." }, 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT, 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a floating point value, such as \"<code>1.2</code>\"."}, 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION, 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n" 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n" 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "in (inches), mm (millimeters)." }, 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION, 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n" 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n" 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "some parent container." }, 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL }, 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL }, 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' }; 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry l10nRequiredFlags[] = { 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL }, 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t nulStr[] = { 0 }; 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic uint32_t parse_flags(const char16_t* str, size_t len, 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags, bool* outError = NULL) 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(*str)) { 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(str[len-1])) { 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + len; 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value = 0; 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* div = str; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (div < end && *div != '|') { 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski div++; 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* cur = flags; 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (cur->name) { 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value |= cur->value; 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cur++; 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!cur->name) { 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = true; 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = div < end ? div+1 : div; 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = false; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value; 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 mayOrMust(int type, int flags) 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&(~flags)) == 0) { 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>Must"); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>May"); 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg, 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& typeName, const String16& ident, int type, 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags) 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hadType = false; 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (flags->name) { 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&flags->value) != 0 && flags->description != NULL) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 fullMsg(mayOrMust(type, flags->value)); 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(" be ")); 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(flags->description)); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, fullMsg); 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hadType = true; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags++; 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) { 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("<p>This may also be a reference to a resource (in the form\n" 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n" 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "theme attribute (in the form\n" 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n" 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "containing a value of this type.")); 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct PendingAttribute 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage; 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos sourcePos; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool appendComment; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t type; 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment; 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors; 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool added; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute(String16 _package, const sp<AaptFile>& in, 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, bool _appendComment) 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : myPackage(_package) 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , sourcePos(in->getPrintableSource(), block.getLineNumber()) 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , appendComment(_appendComment) 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , type(ResTable_map::TYPE_ANY) 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , hasErrors(false) 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , added(false) 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t createIfNeeded(ResourceTable* outTable) 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (added || hasErrors) { 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski added = true; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outTable->hasBagOrEntry(myPackage, attr16, ident)) { 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Attribute \"%s\" has already been defined\n", 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string()); 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", type); 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = outTable->addBag(sourcePos, myPackage, 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, ident, String16(""), 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, attr16, ident, comment, appendComment); 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(ident).string(), 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t compileAttribute(const sp<AaptFile>& in, 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable, 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outIdent = NULL, 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inStyleable = false) 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute attr(myPackage, in, block, inStyleable); 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 flag16("flag"); 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.ident = String16(block.getAttributeStringValue(identIdx, &len)); 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outIdent) { 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outIdent = attr.ident; 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("A 'name' attribute is required for <attr>\n"); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.comment = String16( 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == 0) { 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeStr).string()); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!inStyleable) { 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute definitions outside of styleables always define the 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // attribute as a generic value. 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minIdx = block.indexOfAttribute(NULL, "min"); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minIdx >= 0) { 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(minIdx, &len)); 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^min"), String16(val), NULL, NULL); 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxIdx >= 0) { 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^max"), String16(val), NULL, NULL); 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) { 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n"); 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization"); 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (l10nIdx >= 0) { 4074bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski const char16_t* str = block.getAttributeStringValue(l10nIdx, &len); 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool error; 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error) { 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string()); 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[11]; 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", l10n_required); 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^l10n"), String16(buf), NULL, NULL); 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 enumOrFlagsComment; 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t localType = 0; 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_ENUM; 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_FLAGS; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == ResTable_map::TYPE_ANY) { 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // No type was explicitly stated, so supplying enum tags 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // implicitly creates an enum or flag. 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = 0; 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) { 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Wasn't originally specified as an enum, so update its type. 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type |= localType; 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", attr.type); 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, attr16, attr.ident, String16(""), 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), String16(numberStr), NULL, NULL, true); 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) { 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localType == ResTable_map::TYPE_ENUM) { 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<enum> attribute can not be used inside a flags format\n"); 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<flag> attribute can not be used inside a enum format\n"); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'name' attribute is required for <enum> or <flag>\n"); 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value; 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t valueIdx = block.indexOfAttribute(NULL, "value"); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (valueIdx >= 0) { 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value = String16(block.getAttributeStringValue(valueIdx, &len)); 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'value' attribute is required for <enum> or <flag>\n"); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <enum> or <flag> 'value' attribute must be a number," 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " not \"%s\"\n", 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(value).string()); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (enumOrFlagsComment.size() == 0) { 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(mayOrMust(attr.type, 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)); 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM) 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? String16(" be one of the following constant values.") 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : String16(" be one or more (separated by '|') of the following constant values.")); 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</p>\n<table>\n" 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>")); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n<tr><td><code>")); 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(itemIdent); 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</code></td><td>")); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(value); 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td><td>")); 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getComment(&len)) { 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16(block.getComment(&len))); 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td></tr>")); 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, attr.ident, String16(""), 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent, value, NULL, NULL, false, true); 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </enum> is expected\n", 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </flag> is expected\n", 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && attr.added) { 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags); 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && enumOrFlagsComment.size() > 0) { 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n</table>")); 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment); 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool localeIsDefined(const ResTable_config& config) 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return config.locale == 0; 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddBag(Bundle* bundle, 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& parentIdent, 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& itemIdent, 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 587a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 593a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block, item16, &str, &spans, isFormatted, 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pseudolocalize); 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d " 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " pid=%s, bag=%s, id=%s: %s\n", 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parentIdent).string(), 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(itemIdent).string(), 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string())); 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, parentIdent, itemIdent, str, 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &spans, &config, overwrite, false, curFormat); 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns true if needle is one of the elements in the comma-separated list 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * haystack, false otherwise. 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isInProductList(const String16& needle, const String16& haystack) { 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *needle2 = needle.string(); 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *haystack2 = haystack.string(); 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t needlesize = needle.size(); 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0') { 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncmp16(haystack2, needle2, needlesize) == 0) { 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') { 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0' && *haystack2 != ',') { 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*haystack2 == ',') { 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 6468ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski/* 6478ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * A simple container that holds a resource type and name. It is ordered first by type then 6488ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * by name. 6498ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 6508ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinskistruct type_ident_pair_t { 6518ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 type; 6528ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 ident; 6538ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6548ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t() { }; 6558ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { } 6568ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { } 6578ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski inline bool operator < (const type_ident_pair_t& o) const { 6588ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski int cmp = compare_type(type, o.type); 6598ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (cmp < 0) { 6608ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return true; 6618ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else if (cmp > 0) { 6628ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return false; 6638ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else { 6648ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return strictly_order_type(ident, o.ident); 6658ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6668ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6678ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski}; 6688ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6698ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddEntry(Bundle* bundle, 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curTag, 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled, 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 682a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 6848ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool>* skippedResourceNames, 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), block, 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag, &str, curIsStyled ? &spans : NULL, 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isFormatted, pseudolocalize); 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a product type was specified on the command line 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and also in the string, and the two are not the same, 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * return without adding the string. 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *bundleProduct = bundle->getProduct(); 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct == NULL) { 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundleProduct = ""; 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (product.size() != 0) { 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the command-line-specified product is empty, only "default" 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * matches. Other variants are skipped. This is so generation 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * of the R.java file when the product is not known is predictable. 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct[0] == '\0') { 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(String16("default").string(), product.string()) != 0) { 7198ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski /* 7208ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * This string has a product other than 'default'. Do not add it, 7218ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * but record it so that if we do not see the same string with 7228ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * product 'default' or no product, then report an error. 7238ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 7248ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski skippedResourceNames->replaceValueFor( 7258ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(curType, ident), true); 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The command-line product is not empty. 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the product for this string is on the command-line list, 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it matches. "default" also matches, but only if nothing 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * else has matched already. 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isInProductList(product, String16(bundleProduct))) { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(String16("default").string(), product.string()) == 0 && 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n", 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), String8(str).string())); 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, str, &spans, &config, 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski false, curFormat, overwrite); 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileResourceFile(Bundle* bundle, 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& defParams, 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(in, &block, false, true); 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Top-level tag. 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 resources16("resources"); 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Identifier declaration tags. 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 declare_styleable16("declare-styleable"); 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation organizational tags. 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string16("string"); 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 drawable16("drawable"); 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 color16("color"); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bool16("bool"); 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer16("integer"); 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 dimen16("dimen"); 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 fraction16("fraction"); 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 plurals16("plurals"); 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 array16("array"); 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string_array16("string-array"); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer_array16("integer-array"); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public16("public"); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public_padding16("public-padding"); 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 private_symbols16("private-symbols"); 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 java_symbol16("java-symbol"); 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 add_resource16("add-resource"); 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 skip16("skip"); 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 eat_comment16("eat-comment"); 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation tags. 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bag16("bag"); 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // plural values 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 other16("other"); 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOther16("^other"); 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 zero16("zero"); 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityZero16("^zero"); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 one16("one"); 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOne16("^one"); 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 two16("two"); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityTwo16("^two"); 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 few16("few"); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityFew16("^few"); 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 many16("many"); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityMany16("^many"); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // useful attribute names and special values 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 name16("name"); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 translatable16("translatable"); 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 formatted16("formatted"); 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 false16("false"); 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage(assets->getPackage()); 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool fileIsTranslatable = true; 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) { 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileIsTranslatable = false; 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t> nextPublicId(0); 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8398ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // Stores the resource names that were skipped. Typically this happens when 8408ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // AAPT is invoked without a product specified and a resource has no 8418ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // 'default' product attribute. 8428ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool> skippedResourceNames; 8438ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = block.next(); 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (code == ResXMLTree::START_NAMESPACE); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "No start tag found\n"); 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config curParams(defParams); 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config pseudoParams(curParams); 864a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[0] = 'e'; 865a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[1] = 'n'; 866a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[0] = 'X'; 867a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[1] = 'A'; 868a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 869a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ResTable_config pseudoBidiParams(curParams); 870a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[0] = 'a'; 871a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[1] = 'r'; 872a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[0] = 'X'; 873a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[1] = 'B'; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // We should skip resources for pseudolocales if they were 87647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // already added automatically. This is a fix for a transition period when 87747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // manually pseudolocalized resources may be expected. 87847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // TODO: remove this check after next SDK version release. 87947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED && 88047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoParams.locale) || 88147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk (bundle->getPseudolocalize() & PSEUDO_BIDI && 88247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoBidiParams.locale)) { 88347843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk SourcePos(in->getPrintableSource(), 0).warning( 88447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk "Resource file %s is skipped as pseudolocalization" 88547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk " was done automatically.", 88647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk in->getPrintableSource().string()); 88747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk return NO_ERROR; 88847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk } 88947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* curTag = NULL; 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curType; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat = ResTable_map::TYPE_ANY; 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBag = false; 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBagReplaceOnOverwrite = false; 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled = false; 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsPseudolocalizable = false; 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsFormatted = fileIsTranslatable; 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool localHasErrors = false; 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t ident = 0; 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "id"); 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* identStr = block.getAttributeStringValue(identIdx, &len); 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value identValue; 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(identStr, len, &identValue)) { 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'id' attribute is not an integer: %s\n", 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(identIdx, &len)).string()); 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = identValue.data; 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'id' attribute supplied <public>," 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = nextPublicId.valueFor(type); 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, name, ident); 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(name), srcPos); 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public-padding>\n"); 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public-padding>\n"); 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t start = 0; 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t startIdx = block.indexOfAttribute(NULL, "start"); 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (startIdx >= 0) { 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* startStr = block.getAttributeStringValue(startIdx, &len); 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value startValue; 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(startStr, len, &startValue)) { 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'start' attribute is not an integer: %s\n", 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(startIdx, &len)).string()); 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = startValue.data; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'start' attribute supplied <public-padding>," 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = nextPublicId.valueFor(type); 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t end = 0; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t endIdx = block.indexOfAttribute(NULL, "end"); 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (endIdx >= 0) { 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* endStr = block.getAttributeStringValue(endIdx, &len); 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value endValue; 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(endStr, len, &endValue)) { 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'end' attribute is not an integer: %s\n", 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(endIdx, &len)).string()); 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski end = endValue.data; 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'end' attribute supplied <public-padding>\n"); 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (end >= start) { 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, end+1); 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Padding start '%ul' is after end '%ul'\n", 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start, end); 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (uint32_t curIdent=start; curIdent<=end; curIdent++) { 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localHasErrors) { 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curName(name); 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[64]; 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", (int)(end-curIdent+1)); 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName.append(String16(buf)); 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(srcPos, myPackage, type, curName, 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("padding"), NULL, &curParams, false, 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_STRING, overwrite); 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName, curIdent); 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(curName), srcPos); 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(curName), comment, srcPos); 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 pkg; 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkgIdx < 0) { 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'package' attribute is required for <private-symbols>\n"); 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = String16(block.getAttributeStringValue(pkgIdx, &len)); 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setSymbolsPrivatePackage(String8(pkg)); 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R")); 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolJavaSymbol(String8(name), srcPos); 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName; 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <add-resource>\n"); 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeName = String16(block.getAttributeStringValue(typeIdx, &len)); 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <add-resource>\n"); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->canAddEntry(srcPos, myPackage, typeName, name); 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx < 0) { 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <declare-styleable>\n"); 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8("styleable"), srcPos); 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleSymbols = symbols; 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(ident), srcPos); 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols == NULL) { 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleSymbols->appendComment(String8(ident), comment, srcPos); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = NULL; 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true); 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->addSymbol(String8(itemIdent), 0, srcPos); 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(itemIdent), comment, srcPos); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </attr> is expected\n", 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, NULL); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &item16; 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <item> 'format' attribute value \"%s\" not valid\n", 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <item>\n"); 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note the existence and locale of every string we process 132391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath char rawLocale[RESTABLE_MAX_LOCALE_LEN]; 132491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath curParams.getBcp47Locale(rawLocale); 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 locale(rawLocale); 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 translatable; 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatted; 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 13334bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski const char16_t* attr = block.getAttributeName(i, &length); 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(attr, name16.string()) == 0) { 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.setTo(block.getAttributeStringValue(i, &length)); 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, translatable16.string()) == 0) { 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski translatable.setTo(block.getAttributeStringValue(i, &length)); 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, formatted16.string()) == 0) { 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatted.setTo(block.getAttributeStringValue(i, &length)); 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name.size() > 0) { 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (translatable == false16) { 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Untranslatable strings must only exist in the default [empty] locale 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (locale.size() > 0) { 1348a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 1349a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski "string '%s' marked untranslatable but exists in locale '%s'\n", 1350a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(name).string(), 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski locale.string()); 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // hasErrors = localHasErrors = true; 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Intentionally empty block: 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Don't add untranslatable strings to the localization table; that 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // way if we later see localizations of them, they'll be flagged as 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // having no default translation. 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1361a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski outTable->addLocalization( 1362a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski name, 1363a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locale, 1364a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber())); 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatted == false16) { 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string16; 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = string16; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 137684410b054c7db0b6685a0f15cb2d1ffcb264f6c9Igor Viarheichyk curIsPseudolocalizable = fileIsTranslatable && (translatable != false16); 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &drawable16; 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = drawable16; 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &color16; 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = color16; 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bool16; 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = bool16; 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer16; 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = integer16; 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &dimen16; 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = dimen16; 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &fraction16; 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = fraction16; 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bag16; 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <bag>\n"); 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &style16; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = style16; 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &plurals16; 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = plurals16; 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1420a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = fileIsTranslatable; 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &array16; 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <array> 'format' attribute value \"%s\" not valid\n", 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check whether these strings need valid formats. 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (simplified form of what string16 does above) 1442a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bool isTranslatable = false; 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 14449a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath 14459a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // Pseudolocalizable by default, unless this string array isn't 14469a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // translatable. 1447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 14494bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski const char16_t* attr = block.getAttributeName(i, &length); 1450a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (strcmp16(attr, formatted16.string()) == 0) { 14514bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski const char16_t* value = block.getAttributeStringValue(i, &length); 14529a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath if (strcmp16(value, false16.string()) == 0) { 1453a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted = false; 14549a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath } 1455a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } else if (strcmp16(attr, translatable16.string()) == 0) { 14564bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski const char16_t* value = block.getAttributeStringValue(i, &length); 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(value, false16.string()) == 0) { 1458a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin isTranslatable = false; 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string_array16; 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1468a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = isTranslatable && fileIsTranslatable; 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer_array16; 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag %s where item is expected\n", 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <%s>\n", 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 product; 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski identIdx = block.indexOfAttribute(NULL, "product"); 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski product = String16(block.getAttributeStringValue(identIdx, &len)); 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsBag) { 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Figure out the parent of this bag... 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 parentIdent; 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent"); 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (parentIdentIdx >= 0) { 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len)); 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t sep = ident.findLast('.'); 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sep >= 0) { 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent.setTo(ident, sep); 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->startBag(SourcePos(in->getPrintableSource(), 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getLineNumber()), myPackage, curType, ident, 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent, &curParams, 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overwrite, curIsBagReplaceOnOverwrite); 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t elmIndex = 0; 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char elmIndexStr[14]; 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), item16.string()) != 0) { 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <%s>, only <item>\n", 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curType == array16) { 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(elmIndexStr, "^index_%d", (int)elmIndex++); 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(elmIndexStr); 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (curType == plurals16) { 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity"); 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len)); 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (quantity16 == other16) { 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOther16; 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == zero16) { 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityZero16; 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == one16) { 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOne16; 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == two16) { 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityTwo16; 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == few16) { 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityFew16; 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == many16) { 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityMany16; 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Illegal 'quantity' attribute is <item> inside <plurals>\n"); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'quantity' attribute is required for <item> inside <plurals>\n"); 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <item>\n"); 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident, parentIdent, itemIdent, curFormat, curIsFormatted, 1590a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, outTable); 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1593a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1595a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1596a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1597a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1598a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, 1599a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1600a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_ACCENTED, 1601a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1602a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1603a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1604a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1605a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1606a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage, 1607a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1608a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_BIDI, 1609a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1610a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1612a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </%s> is expected\n", 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *curTag, curIsStyled, curFormat, curIsFormatted, 1633a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable); 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (err == NO_ERROR) { 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1640a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1642a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1643a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1644a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1645a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, 1646a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ident, *curTag, curIsStyled, curFormat, 1647a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1648a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable); 1649a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1650a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1651a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1652a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1653a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams, 1654a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin myPackage, curType, ident, *curTag, curIsStyled, curFormat, 1655a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1656a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable); 1657a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(curType).string(), String8(ident).string(), 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, curType, ident, comment, false); 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::END_TAG) { 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) { 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::TEXT) { 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isWhitespace(block.getText(&len))) { 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found text \"%s\" where item tag is expected\n", 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getText(&len)).string()); 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16968ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // For every resource defined, there must be exist one variant with a product attribute 16978ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // set to 'default' (or no product attribute at all). 16988ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // We check to see that for every resource that was ignored because of a mismatched 16998ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // product attribute, some product variant of that resource was processed. 17008ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski for (size_t i = 0; i < skippedResourceNames.size(); i++) { 17018ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (skippedResourceNames[i]) { 17028ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const type_ident_pair_t& p = skippedResourceNames.keyAt(i); 17038ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) { 17048ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const char* bundleProduct = 17058ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski (bundle->getProduct() == NULL) ? "" : bundle->getProduct(); 17068ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "In resource file %s: %s\n", 17078ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski in->getPrintableSource().string(), 17088ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski curParams.toString().string()); 17098ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 17108ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "\t%s '%s' does not match product %s.\n" 17118ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski "\tYou may have forgotten to include a 'default' product variant" 17128ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski " of the resource.\n", 17138ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String8(p.type).string(), String8(p.ident).string(), 17148ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski bundleProduct[0] == 0 ? "default" : bundleProduct); 17158ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return UNKNOWN_ERROR; 17168ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17178ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17188ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17198ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1723833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type) 1724833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mAssetsPackage(assetsPackage) 1725833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mPackageType(type) 1726833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mTypeIdOffset(0) 1727833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mNumLocal(0) 1728833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mBundle(bundle) 1729833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski{ 1730833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t packageId = -1; 1731833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski switch (mPackageType) { 1732833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case App: 1733833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case AppFeature: 1734833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x7f; 1735833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1736833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1737833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case System: 1738833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x01; 1739833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1740833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1741833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case SharedLibrary: 1742833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x00; 1743833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1744833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1745833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski default: 1746833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski assert(0); 1747833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1748833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1749833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> package = new Package(mAssetsPackage, packageId); 1750833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mPackages.add(assetsPackage, package); 1751833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mOrderedPackages.add(package); 1752833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1753833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Every resource table always has one first entry, the bag attributes. 1754833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const SourcePos unknown(String8("????"), 0); 1755833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski getType(mAssetsPackage, String16("attr"), unknown); 1756833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski} 1757833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1758833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinskistatic uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) { 1759833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 1760833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 1761833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (packageName == table.getBasePackageName(i)) { 1762833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return table.getLastTypeIdForPackage(i); 1763833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1764833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1765833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets) 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = assets->buildIncludedResources(bundle); 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mAssets = assets; 1776833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage); 1777833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1778833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const String8& featureAfter = bundle->getFeatureAfterPackage(); 1779833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAfter.isEmpty()) { 1780833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski AssetManager featureAssetManager; 1781833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAssetManager.addAssetPath(featureAfter, NULL)) { 1782833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "ERROR: Feature package '%s' not found.\n", 1783833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski featureAfter.string()); 1784833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1787833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const ResTable& featureTable = featureAssetManager.getResources(false); 1788833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mTypeIdOffset = max(mTypeIdOffset, 1789833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski findLargestTypeIdForPackage(featureTable, mAssetsPackage)); 1790833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addPublic(const SourcePos& sourcePos, 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Error declaring public resource %s/%s for included package %s\n", 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(type).string(), String8(name).string(), 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string()); 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos); 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->addPublic(sourcePos, name, ident); 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addEntry(const SourcePos& sourcePos, 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool doSetIndex, 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int32_t format, 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1835833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1836833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1837833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite, 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski params, doSetIndex); 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->setItem(sourcePos, value, style, format, overwrite); 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::startBag(const SourcePos& sourcePos, 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId) 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1870833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1871833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1872833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1874833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) { 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool canAdd = false; 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t->getCanAddEntries().indexOf(name) >= 0) { 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski canAdd = true; 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!canAdd) { 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n", 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string()); 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params); 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((result = e->makeItABag(sourcePos)) != NO_ERROR) { 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && replace) { 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e->emptyBag(sourcePos); 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addBag(const SourcePos& sourcePos, 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagKey, 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, const int32_t format) 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding bag left: file=%s, line=%d, type=%s\n", 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.striing(), sourcePos.line, String8(type).string()); 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params); 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool first = e->getBag().indexOfKey(bagKey) < 0; 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format); 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR && first) { 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name) const 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) return true; 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config) const 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(config); 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& ref, 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage) 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasBagOrEntry(package, type, name); 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendComment(const String16& package, 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment, 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendComment(comment, onlyIfEmpty); 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendTypeComment(const String16& package, 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment) 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendTypeComment(comment); 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::canAddEntry(const SourcePos& pos, 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, pos); 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->canAddEntry(name); 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::size() const { 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPackages.size(); 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::numLocalResources() const { 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal; 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasResources() const { 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal > 0; 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 209327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskisp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 209427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 209727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flatten(bundle, filter, data, isBase); 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err == NO_ERROR ? data : NULL; 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiinline uint32_t ResourceTable::getResId(const sp<Package>& p, 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<Type>& t, 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t nameId) 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return makeResId(p->getAssignedId(), t->getIndex(), nameId); 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& package, 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic); 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) return id; // cache hit 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size(), 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &specFlags); 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyPublic) { 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2130833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, rid); 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2133833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2134833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (p == NULL) return 0; 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 21379b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 21389b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 21399b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (type != String16("attr")) { 21409b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return 0; 21419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 21429b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski t = p->getTypes().valueFor(String16(kAttrPrivateType)); 21439b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t == NULL) return 0; 21449b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski c = t->getConfigs().valueFor(name); 21459b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) return 0; 21469b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(p, t, ei)); 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& ref, 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage, 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char** outErrorMsg, 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool refOnlyPublic = true; 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef( 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ref.string(), ref.size(), &package, &type, &name, 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outErrorMsg, &refOnlyPublic)) { 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ref).string())); 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defType=%s\n", 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType ? String8(*defType).string() : "NULL")); 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defPackage=%s\n", 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defPackage ? String8(*defPackage).string() : "NULL")); 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string())); 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string())); 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), res)); 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res == 0) { 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outErrorMsg) 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outErrorMsg = "No resource found that matches the given name"; 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::isValidResourceName(const String16& s) 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = s.string(); 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*p >= 'a' && *p <= 'z') 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*p >= 'A' && *p <= 'Z') 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *p == '_' 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (!first && *p >= '0' && *p <= '9')) { 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& str, 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool preserveSpaces, bool coerceType, 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outStr, void* accessorCookie, 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrType, const String8* configTypeName, 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription* config) 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 finalStr; 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = true; 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style == NULL || style->size() == 0) { 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Text is not styled so it can be any type... let's figure it out. 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = mAssets->getIncludedResources() 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski coerceType, attrID, NULL, &mAssetsPackage, this, 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski accessorCookie, attrType); 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Styled text can only be a string, and while collecting the style 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // information we have already processed that string! 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->size = sizeof(Res_value); 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->res0 = 0; 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = outValue->TYPE_STRING; 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finalStr = str; 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!res) { 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outValue->dataType == outValue->TYPE_STRING) { 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should do better merging styles. 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool) { 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configStr; 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = config->toString(); 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = "(null)"; 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding to pool string style #%d config %s: %s\n", 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style != NULL ? style->size() : 0, 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr.string(), String8(finalStr).string())); 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style != NULL && style->size() > 0) { 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, *style, configTypeName, config); 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, true, configTypeName, config); 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Caller will fill this in later. 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outStr) { 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outStr = finalStr; 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResource( 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) const 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getCustomResource: %s %s %s\n", String8(package).string(), 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(type).string(), String8(name).string()); 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) return 0; 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 22809b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 22819b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (type != String16("attr")) { 22829b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return 0; 22839b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 22849b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski t = p->getTypes().valueFor(String16(kAttrPrivateType)); 22859b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t == NULL) return 0; 22869b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski c = t->getConfigs().valueFor(name); 22879b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) return 0; 22889b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getResId(p, t, ei); 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResourceWithCreation( 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name, 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool createIfNotFound) 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resId = getCustomResource(package, type, name); 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resId != 0 || !createIfNotFound) { 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2303f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (mAssetsPackage != package) { 2304833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.error("creating resource for external package %s: %s/%s.", 2305f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8(package).string(), String8(type).string(), String8(name).string()); 2306833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package == String16("android")) { 2307833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?"); 2308833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2309833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 2310f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 2311f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2312f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String16 value("false"); 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true); 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status == NO_ERROR) { 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resId = getResId(package, type, name); 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return origPackage; 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x\n", attrID); 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x (%s): #%08x\n", attrID, 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(getEntry(attrID)->getName()).string(), value.data); 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outType = value.data; 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin) 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMin #%08x\n", attrID); 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) { 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMin = value.data; 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax) 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMax #%08x\n", attrID); 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) { 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMax = value.data; 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getAttributeL10N(uint32_t attrID) 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeL10N #%08x\n", attrID); 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) { 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResTable_map::L10N_NOT_REQUIRED; 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getLocalizationSetting() 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mBundle->getRequireLocalization(); 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (accessorCookie != NULL && fmt != NULL) { 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie* ac = (AccessorCookie*)accessorCookie; 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retval=0; 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[1024]; 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_list ap; 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_start(ap, fmt); 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retval = vsnprintf(buf, sizeof(buf), fmt, ap); 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_end(ap); 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf, ac->attr.string(), ac->value.string()); 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeKeys( 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, Vector<String16>* outKeys) 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = e->getBag().keyAt(i); 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (key.size() > 0 && key.string()[0] != '^') { 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outKeys->add(key); 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeEnum( 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing %s to %s\n", String8(name, nameLen).string(), 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeFlags( 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = Res_value::TYPE_INT_HEX; 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* end = name + nameLen; 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* pos = name; 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end) { 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* start = pos; 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end && *pos != '|') { 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(start, pos-start); 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value val; 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!got) { 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got value: 0x%08x\n", val.data); 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data |= val.data; 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= N) { 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Didn't find this flag identifier. 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::assignResourceIds() 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t firstError = NO_ERROR; 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First generate all bag attributes and assign indices. 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL || p->getTypes().size() == 0) { 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 24929b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mPackageType == System) { 24939b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski p->movePrivateAttrs(); 24949b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 24959b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2496833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // This has no sense for packages being built as AppFeature (aka with a non-zero offset). 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = p->applyPublicTypeOrder(); 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate attributes... 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->generateAttributes(this, p->getName()); 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2530833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski uint32_t typeIdOffset = 0; 2531833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (mPackageType == AppFeature && p->getName() == mAssetsPackage) { 2532833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeIdOffset = mTypeIdOffset; 2533833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2534833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos unknown(String8("????"), 0); 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> attr = p->getType(String16("attr"), unknown); 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign indices... 253943a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 254043a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 254543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = t->applyPublicEntryOrder(); 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2552833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski t->setIndex(ti + 1 + typeIdOffset); 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t, 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "First type is not attr!"); 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei); 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(ei); 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25669b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign resource IDs to keys in bags... 256843a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 25739b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 25779b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c == NULL) { 25789b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 25799b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordered config #%d: %p\n", ci, c.get()); 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->assignResourceIds(this, p->getName()); 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return firstError; 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 26179b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 26199b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<AaptSymbols> typeSymbols; 26209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (t->getName() == String16(kAttrPrivateType)) { 26219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski typeSymbols = outSymbols->addNestedSymbol(String8("attr"), t->getPos()); 26229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } else { 26239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); 26249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 26259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 26263fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski if (typeSymbols == NULL) { 26273fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski return UNKNOWN_ERROR; 26283fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski } 26293fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = getResId(p, t, ci); 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid == 0) { 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2639833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) { 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos()); 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(c->getComment()); 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); 26448ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski //printf("Type symbol [%08x] %s comment: %s\n", rid, 26458ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // String8(c->getName()).string(), String8(comment).string()); 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = c->getTypeComment(); 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendTypeComment(String8(c->getName()), comment); 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2657a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src) 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2659a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski mLocalizations[name][locale] = src; 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*! 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Flag various sorts of localization problems. '+' indicates checks already implemented; 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * '-' indicates checks that will be implemented in the future. 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized string for which no default-locale version exists => warning 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A string for which no version in an explicitly-requested locale exists => warning 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized translation of an translateable="false" string => warning 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - A localized string not provided in every locale used by the table 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::validateLocalizations(void) 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 defaultLocale; 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For all strings... 2679a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String16, map<String8, SourcePos> >::iterator nameIter = mLocalizations.begin(); 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter != mLocalizations.end(); 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter++) { 2682a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski const map<String8, SourcePos>& configSrcMap = nameIter->second; 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Look for strings with no default localization 2685a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.count(defaultLocale) == 0) { 2686a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' has no default translation.", 2687a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string()); 2688a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (mBundle->getVerbose()) { 2689a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String8, SourcePos>::const_iterator locales = configSrcMap.begin(); 2690a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales != configSrcMap.end(); 2691a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales++) { 2692a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales->second.printf("locale %s found", locales->first.string()); 2693a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // !!! TODO: throw an error here in some circumstances 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check that all requested localizations are present for this string 2699fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) { 2700fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* allConfigs = mBundle->getConfigurations().string(); 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* start = allConfigs; 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* comma; 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2704a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski set<String8> missingConfigs; 2705a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski AaptLocaleValue locale; 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 config; 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comma = strchr(start, ','); 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comma != NULL) { 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start, comma - start); 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = comma + 1; 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start); 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2716a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!locale.initFromFilterString(config)) { 2717a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski continue; 2718a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2719a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2720a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // don't bother with the pseudolocale "en_XA" or "ar_XB" 2721a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (config != "en_XA" && config != "ar_XB") { 2722a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(config) == configSrcMap.end()) { 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // okay, no specific localization found. it's possible that we are 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // requiring a specific regional localization [e.g. de_DE] but there is an 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // available string in the generic language localization [e.g. de]; 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // consider that string to have fulfilled the localization requirement. 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 region(config.string(), 2); 2728a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(region) == configSrcMap.end() && 2729a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configSrcMap.count(defaultLocale) == 0) { 2730a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski missingConfigs.insert(config); 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2734a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } while (comma != NULL); 2735a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2736a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!missingConfigs.empty()) { 2737a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8 configStr; 2738a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (set<String8>::iterator iter = missingConfigs.begin(); 2739a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter != missingConfigs.end(); 2740a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter++) { 2741a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.appendFormat(" %s", iter->string()); 2742a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2743a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' is missing %u required localizations:%s", 2744a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string(), 2745a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski (unsigned int)missingConfigs.size(), 2746a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.string()); 2747a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 275427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskistatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 275527f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const sp<AaptFile>& dest, 275627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription nullConfig; 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const static String16 mipmap16("mipmap"); 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool useUTF8 = !bundle->getUTF16StringsOption(); 2766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2767de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // The libraries this table references. 2768de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski Vector<sp<Package> > libraryPackages; 27696022debdbcc4498736580640c6287b57872617a2Adam Lesinski const ResTable& table = mAssets->getIncludedResources(); 27706022debdbcc4498736580640c6287b57872617a2Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 27716022debdbcc4498736580640c6287b57872617a2Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 27726022debdbcc4498736580640c6287b57872617a2Adam Lesinski size_t packageId = table.getBasePackageId(i); 27736022debdbcc4498736580640c6287b57872617a2Adam Lesinski String16 packageName(table.getBasePackageName(i)); 27746022debdbcc4498736580640c6287b57872617a2Adam Lesinski if (packageId > 0x01 && packageId != 0x7f && 27756022debdbcc4498736580640c6287b57872617a2Adam Lesinski packageName != String16("android")) { 27766022debdbcc4498736580640c6287b57872617a2Adam Lesinski libraryPackages.add(sp<Package>(new Package(packageName, packageId))); 27776022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 27786022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 2779de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through all data, collecting all values (strings, 2781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // references, etc). 2782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool valueStrings(useUTF8); 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Entry> > allEntries; 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool typeStrings(useUTF8); 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool keyStrings(useUTF8); 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2793833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t stringsAdded = 0; 2794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(String16("<empty>"), false); 2799833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2802833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2803833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski while (stringsAdded < t->getIndex() - 1) { 2804833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeStrings.add(String16("<empty>"), false); 2805833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2806833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2807833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 typeName(t->getName()); 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(typeName, false); 2810833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a hack to tweak the sorting order of the final strings, 2813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to put stuff that is generally not language-specific first. 2814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configTypeName(typeName); 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (configTypeName == "drawable" || configTypeName == "layout" 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "color" || configTypeName == "anim" 2817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "interpolator" || configTypeName == "animator" 2818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "xml" || configTypeName == "menu" 2819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "mipmap" || configTypeName == "raw") { 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "1complex"; 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "2value"; 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 282527f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // mipmaps don't get filtered, so they will 282627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // allways end up in the base. Make sure they 282727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // don't end up in a split. 282827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (typeName == mipmap16 && !isBase) { 282927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 283027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 283127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 2832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 2833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = c->getEntries().keyAt(ei); 2843fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 2844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setNameIndex(keyStrings.add(e->getName(), true)); 2851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this entry has no values for other configs, 2853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and is the default config, then it is special. Otherwise 2854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we want to add it with the config info. 2855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription* valueConfig = NULL; 2856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != 1 || config == nullConfig) { 2857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueConfig = &config; 2858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->prepareFlatten(&valueStrings, this, 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &configTypeName, &config); 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries.add(e); 2866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setTypeStrings(typeStrings.createStringBlock()); 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setKeyStrings(keyStrings.createStringBlock()); 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now we want to sort the value strings for better locality. This will 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // cause the positions of the strings to change, so we need to go back 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // through out resource entries and update them accordingly. Only need 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to do this if actually writing the output file. 2879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueStrings.sortByConfig(); 2880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<allEntries.size(); pi++) { 2881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries[pi]->remapStringValue(&valueStrings); 2882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strAmt = 0; 2886de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now build the array of package chunks. 2888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<AaptFile> > flatPackages; 2889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getTypeStrings().size(); 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t baseSize = sizeof(ResTable_package); 2899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Start the package data. 2901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 2902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_package* header = (ResTable_package*)data->editData(baseSize); 2903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (header == NULL) { 2904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_package\n"); 2905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(header, 0, sizeof(*header)); 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.type = htods(RES_TABLE_PACKAGE_TYPE); 2909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.headerSize = htods(sizeof(*header)); 2910833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski header->id = htodl(static_cast<uint32_t>(p->getAssignedId())); 2911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy16_htod(header->name, p->getName().string()); 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the string blocks. 2914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStringsStart = data->getSize(); 2915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> strFile = p->getTypeStringsData(); 2916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = data->writeData(strFile->getData(), strFile->getSize()); 2917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** type strings: %d\n", amt); 2919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t keyStringsStart = data->getSize(); 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strFile = p->getKeyStringsData(); 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt = data->writeData(strFile->getData(), strFile->getSize()); 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** key strings: %d\n", amt); 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293527f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (isBase) { 293627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flattenLibraryTable(data, libraryPackages); 293727f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (err != NO_ERROR) { 293827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski fprintf(stderr, "ERROR: failed to write library table\n"); 293927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski return err; 294027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 2941de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 2942de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the type chunks inside of this package. 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve them in the same order as the type string block. 2946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName(p->getTypeStrings().stringAt(ti, &len)); 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(typeName); 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), 2950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Type name %s not found", 2951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeName).string()); 2952833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (t == NULL) { 2953833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski continue; 2954833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 295627f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool skipEntireType = (typeName == mipmap16 && !isBase); 2957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; 2959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Until a non-NO_ENTRY value has been written for a resource, 2961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that resource is invalid; validResources[i] represents 2962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the item at t->getOrderedConfigs().itemAt(i). 2963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> validResources; 2964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.insertAt(false, 0, N); 2965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First write the typeSpec chunk, containing information about 2967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // each resource entry in this type. 2968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 2969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N; 2970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecStart = data->getSize(); 2971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_typeSpec* tsHeader = (ResTable_typeSpec*) 2972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart); 2973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tsHeader == NULL) { 2974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n"); 2975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tsHeader, 0, sizeof(*tsHeader)); 2978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE); 2979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.headerSize = htods(sizeof(*tsHeader)); 2980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.size = htodl(typeSpecSize); 2981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->id = ti+1; 2982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->entryCount = htodl(N); 2983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* typeSpecFlags = (uint32_t*) 2985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 2986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeSpecStart + sizeof(ResTable_typeSpec)); 2987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(typeSpecFlags, 0, sizeof(uint32_t)*N); 2988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 29919b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (cl == NULL) { 29929b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 29939b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 29949b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 2995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cl->getPublic()) { 2996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); 2997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 299827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 299927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 300027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 300127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 300227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 3003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t CN = cl->getEntries().size(); 3004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<CN; ci++) { 3005fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(ci))) { 3006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t cj=ci+1; cj<CN; cj++) { 3009fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(cj))) { 3010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl( 3013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj))); 3014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 301927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 302027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 302127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 302227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 3023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We need to write one type chunk for each configuration for 3024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // which we have entries in this type. 30259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const SortedVector<ConfigDescription> uniqueConfigs(t->getUniqueConfigs()); 30269b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t NC = uniqueConfigs.size(); 3027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; 3029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<NC; ci++) { 30319b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const ConfigDescription& config = uniqueConfigs[ci]; 3032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 3034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 3037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.mcc, config.mnc, 3038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] ? config.language[0] : '-', 3039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] ? config.language[1] : '-', 3040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] ? config.country[0] : '-', 3041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] ? config.country[1] : '-', 3042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, 3043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.uiMode, 3044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.touchscreen, 3045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density, 3046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.keyboard, 3047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.inputFlags, 3048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.navigation, 3049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidth, 3050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeight, 3051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp, 3052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp, 3053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp, 3054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.layoutDirection)); 3055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3056fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 3057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStart = data->getSize(); 3061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_type* tHeader = (ResTable_type*) 3063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart); 3064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tHeader == NULL) { 3065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_type\n"); 3066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tHeader, 0, sizeof(*tHeader)); 3070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.type = htods(RES_TABLE_TYPE_TYPE); 3071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.headerSize = htods(sizeof(*tHeader)); 3072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->id = ti+1; 3073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entryCount = htodl(N); 3074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entriesStart = htodl(typeSize); 3075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config = config; 3076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 3077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 3080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.mcc, tHeader->config.mnc, 3081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[0] ? tHeader->config.language[0] : '-', 3082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[1] ? tHeader->config.language[1] : '-', 3083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[0] ? tHeader->config.country[0] : '-', 3084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[1] ? tHeader->config.country[1] : '-', 3085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.orientation, 3086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.uiMode, 3087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.touchscreen, 3088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.density, 3089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.keyboard, 3090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.inputFlags, 3091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.navigation, 3092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidth, 3093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeight, 3094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.smallestScreenWidthDp, 3095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidthDp, 3096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeightDp, 3097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.layoutDirection)); 3098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.swapHtoD(); 3099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the entries inside of this type. 3101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 3102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 31039b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Entry> e = NULL; 31049b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (cl != NULL) { 31059b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski e = cl->getEntries().valueFor(config); 31069b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 3107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set the offset for this entry in its type. 3109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* index = (uint32_t*) 3110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 3111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeStart + sizeof(ResTable_type)); 3112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 3113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(data->getSize()-typeStart-typeSize); 3114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create the entry. 3116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = e->flatten(bundle, data, cl->getPublic()); 3117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.editItemAt(ei) = true; 3121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(ResTable_type::NO_ENTRY); 3123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the type information. 3127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader = (ResTable_type*) 3128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) + typeStart); 3129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.size = htodl(data->getSize()-typeStart); 3130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3132833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // If we're building splits, then each invocation of the flattening 3133833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // step will have 'missing' entries. Don't warn/error for this case. 3134833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getSplitConfigurations().isEmpty()) { 3135833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski bool missing_entry = false; 3136833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ? 3137833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski "error" : "warning"; 3138833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; ++i) { 3139833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!validResources[i]) { 3140833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); 31419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (c != NULL) { 31429b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski fprintf(stderr, "%s: no entries written for %s/%s (0x%08x)\n", log_prefix, 31439b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski String8(typeName).string(), String8(c->getName()).string(), 31449b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Res_MAKEID(p->getAssignedId() - 1, ti, i)); 31459b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 3146833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski missing_entry = true; 3147833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3148833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3149833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getErrorOnMissingConfigEntry() && missing_entry) { 3150833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "Error: Missing entries, quit!\n"); 3151833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NOT_ENOUGH_DATA; 3152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3153cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang } 3154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the package information. 3157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header = (ResTable_package*)data->editData(); 3158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(data->getSize()); 3159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->typeStrings = htodl(typeStringsStart); 3160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicType = htodl(p->getTypeStrings().size()); 3161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->keyStrings = htodl(keyStringsStart); 3162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicKey = htodl(p->getKeyStrings().size()); 3163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages.add(data); 3165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // And now write out the final chunks. 3168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dataStart = dest->getSize(); 3169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 3171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // blah 3172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header header; 3173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.type = htods(RES_TABLE_TYPE); 3175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.headerSize = htods(sizeof(header)); 3176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.packageCount = htodl(flatPackages.size()); 3177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dest->writeData(&header, sizeof(header)); 3178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_header\n"); 3180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strStart = dest->getSize(); 3185fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = valueStrings.writeStringBlock(dest); 3186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = (dest->getSize()-strStart); 3191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 3192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** value strings: %d\n", amt); 3194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total strings: %d\n", strAmt); 3195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3196de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<flatPackages.size(); pi++) { 3198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = dest->writeData(flatPackages[pi]->getData(), 3199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages[pi]->getSize()); 3200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n"); 3202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header* header = (ResTable_header*) 3207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)dest->getData()) + dataStart); 3208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(dest->getSize() - dataStart); 3209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Resource table:" 3211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(dest->getData(), dest->getSize()) << endl); 3212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total resource table size: %d / %d%% strings\n", 3215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->getSize(), (strAmt*100)/dest->getSize()); 3216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3221de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskistatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) { 3222de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write out the library table if necessary 3223de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (libs.size() > 0) { 3224de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, "Writing library reference table\n")); 3225de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3226de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t libStart = dest->getSize(); 3227de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t count = libs.size(); 32286022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange( 32296022debdbcc4498736580640c6287b57872617a2Adam Lesinski libStart, sizeof(ResTable_lib_header)); 3230de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3231de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(libHeader, 0, sizeof(*libHeader)); 3232de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE); 3233de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.headerSize = htods(sizeof(*libHeader)); 3234de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count)); 3235de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->count = htodl(count); 3236de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3237de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write the library entries 3238de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski for (size_t i = 0; i < count; i++) { 3239de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t entryStart = dest->getSize(); 3240de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski sp<Package> libPackage = libs[i]; 3241de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, " Entry %s -> 0x%02x\n", 3242de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski String8(libPackage->getName()).string(), 3243de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski (uint8_t)libPackage->getAssignedId())); 3244de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 32456022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange( 32466022debdbcc4498736580640c6287b57872617a2Adam Lesinski entryStart, sizeof(ResTable_lib_entry)); 3247de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(entry, 0, sizeof(*entry)); 3248de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski entry->packageId = htodl(libPackage->getAssignedId()); 3249de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski strcpy16_htod(entry->packageName, libPackage->getName().string()); 3250de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3251de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3252de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return NO_ERROR; 3253de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 3254de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) 3256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<!-- This file contains <public> resource definitions for all\n" 3259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " resources that were generated from the source data. -->\n" 3260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<resources>\n"); 3262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, true); 3264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, false); 3265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "</resources>\n"); 3269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub) 3272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didHeader = false; 3274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> pkg = mPackages.valueFor(package); 3276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 3277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NT = pkg->getOrderedTypes().size(); 3278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NT; i++) { 3279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = pkg->getOrderedTypes().itemAt(i); 3280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didType = false; 3285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getOrderedConfigs().size(); 3287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NC; j++) { 3288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(j); 3289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c->getPublic() != pub) { 3294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didType) { 3298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n"); 3299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didType = true; 3300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didHeader) { 3302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 3303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PUBLIC SECTION. These resources have been declared public.\n"); 3304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," Changes to these definitions will break binary compatibility. -->\n\n"); 3305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PRIVATE SECTION. These resources have not been declared public.\n"); 3307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," You can make them public my moving these lines into a file in res/values. -->\n\n"); 3308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didHeader = true; 3310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!pub) { 3312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NE = c->getEntries().size(); 3313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<NE; k++) { 3314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); 3315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos.file != "") { 3316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- Declared at %s:%d -->\n", 3317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.file.string(), pos.line); 3318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", 3322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(c->getName()).string(), 3324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(pkg, t, c->getEntryIndex())); 3325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3330282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::Item::Item(const SourcePos& _sourcePos, 3331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool _isId, 3332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& _value, 3333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* _style, 3334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t _format) 3335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : sourcePos(_sourcePos) 3336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , isId(_isId) 3337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , value(_value) 3338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , format(_format) 3339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , bagKeyId(0) 3340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , evaluating(false) 3341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_style) { 3343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style = *_style; 3344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam LesinskiResourceTable::Entry::Entry(const Entry& entry) 334882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski : RefBase() 334982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mName(entry.mName) 335082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParent(entry.mParent) 335182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mType(entry.mType) 335282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItem(entry.mItem) 335382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItemFormat(entry.mItemFormat) 335482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mBag(entry.mBag) 335582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mNameIndex(entry.mNameIndex) 335682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParentId(entry.mParentId) 335782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mPos(entry.mPos) {} 335882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3359978ab9d92934b79409638cf220de3002fea8d505Adam LesinskiResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) { 3360978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mName = entry.mName; 3361978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mParent = entry.mParent; 3362978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mType = entry.mType; 3363978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mItem = entry.mItem; 3364978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mItemFormat = entry.mItemFormat; 3365978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mBag = entry.mBag; 3366978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mNameIndex = entry.mNameIndex; 3367978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mParentId = entry.mParentId; 3368978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski mPos = entry.mPos; 3369978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski return *this; 3370978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski} 3371978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski 3372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) 3373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_UNKNOWN) { 3378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_BAG; 3379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined as a single item.\n" 3382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, 3389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 3390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t format, 3392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 3393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, false, value, style); 3395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 339743a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski if (mBag.size() == 0) { 339843a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.", 339943a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string()); 340043a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } else { 340143a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const Item& item(mBag.valueAt(0)); 340243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.\n" 340343a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski "%s:%d: Originally defined here.\n", 340443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string(), 340543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 340643a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } 3407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { 3410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined.\n" 3411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_ITEM; 3418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem = item; 3419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItemFormat = format; 3420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, 3424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key, const String16& value, 3425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, int32_t format) 3427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, isId, value, style, format); 3434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX NOTE: there is an error if you try to have a bag with two keys, 3436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one an attr and one an id, with the same name. Not something we 3437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // currently ever have to worry about. 3438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t origKey = mBag.indexOfKey(key); 3439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (origKey >= 0) { 3440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!replace) { 3441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& item(mBag.valueAt(origKey)); 3442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s already has bag item %s.\n" 3443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(key).string(), 3445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 3446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Replacing %s with %s\n", 3449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mBag.valueFor(key).value).string(), String8(value).string()); 3450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.replaceValueFor(key, item); 3451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.add(key, item); 3454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 345782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::Entry::removeFromBag(const String16& key) { 345882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mType != Entry::TYPE_BAG) { 345982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 346082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 346182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 346282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mBag.removeItem(key) >= 0) { 346382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 346482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 346582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return UNKNOWN_ERROR; 346682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 346782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos) 3469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.clear(); 3476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table, 3480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.isId) { 3489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->hasBagOrEntry(key, &id16, &package)) { 3490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value("false"); 349143a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski NOISY(fprintf(stderr, "Generating %s:id/%s\n", 349243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(package).string(), 349343a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(key).string())); 3494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, 3495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id16, key, value); 3496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!table->hasBagOrEntry(key, &attr16, &package)) { 3501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 1 3503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", 3504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// String8(key).string()); 3505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// const Item& item(mBag.valueAt(i)); 3506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "Referenced from file %s line %d\n", 3507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// item.sourcePos.file.string(), item.sourcePos.line); 3508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// return UNKNOWN_ERROR; 3509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 3510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 3511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", ResTable_map::TYPE_ANY); 3512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addBag(SourcePos("<generated>", 0), package, 3513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, key, String16(""), 3514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 3515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 3516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 3520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, 3526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 3529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* errorMsg; 3532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 3533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = 0; 3536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParent.size() > 0) { 3537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); 3538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParentId == 0) { 3539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error retrieving parent for item: %s '%s'.\n", 3540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorMsg, String8(mParent).string()); 3541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.bagKeyId = table->getResId(key, 3549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.isId ? &id16 : &attr16, NULL, &errorMsg); 3550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); 3551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 3552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, 3553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(it.isId ? id16 : attr16).string(), 3554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(key).string()); 3555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 3560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table, 3563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8* configTypeName, const ConfigDescription* config) 3564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value)); 3568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, 0, 3570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, mItemFormat, 3571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(key), String8(it.value)); 3580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, it.bagKeyId, 3582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, it.format, 3583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::remapStringValue(StringPool* strings) 3596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic) 3619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t amt = 0; 3621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_entry header; 3622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.size = htods(sizeof(header)); 3624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const type ty = this != NULL ? mType : TYPE_ITEM; 3625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (this != NULL) { 3626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty == TYPE_BAG) { 3627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_COMPLEX); 3628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isPublic) { 3630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_PUBLIC); 3631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.key.index = htodl(mNameIndex); 3633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty != TYPE_BAG) { 3635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&header, sizeof(header)); 3636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mItem; 3642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value par; 3643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&par, 0, sizeof(par)); 3644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.size = htods(it.parsedValue.size); 3645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.dataType = it.parsedValue.dataType; 3646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.res0 = it.parsedValue.res0; 3647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.data = htodl(it.parsedValue.data); 3648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", 3650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), it.parsedValue.dataType, 3651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data, par.res0); 3652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&par, it.parsedValue.size); 3654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += it.parsedValue.size; 3659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mBag.size(); 3661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create correct ordering of items. 3663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<uint32_t, const Item*> items; 3664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items.add(it.bagKeyId, &it); 3667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = items.size(); 3669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map_entry mapHeader; 3671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(&mapHeader, &header, sizeof(header)); 3672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.size = htods(sizeof(mapHeader)); 3673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.parent.ident = htodl(mParentId); 3674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.count = htodl(N); 3675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&mapHeader, sizeof(mapHeader)); 3676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = *items.valueAt(i); 3683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map map; 3684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.name.ident = htodl(it.bagKeyId); 3685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.size = htods(it.parsedValue.size); 3686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.dataType = it.parsedValue.dataType; 3687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.res0 = it.parsedValue.res0; 3688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.data = htodl(it.parsedValue.data); 3689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&map, sizeof(map)); 3690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += sizeof(map); 3695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendComment(const String16& comment, 3701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 3702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyIfEmpty && mComment.size() > 0) { 3707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mComment.size() > 0) { 3710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(String16("\n")); 3711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(comment); 3713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendTypeComment(const String16& comment) 3716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mTypeComment.size() > 0) { 3721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(String16("\n")); 3722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(comment); 3724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, 3727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 3728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 3729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t entryIdx = Res_GETENTRY(ident); 3732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryIdx < 0) { 3733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", 3734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), ident); 3735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t typeIdx = Res_GETTYPE(ident); 3740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 3741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdx++; 3742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublicIndex > 0 && mPublicIndex != typeIdx) { 3743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting type codes for its" 3744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " public identifiers (0x%x vs 0x%x).\n", 3745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), 3746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex, typeIdx); 3747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex = typeIdx; 3750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFirstPublicSourcePos == NULL) { 3753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFirstPublicSourcePos = new SourcePos(sourcePos); 3754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublic.indexOfKey(name) < 0) { 3757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublic.add(name, Public(sourcePos, String16(), ident)); 3758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Public& p = mPublic.editValueFor(name); 3760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p.ident != ident) { 3761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting public identifiers" 3762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " (0x%08x vs 0x%08x).\n" 3763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), p.ident, ident, 3765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.file.string(), p.sourcePos.line); 3766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::Type::canAddEntry(const String16& name) 3774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanAddEntries.add(name); 3776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, 3779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 3781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex, 3782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 3783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool autoAddOverlay) 3784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pos = -1; 3786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = mConfigs.valueFor(entry); 3787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) { 3789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource at %s appears in overlay but not" 3790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " in the base package; use <add-resource> to add.\n", 3791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(entry).string()); 3792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c = new ConfigList(entry, sourcePos); 3795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mConfigs.add(entry, c); 3796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos = (int)mOrderedConfigs.size(); 3797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.add(c); 3798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(pos); 3800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 3804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 3805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 3807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 3808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 3809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " 3810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line, 3813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->mcc, config->mnc, 3814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[0] ? config->language[0] : '-', 3815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[1] ? config->language[1] : '-', 3816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[0] ? config->country[0] : '-', 3817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[1] ? config->country[1] : '-', 3818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->orientation, 3819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->touchscreen, 3820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->density, 3821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->keyboard, 3822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->inputFlags, 3823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->navigation, 3824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidth, 3825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeight, 3826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->smallestScreenWidthDp, 3827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidthDp, 3828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeightDp, 3829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->layoutDirection)); 3830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: NULL config\n", 3832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line)); 3833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e = new Entry(entry, sourcePos); 3835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->addEntry(cdesc, e); 3836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 3837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 3839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) { 3840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedConfigs[pos] == c) { 3841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= (int)mOrderedConfigs.size()) { 3845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry"); 3846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setEntryIndex(pos); 3850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 3852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 3855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 38579b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskisp<ResourceTable::ConfigList> ResourceTable::Type::removeEntry(const String16& entry) { 38589b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski ssize_t idx = mConfigs.indexOfKey(entry); 38599b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (idx < 0) { 38609b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return NULL; 38619b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 38629b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 38639b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<ConfigList> removed = mConfigs.valueAt(idx); 38649b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mConfigs.removeItemsAt(idx); 38659b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 38669b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Vector<sp<ConfigList> >::iterator iter = std::find( 38679b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.begin(), mOrderedConfigs.end(), removed); 38689b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (iter != mOrderedConfigs.end()) { 38699b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.erase(iter); 38709b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 38719b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 38729b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mPublic.removeItem(entry); 38739b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return removed; 38749b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 38759b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 38769b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam LesinskiSortedVector<ConfigDescription> ResourceTable::Type::getUniqueConfigs() const { 38779b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski SortedVector<ConfigDescription> unique; 38789b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t entryCount = mOrderedConfigs.size(); 38799b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < entryCount; i++) { 38809b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mOrderedConfigs[i] == NULL) { 38819b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 38829b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 38839b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configs = 38849b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs[i]->getEntries(); 38859b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t configCount = configs.size(); 38869b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t j = 0; j < configCount; j++) { 38879b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski unique.add(configs.keyAt(j)); 38889b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 38899b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 38909b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return unique; 38919b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 38929b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 3893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::applyPublicEntryOrder() 3894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedConfigs.size(); 3896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<ConfigList> > origOrder(mOrderedConfigs); 3897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasError = false; 3898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(NULL, i); 3902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NP = mPublic.size(); 3905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordering %d configs from %d public defs\n", N, NP); 3906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 3907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j=0; j<NP; j++) { 3908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name = mPublic.keyAt(j); 3909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Public& p = mPublic.valueAt(j); 3910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = Res_GETENTRY(p.ident); 3911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", 3912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mName).string(), String8(name).string(), p.ident, N); 3913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool found = false; 3914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); 3917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getName() == name) { 3918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx >= (int32_t)mOrderedConfigs.size()) { 39199b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski mOrderedConfigs.resize(idx + 1); 39209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 39219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 39229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (mOrderedConfigs.itemAt(idx) == NULL) { 3923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublic(true); 3924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublicSourcePos(p.sourcePos); 3925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, idx); 3926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 3927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 3928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski found = true; 3929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> oe = mOrderedConfigs.itemAt(idx); 3932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Multiple entry names declared for public entry" 3934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x in type %s (%s vs %s).\n" 3935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 3936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx+1, String8(mName).string(), 3937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(oe->getName()).string(), 3938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), 3939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().file.string(), 3940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().line); 3941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!found) { 3947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public symbol %s/%s declared here is not defined.", 3948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string()); 3949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size()); 3954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != origOrder.size()) { 3956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Internal error: remaining private symbol count mismatch\n"); 3957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = origOrder.size(); 3958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j = 0; 3961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining entries. 3964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedConfigs.itemAt(j) != NULL) { 3965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, j); 3968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasError ? UNKNOWN_ERROR : NO_ERROR; 3972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3974833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::Package::Package(const String16& name, size_t packageId) 3975833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mName(name), mPackageId(packageId), 3976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeStringsMapping(0xffffffff), 3977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mKeyStringsMapping(0xffffffff) 3978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type, 3982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 3984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = mTypes.valueFor(type); 3986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = new Type(type, sourcePos); 3988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypes.add(type, t); 3989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(t); 3990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For some reason the type's index is set to one plus the index 3992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the mOrderedTypes list, rather than just the index. 3993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->setIndex(mOrderedTypes.size()); 3994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t; 3997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data) 4000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping); 4002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 4003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Type string data is corrupt!\n"); 400457079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 4005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 400657079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 400757079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 400857079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 400957079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mTypeStringsData = data; 401057079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 4011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data) 4014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping); 4016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 4017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Key string data is corrupt!\n"); 401857079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 4019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 402057079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 402157079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 402257079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 402357079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mKeyStringsData = data; 402457079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 4025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data, 4028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResStringPool* strings, 4029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t>* mappings) 4030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data->getData() == NULL) { 4032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 4033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Setting restable string pool: " 4036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(data->getData(), data->getSize()) << endl); 4037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = strings->setTo(data->getData(), data->getSize()); 4039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 4040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = strings->size(); 4041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 4043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mappings->add(String16(strings->stringAt(i, &len)), i); 4044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 4047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::applyPublicTypeOrder() 4050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedTypes.size(); 4052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Type> > origOrder(mOrderedTypes); 4053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(NULL, i); 4057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 4061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = t->getPublicIndex(); 4062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx > 0) { 4063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx--; 4064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (idx >= (int32_t)mOrderedTypes.size()) { 4065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(); 4066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedTypes.itemAt(idx) != NULL) { 4068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> ot = mOrderedTypes.itemAt(idx); 4069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->getFirstPublicSourcePos().error("Multiple type names declared for public type" 4070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x (%s vs %s).\n" 4071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 4072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx, String8(ot->getName()).string(), 4073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 4074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().file.string(), 4075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().line); 4076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 4077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, idx); 4079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 4080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i--; 4081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 4082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j=0; 4086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 4088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining types. 4089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedTypes.itemAt(j) != NULL) { 4090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 4091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, j); 4093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 4096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 40989b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinskivoid ResourceTable::Package::movePrivateAttrs() { 40999b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Type> attr = mTypes.valueFor(String16("attr")); 41009b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (attr == NULL) { 41019b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Nothing to do. 41029b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return; 41039b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41049b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41059b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski Vector<sp<ConfigList> > privateAttrs; 41069b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41079b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski bool hasPublic = false; 41089b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const Vector<sp<ConfigList> >& configs = attr->getOrderedConfigs(); 41099b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t configCount = configs.size(); 41109b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < configCount; i++) { 41119b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (configs[i] == NULL) { 41129b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski continue; 41139b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41149b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41159b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (attr->isPublic(configs[i]->getName())) { 41169b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski hasPublic = true; 41179b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } else { 41189b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski privateAttrs.add(configs[i]); 41199b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41209b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41219b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41229b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Only if we have public attributes do we create a separate type for 41239b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // private attributes. 41249b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski if (!hasPublic) { 41259b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski return; 41269b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41279b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41289b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Create a new type for private attributes. 41299b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Type> privateAttrType = getType(String16(kAttrPrivateType), SourcePos()); 41309b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41319b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t privateAttrCount = privateAttrs.size(); 41329b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t i = 0; i < privateAttrCount; i++) { 41339b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const sp<ConfigList>& cl = privateAttrs[i]; 41349b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41359b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Remove the private attributes from their current type. 41369b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski attr->removeEntry(cl->getName()); 41379b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41389b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Add it to the new type. 41399b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = cl->getEntries(); 41409b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const size_t entryCount = entries.size(); 41419b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski for (size_t j = 0; j < entryCount; j++) { 41429b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski const sp<Entry>& oldEntry = entries[j]; 41439b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski sp<Entry> entry = privateAttrType->getEntry( 41449b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski cl->getName(), oldEntry->getPos(), &entries.keyAt(j)); 41459b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski *entry = *oldEntry; 41469b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41479b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41489b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski // Move the symbols to the new type. 41499b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 41509b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski } 41519b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski} 41529b624c186cb6059dfb3ec24bfb6386a0fc17b88cAdam Lesinski 4153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) 4154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4155833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package != mAssetsPackage) { 4156833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NULL; 4157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4158833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return mPackages.valueFor(package); 4159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::getType(const String16& package, 4162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = getPackage(package); 4167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return p->getType(type, sourcePos, doSetIndex); 4171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, 4174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 4176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 4178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 4179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos, doSetIndex); 4182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 4183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay()); 4186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4188e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskisp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package, 4189e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& type, const String16& name) const 4190e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski{ 4191e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t packageCount = mOrderedPackages.size(); 4192e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 4193e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Package>& p = mOrderedPackages[pi]; 4194e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (p == NULL || p->getName() != package) { 4195e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4196e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4197e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4198e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<Type> >& types = p->getOrderedTypes(); 4199e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t typeCount = types.size(); 4200e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 4201e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Type>& t = types[ti]; 4202e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (t == NULL || t->getName() != type) { 4203e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4204e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4205e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4206e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs(); 4207e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t configCount = configs.size(); 4208e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 4209e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<ConfigList>& cl = configs[ci]; 4210e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (cl == NULL || cl->getName() != name) { 4211e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4212e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4213e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4214e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return cl; 4215e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4216e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4217e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4218e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NULL; 4219e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4220e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, 4222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config) const 4223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4224833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski size_t pid = Res_GETPACKAGE(resID)+1; 4225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 4226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p; 4227833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; i++) { 4228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> check = mOrderedPackages[i]; 4229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (check->getAssignedId() == pid) { 4230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = check; 4231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Package not found for resource #%08x\n", resID); 4237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int tid = Res_GETTYPE(resID); 4241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) { 4242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Type not found for resource #%08x\n", resID); 4243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes()[tid]; 4246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int eid = Res_GETENTRY(resID); 4248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) { 4249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs()[eid]; 4254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 4260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 4261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 4262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID); 4264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 4268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const 4271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 4274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = e->getBag().valueAt(i); 4280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 4281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n", 4282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == attrID) { 4286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ⁢ 4287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getItemValue( 4294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resID, uint32_t attrID, Res_value* outValue) 4295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item* item = getItem(resID, attrID); 4297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = false; 4299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item != NULL) { 4300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item->evaluating) { 4301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&e->getBag().valueAt(i) == item) { 4306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n", 4310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 4313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = true; 4315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId); 4316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY( 4317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 4318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", 4319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID, String8(getEntry(resID)->getName()).string(), 4320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType, outValue->data); 4321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x]: failed\n", 4323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID); 4324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ); 4326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = false; 4327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 4329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 433082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 433182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 433228994d8d181c286b39811441ce78399576c2d315Adam Lesinski * Returns the SDK version at which the attribute was 433328994d8d181c286b39811441ce78399576c2d315Adam Lesinski * made public, or -1 if the resource ID is not an attribute 433428994d8d181c286b39811441ce78399576c2d315Adam Lesinski * or is not public. 433582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 433628994d8d181c286b39811441ce78399576c2d315Adam Lesinskiint ResourceTable::getPublicAttributeSdkLevel(uint32_t attrId) const { 433728994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (Res_GETPACKAGE(attrId) + 1 != 0x01 || Res_GETTYPE(attrId) + 1 != 0x01) { 433828994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 433982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 434082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 434182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski uint32_t specFlags; 434282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (!mAssets->getIncludedResources().getResourceFlags(attrId, &specFlags)) { 434328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 434428994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 434528994d8d181c286b39811441ce78399576c2d315Adam Lesinski 434628994d8d181c286b39811441ce78399576c2d315Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 434728994d8d181c286b39811441ce78399576c2d315Adam Lesinski return -1; 434828994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 434928994d8d181c286b39811441ce78399576c2d315Adam Lesinski 435028994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t entryId = Res_GETENTRY(attrId); 435128994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (entryId <= 0x021c) { 435228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 1; 435328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x021d) { 435428994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 2; 435528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0269) { 435628994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_CUPCAKE; 435728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x028d) { 435828994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_DONUT; 435928994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02ad) { 436028994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR; 436128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02b3) { 436228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR_0_1; 436328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02b5) { 436428994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_ECLAIR_MR1; 436528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02bd) { 436628994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_FROYO; 436728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x02cb) { 436828994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_GINGERBREAD; 436928994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0361) { 437028994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB; 437128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x0366) { 437228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB_MR1; 437328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03a6) { 437428994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_HONEYCOMB_MR2; 437528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03ae) { 437628994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN; 437728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03cc) { 437828994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN_MR1; 437928994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03da) { 438028994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_JELLY_BEAN_MR2; 438128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03f1) { 438228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_KITKAT; 438328994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x03f6) { 438428994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_KITKAT_WATCH; 438528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (entryId <= 0x04ce) { 438628994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_LOLLIPOP; 438728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else { 438828994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Anything else is marked as defined in 438928994d8d181c286b39811441ce78399576c2d315Adam Lesinski // SDK_LOLLIPOP_MR1 since after this 439028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // version no attribute compat work 439128994d8d181c286b39811441ce78399576c2d315Adam Lesinski // needs to be done. 439228994d8d181c286b39811441ce78399576c2d315Adam Lesinski return SDK_LOLLIPOP_MR1; 439382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 439482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 439582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 439628994d8d181c286b39811441ce78399576c2d315Adam Lesinski/** 439728994d8d181c286b39811441ce78399576c2d315Adam Lesinski * First check the Manifest, then check the command line flag. 439828994d8d181c286b39811441ce78399576c2d315Adam Lesinski */ 439928994d8d181c286b39811441ce78399576c2d315Adam Lesinskistatic int getMinSdkVersion(const Bundle* bundle) { 440028994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (bundle->getManifestMinSdkVersion() != NULL && strlen(bundle->getManifestMinSdkVersion()) > 0) { 440128994d8d181c286b39811441ce78399576c2d315Adam Lesinski return atoi(bundle->getManifestMinSdkVersion()); 440228994d8d181c286b39811441ce78399576c2d315Adam Lesinski } else if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) { 440328994d8d181c286b39811441ce78399576c2d315Adam Lesinski return atoi(bundle->getMinSdkVersion()); 4404e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 440528994d8d181c286b39811441ce78399576c2d315Adam Lesinski return 0; 4406e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4407e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 440882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 440982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Modifies the entries in the resource table to account for compatibility 441082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * issues with older versions of Android. 441182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 441282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * This primarily handles the issue of private/public attribute clashes 441382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * in framework resources. 441482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 441582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * AAPT has traditionally assigned resource IDs to public attributes, 441682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * and then followed those public definitions with private attributes. 441782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 441882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 441982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 442082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 442182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 442282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 442382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/secret 442482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/shhh 442582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 442682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Each release, when attributes are added, they take the place of the private 442782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attributes and the private attributes are shifted down again. 442882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 442982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 443082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 443182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 443282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/shinyNewAttr 443382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/highlyValuedFeature 443482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 443582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 443682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010238 | attr/secret 443782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010239 | attr/shhh 443882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 443982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Platform code may look for private attributes set in a theme. If an app 444082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * compiled against a newer version of the platform uses a new public 444182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute that happens to have the same ID as the private attribute 444282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * the older platform is expecting, then the behavior is undefined. 444382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 444482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * We get around this by detecting any newly defined attributes (in L), 444582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * copy the resource into a -v21 qualified resource, and delete the 444682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute from the original resource. This ensures that older platforms 444782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * don't see the new attribute, but when running on L+ platforms, the 444882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute will be respected. 444982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 445082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle) { 445128994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int minSdk = getMinSdkVersion(bundle); 445228994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (minSdk >= SDK_LOLLIPOP_MR1) { 445328994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Lollipop MR1 and up handles public attributes differently, no 445428994d8d181c286b39811441ce78399576c2d315Adam Lesinski // need to do any compat modifications. 4455e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 445682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 445782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 445882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const String16 attr16("attr"); 445982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 446082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t packageCount = mOrderedPackages.size(); 446182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 446282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 446382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (p == NULL || p->getTypes().size() == 0) { 446482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Empty, skip! 446582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 446682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 446782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 446882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 446982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 447082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 447182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (t == NULL) { 447282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 447382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 447482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 447582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t configCount = t->getOrderedConfigs().size(); 447682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 447782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 447882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (c == NULL) { 447982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 448082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 448182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 448282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski Vector<key_value_pair_t<ConfigDescription, sp<Entry> > > entriesToAdd; 448382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = 448482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski c->getEntries(); 448582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entryCount = entries.size(); 448682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ei = 0; ei < entryCount; ei++) { 448782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Entry> e = entries.valueAt(ei); 448882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (e == NULL || e->getType() != Entry::TYPE_BAG) { 448982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 449082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 449182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 449282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const ConfigDescription& config = entries.keyAt(ei); 449328994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (config.sdkVersion >= SDK_LOLLIPOP_MR1) { 449482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 449582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 449682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 449728994d8d181c286b39811441ce78399576c2d315Adam Lesinski KeyedVector<int, Vector<String16> > attributesToRemove; 449882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const KeyedVector<String16, Item>& bag = e->getBag(); 449982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t bagCount = bag.size(); 450082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t bi = 0; bi < bagCount; bi++) { 450182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const Item& item = bag.valueAt(bi); 450282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const uint32_t attrId = getResId(bag.keyAt(bi), &attr16); 450328994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = getPublicAttributeSdkLevel(attrId); 450428994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) { 450528994d8d181c286b39811441ce78399576c2d315Adam Lesinski AaptUtil::appendValue(attributesToRemove, sdkLevel, bag.keyAt(bi)); 450682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 450782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 450882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 450982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (attributesToRemove.isEmpty()) { 451082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 451182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 451282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 451328994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t sdkCount = attributesToRemove.size(); 451428994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t i = 0; i < sdkCount; i++) { 451528994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = attributesToRemove.keyAt(i); 451628994d8d181c286b39811441ce78399576c2d315Adam Lesinski 451728994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Duplicate the entry under the same configuration 451828994d8d181c286b39811441ce78399576c2d315Adam Lesinski // but with sdkVersion == sdkLevel. 451928994d8d181c286b39811441ce78399576c2d315Adam Lesinski ConfigDescription newConfig(config); 452028994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion = sdkLevel; 452128994d8d181c286b39811441ce78399576c2d315Adam Lesinski 452228994d8d181c286b39811441ce78399576c2d315Adam Lesinski sp<Entry> newEntry = new Entry(*e); 452328994d8d181c286b39811441ce78399576c2d315Adam Lesinski 452428994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Remove all items that have a higher SDK level than 452528994d8d181c286b39811441ce78399576c2d315Adam Lesinski // the one we are synthesizing. 452628994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t j = 0; j < sdkCount; j++) { 452728994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (j == i) { 452828994d8d181c286b39811441ce78399576c2d315Adam Lesinski continue; 452928994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 453028994d8d181c286b39811441ce78399576c2d315Adam Lesinski 453128994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (attributesToRemove.keyAt(j) > sdkLevel) { 453228994d8d181c286b39811441ce78399576c2d315Adam Lesinski const size_t attrCount = attributesToRemove[j].size(); 453328994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t k = 0; k < attrCount; k++) { 453428994d8d181c286b39811441ce78399576c2d315Adam Lesinski newEntry->removeFromBag(attributesToRemove[j][k]); 453528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 453628994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 453728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 453828994d8d181c286b39811441ce78399576c2d315Adam Lesinski 453928994d8d181c286b39811441ce78399576c2d315Adam Lesinski entriesToAdd.add(key_value_pair_t<ConfigDescription, sp<Entry> >( 454028994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig, newEntry)); 454128994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 454282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 454382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Remove the attribute from the original. 454482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < attributesToRemove.size(); i++) { 454528994d8d181c286b39811441ce78399576c2d315Adam Lesinski for (size_t j = 0; j < attributesToRemove[i].size(); j++) { 454628994d8d181c286b39811441ce78399576c2d315Adam Lesinski e->removeFromBag(attributesToRemove[i][j]); 454728994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 454882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 454982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 455082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 455182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entriesToAddCount = entriesToAdd.size(); 455282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < entriesToAddCount; i++) { 455382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (entries.indexOfKey(entriesToAdd[i].key) >= 0) { 455482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // An entry already exists for this config. 455582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // That means that any attributes that were 455682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // defined in L in the original bag will be overriden 455782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // anyways on L devices, so we do nothing. 455882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 455982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 456082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 4561f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski if (bundle->getVerbose()) { 4562f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski entriesToAdd[i].value->getPos() 4563f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski .printf("using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 456428994d8d181c286b39811441ce78399576c2d315Adam Lesinski entriesToAdd[i].key.sdkVersion, 4565f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(p->getName()).string(), 4566f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(t->getName()).string(), 4567f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(entriesToAdd[i].value->getName()).string(), 4568f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski entriesToAdd[i].key.toString().string()); 4569f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski } 457082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 4571978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski sp<Entry> newEntry = t->getEntry(c->getName(), 4572978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski entriesToAdd[i].value->getPos(), 4573978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski &entriesToAdd[i].key); 4574978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski 4575978ab9d92934b79409638cf220de3002fea8d505Adam Lesinski *newEntry = *entriesToAdd[i].value; 457682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 457782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 457882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 457982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 458082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 458182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 4582e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4583e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle, 4584e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 4585e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptFile>& target, 4586e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<XMLNode>& root) { 458728994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int minSdk = getMinSdkVersion(bundle); 458828994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (minSdk >= SDK_LOLLIPOP_MR1) { 458928994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Lollipop MR1 and up handles public attributes differently, no 459028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // need to do any compat modifications. 4591e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4592e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4593e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 459428994d8d181c286b39811441ce78399576c2d315Adam Lesinski const ConfigDescription config(target->getGroupEntry().toParams()); 459528994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (target->getResourceType() == "" || config.sdkVersion >= SDK_LOLLIPOP_MR1) { 4596e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Skip resources that have no type (AndroidManifest.xml) or are already version qualified with v21 4597e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // or higher. 4598e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4599e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4600e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4601ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski sp<XMLNode> newRoot = NULL; 460228994d8d181c286b39811441ce78399576c2d315Adam Lesinski ConfigDescription newConfig(target->getGroupEntry().toParams()); 460328994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion = SDK_LOLLIPOP_MR1; 4604e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4605e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski Vector<sp<XMLNode> > nodesToVisit; 4606e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(root); 4607e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski while (!nodesToVisit.isEmpty()) { 4608e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<XMLNode> node = nodesToVisit.top(); 4609e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.pop(); 4610e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4611e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes(); 4612ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski for (size_t i = 0; i < attrs.size(); i++) { 4613e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const XMLNode::attribute_entry& attr = attrs[i]; 461428994d8d181c286b39811441ce78399576c2d315Adam Lesinski const int sdkLevel = getPublicAttributeSdkLevel(attr.nameResId); 461528994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) { 4616ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (newRoot == NULL) { 4617ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski newRoot = root->clone(); 4618ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski } 4619ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski 462028994d8d181c286b39811441ce78399576c2d315Adam Lesinski // Find the smallest sdk version that we need to synthesize for 462128994d8d181c286b39811441ce78399576c2d315Adam Lesinski // and do that one. Subsequent versions will be processed on 462228994d8d181c286b39811441ce78399576c2d315Adam Lesinski // the next pass. 462328994d8d181c286b39811441ce78399576c2d315Adam Lesinski if (sdkLevel < newConfig.sdkVersion) { 462428994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion = sdkLevel; 462528994d8d181c286b39811441ce78399576c2d315Adam Lesinski } 462628994d8d181c286b39811441ce78399576c2d315Adam Lesinski 4627ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (bundle->getVerbose()) { 4628ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski SourcePos(node->getFilename(), node->getStartLineNumber()).printf( 4629ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski "removing attribute %s%s%s from <%s>", 4630ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(attr.ns).string(), 4631ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski (attr.ns.size() == 0 ? "" : ":"), 4632ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(attr.name).string(), 4633ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski String8(node->getElementName()).string()); 4634ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski } 4635ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski node->removeAttribute(i); 4636ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski i--; 4637e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4638e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4639e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4640e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule a visit to the children. 4641e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<XMLNode> >& children = node->getChildren(); 4642e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t childCount = children.size(); 4643e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t i = 0; i < childCount; i++) { 4644e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(children[i]); 4645e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4646e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4647e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4648ea4e5ecc27793b5c1dd2eda291f752b3f900ee6cAdam Lesinski if (newRoot == NULL) { 4649e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4650e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4651e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4652e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Look to see if we already have an overriding v21 configuration. 4653e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), 4654e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), resourceName); 4655e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (cl->getEntries().indexOfKey(newConfig) < 0) { 4656e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // We don't have an overriding entry for v21, so we must duplicate this one. 4657e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), 4658e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski AaptGroupEntry(newConfig), target->getResourceType()); 4659e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8 resPath = String8::format("res/%s/%s", 4660e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newFile->getGroupEntry().toDirName(target->getResourceType()).string(), 4661aff7c2447df1ddfe094628317b6d22121cd657f8Adam Lesinski target->getSourceFile().getPathLeaf().string()); 4662e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resPath.convertToResPath(); 4663e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4664e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Add a resource table entry. 4665f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski if (bundle->getVerbose()) { 4666f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski SourcePos(target->getSourceFile(), -1).printf( 4667f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski "using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 466828994d8d181c286b39811441ce78399576c2d315Adam Lesinski newConfig.sdkVersion, 4669f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski mAssets->getPackage().string(), 4670f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski newFile->getResourceType().string(), 4671f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski String8(resourceName).string(), 4672f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski newConfig.toString().string()); 4673f15de2e2151ae48338afd27f3ebd33fce5009103Adam Lesinski } 4674e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4675e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski addEntry(SourcePos(), 4676e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(mAssets->getPackage()), 4677e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), 4678e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resourceName, 4679e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(resPath), 4680e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski NULL, 4681e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski &newConfig); 4682e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4683e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule this to be compiled. 4684e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski CompileResourceWorkItem item; 4685e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resourceName = resourceName; 4686e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resPath = resPath; 4687e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.file = newFile; 4688e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski mWorkQueue.push(item); 4689e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4690e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4691e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4692e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4693de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4694de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinskivoid ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { 4695de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const ConfigDescription nullConfig; 4696de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4697de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t packageCount = mOrderedPackages.size(); 4698de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t p = 0; p < packageCount; p++) { 4699de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes(); 4700de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t typeCount = types.size(); 4701de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t t = 0; t < typeCount; t++) { 4702de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); 4703de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t configCount = configs.size(); 4704de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t c = 0; c < configCount; c++) { 4705de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); 4706de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t configEntryCount = configEntries.size(); 4707de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t ce = 0; ce < configEntryCount; ce++) { 4708de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const ConfigDescription& config = configEntries.keyAt(ce); 4709de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (AaptConfig::isDensityOnly(config)) { 4710de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // This configuration only varies with regards to density. 4711de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Symbol symbol(mOrderedPackages[p]->getName(), 4712de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski types[t]->getName(), 4713de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski configs[c]->getName(), 4714de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); 4715de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 4716de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const sp<Entry>& entry = configEntries.valueAt(ce); 4717de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); 4718de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4719de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4720de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4721de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4722de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 4723de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski} 4724