Resource.cpp revision 27f69f4e06961fdecd1078b2292d764a157e5e1c
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#include "Main.h" 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "AaptAssets.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "StringPool.h" 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Images.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "CrunchCache.h" 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "FileFinder.h" 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "CacheUpdater.h" 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "WorkQueue.h" 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if HAVE_PRINTF_ZD 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski# define ZD "%zd" 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski# define ZD_TYPE ssize_t 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski# define ZD "%ld" 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski# define ZD_TYPE long 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) // x 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Number of threads to use for preprocessing images. 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t MAX_THREADS = 4; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass PackageInfo 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PackageInfo() 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ~PackageInfo() 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t parsePackage(const sp<AaptGroup>& grp); 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 parseResourceName(const String8& leaf) 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* firstDot = strchr(leaf.string(), '.'); 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* str = leaf.string(); 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (firstDot) { 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(str, firstDot-str); 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(str); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTypeSet::ResourceTypeSet() 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :RefBase(), 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8,sp<AaptGroup> >() 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiFilePathStore::FilePathStore() 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :RefBase(), 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8>() 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass ResourceDirIterator 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType) 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0) 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 8391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&mParams, 0, sizeof(ResTable_config)); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const sp<AaptGroup>& getGroup() const { return mGroup; } 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const sp<AaptFile>& getFile() const { return mFile; } 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const String8& getBaseName() const { return mBaseName; } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const String8& getLeafName() const { return mLeafName; } 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline String8 getPath() const { return mPath; } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const ResTable_config& getParams() const { return mParams; } 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enum { 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski EOD = 1 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t next() 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (true) { 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Try to get next file in this current group. 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) { 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = mGroup; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = group->getFiles().valueAt(mGroupPos++); 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Try to get the next group/file in this directory 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mSetPos < mSet->size()) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroup = group = mSet->valueAt(mSetPos++); 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (group->getFiles().size() < 1) { 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = group->getFiles().valueAt(0); 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupPos = 1; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // All done! 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return EOD; 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFile = file; 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 leaf(group->getLeaf()); 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLeafName = String8(leaf); 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams = file->getGroupEntry().toParams(); 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n", 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group->getPath().string(), mParams.mcc, mParams.mnc, 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.language[0] ? mParams.language[0] : '-', 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.language[1] ? mParams.language[1] : '-', 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.country[0] ? mParams.country[0] : '-', 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.country[1] ? mParams.country[1] : '-', 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.orientation, mParams.uiMode, 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.density, mParams.touchscreen, mParams.keyboard, 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams.inputFlags, mParams.navigation)); 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath = "res"; 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath.appendPath(file->getGroupEntry().toDirName(mResType)); 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath.appendPath(leaf); 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBaseName = parseResourceName(leaf); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mBaseName == "") { 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Error: malformed resource filename %s\n", 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("file name=%s\n", mBaseName.string())); 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate: 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mResType; 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet> mSet; 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t mSetPos; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> mGroup; 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t mGroupPos; 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> mFile; 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mBaseName; 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mLeafName; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mPath; 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config mParams; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 169eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownclass AnnotationProcessor { 170eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownpublic: 171eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { } 172eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 173eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown void preprocessComment(String8& comment) { 174eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.size() > 0) { 175eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.contains("@deprecated")) { 176eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown mDeprecated = true; 177eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 178eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.removeAll("@SystemApi")) { 179eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown mSystemApi = true; 180eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 181eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 182eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 183eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 184eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown void printAnnotations(FILE* fp, const char* indentStr) { 185eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (mDeprecated) { 186eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown fprintf(fp, "%s@Deprecated\n", indentStr); 187eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 188eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (mSystemApi) { 189eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown fprintf(fp, "%s@android.annotation.SystemApi\n", indentStr); 190eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 191eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 192eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 193eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownprivate: 194eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown bool mDeprecated; 195eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown bool mSystemApi; 196eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}; 197eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isValidResourceType(const String8& type) 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return type == "anim" || type == "animator" || type == "interpolator" 2057cce7bb5d8d68e78a414c176dc89a803f706c9ceChet Haase || type == "transition" 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "drawable" || type == "layout" 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "values" || type == "xml" || type == "raw" 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "color" || type == "menu" || type == "mipmap"; 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& grp) 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (grp->getFiles().size() != 1) { 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grp->getFiles().valueAt(0)->getPrintableSource().string()); 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(0); 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(file, &block); 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printXMLBlock(&block); 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::START_TAG 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::END_DOCUMENT 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: No start tag found\n", 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber()); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n", 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber(), 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIndex = block.indexOfAttribute(NULL, "package"); 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIndex < 0) { 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n", 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber()); 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len))); 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 uses_sdk16("uses-sdk"); 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) { 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "minSdkVersion"); 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minSdkIndex >= 0) { 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* minSdk8 = strdup(String8(minSdk16).string()); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->setManifestMinSdkVersion(minSdk8); 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets, 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet>& set, 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resType) 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 type8(resType); 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type16(resType); 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(set, String8(resType)); 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res; 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" (new resource id %s from %s)\n", 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.getBaseName().string(), it.getFile()->getPrintableSource().string()); 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 baseName(it.getBaseName()); 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* str = baseName.string(); 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + baseName.size(); 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!((*str >= 'a' && *str <= 'z') 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*str >= '0' && *str <= '9') 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *str == '_' || *str == '.')) { 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n", 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.getPath().string()); 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resPath = it.getPath(); 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resPath.convertToResPath(); 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()), 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type16, 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseName, 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(resPath), 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL, 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.getParams()); 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->addResource(it.getLeafName(), resPath, it.getFile(), type8); 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass PreProcessImageWorkUnit : public WorkQueue::WorkUnit { 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets, 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& file, volatile bool* hasErrors) : 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) { 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski virtual bool run() { 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = preProcessImage(mBundle, mAssets, mFile, NULL); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *mHasErrors = true; 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; // continue even if there are errors 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate: 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Bundle* mBundle; 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> mAssets; 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> mFile; 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski volatile bool* mHasErrors; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets, 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet>& set, const char* type) 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski volatile bool hasErrors = false; 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = NO_ERROR; 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUseCrunchCache() == false) { 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski WorkQueue wq(MAX_THREADS, false); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(set, String8(type)); 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit( 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle, assets, it.getFile(), &hasErrors); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = wq.schedule(w); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete w; 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = wq.finish(); 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR; 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void collect_files(const sp<AaptDir>& dir, 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* resources) 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles(); 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N = groups.size(); 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 leafName = groups.keyAt(i); 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& group = groups.valueAt(i); 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski = group->getFiles(); 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (files.size() == 0) { 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType = files.valueAt(0)->getResourceType(); 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(resType); 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> set = new ResourceTypeSet(); 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Creating new resource type set for leaf %s with group %s (%p)\n", 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski leafName.string(), group->getPath().string(), group.get())); 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set->add(leafName, group); 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resources->add(resType, set); 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> set = resources->valueAt(index); 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index = set->indexOfKey(leafName); 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding to resource type set for leaf %s group %s (%p)\n", 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski leafName.string(), group->getPath().string(), group.get())); 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set->add(leafName, group); 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> existingGroup = set->valueAt(index); 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Extending to resource type set for leaf %s group %s (%p)\n", 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski leafName.string(), group->getPath().string(), group.get())); 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<files.size(); j++) { 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding file %s in group %s resType %s\n", 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski files.valueAt(j)->getSourceFile().string(), 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski files.keyAt(j).toDirName(String8()).string(), 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resType.string())); 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = existingGroup->addFile(files.valueAt(j)); 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void collect_files(const sp<AaptAssets>& ass, 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* resources) 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& dirs = ass->resDirs(); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N = dirs.size(); 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> d = dirs.itemAt(i); 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(), 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d->getLeaf().string())); 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(d, resources); 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // don't try to include the res dir 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Removing dir leaf %s\n", d->getLeaf().string())); 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ass->removeDir(d->getLeaf()); 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_OKAY = -1, 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_NOT_FOUND = -2, 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_LEADING_SPACES = -3, 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_TRAILING_SPACES = -4 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int validateAttr(const String8& path, const ResTable& table, 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResXMLParser& parser, 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* ns, const char* attr, const char* validChars, bool required) 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = parser.indexOfAttribute(ns, attr); 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str; 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = &parser.getStrings(); 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_REFERENCE) { 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int strIdx; 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) { 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n", 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value.data); 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pool = table.getTableStringBlock(strIdx); 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool != NULL) { 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = pool->stringAt(value.data, &len); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr, 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specFlags, strIdx, str != NULL ? String8(str).string() : "???"); 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) { 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n", 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specFlags); 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_STRING) { 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool == NULL) { 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n", 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((str=pool->stringAt(value.data, &len)) == NULL) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n", 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n", 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value.dataType); 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validChars) { 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<len; i++) { 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint16_t c = str[i]; 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = validChars; 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool okay = false; 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == *p) { 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski okay = true; 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!okay) { 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n", 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, (char)str[i]); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int)i; 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*str == ' ') { 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n", 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_LEADING_SPACES; 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (str[len-1] == ' ') { 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n", 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_TRAILING_SPACES; 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_OKAY; 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (required) { 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n", 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_OKAY; 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void checkForIds(const String8& path, ResXMLParser& parser) 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=parser.next()) != ResXMLTree::END_DOCUMENT 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = parser.indexOfAttribute(NULL, "id"); 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n", 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber()); 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool applyFileOverlay(Bundle *bundle, 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> *baseSet, 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *resType) 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("applyFileOverlay for %s\n", resType); 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Replace any base level files in this category with any found from the overlay 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also add any found only in the overlay. 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> overlay = assets->getOverlay(); 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resTypeString(resType); 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // work through the linked list of overlays 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (overlay.get()) { 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources(); 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the overlay resources of the requested type 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = overlayRes->indexOfKey(resTypeString); 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for each of the resources, check for a match in the previously built 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-overlay "baseset". 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayCount = overlaySet->size(); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) { 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string()); 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 592f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski ssize_t baseIndex = -1; 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (baseSet->get() != NULL) { 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex)); 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 596f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (baseIndex >= 0) { 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // look for same flavor. For a given file (strings.xml, for example) 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // there may be a locale specific or other flavors - we want to match 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the same flavor. 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex); 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex); 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getFiles(); 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles = 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->getFiles(); 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i < baseFiles.size(); i++) { 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i, 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseFiles.keyAt(i).toString().string()); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i < overlayFiles.size(); i++) { 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i, 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(i).toString().string()); 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayGroupSize = overlayFiles.size(); 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayGroupIndex = 0; 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex<overlayGroupSize; 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex++) { 622f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski ssize_t baseFileIndex = 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->getFiles().indexOfKey(overlayFiles. 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keyAt(overlayGroupIndex)); 625f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (baseFileIndex >= 0) { 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("found a match (" ZD ") for overlay file %s, for flavor %s\n", 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (ZD_TYPE) baseFileIndex, 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getLeaf().string(), 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(overlayGroupIndex).toString().string()); 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->removeFile(baseFileIndex); 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // didn't find a match fall through and add it.. 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (true || bundle->getVerbose()) { 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("nothing matches overlay file %s, for flavor %s\n", 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getLeaf().string(), 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(overlayGroupIndex).toString().string()); 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex)); 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex)); 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (baseSet->get() == NULL) { 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *baseSet = new ResourceTypeSet(); 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getResources()->add(String8(resType), *baseSet); 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // this group doesn't exist (a file that's only in the overlay) 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*baseSet)->add(overlaySet->keyAt(overlayIndex), 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlaySet->valueAt(overlayIndex)); 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // make sure all flavors are defined in the resources. 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex); 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getFiles(); 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayGroupSize = overlayFiles.size(); 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayGroupIndex = 0; 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex<overlayGroupSize; 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex++) { 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex)); 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // this overlay didn't have resources for this type 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // try next overlay 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlay = overlay->getOverlay(); 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 673df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Inserts an attribute in a given node. 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If errorOnFailedInsert is true, and the attribute already exists, returns false. 675df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * If replaceExisting is true, the attribute will be updated if it already exists. 676df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Returns true otherwise, even if the attribute already exists, and does not modify 677df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * the existing attribute's value. 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool addTagAttribute(const sp<XMLNode>& node, const char* ns8, 680df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson const char* attr8, const char* value, bool errorOnFailedInsert, 681df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bool replaceExisting) 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value == NULL) { 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 ns(ns8); 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr(attr8); 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 690df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr); 691df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson if (existingEntry != NULL) { 692df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson if (replaceExisting) { 693df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);" 694df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson " overwriting existing value from manifest.\n", 695df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson String8(attr).string(), String8(ns).string())); 696df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson existingEntry->string = String16(value); 697df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson return true; 698df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson } 699df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (errorOnFailedInsert) { 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " cannot insert new value %s.\n", 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(attr).string(), String8(ns).string(), value); 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);" 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " using existing value in manifest.\n", 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(attr).string(), String8(ns).string()); 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // don't stop the build. 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski node->addAttribute(ns, attr, String16(value)); 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 719df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson/* 720df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Inserts an attribute in a given node, only if the attribute does not 721df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * exist. 722df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * If errorOnFailedInsert is true, and the attribute already exists, returns false. 723df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Returns true otherwise, even if the attribute already exists. 724df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson */ 725df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidsonbool addTagAttribute(const sp<XMLNode>& node, const char* ns8, 726df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson const char* attr8, const char* value, bool errorOnFailedInsert) 727df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson{ 728df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false); 729df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson} 730df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void fullyQualifyClassName(const String8& package, sp<XMLNode> node, 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& attrName) { 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = node->editAttribute( 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("http://schemas.android.com/apk/res/android"), attrName); 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr != NULL) { 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(attr->string); 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf --> package.asdf 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // .asdf .a.b --> package.asdf package.a.b 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf.adsf --> asdf.asdf 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className; 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = name.string(); 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* q = strchr(p, '.'); 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == q) { 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += package; 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (q == NULL) { 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += package; 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += "."; 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string())); 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(className)); 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t massageManifest(Bundle* bundle, sp<XMLNode> root) 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root = root->searchElement(String16(), String16("manifest")); 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "No <manifest> tag.\n"); 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool errorOnFailedInsert = bundle->getErrorOnFailedInsert(); 768df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bool replaceVersion = bundle->getReplaceVersion(); 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode", 771df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) { 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 7736a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski } else { 7746a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski const XMLNode::attribute_entry* attr = root->getAttribute( 7756a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode")); 7766a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski if (attr != NULL) { 7776a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski bundle->setVersionCode(strdup(String8(attr->string).string())); 7786a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski } 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 7806a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName", 782df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) { 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMinSdkVersion() != NULL 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || bundle->getTargetSdkVersion() != NULL 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || bundle->getMaxSdkVersion() != NULL) { 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk")); 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (vers == NULL) { 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk")); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->insertChildAt(vers, 0); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion", 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getMinSdkVersion(), errorOnFailedInsert)) { 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion", 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getTargetSdkVersion(), errorOnFailedInsert)) { 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion", 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getMaxSdkVersion(), errorOnFailedInsert)) { 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getDebugMode()) { 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> application = root->getChildElement(String16(), String16("application")); 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (application != NULL) { 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true", 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorOnFailedInsert)) { 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Deal with manifest package name overrides 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestPackageNameOverride != NULL) { 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update the actual package name 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package")); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr == NULL) { 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "package name is required with --rename-manifest-package.\n"); 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 origPackage(attr->string); 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(manifestPackageNameOverride)); 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride)); 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make class names fully qualified 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> application = root->getChildElement(String16(), String16("application")); 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (application != NULL) { 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, application, String16("name")); 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, application, String16("backupAgent")); 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren()); 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> child = children.editItemAt(i); 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(child->getElementName()); 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("name")); 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "activity-alias") { 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("name")); 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("targetActivity")); 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Deal with manifest package name overrides 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride(); 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (instrumentationPackageNameOverride != NULL) { 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fix up instrumentation targets. 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren()); 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> child = children.editItemAt(i); 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(child->getElementName()); 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "instrumentation") { 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = child->editAttribute( 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("http://schemas.android.com/apk/res/android"), String16("targetPackage")); 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr != NULL) { 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(instrumentationPackageNameOverride)); 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 870833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Generate split name if feature is present. 871833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16("featureName")); 872833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (attr != NULL) { 873833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String16 splitName("feature_"); 874833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski splitName.append(attr->string); 875833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski status_t err = root->addAttribute(String16(), String16("split"), splitName); 876833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (err != NO_ERROR) { 877833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ALOGE("Failed to insert split name into AndroidManifest.xml"); 878833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return err; 879833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 880833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 881833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define ASSIGN_IT(n) \ 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { \ 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(String8(#n)); \ 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { \ 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski n ## s = resources->valueAt(index); \ 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } \ 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (0) 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t updatePreProcessedCache(Bundle* bundle) 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if BENCHMARK 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n"); 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long startPNGTime = clock(); 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif /* BENCHMARK */ 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 source(bundle->getResourceSourceDirs()[0]); 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dest(bundle->getCrunchedOutputDir()); 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileFinder* ff = new SystemFileFinder(); 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CrunchCache cc(source,dest,ff); 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CacheUpdater* cu = new SystemCacheUpdater(bundle); 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t numFiles = cc.crunch(cu); 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles); 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete ff; 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete cu; 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if BENCHMARK 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n" 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ,(clock() - startPNGTime)/1000.0); 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif /* BENCHMARK */ 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 9222cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkeystatus_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets, 9232cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) { 924fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8 filename("AndroidManifest.xml"); 925fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String16 androidPrefix("android"); 926fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String16 androidNSUri("http://schemas.android.com/apk/res/android"); 927fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri); 928fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 929fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Build the <manifest> tag 930fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16("manifest")); 931fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 9322cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey // Add the 'package' attribute which is set to the package name. 9332cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const char* packageName = assets->getPackage(); 9342cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); 9352cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (manifestPackageNameOverride != NULL) { 9362cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey packageName = manifestPackageNameOverride; 9372cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey } 9382cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey manifest->addAttribute(String16(), String16("package"), String16(packageName)); 9392cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey 9402cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey // Add the 'versionCode' attribute which is set to the original version code. 9412cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "versionCode", 9422cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey bundle->getVersionCode(), true, true)) { 9432cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey return UNKNOWN_ERROR; 9442cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey } 945fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 946fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Add the 'split' attribute which describes the configurations included. 9476240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski String8 splitName("config."); 9486240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski splitName.append(split->getPackageSafeName()); 949fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski manifest->addAttribute(String16(), String16("split"), String16(splitName)); 950fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 951fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Build an empty <application> tag (required). 952fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16("application")); 95378a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey 95478a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey // Add the 'hasCode' attribute which is never true for resource splits. 95578a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, "hasCode", 95678a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey "false", true, true)) { 95778a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey return UNKNOWN_ERROR; 95878a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey } 95978a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey 960fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski manifest->addChild(app); 961fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski root->addChild(manifest); 962fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 9632cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey int err = compileXmlFile(assets, root, outFile, table); 9642cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (err < NO_ERROR) { 965fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 966fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 967fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski outFile->setCompressionMethod(ZipEntry::kCompressDeflated); 968fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return NO_ERROR; 969fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 970fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 971fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatus_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder) 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, look for a package file to parse. This is required to 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be able to generate the resource information. 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> androidManifestFile = 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getFiles().valueFor(String8("AndroidManifest.xml")); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (androidManifestFile == NULL) { 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n"); 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parsePackage(bundle, assets, androidManifestFile); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Creating resources for package %s\n", 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getPackage().string())); 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 990833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ResourceTable::PackageType packageType = ResourceTable::App; 991833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getBuildSharedLibrary()) { 992833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::SharedLibrary; 993833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } else if (bundle->getExtending()) { 994833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::System; 995833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } else if (!bundle->getFeatureOfPackage().isEmpty()) { 996833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::AppFeature; 997833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 998833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 999833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ResourceTable table(bundle, String16(assets->getPackage()), packageType); 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = table.addIncludedResources(bundle, assets); 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Found %d included resource packages\n", (int)table.size())); 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Standard flags for compiled XML and optional UTF-8 encoding 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xmlFlags = XML_COMPILE_STANDARD_RESOURCE; 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Only enable UTF-8 if the caller of aapt didn't specifically 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * request UTF-16 encoding and the parameters of this package 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * allow UTF-8 to be used. 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getUTF16StringsOption()) { 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xmlFlags |= XML_COMPILE_UTF8; 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, gather all resource information. 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resType -> leafName -> group 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new KeyedVector<String8, sp<ResourceTypeSet> >; 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(assets, resources); 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> drawables; 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> layouts; 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> anims; 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> animators; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> interpolators; 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> transitions; 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> xmls; 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> raws; 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> colors; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> menus; 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> mipmaps; 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(drawable); 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(layout); 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(anim); 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(animator); 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(interpolator); 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(transition); 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(xml); 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(raw); 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(color); 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(menu); 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(mipmap); 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setResources(resources); 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // now go through any resource overlays and collect their files 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> current = assets->getOverlay(); 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while(current.get()) { 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new KeyedVector<String8, sp<ResourceTypeSet> >; 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setResources(resources); 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(current, resources); 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = current->getOverlay(); 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // apply the overlay files to the base set 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!applyFileOverlay(bundle, assets, &drawables, "drawable") || 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &layouts, "layout") || 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &anims, "anim") || 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &animators, "animator") || 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &interpolators, "interpolator") || 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &transitions, "transition") || 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &xmls, "xml") || 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &raws, "raw") || 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &colors, "color") || 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &menus, "menu") || 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) { 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (drawables != NULL) { 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = preProcessImages(bundle, assets, drawables, "drawable"); 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, drawables, "drawable"); 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mipmaps != NULL) { 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = preProcessImages(bundle, assets, mipmaps, "mipmap"); 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap"); 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (layouts != NULL) { 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, layouts, "layout"); 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anims != NULL) { 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, anims, "anim"); 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (animators != NULL) { 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, animators, "animator"); 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (transitions != NULL) { 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, transitions, "transition"); 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (interpolators != NULL) { 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, interpolators, "interpolator"); 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xmls != NULL) { 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, xmls, "xml"); 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (raws != NULL) { 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, raws, "raw"); 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // compile resources 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = assets; 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while(current.get()) { 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->getResources(); 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(String8("values")); 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(resources->valueAt(index), String8("values")); 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res; 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = it.getFile(); 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = compileResourceFile(bundle, assets, file, it.getParams(), 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (current!=assets), &table); 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = current->getOverlay(); 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colors != NULL) { 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, colors, "color"); 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (menus != NULL) { 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, menus, "menu"); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------------- 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assignment of resource IDs and initial generation of resource table. 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------------- 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.hasResources()) { 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = table.assignResourceIds(); 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Finally, we can now we can compile XML files, which may reference 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resources. 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (layouts != NULL) { 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(layouts, String8("layout")); 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 src = it.getFile()->getPrintableSource(); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checkForIds(src, block); 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anims != NULL) { 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(anims, String8("anim")); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (animators != NULL) { 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(animators, String8("animator")); 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (interpolators != NULL) { 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(interpolators, String8("interpolator")); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (transitions != NULL) { 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(transitions, String8("transition")); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xmls != NULL) { 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(xmls, String8("xml")); 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (drawables != NULL) { 1303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResourceDirIterator it(drawables, String8("drawable")); 1304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = postProcessImage(assets, &table, it.getFile()); 1306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski hasErrors = true; 1308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err < NO_ERROR) { 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = NO_ERROR; 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colors != NULL) { 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(colors, String8("color")); 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (menus != NULL) { 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(menus, String8("menu")); 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 src = it.getFile()->getPrintableSource(); 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); 1337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err == NO_ERROR) { 1338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResXMLTree block; 1339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); 1340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski checkForIds(src, block); 1341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.validateLocalizations()) { 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0)); 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 manifestPath(manifestFile->getPrintableSource()); 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate final compiled manifest file. 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->clearData(); 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> manifestTree = XMLNode::parse(manifestFile); 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestTree == NULL) { 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = massageManifest(bundle, manifestTree); 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, manifestTree, manifestFile, &table); 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //block.restart(); 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printXMLBlock(&block); 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate the final resource table. 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Re-flatten because we may have added new resource IDs 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable finalResTable; 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> resFile; 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.hasResources()) { 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = table.addSymbols(symbols); 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1396fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<sp<ApkSplit> >& splits = builder->getSplits(); 1397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splits.size(); 1398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 1399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<ApkSplit>& split = splits.editItemAt(i); 1400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> flattenedTable = new AaptFile(String8("resources.arsc"), 1401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski AaptGroupEntry(), String8()); 140227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski err = table.flatten(bundle, split->getResourceFilter(), 140327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski flattenedTable, split->isBase()); 1404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to generate resource table for split '%s'\n", 1406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getPrintableName().string()); 1407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 1408fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->addEntry(String8("resources.arsc"), flattenedTable); 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (split->isBase()) { 1412fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski resFile = flattenedTable; 1413f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize()); 1414f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 1415f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski fprintf(stderr, "Generated resource table is corrupt.\n"); 1416f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 1417f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 1418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 1419fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"), 1420fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski AaptGroupEntry(), String8()); 14212cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey err = generateAndroidManifestForSplit(bundle, assets, split, 14222cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey generatedManifest, &table); 1423fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1424fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n", 1425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getPrintableName().string()); 1426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 1427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->addEntry(String8("AndroidManifest.xml"), generatedManifest); 1429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getPublicOutputFile()) { 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(bundle->getPublicOutputFile(), "w+"); 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n", 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (const char*)bundle->getPublicOutputFile(), strerror(errno)); 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing public definitions to %s.\n", bundle->getPublicOutputFile()); 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski table.writePublicDefinitions(String16(assets->getPackage()), fp); 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1446fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (finalResTable.getTableCount() == 0 || resFile == NULL) { 1447fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "No resource table was generated.\n"); 1448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return UNKNOWN_ERROR; 1449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Perform a basic validation of the manifest file. This time we 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // parse it with the comments intact, so that we can use them to 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate java docs... so we are not going to write this one 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back out to the final manifest data. 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(), 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->getGroupEntry(), 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->getResourceType()); 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileXmlFile(assets, manifestFile, 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outManifestFile, &table, 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XML_COMPILE_ASSIGN_ATTRIBUTE_IDS 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES); 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true); 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 manifest16("manifest"); 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 permission16("permission"); 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 permission_group16("permission-group"); 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 uses_permission16("uses-permission"); 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 instrumentation16("instrumentation"); 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 application16("application"); 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 provider16("provider"); 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 service16("service"); 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 receiver16("receiver"); 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 activity16("activity"); 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 action16("action"); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 category16("category"); 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 data16("scheme"); 1481d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski String16 feature_group16("feature-group"); 1482d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski String16 uses_feature16("uses-feature"); 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz" 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789"; 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz" 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz" 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$"; 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz" 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:"; 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz" 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;"; 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz" 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+"; 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz" 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> permissionSymbols; 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> permissionGroupSymbols; 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getElementNamespace(&len) != NULL) { 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) { 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, NULL, "package", 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sharedUserId", packageIdentChars, false) != ATTR_OKAY) { 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) { 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool isGroup = strcmp16(block.getElementName(&len), 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski permission_group16.string()) == 0; 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", isGroup ? packageIdentCharsWithTheStupid 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : packageIdentChars, true) != ATTR_OKAY) { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(manifestPath, block.getLineNumber()); 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> syms; 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!isGroup) { 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionSymbols; 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (syms == NULL) { 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getSymbolsFor(String8("Manifest")); 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionSymbols = symbols->addNestedSymbol( 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8("permission"), srcPos); 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionGroupSymbols; 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (syms == NULL) { 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getSymbolsFor(String8("Manifest")); 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionGroupSymbols = symbols->addNestedSymbol( 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8("permission_group"), srcPos); 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name"); 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* id = block.getAttributeStringValue(index, &len); 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id == NULL) { 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestPath.string(), block.getLineNumber(), 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 idStr(id); 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* p = idStr.lockBuffer(idStr.size()); 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* e = p + idStr.size(); 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool begins_with_digit = true; // init to true so an empty string fails 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (e > p) { 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e--; 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*e >= '0' && *e <= '9') { 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = true; 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*e >= 'a' && *e <= 'z') || 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*e >= 'A' && *e <= 'Z') || 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*e == '_')) { 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = false; 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isGroup && (*e == '-')) { 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *e = '_'; 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = false; 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e++; 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idStr.unlockBuffer(); 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // verify that we stopped because we hit a period or 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the beginning of the string, and that the 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // identifier didn't begin with a digit. 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (begins_with_digit || (e != p && *(e-1) != '.')) { 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Permission name <%s> is not a valid Java symbol\n", 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestPath.string(), block.getLineNumber(), idStr.string()); 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->addStringSymbol(String8(e), idStr, srcPos); 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* cmt = block.getComment(&len); 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cmt != NULL && *cmt != 0) { 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comment of %s: %s\n", String8(e).string(), 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(cmt).string()); 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->appendComment(String8(e), String16(cmt), srcPos); 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("No comment for %s\n", String8(e).string()); 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->makeSymbolPublic(String8(e), srcPos); 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) { 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", packageIdentChars, true) != ATTR_OKAY) { 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) { 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "targetPackage", 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) { 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, false) != ATTR_OKAY) { 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "taskAffinity", 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) { 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "authorities", 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski authoritiesIdentChars, true) != ATTR_OKAY) { 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 1645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 1646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 1650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), service16.string()) == 0 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), receiver16.string()) == 0 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), activity16.string()) == 0) { 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "taskAffinity", 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), action16.string()) == 0 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), category16.string()) == 0) { 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "name", 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) { 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "mimeType", 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdentChars, true) != ATTR_OKAY) { 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "scheme", 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski schemeIdentChars, true) != ATTR_OKAY) { 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1693d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) { 1694d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski int depth = 1; 1695d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1696d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 1697d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (code == ResXMLTree::START_TAG) { 1698d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski depth++; 1699d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) { 1700d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski ssize_t idx = block.indexOfAttribute( 1701d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski RESOURCES_ANDROID_NAMESPACE, "required"); 1702d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (idx < 0) { 1703d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski continue; 1704d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1705d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski 1706d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski int32_t data = block.getAttributeData(idx); 1707d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (data == 0) { 1708d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski fprintf(stderr, "%s:%d: Tag <uses-feature> can not have " 1709d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski "android:required=\"false\" when inside a " 1710d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski "<feature-group> tag.\n", 1711d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski manifestPath.string(), block.getLineNumber()); 1712d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski hasErrors = true; 1713d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1714d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1715d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } else if (code == ResXMLTree::END_TAG) { 1716d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski depth--; 1717d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (depth == 0) { 1718d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski break; 1719d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1720d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1721d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1726d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (hasErrors) { 1727d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski return UNKNOWN_ERROR; 1728d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 1729d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resFile != NULL) { 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These resources are now considered to be a part of the included 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resources, for others to reference. 1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->addIncludedResources(resFile); 1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n"); 1736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* getIndentSpace(int indent) 1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char whitespace[] = 1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski" "; 1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return whitespace + sizeof(whitespace) - 1 - indent*4; 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 flattenSymbol(const String8& symbol) { 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 result(symbol); 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t first; 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((first = symbol.find(":", 0)) >= 0 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (first = symbol.find(".", 0)) >= 0) { 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t size = symbol.size(); 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* buf = result.lockBuffer(size); 1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = first; i < size; i++) { 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf[i] == ':' || buf[i] == '.') { 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf[i] = '_'; 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result.unlockBuffer(size); 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) { 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t colon = symbol.find(":", 0); 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colon >= 0) { 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(symbol.string(), colon); 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage(); 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getSymbolName(const String8& symbol) { 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t colon = symbol.find(":", 0); 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colon >= 0) { 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(symbol.string() + colon + 1); 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return symbol; 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 getAttributeComment(const sp<AaptAssets>& assets, 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name, 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outTypeComment = NULL) 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R")); 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asym != NULL) { 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got R symbols!\n"); 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asym = asym->getNestedSymbols().valueFor(String8("attr")); 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asym != NULL) { 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got attrs symbols! comment %s=%s\n", 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // name.string(), String8(asym->getComment(name)).string()); 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outTypeComment != NULL) { 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outTypeComment = asym->getTypeComment(name); 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return asym->getComment(name); 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16(); 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeLayoutClasses( 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, 1806e8e91925074479fc06310418b58b54f49d051801Adam Lesinski const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId) 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* indentStr = getIndentSpace(indent); 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!includePrivate) { 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/** @doconly */\n", indentStr); 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic static final class styleable {\n", indentStr); 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent++; 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package16(assets->getPackage()); 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr = getIndentSpace(indent); 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getNestedSymbols().size(); 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 realClassName(symbols->getNestedSymbols().keyAt(i)); 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(flattenSymbol(realClassName)); 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<uint32_t> idents; 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<uint32_t> origOrder; 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> publicFlags; 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t a; 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t NA = nsymbols->getSymbols().size(); 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a)); 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? sym.int32Val : 0; 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isPublic = true; 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags; 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = assets->getIncludedResources().identifierForName( 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), sym.name.string()); 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idents.add(code); 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.add(code); 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski publicFlags.add(isPublic); 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NA = idents.size(); 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment = symbols->getComment(realClassName); 1861eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/** ", indentStr); 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 1865eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s\n", cmt.string()); 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string()); 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasTable = false; 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasTable) { 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasTable = true; 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>Includes the following attributes:</p>\n" 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <table>\n" 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <colgroup align=\"left\" />\n" 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <colgroup align=\"left\" />\n" 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <tr><th>Attribute</th><th>Description</th></tr>\n", 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr); 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8); 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = comment.string(); 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p != 0 && *p != '.') { 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*p == '{') { 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p != 0 && *p != '}') { 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*p == '.') { 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = String16(comment.string(), p-comment.string()); 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n", 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, true).string(), 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string(), 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasTable) { 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s </table>\n", indentStr); 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s @see #%s_%s\n", 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(sym.name).string()); 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s */\n", getIndentSpace(indent)); 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1938eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, indentStr); 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static final int[] %s = {\n" 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s", 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent+1)); 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a != 0) { 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((a&3) == 0) { 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ",\n%s", getIndentSpace(indent+1)); 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ", "); 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "0x%08x", idents[a]); 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n%s};\n", indentStr); 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment; 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8, &typeComment); 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getAttributeComment(assets, name8, &typeComment); 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags = 0; 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getIncludedResources().identifierForName( 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(attr16).string(), String8(name16).string(), typeSpecFlags); 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 1984eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 1985eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/**\n", indentStr); 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 1989eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s <p>\n%s @attr description\n", indentStr, indentStr); 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s %s\n", indentStr, cmt.string()); 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This symbol is the offset where the {@link %s.R.attr#%s}\n" 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s attribute's value can be found in the {@link #%s} array.\n", 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, pub).string(), 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string(), 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string()); 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeComment.size() > 0) { 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(typeComment); 2003eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n\n%s %s\n", indentStr, cmt.string()); 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This corresponds to the global attribute\n" 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s resource symbol {@link %s.R.attr#%s}.\n", 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, indentStr, 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, true).string(), 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string()); 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This is a private symbol.\n", indentStr); 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s @attr name %s:%s\n", indentStr, 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, pub).string(), 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string()); 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s*/\n", indentStr); 2023eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, indentStr); 2024e8e91925074479fc06310418b58b54f49d051801Adam Lesinski 2025e8e91925074479fc06310418b58b54f49d051801Adam Lesinski const char * id_format = nonConstantId ? 2026e8e91925074479fc06310418b58b54f49d051801Adam Lesinski "%spublic static int %s_%s = %d;\n" : 2027e8e91925074479fc06310418b58b54f49d051801Adam Lesinski "%spublic static final int %s_%s = %d;\n"; 2028e8e91925074479fc06310418b58b54f49d051801Adam Lesinski 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2030e8e91925074479fc06310418b58b54f49d051801Adam Lesinski id_format, 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)pos); 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent--; 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s};\n", getIndentSpace(indent)); 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeTextLayoutClasses( 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, bool includePrivate) 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package16(assets->getPackage()); 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getNestedSymbols().size(); 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 realClassName(symbols->getNestedSymbols().keyAt(i)); 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(flattenSymbol(realClassName)); 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<uint32_t> idents; 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<uint32_t> origOrder; 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> publicFlags; 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t a; 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t NA = nsymbols->getSymbols().size(); 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a)); 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? sym.int32Val : 0; 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isPublic = true; 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags; 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = assets->getIncludedResources().identifierForName( 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), sym.name.string()); 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idents.add(code); 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.add(code); 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski publicFlags.add(isPublic); 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NA = idents.size(); 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "int[] styleable %s {", nclassName.string()); 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a != 0) { 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ","); 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " 0x%08x", idents[a]); 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " }\n"); 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment; 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8, &typeComment); 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getAttributeComment(assets, name8, &typeComment); 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags = 0; 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getIncludedResources().identifierForName( 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(attr16).string(), String8(name16).string(), typeSpecFlags); 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "int styleable %s_%s %d\n", 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)pos); 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeSymbolClass( 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, const String8& className, int indent, 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool nonConstantId) 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic %sfinal class %s {\n", 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent != 0 ? "static " : "", className.string()); 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent++; 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char * id_format = nonConstantId ? 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static int %s=0x%08x;\n" : 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static final int %s=0x%08x;\n"; 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getSymbols().size(); 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool haveComment = false; 2167eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haveComment = true; 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2171eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n", 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), cmt.string()); 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sym.isPublic && !includePrivate) { 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym.sourcePos.warning("No comment for public symbol %s:%s/%s", 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getPackage().string(), className.string(), 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(sym.name).string()); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment(sym.typeComment); 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeComment.size() > 0) { 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(typeComment); 2183eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!haveComment) { 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haveComment = true; 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n", getIndentSpace(indent), cmt.string()); 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s %s\n", getIndentSpace(indent), cmt.string()); 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haveComment) { 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp,"%s */\n", getIndentSpace(indent)); 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2196eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, getIndentSpace(indent)); 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, id_format, 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)sym.int32Val); 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) { 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2212eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2215eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n" 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s */\n", 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), cmt.string(), 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent)); 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (sym.isPublic && !includePrivate) { 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym.sourcePos.warning("No comment for public symbol %s:%s/%s", 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getPackage().string(), className.string(), 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(sym.name).string()); 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2226eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, getIndentSpace(indent)); 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic static final String %s=\"%s\";\n", 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), sym.stringVal.string()); 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleableSymbols; 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = symbols->getNestedSymbols().size(); 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(symbols->getNestedSymbols().keyAt(i)); 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nclassName == "styleable") { 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleableSymbols = nsymbols; 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent, nonConstantId); 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (styleableSymbols != NULL) { 2249e8e91925074479fc06310418b58b54f49d051801Adam Lesinski err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId); 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent--; 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s}\n", getIndentSpace(indent)); 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeTextSymbolClass( 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, const String8& className) 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getSymbols().size(); 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "int %s %s 0x%08x\n", 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.string(), 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)sym.int32Val); 2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = symbols->getNestedSymbols().size(); 2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(symbols->getNestedSymbols().keyAt(i)); 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nclassName == "styleable") { 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate); 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName); 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& package, bool includePrivate) 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getRClassDir()) { 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* textSymbolsDest = bundle->getOutputTextSymbols(); 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 R("R"); 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = assets->getSymbols().size(); 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i); 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className(assets->getSymbols().keyAt(i)); 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dest(bundle->getRClassDir()); 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMakePackageDirs()) { 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg(package); 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* last = pkg.string(); 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* s = last-1; 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski s++; 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (s > last && (*s == '.' || *s == 0)) { 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 part(last, s-last); 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.appendPath(part); 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_MS_C_RUNTIME 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _mkdir(dest.string()); 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski last = s+1; 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (*s); 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.appendPath(className); 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.append(".java"); 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(dest.string(), "w+"); 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.string(), strerror(errno)); 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing symbols for class %s.\n", className.string()); 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " *\n" 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * This class was automatically generated by the\n" 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * aapt tool from the resource data it found. It\n" 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * should not be modified by hand.\n" 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " */\n" 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "package %s;\n\n", package.string()); 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className, 0, bundle->getNonConstantId()); 2359b30296b5fda75bf383c7ab3f567eb41820747869Elliott Hughes fclose(fp); 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (textSymbolsDest != NULL && R == className) { 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 textDest(textSymbolsDest); 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.appendPath(className); 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.append(".txt"); 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(textDest.string(), "w+"); 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n", 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.string(), strerror(errno)); 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing text symbols for class %s.\n", className.string()); 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols, 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className); 2381b30296b5fda75bf383c7ab3f567eb41820747869Elliott Hughes fclose(fp); 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we were asked to generate a dependency file, we'll go ahead and add this R.java 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // as a target in the dependency file right next to it. 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies() && R == className) { 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add this R.java to the dependency file 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile(bundle->getRClassDir()); 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE *fp = fopen(dependencyFile.string(), "a"); 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp,"%s \\\n", dest.string()); 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass ProguardKeepSet 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // { rule --> { file locations } } 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, SortedVector<String8> > rules; 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void add(const String8& rule, const String8& where); 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ProguardKeepSet::add(const String8& rule, const String8& where) 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = rules.indexOfKey(rule); 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index = rules.add(rule, SortedVector<String8>()); 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rules.editValueAt(index).add(where); 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiaddProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName, 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* pkg, const String8& srcName, int line) 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className(inClassName); 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf --> package.asdf 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // .asdf .a.b --> package.asdf package.a.b 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf.adsf --> asdf.asdf 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = className.string(); 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* q = strchr(p, '.'); 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == q) { 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className = pkg; 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append(inClassName); 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (q == NULL) { 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className = pkg; 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append("."); 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append(inClassName); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 rule("-keep class "); 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += className; 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += " { <init>(...); }"; 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 location("view "); 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += srcName; 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char lineno[20]; 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(lineno, ":%d", line); 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += lineno; 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keep->add(rule, location); 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiaddProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName, 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* pkg, const String8& srcName, int line) 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 rule("-keepclassmembers class * { *** "); 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += memberName; 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += "(...); }"; 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 location("onClick "); 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += srcName; 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char lineno[20]; 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(lineno, ":%d", line); 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += lineno; 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keep->add(rule, location); 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets) 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inApplication = false; 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> assGroup; 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> assFile; 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, look for a package file to parse. This is required to 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be able to generate the resource information. 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assGroup = assets->getFiles().valueFor(String8("AndroidManifest.xml")); 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (assGroup == NULL) { 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n"); 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (assGroup->getFiles().size() != 1) { 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assGroup->getFiles().valueAt(0)->getPrintableSource().string()); 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile = assGroup->getFiles().valueAt(0); 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseXMLResource(assFile, &tree); 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (/* name == "Application" && */ depth == 2) { 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inApplication = false; 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // printf("Depth %d tag %s\n", depth, tag.string()); 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool keepTag = false; 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = getAttribute(tree, NULL, "package", NULL); 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inApplication = true; 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 agent = getAttribute(tree, "http://schemas.android.com/apk/res/android", 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "backupAgent", &error); 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (agent.length() > 0) { 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, agent, pkg.string(), 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile->getPrintableSource(), tree.getLineNumber()); 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "instrumentation") { 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!keepTag && inApplication && depth == 3) { 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (keepTag) { 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name = getAttribute(tree, "http://schemas.android.com/apk/res/android", 2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", &error); 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name.length() > 0) { 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, name, pkg.string(), 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile->getPrintableSource(), tree.getLineNumber()); 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct NamespaceAttributePair { 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* ns; 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* attr; 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {} 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NamespaceAttributePair() : ns(NULL), attr(NULL) {} 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile, 25779cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs) 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseXMLResource(layoutFile, &tree); 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25919cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski if (!startTags.isEmpty()) { 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool haveStart = false; 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 25989cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski const size_t numStartTags = startTags.size(); 25999cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski for (size_t i = 0; i < numStartTags; i++) { 26009cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski if (tag == startTags[i]) { 26019cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski haveStart = true; 26029cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski } 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!haveStart) { 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If there is no '.', we'll assume that it's one of the built in names. 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strchr(tag.string(), '.')) { 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, tag, NULL, 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tagAttrPairs != NULL) { 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t tagIndex = tagAttrPairs->indexOfKey(tag); 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tagIndex >= 0) { 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex); 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < nsAttrVector.size(); i++) { 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const NamespaceAttributePair& nsAttr = nsAttrVector[i]; 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr); 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attrIndex < 0) { 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n", 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // layoutFile->getPrintableSource().string(), tree.getLineNumber(), 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag.string(), nsAttr.ns, nsAttr.attr); 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(tree.getAttributeStringValue(attrIndex, &len)), NULL, 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick"); 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attrIndex >= 0) { 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepMethodRule(keep, 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(tree.getAttributeStringValue(attrIndex, &len)), NULL, 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest, 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* tag, const char* ns, const char* attr) { 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tagStr(tag); 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = dest->indexOfKey(tagStr); 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<NamespaceAttributePair> vector; 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski vector.add(NamespaceAttributePair(ns, attr)); 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->add(tagStr, vector); 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->editValueAt(index).add(NamespaceAttributePair(ns, attr)); 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets) 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag:attribute pairs that should be checked in layout files. 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs; 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, "class"); 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, "fragment", NULL, "class"); 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, "fragment", RESOURCES_ANDROID_NAMESPACE, "name"); 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag:attribute pairs that should be checked in xml files. 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs; 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, "fragment"); 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, "fragment"); 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& dirs = assets->resDirs(); 2685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t K = dirs.size(); 2686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<K; k++) { 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = dirs.itemAt(k); 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& dirName = d->getLeaf(); 26899cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski Vector<String8> startTags; 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* startTag = NULL; 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL; 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) { 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = &kLayoutTagAttrPairs; 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) { 26959cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("PreferenceScreen")); 26969cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("preference-headers")); 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = &kXmlTagAttrPairs; 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) { 26999cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("menu")); 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = NULL; 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles(); 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = groups.size(); 2707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& group = groups.valueAt(i); 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles(); 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t M = files.size(); 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<M; j++) { 27129cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs); 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Handle the overlays 2720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> overlay = assets->getOverlay(); 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay.get()) { 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return writeProguardForLayouts(keep, overlay); 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardFile(Bundle* bundle, const sp<AaptAssets>& assets) 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = -1; 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getProguardFile()) { 2734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ProguardKeepSet keep; 2738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardForAndroidManifest(&keep, assets); 2740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardForLayouts(&keep, assets); 2745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 2746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(bundle->getProguardFile(), "w+"); 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getProguardFile(), strerror(errno)); 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules; 2757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = rules.size(); 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SortedVector<String8>& locations = rules.valueAt(i); 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t M = locations.size(); 2761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<M; j++) { 2762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "# %s\n", locations.itemAt(j).string()); 2763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s\n\n", rules.keyAt(i).string()); 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Loops through the string paths and writes them to the file pointer 2772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Each file path is written on its own line with a terminating backslash. 2773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp) 2774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t deps = -1; 2776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t file_i = 0; file_i < files->size(); ++file_i) { 2777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the full file path to the dependency file 2778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", files->itemAt(file_i).string()); 2779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps++; 2780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return deps; 2782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw) 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t deps = -1; 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps += writePathsToFile(assets->getFullResPaths(), fp); 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (includeRaw) { 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps += writePathsToFile(assets->getFullAssetPaths(), fp); 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return deps; 2793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2794