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 "AaptAssets.h" 7de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#include "AaptUtil.h" 8ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski#include "AaptXml.h" 91e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "CacheUpdater.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "CrunchCache.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "FileFinder.h" 121e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "Images.h" 131e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "IndentPrinter.h" 141e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "Main.h" 151e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "ResourceTable.h" 161e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "StringPool.h" 17de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#include "Symbol.h" 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "WorkQueue.h" 191e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski#include "XMLNode.h" 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#include <algorithm> 22de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 232412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary. 24685d363d7a3e8833edc9368a3c59b69755e0ba29Adam Lesinski 25b12f2410c7bdbf90bd8a77b897846ee2763e3037Elliott Hughes#if !defined(_WIN32) 262412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define STATUST(x) x 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 282412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe# define STATUST(x) (status_t)x 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe// Set to true for noisy debug output. 322412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampestatic const bool kIsDebug = false; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Number of threads to use for preprocessing images. 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t MAX_THREADS = 4; 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass PackageInfo 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PackageInfo() 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ~PackageInfo() 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t parsePackage(const sp<AaptGroup>& grp); 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam LesinskiString8 parseResourceName(const String8& leaf) 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* firstDot = strchr(leaf.string(), '.'); 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* str = leaf.string(); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (firstDot) { 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(str, firstDot-str); 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(str); 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTypeSet::ResourceTypeSet() 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :RefBase(), 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8,sp<AaptGroup> >() 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiFilePathStore::FilePathStore() 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :RefBase(), 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8>() 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass ResourceDirIterator 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType) 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0) 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 8891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath memset(&mParams, 0, sizeof(ResTable_config)); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const sp<AaptGroup>& getGroup() const { return mGroup; } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const sp<AaptFile>& getFile() const { return mFile; } 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const String8& getBaseName() const { return mBaseName; } 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const String8& getLeafName() const { return mLeafName; } 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline String8 getPath() const { return mPath; } 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inline const ResTable_config& getParams() const { return mParams; } 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enum { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski EOD = 1 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t next() 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (true) { 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Try to get next file in this current group. 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = mGroup; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = group->getFiles().valueAt(mGroupPos++); 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Try to get the next group/file in this directory 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mSetPos < mSet->size()) { 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroup = group = mSet->valueAt(mSetPos++); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (group->getFiles().size() < 1) { 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = group->getFiles().valueAt(0); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupPos = 1; 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // All done! 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return EOD; 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFile = file; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 leaf(group->getLeaf()); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLeafName = String8(leaf); 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParams = file->getGroupEntry().toParams(); 1332412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 1342412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe 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", 1352412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe group->getPath().string(), mParams.mcc, mParams.mnc, 1362412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.language[0] ? mParams.language[0] : '-', 1372412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.language[1] ? mParams.language[1] : '-', 1382412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.country[0] ? mParams.country[0] : '-', 1392412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.country[1] ? mParams.country[1] : '-', 1402412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.orientation, mParams.uiMode, 1412412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.density, mParams.touchscreen, mParams.keyboard, 1422412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe mParams.inputFlags, mParams.navigation); 1432412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath = "res"; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath.appendPath(file->getGroupEntry().toDirName(mResType)); 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPath.appendPath(leaf); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBaseName = parseResourceName(leaf); 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mBaseName == "") { 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Error: malformed resource filename %s\n", 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1542412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 1552412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("file name=%s\n", mBaseName.string()); 1562412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate: 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mResType; 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet> mSet; 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t mSetPos; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> mGroup; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t mGroupPos; 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> mFile; 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mBaseName; 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mLeafName; 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 mPath; 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config mParams; 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 178eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownclass AnnotationProcessor { 179eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownpublic: 180eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { } 181eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 182eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown void preprocessComment(String8& comment) { 183eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.size() > 0) { 184eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.contains("@deprecated")) { 185eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown mDeprecated = true; 186eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 187eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (comment.removeAll("@SystemApi")) { 188eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown mSystemApi = true; 189eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 190eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 191eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 192eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 193eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown void printAnnotations(FILE* fp, const char* indentStr) { 194eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (mDeprecated) { 195eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown fprintf(fp, "%s@Deprecated\n", indentStr); 196eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 197eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown if (mSystemApi) { 198eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown fprintf(fp, "%s@android.annotation.SystemApi\n", indentStr); 199eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 200eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown } 201eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 202eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brownprivate: 203eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown bool mDeprecated; 204eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown bool mSystemApi; 205eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}; 206eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isValidResourceType(const String8& type) 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return type == "anim" || type == "animator" || type == "interpolator" 21483b4f7daba75e73ca9aad6033ed513902dc3b5bbAdam Lesinski || type == "transition" || type == "font" 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "drawable" || type == "layout" 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "values" || type == "xml" || type == "raw" 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || type == "color" || type == "menu" || type == "mipmap"; 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& grp) 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (grp->getFiles().size() != 1) { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grp->getFiles().valueAt(0)->getPrintableSource().string()); 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(0); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(file, &block); 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printXMLBlock(&block); 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::START_TAG 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::END_DOCUMENT 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: No start tag found\n", 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber()); 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) { 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n", 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber(), 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIndex = block.indexOfAttribute(NULL, "package"); 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIndex < 0) { 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n", 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string(), block.getLineNumber()); 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len))); 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26554de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "revisionCode"); 26654de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski if (revisionCodeIndex >= 0) { 26754de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string()); 26854de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski } 26954de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 uses_sdk16("uses-sdk"); 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) { 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "minSdkVersion"); 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minSdkIndex >= 0) { 278f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len); 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* minSdk8 = strdup(String8(minSdk16).string()); 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->setManifestMinSdkVersion(minSdk8); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================== 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets, 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet>& set, 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* resType) 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 type8(resType); 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type16(resType); 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(set, String8(resType)); 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" (new resource id %s from %s)\n", 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.getBaseName().string(), it.getFile()->getPrintableSource().string()); 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 baseName(it.getBaseName()); 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* str = baseName.string(); 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + baseName.size(); 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!((*str >= 'a' && *str <= 'z') 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*str >= '0' && *str <= '9') 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *str == '_' || *str == '.')) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n", 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.getPath().string()); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resPath = it.getPath(); 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resPath.convertToResPath(); 325526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski status_t result = table->addEntry(SourcePos(it.getPath(), 0), 326526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski String16(assets->getPackage()), 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type16, 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseName, 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(resPath), 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL, 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.getParams()); 332526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski if (result != NO_ERROR) { 333526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski hasErrors = true; 334526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski } else { 335526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski assets->addResource(it.getLeafName(), resPath, it.getFile(), type8); 336526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski } 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3392412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass PreProcessImageWorkUnit : public WorkQueue::WorkUnit { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets, 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& file, volatile bool* hasErrors) : 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) { 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski virtual bool run() { 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = preProcessImage(mBundle, mAssets, mFile, NULL); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *mHasErrors = true; 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; // continue even if there are errors 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate: 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Bundle* mBundle; 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> mAssets; 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> mFile; 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski volatile bool* mHasErrors; 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets, 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<ResourceTypeSet>& set, const char* type) 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski volatile bool hasErrors = false; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = NO_ERROR; 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getUseCrunchCache() == false) { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski WorkQueue wq(MAX_THREADS, false); 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(set, String8(type)); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit( 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle, assets, it.getFile(), &hasErrors); 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = wq.schedule(w); 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status); 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete w; 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = wq.finish(); 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status) { 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status); 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3892412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return (hasErrors || (res < NO_ERROR)) ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void collect_files(const sp<AaptDir>& dir, 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* resources) 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles(); 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N = groups.size(); 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 3989b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const String8& leafName = groups.keyAt(i); 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& group = groups.valueAt(i); 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski = group->getFiles(); 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (files.size() == 0) { 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType = files.valueAt(0)->getResourceType(); 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(resType); 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> set = new ResourceTypeSet(); 4142412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4152412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Creating new resource type set for leaf %s with group %s (%p)\n", 4162412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe leafName.string(), group->getPath().string(), group.get()); 4172412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set->add(leafName, group); 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resources->add(resType, set); 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4219b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<ResourceTypeSet>& set = resources->valueAt(index); 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index = set->indexOfKey(leafName); 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 4242412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4252412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Adding to resource type set for leaf %s group %s (%p)\n", 4262412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe leafName.string(), group->getPath().string(), group.get()); 4272412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set->add(leafName, group); 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> existingGroup = set->valueAt(index); 4312412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4322412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Extending to resource type set for leaf %s group %s (%p)\n", 4332412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe leafName.string(), group->getPath().string(), group.get()); 4342412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<files.size(); j++) { 4362412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4372412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Adding file %s in group %s resType %s\n", 4382412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe files.valueAt(j)->getSourceFile().string(), 4392412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe files.keyAt(j).toDirName(String8()).string(), 4402412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe resType.string()); 4412412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 4422412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe existingGroup->addFile(files.valueAt(j)); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void collect_files(const sp<AaptAssets>& ass, 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* resources) 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& dirs = ass->resDirs(); 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int N = dirs.size(); 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 4569b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<AaptDir>& d = dirs.itemAt(i); 4572412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4582412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(), 4592412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe d->getLeaf().string()); 4602412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(d, resources); 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // don't try to include the res dir 4642412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 4652412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Removing dir leaf %s\n", d->getLeaf().string()); 4662412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ass->removeDir(d->getLeaf()); 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum { 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_OKAY = -1, 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_NOT_FOUND = -2, 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_LEADING_SPACES = -3, 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ATTR_TRAILING_SPACES = -4 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int validateAttr(const String8& path, const ResTable& table, 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResXMLParser& parser, 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* ns, const char* attr, const char* validChars, bool required) 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = parser.indexOfAttribute(ns, attr); 484f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* str; 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) { 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResStringPool* pool = &parser.getStrings(); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_REFERENCE) { 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int strIdx; 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n", 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value.data); 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pool = table.getTableStringBlock(strIdx); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool != NULL) { 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = pool->stringAt(value.data, &len); 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr, 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specFlags, strIdx, str != NULL ? String8(str).string() : "???"); 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) { 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n", 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski specFlags); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.dataType == Res_value::TYPE_STRING) { 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool == NULL) { 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n", 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((str=pool->stringAt(value.data, &len)) == NULL) { 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n", 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n", 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value.dataType); 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validChars) { 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<len; i++) { 5374bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski char16_t c = str[i]; 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = validChars; 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool okay = false; 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == *p) { 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski okay = true; 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!okay) { 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n", 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr, (char)str[i]); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int)i; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*str == ' ') { 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n", 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_LEADING_SPACES; 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 561d395f7913336417bcbbea740fcdc8589789626bcDan Albert if (len != 0 && str[len-1] == ' ') { 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n", 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_TRAILING_SPACES; 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_OKAY; 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (required) { 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n", 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber(), 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parser.getElementName(&len)).string(), attr); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_NOT_FOUND; 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ATTR_OKAY; 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void checkForIds(const String8& path, ResXMLParser& parser) 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=parser.next()) != ResXMLTree::END_DOCUMENT 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = parser.indexOfAttribute(NULL, "id"); 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n", 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path.string(), parser.getLineNumber()); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool applyFileOverlay(Bundle *bundle, 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> *baseSet, 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *resType) 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("applyFileOverlay for %s\n", resType); 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Replace any base level files in this category with any found from the overlay 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also add any found only in the overlay. 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> overlay = assets->getOverlay(); 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resTypeString(resType); 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // work through the linked list of overlays 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (overlay.get()) { 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources(); 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the overlay resources of the requested type 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = overlayRes->indexOfKey(resTypeString); 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 6149b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<ResourceTypeSet>& overlaySet = overlayRes->valueAt(index); 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for each of the resources, check for a match in the previously built 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // non-overlay "baseset". 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayCount = overlaySet->size(); 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string()); 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 623f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski ssize_t baseIndex = -1; 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (baseSet->get() != NULL) { 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex)); 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 627f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (baseIndex >= 0) { 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // look for same flavor. For a given file (strings.xml, for example) 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // there may be a locale specific or other flavors - we want to match 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the same flavor. 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex); 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex); 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getFiles(); 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles = 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->getFiles(); 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i < baseFiles.size(); i++) { 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i, 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseFiles.keyAt(i).toString().string()); 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i < overlayFiles.size(); i++) { 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i, 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(i).toString().string()); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayGroupSize = overlayFiles.size(); 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayGroupIndex = 0; 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex<overlayGroupSize; 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex++) { 653f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski ssize_t baseFileIndex = 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->getFiles().indexOfKey(overlayFiles. 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keyAt(overlayGroupIndex)); 656f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (baseFileIndex >= 0) { 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("found a match (" ZD ") for overlay file %s, for flavor %s\n", 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (ZD_TYPE) baseFileIndex, 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getLeaf().string(), 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(overlayGroupIndex).toString().string()); 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->removeFile(baseFileIndex); 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // didn't find a match fall through and add it.. 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (true || bundle->getVerbose()) { 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("nothing matches overlay file %s, for flavor %s\n", 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getLeaf().string(), 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayFiles.keyAt(overlayGroupIndex).toString().string()); 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex)); 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex)); 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (baseSet->get() == NULL) { 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *baseSet = new ResourceTypeSet(); 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getResources()->add(String8(resType), *baseSet); 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // this group doesn't exist (a file that's only in the overlay) 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*baseSet)->add(overlaySet->keyAt(overlayIndex), 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlaySet->valueAt(overlayIndex)); 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // make sure all flavors are defined in the resources. 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex); 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroup->getFiles(); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t overlayGroupSize = overlayFiles.size(); 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t overlayGroupIndex = 0; 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex<overlayGroupSize; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlayGroupIndex++) { 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex)); 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // this overlay didn't have resources for this type 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // try next overlay 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overlay = overlay->getOverlay(); 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 704df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Inserts an attribute in a given node. 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If errorOnFailedInsert is true, and the attribute already exists, returns false. 706df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * If replaceExisting is true, the attribute will be updated if it already exists. 707df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Returns true otherwise, even if the attribute already exists, and does not modify 708df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * the existing attribute's value. 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool addTagAttribute(const sp<XMLNode>& node, const char* ns8, 711df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson const char* attr8, const char* value, bool errorOnFailedInsert, 712df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bool replaceExisting) 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value == NULL) { 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 ns(ns8); 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr(attr8); 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 721df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr); 722df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson if (existingEntry != NULL) { 723df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson if (replaceExisting) { 724df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson existingEntry->string = String16(value); 725df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson return true; 726df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson } 727df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (errorOnFailedInsert) { 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " cannot insert new value %s.\n", 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(attr).string(), String8(ns).string(), value); 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // don't stop the build. 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski node->addAttribute(ns, attr, String16(value)); 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 743df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson/* 744df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Inserts an attribute in a given node, only if the attribute does not 745df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * exist. 746df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * If errorOnFailedInsert is true, and the attribute already exists, returns false. 747df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson * Returns true otherwise, even if the attribute already exists. 748df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson */ 749df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidsonbool addTagAttribute(const sp<XMLNode>& node, const char* ns8, 750df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson const char* attr8, const char* value, bool errorOnFailedInsert) 751df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson{ 752df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false); 753df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson} 754df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson 7559b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsiehstatic void fullyQualifyClassName(const String8& package, const sp<XMLNode>& node, 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& attrName) { 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = node->editAttribute( 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("http://schemas.android.com/apk/res/android"), attrName); 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr != NULL) { 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(attr->string); 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf --> package.asdf 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // .asdf .a.b --> package.asdf package.a.b 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf.adsf --> asdf.asdf 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className; 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = name.string(); 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* q = strchr(p, '.'); 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == q) { 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += package; 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (q == NULL) { 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += package; 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += "."; 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className += name; 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 7782412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 7792412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Qualifying class '%s' to '%s'", name.string(), className.string()); 7802412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(className)); 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinskistatic sp<ResourceTable::ConfigList> findEntry(const String16& packageStr, const String16& typeStr, 78699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski const String16& nameStr, ResourceTable* table) { 78799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski sp<ResourceTable::Package> pkg = table->getPackage(packageStr); 78899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (pkg != NULL) { 78999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski sp<ResourceTable::Type> type = pkg->getTypes().valueFor(typeStr); 79099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (type != NULL) { 79199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return type->getConfigs().valueFor(nameStr); 79299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 79399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 79499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return NULL; 79599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski} 79699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 79799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinskistatic uint16_t getMaxSdkVersion(const sp<ResourceTable::ConfigList>& configList) { 79899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries = 79999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski configList->getEntries(); 80099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski uint16_t maxSdkVersion = 0u; 80199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski for (size_t i = 0; i < entries.size(); i++) { 80299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski maxSdkVersion = std::max(maxSdkVersion, entries.keyAt(i).sdkVersion); 80399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 80499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return maxSdkVersion; 80599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski} 80699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 80799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinskistatic void massageRoundIconSupport(const String16& iconRef, const String16& roundIconRef, 80899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski ResourceTable* table) { 80999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski bool publicOnly = false; 81099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski const char* err; 81199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 81299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16 iconPackage, iconType, iconName; 81399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (!ResTable::expandResourceRef(iconRef.string(), iconRef.size(), &iconPackage, &iconType, 81499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski &iconName, NULL, &table->getAssetsPackage(), &err, 81599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski &publicOnly)) { 81699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // Errors will be raised in later XML compilation. 81799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return; 81899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 81999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 82099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski sp<ResourceTable::ConfigList> iconEntry = findEntry(iconPackage, iconType, iconName, table); 82199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (iconEntry == NULL || getMaxSdkVersion(iconEntry) < SDK_O) { 82299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // The icon is not adaptive, so nothing to massage. 82399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return; 82499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 82599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 82699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16 roundIconPackage, roundIconType, roundIconName; 82799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (!ResTable::expandResourceRef(roundIconRef.string(), roundIconRef.size(), &roundIconPackage, 82899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski &roundIconType, &roundIconName, NULL, &table->getAssetsPackage(), 82999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski &err, &publicOnly)) { 83099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // Errors will be raised in later XML compilation. 83199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return; 83299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 83399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 83499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski sp<ResourceTable::ConfigList> roundIconEntry = findEntry(roundIconPackage, roundIconType, 83599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski roundIconName, table); 83699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (roundIconEntry == NULL || getMaxSdkVersion(roundIconEntry) >= SDK_O) { 83799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // The developer explicitly used a v26 compatible drawable as the roundIcon, meaning we should 83899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // not generate an alias to the icon drawable. 83999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski return; 84099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 84199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 84299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16 aliasValue = String16(String8::format("@%s:%s/%s", String8(iconPackage).string(), 84399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String8(iconType).string(), 84499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String8(iconName).string())); 84599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 84699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski // Add an equivalent v26 entry to the roundIcon for each v26 variant of the regular icon. 84799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& configList = 84899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski iconEntry->getEntries(); 84999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski for (size_t i = 0; i < configList.size(); i++) { 85099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (configList.keyAt(i).sdkVersion >= SDK_O) { 85199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski table->addEntry(SourcePos(), roundIconPackage, roundIconType, roundIconName, aliasValue, 85299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski NULL, &configList.keyAt(i)); 85399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 85499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 85599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski} 85699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 85799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinskistatus_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root) 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root = root->searchElement(String16(), String16("manifest")); 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "No <manifest> tag.\n"); 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool errorOnFailedInsert = bundle->getErrorOnFailedInsert(); 866df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bool replaceVersion = bundle->getReplaceVersion(); 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode", 869df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) { 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 8716a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski } else { 8726a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski const XMLNode::attribute_entry* attr = root->getAttribute( 8736a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode")); 8746a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski if (attr != NULL) { 8756a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski bundle->setVersionCode(strdup(String8(attr->string).string())); 8766a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski } 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 8786a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName", 880df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) { 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 88282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } else { 88382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const XMLNode::attribute_entry* attr = root->getAttribute( 88482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName")); 88582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (attr != NULL) { 88682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski bundle->setVersionName(strdup(String8(attr->string).string())); 88782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 89082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk")); 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMinSdkVersion() != NULL 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || bundle->getTargetSdkVersion() != NULL 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || bundle->getMaxSdkVersion() != NULL) { 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (vers == NULL) { 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk")); 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->insertChildAt(vers, 0); 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion", 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getMinSdkVersion(), errorOnFailedInsert)) { 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion", 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getTargetSdkVersion(), errorOnFailedInsert)) { 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion", 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundle->getMaxSdkVersion(), errorOnFailedInsert)) { 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 91382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (vers != NULL) { 91482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const XMLNode::attribute_entry* attr = vers->getAttribute( 91582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion")); 91682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (attr != NULL) { 91782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski bundle->setMinSdkVersion(strdup(String8(attr->string).string())); 91882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 91982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 92082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 92111be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 92211be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (bundle->getCompileSdkVersion() != 0) { 92311be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersion", 92411be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette String8::format("%d", bundle->getCompileSdkVersion()), 92511be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette errorOnFailedInsert, true)) { 92611be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette return UNKNOWN_ERROR; 92711be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 92811be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 92911be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 93011be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (bundle->getCompileSdkVersionCodename() != "") { 93111be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersionCodename", 93211be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->getCompileSdkVersionCodename(), errorOnFailedInsert, true)) { 93311be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette return UNKNOWN_ERROR; 93411be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 93511be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 93611be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 937ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (bundle->getPlatformBuildVersionCode() != "") { 938ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (!addTagAttribute(root, "", "platformBuildVersionCode", 939ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) { 940ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 941ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 942ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 943ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 944ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (bundle->getPlatformBuildVersionName() != "") { 945ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (!addTagAttribute(root, "", "platformBuildVersionName", 946ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) { 947ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 948ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 949ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 950ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getDebugMode()) { 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> application = root->getChildElement(String16(), String16("application")); 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (application != NULL) { 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true", 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorOnFailedInsert)) { 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Deal with manifest package name overrides 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestPackageNameOverride != NULL) { 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update the actual package name 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package")); 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr == NULL) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "package name is required with --rename-manifest-package.\n"); 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 origPackage(attr->string); 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(manifestPackageNameOverride)); 9722412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 9732412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Overriding package '%s' to be '%s'\n", origPackage.string(), 9742412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe manifestPackageNameOverride); 9752412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make class names fully qualified 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> application = root->getChildElement(String16(), String16("application")); 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (application != NULL) { 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, application, String16("name")); 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, application, String16("backupAgent")); 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren()); 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> child = children.editItemAt(i); 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(child->getElementName()); 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("name")); 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "activity-alias") { 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("name")); 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullyQualifyClassName(origPackage, child, String16("targetActivity")); 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Deal with manifest package name overrides 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride(); 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (instrumentationPackageNameOverride != NULL) { 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fix up instrumentation targets. 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren()); 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < children.size(); i++) { 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> child = children.editItemAt(i); 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(child->getElementName()); 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "instrumentation") { 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski XMLNode::attribute_entry* attr = child->editAttribute( 100799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("targetPackage")); 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr != NULL) { 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr->string.setTo(String16(instrumentationPackageNameOverride)); 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 101599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski sp<XMLNode> application = root->getChildElement(String16(), String16("application")); 101699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (application != NULL) { 101799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski XMLNode::attribute_entry* icon_attr = application->editAttribute( 101899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("icon")); 101999d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (icon_attr != NULL) { 102099d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski XMLNode::attribute_entry* round_icon_attr = application->editAttribute( 102199d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski String16(RESOURCES_ANDROID_NAMESPACE), String16("roundIcon")); 102299d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski if (round_icon_attr != NULL) { 102399d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski massageRoundIconSupport(icon_attr->string, round_icon_attr->string, table); 102499d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 102599d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 102699d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski } 102799d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski 1028833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Generate split name if feature is present. 1029833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16("featureName")); 1030833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (attr != NULL) { 1031833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String16 splitName("feature_"); 1032833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski splitName.append(attr->string); 1033833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski status_t err = root->addAttribute(String16(), String16("split"), splitName); 1034833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (err != NO_ERROR) { 1035833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ALOGE("Failed to insert split name into AndroidManifest.xml"); 1036833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return err; 1037833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1038833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1039833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1043ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskistatic int32_t getPlatformAssetCookie(const AssetManager& assets) { 1044ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // Find the system package (0x01). AAPT always generates attributes 1045ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // with the type 0x01, so we're looking for the first attribute 1046ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // resource in the system package. 1047ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski const ResTable& table = assets.getResources(true); 1048ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski Res_value val; 1049ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ssize_t idx = table.getResource(0x01010000, &val, true); 1050ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (idx != NO_ERROR) { 1051ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // Try as a bag. 1052ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski const ResTable::bag_entry* entry; 1053ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ssize_t cnt = table.lockBag(0x01010000, &entry); 1054ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (cnt >= 0) { 1055ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski idx = entry->stringBlock; 1056ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1057ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski table.unlockBag(entry); 1058ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1059ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1060ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (idx < 0) { 1061ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return 0; 1062ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1063ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return table.getTableCookie(idx); 1064ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski} 1065ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1066ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskienum { 1067ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski VERSION_CODE_ATTR = 0x0101021b, 1068ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski VERSION_NAME_ATTR = 0x0101021c, 1069ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski}; 1070ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 107111be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverettestatic ssize_t extractPlatformBuildVersion(const ResTable& table, ResXMLTree& tree, Bundle* bundle) { 107211be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette // First check if we should be recording the compileSdkVersion* attributes. 107311be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette static const String16 compileSdkVersionName("android:attr/compileSdkVersion"); 107411be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.string(), 107511be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette compileSdkVersionName.size()) != 0u; 107611be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 1077ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski size_t len; 1078ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ResXMLTree::event_code_t code; 1079ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1080ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (code != ResXMLTree::START_TAG) { 1081ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski continue; 1082ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1083ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1084ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski const char16_t* ctag16 = tree.getElementName(&len); 1085ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (ctag16 == NULL) { 1086ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n"); 1087ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1088ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1089ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1090ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 tag(ctag16, len); 1091ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (tag != "manifest") { 1092ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski continue; 1093ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1094ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1095ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 error; 1096ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); 1097ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (error != "") { 1098ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR: failed to get platform version code\n"); 1099ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1100ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1101ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1102ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (versionCode >= 0 && bundle->getPlatformBuildVersionCode() == "") { 1103ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bundle->setPlatformBuildVersionCode(String8::format("%d", versionCode)); 1104ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1105ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 110611be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (useCompileSdkVersion && versionCode >= 0 && bundle->getCompileSdkVersion() == 0) { 110711be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->setCompileSdkVersion(versionCode); 110811be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 110911be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 1110ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error); 1111ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (error != "") { 1112ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR: failed to get platform version name\n"); 1113ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1114ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1115ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1116ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (versionName != "" && bundle->getPlatformBuildVersionName() == "") { 1117ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski bundle->setPlatformBuildVersionName(versionName); 1118ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 111911be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette 112011be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette if (useCompileSdkVersion && versionName != "" 112111be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette && bundle->getCompileSdkVersionCodename() == "") { 112211be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->setCompileSdkVersionCodename(versionName); 112311be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette } 1124ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return NO_ERROR; 1125ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1126ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1127ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR: no <manifest> tag found in platform AndroidManifest.xml\n"); 1128ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1129ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski} 1130ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1131ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskistatic ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) { 1132ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski int32_t cookie = getPlatformAssetCookie(assets); 1133ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (cookie == 0) { 113482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // No platform was loaded. 113582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 1136ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1137ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1138ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski Asset* asset = assets.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_STREAMING); 1139ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (asset == NULL) { 1140ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski fprintf(stderr, "ERROR: Platform AndroidManifest.xml not found\n"); 1141ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1142ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1143ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1144ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski ssize_t result = NO_ERROR; 1145193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski 1146193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski // Create a new scope so that ResXMLTree is destroyed before we delete the memory over 1147193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski // which it iterates (asset). 1148193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski { 1149193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski ResXMLTree tree; 1150193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) { 1151193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n"); 1152193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski result = UNKNOWN_ERROR; 1153193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski } else { 115411be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette result = extractPlatformBuildVersion(assets.getResources(true), tree, bundle); 1155193ed74c2d9228368941de948fe03e05ca7fd3e3Adam Lesinski } 1156ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1157ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1158ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski delete asset; 1159ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return result; 1160ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski} 1161ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define ASSIGN_IT(n) \ 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { \ 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(String8(#n)); \ 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { \ 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski n ## s = resources->valueAt(index); \ 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } \ 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (0) 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t updatePreProcessedCache(Bundle* bundle) 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if BENCHMARK 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n"); 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long startPNGTime = clock(); 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif /* BENCHMARK */ 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 source(bundle->getResourceSourceDirs()[0]); 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dest(bundle->getCrunchedOutputDir()); 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileFinder* ff = new SystemFileFinder(); 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CrunchCache cc(source,dest,ff); 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CacheUpdater* cu = new SystemCacheUpdater(bundle); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t numFiles = cc.crunch(cu); 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles); 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete ff; 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete cu; 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if BENCHMARK 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n" 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ,(clock() - startPNGTime)/1000.0); 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif /* BENCHMARK */ 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 11992cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkeystatus_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets, 12002cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) { 1201fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8 filename("AndroidManifest.xml"); 1202fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String16 androidPrefix("android"); 1203fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String16 androidNSUri("http://schemas.android.com/apk/res/android"); 1204fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri); 1205fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1206fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Build the <manifest> tag 1207fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16("manifest")); 1208fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 12092cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey // Add the 'package' attribute which is set to the package name. 12102cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const char* packageName = assets->getPackage(); 12112cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); 12122cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (manifestPackageNameOverride != NULL) { 12132cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey packageName = manifestPackageNameOverride; 12142cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey } 12152cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey manifest->addAttribute(String16(), String16("package"), String16(packageName)); 12162cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey 12172cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey // Add the 'versionCode' attribute which is set to the original version code. 12182cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "versionCode", 12192cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey bundle->getVersionCode(), true, true)) { 12202cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey return UNKNOWN_ERROR; 12212cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey } 1222fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 122354de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski // Add the 'revisionCode' attribute, which is set to the original revisionCode. 122454de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski if (bundle->getRevisionCode().size() > 0) { 122554de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "revisionCode", 122654de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski bundle->getRevisionCode().string(), true, true)) { 122754de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski return UNKNOWN_ERROR; 122854de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski } 122954de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski } 123054de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski 1231fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Add the 'split' attribute which describes the configurations included. 12326240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski String8 splitName("config."); 12336240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski splitName.append(split->getPackageSafeName()); 1234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski manifest->addAttribute(String16(), String16("split"), String16(splitName)); 1235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Build an empty <application> tag (required). 1237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16("application")); 123878a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey 123978a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey // Add the 'hasCode' attribute which is never true for resource splits. 124078a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, "hasCode", 124178a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey "false", true, true)) { 124278a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey return UNKNOWN_ERROR; 124378a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey } 124478a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey 1245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski manifest->addChild(app); 1246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski root->addChild(manifest); 1247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1248e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski int err = compileXmlFile(bundle, assets, String16(), root, outFile, table); 12492cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey if (err < NO_ERROR) { 1250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 1251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski outFile->setCompressionMethod(ZipEntry::kCompressDeflated); 1253fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return NO_ERROR; 1254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 1255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatus_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder) 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, look for a package file to parse. This is required to 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be able to generate the resource information. 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> androidManifestFile = 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getFiles().valueFor(String8("AndroidManifest.xml")); 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (androidManifestFile == NULL) { 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n"); 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parsePackage(bundle, assets, androidManifestFile); 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 12722412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 12732412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Creating resources for package %s\n", assets->getPackage().string()); 12742412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 127678713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski // Set the private symbols package if it was declared. 127778713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski // This can also be declared in XML as <private-symbols name="package" /> 127878713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski if (bundle->getPrivateSymbolsPackage().size() != 0) { 127978713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski assets->setSymbolsPrivatePackage(bundle->getPrivateSymbolsPackage()); 128078713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski } 128178713998f94a2cc2562aa0ae7761bbc563d8eafaAdam Lesinski 1282833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ResourceTable::PackageType packageType = ResourceTable::App; 1283833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getBuildSharedLibrary()) { 1284833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::SharedLibrary; 1285833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } else if (bundle->getExtending()) { 1286833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::System; 1287833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } else if (!bundle->getFeatureOfPackage().isEmpty()) { 1288833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageType = ResourceTable::AppFeature; 1289833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1290833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1291833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ResourceTable table(bundle, String16(assets->getPackage()), packageType); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = table.addIncludedResources(bundle, assets); 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 12972412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe if (kIsDebug) { 12982412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe printf("Found %d included resource packages\n", (int)table.size()); 12992412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe } 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Standard flags for compiled XML and optional UTF-8 encoding 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int xmlFlags = XML_COMPILE_STANDARD_RESOURCE; 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Only enable UTF-8 if the caller of aapt didn't specifically 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * request UTF-16 encoding and the parameters of this package 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * allow UTF-8 to be used. 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getUTF16StringsOption()) { 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xmlFlags |= XML_COMPILE_UTF8; 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, gather all resource information. 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resType -> leafName -> group 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new KeyedVector<String8, sp<ResourceTypeSet> >; 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(assets, resources); 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> drawables; 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> layouts; 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> anims; 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> animators; 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> interpolators; 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> transitions; 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> xmls; 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> raws; 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> colors; 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> menus; 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ResourceTypeSet> mipmaps; 13329bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski sp<ResourceTypeSet> fonts; 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(drawable); 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(layout); 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(anim); 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(animator); 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(interpolator); 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(transition); 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(xml); 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(raw); 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(color); 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(menu); 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ASSIGN_IT(mipmap); 13459bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski ASSIGN_IT(font); 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setResources(resources); 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // now go through any resource overlays and collect their files 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> current = assets->getOverlay(); 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while(current.get()) { 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new KeyedVector<String8, sp<ResourceTypeSet> >; 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setResources(resources); 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski collect_files(current, resources); 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = current->getOverlay(); 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // apply the overlay files to the base set 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!applyFileOverlay(bundle, assets, &drawables, "drawable") || 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &layouts, "layout") || 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &anims, "anim") || 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &animators, "animator") || 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &interpolators, "interpolator") || 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &transitions, "transition") || 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &xmls, "xml") || 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &raws, "raw") || 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &colors, "color") || 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &menus, "menu") || 13689bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski !applyFileOverlay(bundle, assets, &fonts, "font") || 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) { 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (drawables != NULL) { 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = preProcessImages(bundle, assets, drawables, "drawable"); 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, drawables, "drawable"); 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mipmaps != NULL) { 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = preProcessImages(bundle, assets, mipmaps, "mipmap"); 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap"); 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 14039bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (fonts != NULL) { 14049bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski err = makeFileResources(bundle, assets, &table, fonts, "font"); 14059bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (err != NO_ERROR) { 14069bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski hasErrors = true; 14079bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 14089bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 14099bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (layouts != NULL) { 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, layouts, "layout"); 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anims != NULL) { 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, anims, "anim"); 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (animators != NULL) { 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, animators, "animator"); 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (transitions != NULL) { 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, transitions, "transition"); 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (interpolators != NULL) { 1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, interpolators, "interpolator"); 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xmls != NULL) { 1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, xmls, "xml"); 1447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (raws != NULL) { 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, raws, "raw"); 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // compile resources 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = assets; 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while(current.get()) { 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, sp<ResourceTypeSet> > *resources = 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->getResources(); 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = resources->indexOfKey(String8("values")); 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index >= 0) { 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(resources->valueAt(index), String8("values")); 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res; 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((res=it.next()) == NO_ERROR) { 14709b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const sp<AaptFile>& file = it.getFile(); 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = compileResourceFile(bundle, assets, file, it.getParams(), 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (current!=assets), &table); 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = current->getOverlay(); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colors != NULL) { 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, colors, "color"); 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (menus != NULL) { 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = makeFileResources(bundle, assets, &table, menus, "menu"); 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1495526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski if (hasErrors) { 1496526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski return UNKNOWN_ERROR; 1497526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski } 1498526d73be4a3a2714fa6112769e16fb6cd0194451Adam Lesinski 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------------- 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assignment of resource IDs and initial generation of resource table. 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------------- 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.hasResources()) { 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = table.assignResourceIds(); 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Finally, we can now we can compile XML files, which may reference 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resources. 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (layouts != NULL) { 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(layouts, String8("layout")); 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 src = it.getFile()->getPrintableSource(); 1519e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1520e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1521cf1f1d9128853f0fa0cef657e2bbb7bf6904c732Adam Lesinski // Only verify IDs if there was no error and the file is non-empty. 1522cf1f1d9128853f0fa0cef657e2bbb7bf6904c732Adam Lesinski if (err == NO_ERROR && it.getFile()->hasData()) { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checkForIds(src, block); 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (anims != NULL) { 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(anims, String8("anim")); 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1540e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1541e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (animators != NULL) { 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(animators, String8("animator")); 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1556e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1557e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (interpolators != NULL) { 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(interpolators, String8("interpolator")); 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1572e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1573e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (transitions != NULL) { 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(transitions, String8("transition")); 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1588e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1589e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xmls != NULL) { 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(xmls, String8("xml")); 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1604e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1605e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (drawables != NULL) { 1618fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResourceDirIterator it(drawables, String8("drawable")); 1619fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1620e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = postProcessImage(bundle, assets, &table, it.getFile()); 1621fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1622fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski hasErrors = true; 1623fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1624fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1625fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1626fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err < NO_ERROR) { 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1629fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski err = NO_ERROR; 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16322d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski if (mipmaps != NULL) { 16332d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski ResourceDirIterator it(mipmaps, String8("mipmap")); 16342d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski while ((err=it.next()) == NO_ERROR) { 16352d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski err = postProcessImage(bundle, assets, &table, it.getFile()); 16362d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski if (err != NO_ERROR) { 16372d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski hasErrors = true; 16382d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski } 16392d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski } 16402d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski 16412d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski if (err < NO_ERROR) { 16422d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski hasErrors = true; 16432d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski } 16442d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski err = NO_ERROR; 16452d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski } 16462d6fa033e1b2680803d5a9978d0d1d3f8feceb21Adam Lesinski 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colors != NULL) { 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(colors, String8("color")); 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1650e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1651e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (menus != NULL) { 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceDirIterator it(menus, String8("menu")); 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((err=it.next()) == NO_ERROR) { 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 src = it.getFile()->getPrintableSource(); 1667e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 1668e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski it.getFile(), &table, xmlFlags); 1669cf1f1d9128853f0fa0cef657e2bbb7bf6904c732Adam Lesinski if (err == NO_ERROR && it.getFile()->hasData()) { 1670fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResXMLTree block; 1671fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); 1672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski checkForIds(src, block); 1673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = NO_ERROR; 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16849bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (fonts != NULL) { 16859bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski ResourceDirIterator it(fonts, String8("font")); 16869bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski while ((err=it.next()) == NO_ERROR) { 16879bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski // fonts can be resources other than xml. 16889bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (it.getFile()->getPath().getPathExtension() == ".xml") { 16899bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski String8 src = it.getFile()->getPrintableSource(); 16909bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski err = compileXmlFile(bundle, assets, String16(it.getBaseName()), 16919bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski it.getFile(), &table, xmlFlags); 16929bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (err != NO_ERROR) { 16939bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski hasErrors = true; 16949bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 16959bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 16969bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 16979bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski 16989bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski if (err < NO_ERROR) { 16999bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski hasErrors = true; 17009bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 17019bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski err = NO_ERROR; 17029bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski } 17039bbe787822502e8c09d9abe963e6539647bea346Adam Lesinski 1704e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Now compile any generated resources. 1705e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue(); 1706e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski while (!workQueue.empty()) { 1707e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski CompileResourceWorkItem& workItem = workQueue.front(); 170807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski int xmlCompilationFlags = xmlFlags | XML_COMPILE_PARSE_VALUES 170907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS; 171007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski if (!workItem.needsCompiling) { 171107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski xmlCompilationFlags &= ~XML_COMPILE_ASSIGN_ATTRIBUTE_IDS; 171207dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski xmlCompilationFlags &= ~XML_COMPILE_PARSE_VALUES; 171307dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski } 171407dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot, 171507dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.file, &table, xmlCompilationFlags); 171607dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski 1717cf1f1d9128853f0fa0cef657e2bbb7bf6904c732Adam Lesinski if (err == NO_ERROR && workItem.file->hasData()) { 1718e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski assets->addResource(workItem.resPath.getPathLeaf(), 171907dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.resPath, 172007dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.file, 172107dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski workItem.file->getResourceType()); 1722e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } else { 1723e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski hasErrors = true; 1724e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 1725e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski workQueue.pop(); 1726e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 1727e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.validateLocalizations()) { 1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1736ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // If we're not overriding the platform build versions, 1737ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski // extract them from the platform APK. 1738ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (packageType != ResourceTable::System && 1739ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski (bundle->getPlatformBuildVersionCode() == "" || 174011be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->getPlatformBuildVersionName() == "" || 174111be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->getCompileSdkVersion() == 0 || 174211be9317efffafcac52cd2dc5cce1d951c966dd1Alan Viverette bundle->getCompileSdkVersionCodename() == "")) { 1743ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski err = extractPlatformBuildVersion(assets->getAssetManager(), bundle); 1744ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski if (err != NO_ERROR) { 1745ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return UNKNOWN_ERROR; 1746ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1747ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski } 1748ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0)); 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 manifestPath(manifestFile->getPrintableSource()); 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate final compiled manifest file. 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->clearData(); 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> manifestTree = XMLNode::parse(manifestFile); 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (manifestTree == NULL) { 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 175899d36ee8a936d5f9d95305183241ed597bace8e8Adam Lesinski err = massageManifest(bundle, &table, manifestTree); 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1762e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table); 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 176782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (table.modifyForCompat(bundle) != NO_ERROR) { 176882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return UNKNOWN_ERROR; 176982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 177082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //block.restart(); 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printXMLBlock(&block); 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate the final resource table. 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Re-flatten because we may have added new resource IDs 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -------------------------------------------------------------- 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1779de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable finalResTable; 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> resFile; 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (table.hasResources()) { 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 17855892248580859620db90d5ef2e3c2f48531933faAdrian Roos err = table.addSymbols(symbols, bundle->getSkipSymbolsWithoutDefaultLocalization()); 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1790de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources; 1791de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (builder->getSplits().size() > 1) { 1792de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // Only look for density varying resources if we're generating 1793de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // splits. 1794de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski table.getDensityVaryingResources(densityVaryingResources); 1795de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1796de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1797fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<sp<ApkSplit> >& splits = builder->getSplits(); 1798fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const size_t numSplits = splits.size(); 1799fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t i = 0; i < numSplits; i++) { 1800fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<ApkSplit>& split = splits.editItemAt(i); 1801fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> flattenedTable = new AaptFile(String8("resources.arsc"), 1802fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski AaptGroupEntry(), String8()); 180327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski err = table.flatten(bundle, split->getResourceFilter(), 180427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski flattenedTable, split->isBase()); 1805fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1806fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to generate resource table for split '%s'\n", 1807fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getPrintableName().string()); 1808fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 1809fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1810fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->addEntry(String8("resources.arsc"), flattenedTable); 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1812fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (split->isBase()) { 1813fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski resFile = flattenedTable; 1814f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize()); 1815f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 1816f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski fprintf(stderr, "Generated resource table is corrupt.\n"); 1817f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 1818f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 1819fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 1820de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski ResTable resTable; 1821de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski err = resTable.add(flattenedTable->getData(), flattenedTable->getSize()); 1822de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (err != NO_ERROR) { 1823de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n", 1824de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski split->getPrintableName().string()); 1825de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski return err; 1826de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1827de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1828de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski bool hasError = false; 1829de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const std::set<ConfigDescription>& splitConfigs = split->getConfigs(); 1830de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin(); 1831de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski iter != splitConfigs.end(); 1832de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski ++iter) { 1833de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const ConfigDescription& config = *iter; 1834de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (AaptConfig::isDensityOnly(config)) { 1835de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // Each density only split must contain all 1836de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // density only resources. 1837de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski Res_value val; 1838de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski resTable.setParameters(&config); 1839de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t densityVaryingResourceCount = densityVaryingResources.size(); 1840de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t k = 0; k < densityVaryingResourceCount; k++) { 1841de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Symbol& symbol = densityVaryingResources.keyAt(k); 1842de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski ssize_t block = resTable.getResource(symbol.id, &val, true); 1843de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (block < 0) { 1844de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // Maybe it's in the base? 1845de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski finalResTable.setParameters(&config); 1846de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski block = finalResTable.getResource(symbol.id, &val, true); 1847de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1848de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1849de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (block < 0) { 1850de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski hasError = true; 1851de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski SourcePos().error("%s has no definition for density split '%s'", 1852de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski symbol.toString().string(), config.toString().string()); 1853de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1854de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (bundle->getVerbose()) { 1855de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const Vector<SymbolDefinition>& defs = densityVaryingResources[k]; 1856de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const size_t defCount = std::min(size_t(5), defs.size()); 1857de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski for (size_t d = 0; d < defCount; d++) { 1858de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski const SymbolDefinition& def = defs[d]; 1859de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski def.source.error("%s has definition for %s", 1860de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski symbol.toString().string(), def.config.toString().string()); 1861de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1862de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1863de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (defCount < defs.size()) { 1864de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski SourcePos().error("and %d more ...", (int) (defs.size() - defCount)); 1865de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1866de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1867de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1868de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1869de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1870de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1871de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1872de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski if (hasError) { 1873de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski return UNKNOWN_ERROR; 1874de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski } 1875de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski 1876de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski // Generate the AndroidManifest for this split. 1877fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"), 1878fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski AaptGroupEntry(), String8()); 18792cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey err = generateAndroidManifestForSplit(bundle, assets, split, 18802cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey generatedManifest, &table); 1881fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (err != NO_ERROR) { 1882fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n", 1883fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->getPrintableName().string()); 1884fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return err; 1885fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1886fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski split->addEntry(String8("AndroidManifest.xml"), generatedManifest); 1887fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getPublicOutputFile()) { 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(bundle->getPublicOutputFile(), "w+"); 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n", 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (const char*)bundle->getPublicOutputFile(), strerror(errno)); 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing public definitions to %s.\n", bundle->getPublicOutputFile()); 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski table.writePublicDefinitions(String16(assets->getPackage()), fp); 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1903fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1904fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (finalResTable.getTableCount() == 0 || resFile == NULL) { 1905fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "No resource table was generated.\n"); 1906fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return UNKNOWN_ERROR; 1907fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1909fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Perform a basic validation of the manifest file. This time we 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // parse it with the comments intact, so that we can use them to 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generate java docs... so we are not going to write this one 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // back out to the final manifest data. 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(), 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->getGroupEntry(), 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestFile->getResourceType()); 1917e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski err = compileXmlFile(bundle, assets, String16(), manifestFile, 191807dfd2d8642f8a3630ca6429f740865a0c0bfdf7Adam Lesinski outManifestFile, &table, XML_COMPILE_STANDARD_RESOURCE & ~XML_COMPILE_STRIP_COMMENTS); 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true); 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 manifest16("manifest"); 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 permission16("permission"); 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 permission_group16("permission-group"); 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 uses_permission16("uses-permission"); 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 instrumentation16("instrumentation"); 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 application16("application"); 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 provider16("provider"); 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 service16("service"); 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 receiver16("receiver"); 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 activity16("activity"); 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 action16("action"); 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 category16("category"); 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 data16("scheme"); 1937d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski String16 feature_group16("feature-group"); 1938d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski String16 uses_feature16("uses-feature"); 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz" 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789"; 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz" 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz" 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$"; 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz" 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:"; 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz" 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;"; 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz" 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+"; 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz" 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> permissionSymbols; 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> permissionGroupSymbols; 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getElementNamespace(&len) != NULL) { 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) { 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, NULL, "package", 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sharedUserId", packageIdentChars, false) != ATTR_OKAY) { 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) { 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool isGroup = strcmp16(block.getElementName(&len), 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski permission_group16.string()) == 0; 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", isGroup ? packageIdentCharsWithTheStupid 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : packageIdentChars, true) != ATTR_OKAY) { 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(manifestPath, block.getLineNumber()); 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> syms; 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!isGroup) { 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionSymbols; 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (syms == NULL) { 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getSymbolsFor(String8("Manifest")); 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionSymbols = symbols->addNestedSymbol( 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8("permission"), srcPos); 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionGroupSymbols; 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (syms == NULL) { 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getSymbolsFor(String8("Manifest")); 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms = permissionGroupSymbols = symbols->addNestedSymbol( 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8("permission_group"), srcPos); 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name"); 2002f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* id = block.getAttributeStringValue(index, &len); 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id == NULL) { 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestPath.string(), block.getLineNumber(), 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 idStr(id); 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* p = idStr.lockBuffer(idStr.size()); 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* e = p + idStr.size(); 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool begins_with_digit = true; // init to true so an empty string fails 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (e > p) { 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e--; 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*e >= '0' && *e <= '9') { 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = true; 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*e >= 'a' && *e <= 'z') || 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*e >= 'A' && *e <= 'Z') || 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (*e == '_')) { 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = false; 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isGroup && (*e == '-')) { 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *e = '_'; 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski begins_with_digit = false; 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e++; 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idStr.unlockBuffer(); 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // verify that we stopped because we hit a period or 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the beginning of the string, and that the 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // identifier didn't begin with a digit. 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (begins_with_digit || (e != p && *(e-1) != '.')) { 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Permission name <%s> is not a valid Java symbol\n", 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski manifestPath.string(), block.getLineNumber(), idStr.string()); 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->addStringSymbol(String8(e), idStr, srcPos); 2045f348c15ecf78e9d58b8238ffcf1d78a279e3a862Dan Albert const char16_t* cmt = block.getComment(&len); 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cmt != NULL && *cmt != 0) { 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comment of %s: %s\n", String8(e).string(), 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(cmt).string()); 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->appendComment(String8(e), String16(cmt), srcPos); 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syms->makeSymbolPublic(String8(e), srcPos); 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) { 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", packageIdentChars, true) != ATTR_OKAY) { 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) { 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "targetPackage", 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) { 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, false) != ATTR_OKAY) { 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "taskAffinity", 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) { 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "authorities", 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski authoritiesIdentChars, true) != ATTR_OKAY) { 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), service16.string()) == 0 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), receiver16.string()) == 0 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), activity16.string()) == 0) { 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE, 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "name", classIdentChars, true) != ATTR_OKAY) { 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "permission", 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, false) != ATTR_OKAY) { 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "process", 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "taskAffinity", 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processIdentChars, false) != ATTR_OKAY) { 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), action16.string()) == 0 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || strcmp16(block.getElementName(&len), category16.string()) == 0) { 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "name", 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski packageIdentChars, true) != ATTR_OKAY) { 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) { 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "mimeType", 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdentChars, true) != ATTR_OKAY) { 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (validateAttr(manifestPath, finalResTable, block, 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RESOURCES_ANDROID_NAMESPACE, "scheme", 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski schemeIdentChars, true) != ATTR_OKAY) { 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2147d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) { 2148d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski int depth = 1; 2149d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 2150d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski && code > ResXMLTree::BAD_DOCUMENT) { 2151d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (code == ResXMLTree::START_TAG) { 2152d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski depth++; 2153d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) { 2154d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski ssize_t idx = block.indexOfAttribute( 2155d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski RESOURCES_ANDROID_NAMESPACE, "required"); 2156d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (idx < 0) { 2157d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski continue; 2158d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2159d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski 2160d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski int32_t data = block.getAttributeData(idx); 2161d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (data == 0) { 2162d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski fprintf(stderr, "%s:%d: Tag <uses-feature> can not have " 2163d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski "android:required=\"false\" when inside a " 2164d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski "<feature-group> tag.\n", 2165d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski manifestPath.string(), block.getLineNumber()); 2166d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski hasErrors = true; 2167d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2168d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2169d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } else if (code == ResXMLTree::END_TAG) { 2170d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski depth--; 2171d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (depth == 0) { 2172d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski break; 2173d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2174d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2175d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2180d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski if (hasErrors) { 2181d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski return UNKNOWN_ERROR; 2182d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski } 2183d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resFile != NULL) { 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These resources are now considered to be a part of the included 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // resources, for others to reference. 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = assets->addIncludedResources(resFile); 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n"); 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* getIndentSpace(int indent) 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char whitespace[] = 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski" "; 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return whitespace + sizeof(whitespace) - 1 - indent*4; 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 flattenSymbol(const String8& symbol) { 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 result(symbol); 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t first; 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((first = symbol.find(":", 0)) >= 0 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (first = symbol.find(".", 0)) >= 0) { 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t size = symbol.size(); 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char* buf = result.lockBuffer(size); 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = first; i < size; i++) { 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf[i] == ':' || buf[i] == '.') { 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf[i] = '_'; 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result.unlockBuffer(size); 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) { 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t colon = symbol.find(":", 0); 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colon >= 0) { 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(symbol.string(), colon); 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage(); 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String8 getSymbolName(const String8& symbol) { 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t colon = symbol.find(":", 0); 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colon >= 0) { 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String8(symbol.string() + colon + 1); 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return symbol; 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 getAttributeComment(const sp<AaptAssets>& assets, 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name, 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outTypeComment = NULL) 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R")); 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asym != NULL) { 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got R symbols!\n"); 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asym = asym->getNestedSymbols().valueFor(String8("attr")); 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (asym != NULL) { 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got attrs symbols! comment %s=%s\n", 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // name.string(), String8(asym->getComment(name)).string()); 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outTypeComment != NULL) { 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outTypeComment = asym->getTypeComment(name); 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return asym->getComment(name); 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16(); 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 22580f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosibastatic status_t writeResourceLoadedCallbackForLayoutClasses( 22590f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba FILE* fp, const sp<AaptAssets>& assets, 226087332a7109610d02ac7f5db6af99d3a11813d5c1Andreas Gampe const sp<AaptSymbols>& symbols, int indent, bool /* includePrivate */) 22610f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba{ 22620f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String16 attr16("attr"); 22630f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String16 package16(assets->getPackage()); 22640f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 22650f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba const char* indentStr = getIndentSpace(indent); 22660f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba bool hasErrors = false; 22670f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 22680f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba size_t i; 22690f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba size_t N = symbols->getNestedSymbols().size(); 22700f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba for (i=0; i<N; i++) { 22710f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 22720f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String8 realClassName(symbols->getNestedSymbols().keyAt(i)); 22730f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String8 nclassName(flattenSymbol(realClassName)); 22740f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 22750f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba fprintf(fp, 22760f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n" 22770f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n" 22780f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba "%s}\n", 22790f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba indentStr, nclassName.string(), 22800f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba getIndentSpace(indent+1), nclassName.string(), nclassName.string(), 22810f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba indentStr); 22820f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } 22830f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 2284ed811eeaea83453df91fa564287cd2f1b7cb705fDan Albert return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 22850f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba} 22860f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 22870f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosibastatic status_t writeResourceLoadedCallback( 22880f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, 22890f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba const sp<AaptSymbols>& symbols, const String8& className, int indent) 22900f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba{ 22910f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba size_t i; 22920f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba status_t err = NO_ERROR; 22930f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 22940f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba size_t N = symbols->getSymbols().size(); 22950f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba for (i=0; i<N; i++) { 22960f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2297eed585821a0dc55a18897773a52e2b5fdda78b55Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { 22980f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba continue; 22990f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } 23000f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba if (!assets->isJavaSymbol(sym, includePrivate)) { 23010f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba continue; 23020f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } 23030f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String8 flat_name(flattenSymbol(sym.name)); 23040f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba fprintf(fp, 23050f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n", 23060f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba getIndentSpace(indent), className.string(), flat_name.string(), 23070f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba className.string(), flat_name.string()); 23080f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } 23090f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 23100f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba N = symbols->getNestedSymbols().size(); 23110f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba for (i=0; i<N; i++) { 23120f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 23130f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba String8 nclassName(symbols->getNestedSymbols().keyAt(i)); 23140f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba if (nclassName == "styleable") { 23150f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba err = writeResourceLoadedCallbackForLayoutClasses( 23160f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba fp, assets, nsymbols, indent, includePrivate); 23170f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } else { 23180f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols, 23190f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba nclassName, indent); 23200f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba } 23210f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba if (err != NO_ERROR) { 23220f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba return err; 23231e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski } 23241e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski } 23250f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba 23260f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba return NO_ERROR; 23271e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski} 23281e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeLayoutClasses( 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, 2331e8e91925074479fc06310418b58b54f49d051801Adam Lesinski const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId) 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* indentStr = getIndentSpace(indent); 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!includePrivate) { 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/** @doconly */\n", indentStr); 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic static final class styleable {\n", indentStr); 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent++; 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package16(assets->getPackage()); 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr = getIndentSpace(indent); 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getNestedSymbols().size(); 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 realClassName(symbols->getNestedSymbols().keyAt(i)); 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(flattenSymbol(realClassName)); 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<uint32_t> idents; 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<uint32_t> origOrder; 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> publicFlags; 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t a; 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t NA = nsymbols->getSymbols().size(); 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a)); 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? sym.int32Val : 0; 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isPublic = true; 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags; 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = assets->getIncludedResources().identifierForName( 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), sym.name.string()); 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idents.add(code); 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.add(code); 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski publicFlags.add(isPublic); 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NA = idents.size(); 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment = symbols->getComment(realClassName); 2386eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/** ", indentStr); 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2390eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s\n", cmt.string()); 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string()); 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasTable = false; 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasTable) { 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasTable = true; 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>Includes the following attributes:</p>\n" 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <table>\n" 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <colgroup align=\"left\" />\n" 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <colgroup align=\"left\" />\n" 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <tr><th>Attribute</th><th>Description</th></tr>\n", 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr); 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8); 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2422feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright if (comment.contains(u"@removed")) { 2423feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright continue; 2424feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright } 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = comment.string(); 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p != 0 && *p != '.') { 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*p == '{') { 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p != 0 && *p != '}') { 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*p == '.') { 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = String16(comment.string(), p-comment.string()); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n", 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, true).string(), 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string(), 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasTable) { 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s </table>\n", indentStr); 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s @see #%s_%s\n", 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(sym.name).string()); 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s */\n", getIndentSpace(indent)); 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2466eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, indentStr); 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static final int[] %s = {\n" 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s", 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent+1)); 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a != 0) { 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((a&3) == 0) { 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ",\n%s", getIndentSpace(indent+1)); 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ", "); 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "0x%08x", idents[a]); 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n%s};\n", indentStr); 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment; 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8, &typeComment); 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getAttributeComment(assets, name8, &typeComment); 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags = 0; 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getIncludedResources().identifierForName( 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(attr16).string(), String8(name16).string(), typeSpecFlags); 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2512eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown 2513eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s/**\n", indentStr); 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2517eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s <p>\n%s @attr description\n", indentStr, indentStr); 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s %s\n", indentStr, cmt.string()); 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This symbol is the offset where the {@link %s.R.attr#%s}\n" 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s attribute's value can be found in the {@link #%s} array.\n", 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, pub).string(), 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string(), 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string()); 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeComment.size() > 0) { 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(typeComment); 2531eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n\n%s %s\n", indentStr, cmt.string()); 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This corresponds to the global attribute\n" 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s resource symbol {@link %s.R.attr#%s}.\n", 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, indentStr, 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, true).string(), 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string()); 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s <p>This is a private symbol.\n", indentStr); 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s @attr name %s:%s\n", indentStr, 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolPackage(name8, assets, pub).string(), 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getSymbolName(name8).string()); 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s*/\n", indentStr); 2551eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, indentStr); 2552e8e91925074479fc06310418b58b54f49d051801Adam Lesinski 2553e8e91925074479fc06310418b58b54f49d051801Adam Lesinski const char * id_format = nonConstantId ? 2554e8e91925074479fc06310418b58b54f49d051801Adam Lesinski "%spublic static int %s_%s = %d;\n" : 2555e8e91925074479fc06310418b58b54f49d051801Adam Lesinski "%spublic static final int %s_%s = %d;\n"; 2556e8e91925074479fc06310418b58b54f49d051801Adam Lesinski 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2558e8e91925074479fc06310418b58b54f49d051801Adam Lesinski id_format, 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indentStr, nclassName.string(), 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)pos); 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent--; 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s};\n", getIndentSpace(indent)); 25672412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeTextLayoutClasses( 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, bool includePrivate) 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package16(assets->getPackage()); 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getNestedSymbols().size(); 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 realClassName(symbols->getNestedSymbols().keyAt(i)); 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(flattenSymbol(realClassName)); 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<uint32_t> idents; 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<uint32_t> origOrder; 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> publicFlags; 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t a; 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t NA = nsymbols->getSymbols().size(); 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a)); 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? sym.int32Val : 0; 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isPublic = true; 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags; 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = assets->getIncludedResources().identifierForName( 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == 0) { 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), sym.name.string()); 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idents.add(code); 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.add(code); 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski publicFlags.add(isPublic); 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NA = idents.size(); 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "int[] styleable %s {", nclassName.string()); 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a != 0) { 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, ","); 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " 0x%08x", idents[a]); 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " }\n"); 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (a=0; a<NA; a++) { 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = idents.indexOf(origOrder.itemAt(a)); 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= 0) { 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!publicFlags.itemAt(a) && !includePrivate) { 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment; 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = getAttributeComment(assets, name8, &typeComment); 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getAttributeComment(assets, name8, &typeComment); 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t typeSpecFlags = 0; 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name16(sym.name); 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->getIncludedResources().identifierForName( 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name16.string(), name16.size(), 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16.string(), attr16.size(), 2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package16.string(), package16.size(), &typeSpecFlags); 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(attr16).string(), String8(name16).string(), typeSpecFlags); 26532412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe //const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; 2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "int styleable %s_%s %d\n", 2657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nclassName.string(), 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)pos); 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26632412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR; 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeSymbolClass( 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, 2668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, const String8& className, int indent, 26691e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski bool nonConstantId, bool emitCallback) 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic %sfinal class %s {\n", 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent != 0 ? "static " : "", className.string()); 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent++; 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char * id_format = nonConstantId ? 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static int %s=0x%08x;\n" : 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%spublic static final int %s=0x%08x;\n"; 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getSymbols().size(); 2684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool haveComment = false; 2695eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haveComment = true; 2698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2699eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n", 2702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), cmt.string()); 2703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeComment(sym.typeComment); 2705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeComment.size() > 0) { 2706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(typeComment); 2707eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!haveComment) { 2709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haveComment = true; 2710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n", getIndentSpace(indent), cmt.string()); 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s %s\n", getIndentSpace(indent), cmt.string()); 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haveComment) { 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp,"%s */\n", getIndentSpace(indent)); 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2720eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, getIndentSpace(indent)); 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, id_format, 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)sym.int32Val); 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) { 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(sym.comment); 2736eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown AnnotationProcessor ann; 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 2738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cmt(comment); 2739eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.preprocessComment(cmt); 2740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s/** %s\n" 2742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s */\n", 2743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), cmt.string(), 2744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent)); 2745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2746eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown ann.printAnnotations(fp, getIndentSpace(indent)); 2747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%spublic static final String %s=\"%s\";\n", 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getIndentSpace(indent), 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), sym.stringVal.string()); 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleableSymbols; 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = symbols->getNestedSymbols().size(); 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(symbols->getNestedSymbols().keyAt(i)); 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nclassName == "styleable") { 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleableSymbols = nsymbols; 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 27611e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, 27621e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski indent, nonConstantId, false); 2763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (styleableSymbols != NULL) { 2770e8e91925074479fc06310418b58b54f49d051801Adam Lesinski err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId); 2771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27761e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski if (emitCallback) { 27770f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba fprintf(fp, "%spublic static void onResourcesLoaded(int packageId) {\n", 27780f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba getIndentSpace(indent)); 27790f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1); 27800f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba fprintf(fp, "%s}\n", getIndentSpace(indent)); 27811e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski } 27821e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski indent--; 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s}\n", getIndentSpace(indent)); 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t writeTextSymbolClass( 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols, const String8& className) 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = symbols->getSymbols().size(); 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); 2798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { 2799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!assets->isJavaSymbol(sym, includePrivate)) { 2803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name8(sym.name); 2807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "int %s %s 0x%08x\n", 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.string(), 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flattenSymbol(name8).string(), (int)sym.int32Val); 2810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = symbols->getNestedSymbols().size(); 2813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 nclassName(symbols->getNestedSymbols().keyAt(i)); 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nclassName == "styleable") { 2817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate); 2818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName); 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, 28301e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski const String8& package, bool includePrivate, bool emitCallback) 2831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getRClassDir()) { 2833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* textSymbolsDest = bundle->getOutputTextSymbols(); 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 R("R"); 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = assets->getSymbols().size(); 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i); 2842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className(assets->getSymbols().keyAt(i)); 2843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dest(bundle->getRClassDir()); 2844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMakePackageDirs()) { 28469b8528fee4eed35b8e887ded0851d08eb2b10db6Chih-Hung Hsieh const String8& pkg(package); 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* last = pkg.string(); 2848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* s = last-1; 2849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski s++; 2851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (s > last && (*s == '.' || *s == 0)) { 2852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 part(last, s-last); 2853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.appendPath(part); 2854e17788ceff5c676f3783e5aa25d57a613e9f59dbElliott Hughes#ifdef _WIN32 2855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _mkdir(dest.string()); 2856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 2857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); 2858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 2859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski last = s+1; 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (*s); 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.appendPath(className); 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.append(".java"); 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(dest.string(), "w+"); 2866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 2867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", 2868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.string(), strerror(errno)); 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing symbols for class %s.\n", className.string()); 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " *\n" 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * This class was automatically generated by the\n" 2879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * aapt tool from the resource data it found. It\n" 2880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " * should not be modified by hand.\n" 2881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " */\n" 2882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 2883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "package %s;\n\n", package.string()); 2884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, 28861e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski className, 0, bundle->getNonConstantId(), emitCallback); 2887b30296b5fda75bf383c7ab3f567eb41820747869Elliott Hughes fclose(fp); 2888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (textSymbolsDest != NULL && R == className) { 2893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 textDest(textSymbolsDest); 2894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.appendPath(className); 2895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.append(".txt"); 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE* fp = fopen(textDest.string(), "w+"); 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fp == NULL) { 2899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n", 2900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski textDest.string(), strerror(errno)); 2901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 2904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" Writing text symbols for class %s.\n", className.string()); 2905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols, 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className); 2909b30296b5fda75bf383c7ab3f567eb41820747869Elliott Hughes fclose(fp); 2910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we were asked to generate a dependency file, we'll go ahead and add this R.java 2916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // as a target in the dependency file right next to it. 2917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getGenDependencies() && R == className) { 2918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add this R.java to the dependency file 2919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dependencyFile(bundle->getRClassDir()); 2920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyFile.appendPath("R.java.d"); 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FILE *fp = fopen(dependencyFile.string(), "a"); 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp,"%s \\\n", dest.string()); 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fclose(fp); 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass ProguardKeepSet 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 2935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // { rule --> { file locations } } 2936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, SortedVector<String8> > rules; 2937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void add(const String8& rule, const String8& where); 2939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 2940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ProguardKeepSet::add(const String8& rule, const String8& where) 2942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = rules.indexOfKey(rule); 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index = rules.add(rule, SortedVector<String8>()); 2946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rules.editValueAt(index).add(where); 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2951282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiaddProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName, 2952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* pkg, const String8& srcName, int line) 2953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 className(inClassName); 2955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 2956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf --> package.asdf 2957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // .asdf .a.b --> package.asdf package.a.b 2958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asdf.adsf --> asdf.asdf 2959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* p = className.string(); 2960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* q = strchr(p, '.'); 2961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == q) { 2962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className = pkg; 2963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append(inClassName); 2964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (q == NULL) { 2965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className = pkg; 2966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append("."); 2967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className.append(inClassName); 2968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 rule("-keep class "); 2972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += className; 2973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += " { <init>(...); }"; 2974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 location("view "); 2976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += srcName; 2977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char lineno[20]; 2978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(lineno, ":%d", line); 2979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += lineno; 2980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keep->add(rule, location); 2982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2985282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiaddProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName, 29862412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe const char* /* pkg */, const String8& srcName, int line) 2987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 rule("-keepclassmembers class * { *** "); 2989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += memberName; 2990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski rule += "(...); }"; 2991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 location("onClick "); 2993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += srcName; 2994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char lineno[20]; 2995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(lineno, ":%d", line); 2996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski location += lineno; 2997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keep->add(rule, location); 2999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 3002682583c8902efbd33d4394131a2214ce94469535Rohit AgrawalwriteProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets, bool mainDex) 3003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 3005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 3006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 3008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int depth = 0; 3009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inApplication = false; 3010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 error; 3011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> assGroup; 3012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> assFile; 3013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pkg; 3014682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal String8 defaultProcess; 3015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, look for a package file to parse. This is required to 3017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be able to generate the resource information. 3018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assGroup = assets->getFiles().valueFor(String8("AndroidManifest.xml")); 3019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (assGroup == NULL) { 3020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n"); 3021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 3022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (assGroup->getFiles().size() != 1) { 3025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", 3026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assGroup->getFiles().valueAt(0)->getPrintableSource().string()); 3027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile = assGroup->getFiles().valueAt(0); 3030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseXMLResource(assFile, &tree); 3032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 3037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 3039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 3040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (/* name == "Application" && */ depth == 2) { 3041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inApplication = false; 3042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth--; 3044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 3047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski depth++; 3050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 3051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // printf("Depth %d tag %s\n", depth, tag.string()); 3052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool keepTag = false; 3053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (depth == 1) { 3054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != "manifest") { 3055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); 3056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 3057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3058ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski pkg = AaptXml::getAttribute(tree, NULL, "package"); 3059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (depth == 2) { 3060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "application") { 3061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inApplication = true; 3062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 3063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3064ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 agent = AaptXml::getAttribute(tree, 3065ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski "http://schemas.android.com/apk/res/android", 3066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "backupAgent", &error); 3067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (agent.length() > 0) { 3068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, agent, pkg.string(), 3069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile->getPrintableSource(), tree.getLineNumber()); 3070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3071682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3072682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (mainDex) { 3073682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal defaultProcess = AaptXml::getAttribute(tree, 3074682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal "http://schemas.android.com/apk/res/android", "process", &error); 3075682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (error != "") { 3076682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal fprintf(stderr, "ERROR: %s\n", error.string()); 3077682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return -1; 3078682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 3079682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 3080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tag == "instrumentation") { 3081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 3082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!keepTag && inApplication && depth == 3) { 3085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { 3086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski keepTag = true; 3087f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic 3088f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic if (mainDex) { 3089f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic String8 componentProcess = AaptXml::getAttribute(tree, 3090f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic "http://schemas.android.com/apk/res/android", "process", &error); 3091f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic if (error != "") { 3092f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic fprintf(stderr, "ERROR: %s\n", error.string()); 3093f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic return -1; 3094f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic } 3095f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic 3096f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic const String8& process = 3097f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic componentProcess.length() > 0 ? componentProcess : defaultProcess; 3098f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic keepTag = process.length() > 0 && process.find(":") != 0; 3099f580d91dabc443301e2adcfc74509bec9b1960ffIvan Gavrilovic } 3100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (keepTag) { 3103ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski String8 name = AaptXml::getAttribute(tree, 3104ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski "http://schemas.android.com/apk/res/android", "name", &error); 3105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error != "") { 3106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: %s\n", error.string()); 3107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 3108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3109682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3110682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal keepTag = name.length() > 0; 3111682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3112682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (keepTag) { 3113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, name, pkg.string(), 3114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assFile->getPrintableSource(), tree.getLineNumber()); 3115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct NamespaceAttributePair { 3123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* ns; 3124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* attr; 3125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {} 3127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NamespaceAttributePair() : ns(NULL), attr(NULL) {} 3128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 3129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 3131282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile, 31329cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs) 3133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 3135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree tree; 3136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 3138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseXMLResource(layoutFile, &tree); 3140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.restart(); 3145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 31469cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski if (!startTags.isEmpty()) { 3147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool haveStart = false; 3148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 3149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 3150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 31539cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski const size_t numStartTags = startTags.size(); 31549cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski for (size_t i = 0; i < numStartTags; i++) { 31559cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski if (tag == startTags[i]) { 31569cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski haveStart = true; 31579cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski } 3158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!haveStart) { 3162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 3167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 3168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tag(tree.getElementName(&len)); 3171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If there is no '.', we'll assume that it's one of the built in names. 3173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strchr(tag.string(), '.')) { 3174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, tag, NULL, 3175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 3176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (tagAttrPairs != NULL) { 3177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t tagIndex = tagAttrPairs->indexOfKey(tag); 3178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tagIndex >= 0) { 3179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex); 3180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < nsAttrVector.size(); i++) { 3181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const NamespaceAttributePair& nsAttr = nsAttrVector[i]; 3182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr); 3184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attrIndex < 0) { 3185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n", 3186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // layoutFile->getPrintableSource().string(), tree.getLineNumber(), 3187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag.string(), nsAttr.ns, nsAttr.attr); 3188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepRule(keep, 3191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(tree.getAttributeStringValue(attrIndex, &len)), NULL, 3192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 3193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick"); 3198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attrIndex >= 0) { 3199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProguardKeepMethodRule(keep, 3201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(tree.getAttributeStringValue(attrIndex, &len)), NULL, 3202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layoutFile->getPrintableSource(), tree.getLineNumber()); 3203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest, 3210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* tag, const char* ns, const char* attr) { 3211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 tagStr(tag); 3212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t index = dest->indexOfKey(tagStr); 3213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 3215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<NamespaceAttributePair> vector; 3216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski vector.add(NamespaceAttributePair(ns, attr)); 3217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->add(tagStr, vector); 3218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->editValueAt(index).add(NamespaceAttributePair(ns, attr)); 3220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 3224282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets) 3225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 322762c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski const char* kClass = "class"; 322862c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski const char* kFragment = "fragment"; 32294c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski const String8 kTransition("transition"); 32304c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski const String8 kTransitionPrefix("transition-"); 3231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag:attribute pairs that should be checked in layout files. 3233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs; 323462c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, kClass); 323562c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, kFragment, NULL, kClass); 323662c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kLayoutTagAttrPairs, kFragment, RESOURCES_ANDROID_NAMESPACE, "name"); 3237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // tag:attribute pairs that should be checked in xml files. 3239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs; 324062c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, kFragment); 324162c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, kFragment); 3242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32434c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski // tag:attribute pairs that should be checked in transition files. 32444c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs; 324562c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass); 324662c5df52e771e8cf490ee42e5d1516ec10170679Adam Lesinski addTagAttrPair(&kTransitionTagAttrPairs, "pathMotion", NULL, kClass); 32474c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski 3248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& dirs = assets->resDirs(); 3249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t K = dirs.size(); 3250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<K; k++) { 3251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = dirs.itemAt(k); 3252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& dirName = d->getLeaf(); 32539cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski Vector<String8> startTags; 3254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL; 3255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) { 3256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = &kLayoutTagAttrPairs; 3257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) { 32589cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("PreferenceScreen")); 32599cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("preference-headers")); 3260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = &kXmlTagAttrPairs; 3261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) { 32629cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski startTags.add(String8("menu")); 3263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tagAttrPairs = NULL; 32644c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski } else if (dirName == kTransition || (strncmp(dirName.string(), kTransitionPrefix.string(), 32654c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski kTransitionPrefix.size()) == 0)) { 32664c488ff931fe6b2fc79ef854febc98b4cb748402Adam Lesinski tagAttrPairs = &kTransitionTagAttrPairs; 3267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles(); 3272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = groups.size(); 3273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptGroup>& group = groups.valueAt(i); 3275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles(); 3276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t M = files.size(); 3277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<M; j++) { 32789cf4b4a932d0bd84e0b7263540bd9d7174e8d2d0Adam Lesinski err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs); 3279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 3280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Handle the overlays 3286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> overlay = assets->getOverlay(); 3287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay.get()) { 3288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return writeProguardForLayouts(keep, overlay); 3289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 3295682583c8902efbd33d4394131a2214ce94469535Rohit AgrawalwriteProguardSpec(const char* filename, const ProguardKeepSet& keep, status_t err) 3296682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal{ 3297682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal FILE* fp = fopen(filename, "w+"); 3298682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (fp == NULL) { 3299682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", 3300682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal filename, strerror(errno)); 3301682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return UNKNOWN_ERROR; 3302682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 3303682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3304682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules; 3305682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal const size_t N = rules.size(); 3306682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal for (size_t i=0; i<N; i++) { 3307682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal const SortedVector<String8>& locations = rules.valueAt(i); 3308682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal const size_t M = locations.size(); 3309682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal for (size_t j=0; j<M; j++) { 3310682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal fprintf(fp, "# %s\n", locations.itemAt(j).string()); 3311682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 3312682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal fprintf(fp, "%s\n\n", rules.keyAt(i).string()); 3313682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal } 3314682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal fclose(fp); 3315682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3316682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return err; 3317682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal} 3318682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3319682583c8902efbd33d4394131a2214ce94469535Rohit Agrawalstatus_t 3320282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiwriteProguardFile(Bundle* bundle, const sp<AaptAssets>& assets) 3321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = -1; 3323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!bundle->getProguardFile()) { 3325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ProguardKeepSet keep; 3329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3330682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal err = writeProguardForAndroidManifest(&keep, assets, false); 3331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 3332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = writeProguardForLayouts(&keep, assets); 3336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < 0) { 3337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3340682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return writeProguardSpec(bundle->getProguardFile(), keep, err); 3341682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal} 3342682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3343682583c8902efbd33d4394131a2214ce94469535Rohit Agrawalstatus_t 3344682583c8902efbd33d4394131a2214ce94469535Rohit AgrawalwriteMainDexProguardFile(Bundle* bundle, const sp<AaptAssets>& assets) 3345682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal{ 3346682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal status_t err = -1; 3347682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3348682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (!bundle->getMainDexProguardFile()) { 3349682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return NO_ERROR; 3350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3352682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal ProguardKeepSet keep; 3353682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal 3354682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal err = writeProguardForAndroidManifest(&keep, assets, true); 3355682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal if (err < 0) { 3356682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return err; 3357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3359682583c8902efbd33d4394131a2214ce94469535Rohit Agrawal return writeProguardSpec(bundle->getMainDexProguardFile(), keep, err); 3360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Loops through the string paths and writes them to the file pointer 3363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Each file path is written on its own line with a terminating backslash. 3364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp) 3365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t deps = -1; 3367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t file_i = 0; file_i < files->size(); ++file_i) { 3368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the full file path to the dependency file 3369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "%s \\\n", files->itemAt(file_i).string()); 3370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps++; 3371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return deps; 3373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 33762412f84064c26b643c722ce914a97c4ec7776c69Andreas GampewriteDependencyPreReqs(Bundle* /* bundle */, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw) 3377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t deps = -1; 3379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps += writePathsToFile(assets->getFullResPaths(), fp); 3380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (includeRaw) { 3381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski deps += writePathsToFile(assets->getFullAssetPaths(), fp); 3382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return deps; 3384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3385