diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /tools | |
parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
download | frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'tools')
190 files changed, 0 insertions, 42010 deletions
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp deleted file mode 100644 index 6bc1ee6..0000000 --- a/tools/aapt/AaptAssets.cpp +++ /dev/null @@ -1,1717 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// - -#include "AaptAssets.h" -#include "Main.h" - -#include <utils/misc.h> -#include <utils/SortedVector.h> - -#include <ctype.h> -#include <dirent.h> -#include <errno.h> - -static const char* kDefaultLocale = "default"; -static const char* kWildcardName = "any"; -static const char* kAssetDir = "assets"; -static const char* kResourceDir = "res"; -static const char* kInvalidChars = "/\\:"; -static const size_t kMaxAssetFileName = 100; - -static const String8 kResString(kResourceDir); - -/* - * Names of asset files must meet the following criteria: - * - * - the filename length must be less than kMaxAssetFileName bytes long - * (and can't be empty) - * - all characters must be 7-bit printable ASCII - * - none of { '/' '\\' ':' } - * - * Pass in just the filename, not the full path. - */ -static bool validateFileName(const char* fileName) -{ - const char* cp = fileName; - size_t len = 0; - - while (*cp != '\0') { - if ((*cp & 0x80) != 0) - return false; // reject high ASCII - if (*cp < 0x20 || *cp >= 0x7f) - return false; // reject control chars and 0x7f - if (strchr(kInvalidChars, *cp) != NULL) - return false; // reject path sep chars - cp++; - len++; - } - - if (len < 1 || len > kMaxAssetFileName) - return false; // reject empty or too long - - return true; -} - -static bool isHidden(const char *root, const char *path) -{ - const char *type = NULL; - - // Skip all hidden files. - if (path[0] == '.') { - // Skip ., .. and .svn but don't chatter about it. - if (strcmp(path, ".") == 0 - || strcmp(path, "..") == 0 - || strcmp(path, ".svn") == 0) { - return true; - } - type = "hidden"; - } else if (path[0] == '_') { - // skip directories starting with _ (don't chatter about it) - String8 subdirName(root); - subdirName.appendPath(path); - if (getFileType(subdirName.string()) == kFileTypeDirectory) { - return true; - } - } else if (strcmp(path, "CVS") == 0) { - // Skip CVS but don't chatter about it. - return true; - } else if (strcasecmp(path, "thumbs.db") == 0 - || strcasecmp(path, "picasa.ini") == 0) { - // Skip suspected image indexes files. - type = "index"; - } else if (path[strlen(path)-1] == '~') { - // Skip suspected emacs backup files. - type = "backup"; - } else { - // Let everything else through. - return false; - } - - /* If we get this far, "type" should be set and the file - * should be skipped. - */ - String8 subdirName(root); - subdirName.appendPath(path); - fprintf(stderr, " (skipping %s %s '%s')\n", type, - getFileType(subdirName.string())==kFileTypeDirectory ? "dir":"file", - subdirName.string()); - - return true; -} - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -status_t -AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value) -{ - ResTable_config config; - - // IMSI - MCC - if (getMccName(part.string(), &config)) { - *axis = AXIS_MCC; - *value = config.mcc; - return 0; - } - - // IMSI - MNC - if (getMncName(part.string(), &config)) { - *axis = AXIS_MNC; - *value = config.mnc; - return 0; - } - - // locale - language - if (part.length() == 2 && isalpha(part[0]) && isalpha(part[1])) { - *axis = AXIS_LANGUAGE; - *value = part[1] << 8 | part[0]; - return 0; - } - - // locale - language_REGION - if (part.length() == 5 && isalpha(part[0]) && isalpha(part[1]) - && part[2] == '_' && isalpha(part[3]) && isalpha(part[4])) { - *axis = AXIS_LANGUAGE; - *value = (part[4] << 24) | (part[3] << 16) | (part[1] << 8) | (part[0]); - return 0; - } - - // orientation - if (getOrientationName(part.string(), &config)) { - *axis = AXIS_ORIENTATION; - *value = config.orientation; - return 0; - } - - // density - if (getDensityName(part.string(), &config)) { - *axis = AXIS_DENSITY; - *value = config.density; - return 0; - } - - // touchscreen - if (getTouchscreenName(part.string(), &config)) { - *axis = AXIS_TOUCHSCREEN; - *value = config.touchscreen; - return 0; - } - - // keyboard hidden - if (getKeysHiddenName(part.string(), &config)) { - *axis = AXIS_KEYSHIDDEN; - *value = config.inputFlags; - return 0; - } - - // keyboard - if (getKeyboardName(part.string(), &config)) { - *axis = AXIS_KEYBOARD; - *value = config.keyboard; - return 0; - } - - // navigation - if (getNavigationName(part.string(), &config)) { - *axis = AXIS_NAVIGATION; - *value = config.navigation; - return 0; - } - - // screen size - if (getScreenSizeName(part.string(), &config)) { - *axis = AXIS_SCREENSIZE; - *value = config.screenSize; - return 0; - } - - // version - if (getVersionName(part.string(), &config)) { - *axis = AXIS_VERSION; - *value = config.version; - return 0; - } - - return 1; -} - -bool -AaptGroupEntry::initFromDirName(const char* dir, String8* resType) -{ - Vector<String8> parts; - - String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, vers; - - const char *p = dir; - const char *q; - while (NULL != (q = strchr(p, '-'))) { - String8 val(p, q-p); - val.toLower(); - parts.add(val); - //printf("part: %s\n", parts[parts.size()-1].string()); - p = q+1; - } - String8 val(p); - val.toLower(); - parts.add(val); - //printf("part: %s\n", parts[parts.size()-1].string()); - - const int N = parts.size(); - int index = 0; - String8 part = parts[index]; - - // resource type - if (!isValidResourceType(part)) { - return false; - } - *resType = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - - // imsi - mcc - if (getMccName(part.string())) { - mcc = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not mcc: %s\n", part.string()); - } - - // imsi - mnc - if (getMncName(part.string())) { - mnc = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not mcc: %s\n", part.string()); - } - - // locale - language - if (part.length() == 2 && isalpha(part[0]) && isalpha(part[1])) { - loc = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not language: %s\n", part.string()); - } - - // locale - region - if (loc.length() > 0 - && part.length() == 3 && part[0] == 'r' && part[0] && part[1]) { - loc += "-"; - part.toUpper(); - loc += part.string() + 1; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not region: %s\n", part.string()); - } - - // orientation - if (getOrientationName(part.string())) { - orient = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not orientation: %s\n", part.string()); - } - - // density - if (getDensityName(part.string())) { - den = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not density: %s\n", part.string()); - } - - // touchscreen - if (getTouchscreenName(part.string())) { - touch = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not touchscreen: %s\n", part.string()); - } - - // keyboard hidden - if (getKeysHiddenName(part.string())) { - keysHidden = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not keysHidden: %s\n", part.string()); - } - - // keyboard - if (getKeyboardName(part.string())) { - key = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not keyboard: %s\n", part.string()); - } - - if (getNavigationName(part.string())) { - nav = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not navigation: %s\n", part.string()); - } - - if (getScreenSizeName(part.string())) { - size = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not screen size: %s\n", part.string()); - } - - if (getVersionName(part.string())) { - vers = part; - - index++; - if (index == N) { - goto success; - } - part = parts[index]; - } else { - //printf("not version: %s\n", part.string()); - } - - // if there are extra parts, it doesn't match - return false; - -success: - this->mcc = mcc; - this->mnc = mnc; - this->locale = loc; - this->orientation = orient; - this->density = den; - this->touchscreen = touch; - this->keysHidden = keysHidden; - this->keyboard = key; - this->navigation = nav; - this->screenSize = size; - this->version = vers; - - // what is this anyway? - this->vendor = ""; - - return true; -} - -String8 -AaptGroupEntry::toString() const -{ - String8 s = this->mcc; - s += ","; - s += this->mnc; - s += ","; - s += this->locale; - s += ","; - s += this->orientation; - s += ","; - s += density; - s += ","; - s += touchscreen; - s += ","; - s += keysHidden; - s += ","; - s += keyboard; - s += ","; - s += navigation; - s += ","; - s += screenSize; - s += ","; - s += version; - return s; -} - -String8 -AaptGroupEntry::toDirName(const String8& resType) const -{ - String8 s = resType; - if (this->mcc != "") { - s += "-"; - s += mcc; - } - if (this->mnc != "") { - s += "-"; - s += mnc; - } - if (this->locale != "") { - s += "-"; - s += locale; - } - if (this->orientation != "") { - s += "-"; - s += orientation; - } - if (this->density != "") { - s += "-"; - s += density; - } - if (this->touchscreen != "") { - s += "-"; - s += touchscreen; - } - if (this->keysHidden != "") { - s += "-"; - s += keysHidden; - } - if (this->keyboard != "") { - s += "-"; - s += keyboard; - } - if (this->navigation != "") { - s += "-"; - s += navigation; - } - if (this->screenSize != "") { - s += "-"; - s += screenSize; - } - if (this->version != "") { - s += "-"; - s += version; - } - - return s; -} - -bool AaptGroupEntry::getMccName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->mcc = 0; - return true; - } - const char* c = name; - if (tolower(*c) != 'm') return false; - c++; - if (tolower(*c) != 'c') return false; - c++; - if (tolower(*c) != 'c') return false; - c++; - - const char* val = c; - - while (*c >= '0' && *c <= '9') { - c++; - } - if (*c != 0) return false; - if (c-val != 3) return false; - - int d = atoi(val); - if (d != 0) { - if (out) out->mcc = d; - return true; - } - - return false; -} - -bool AaptGroupEntry::getMncName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->mcc = 0; - return true; - } - const char* c = name; - if (tolower(*c) != 'm') return false; - c++; - if (tolower(*c) != 'n') return false; - c++; - if (tolower(*c) != 'c') return false; - c++; - - const char* val = c; - - while (*c >= '0' && *c <= '9') { - c++; - } - if (*c != 0) return false; - if (c-val == 0 || c-val > 3) return false; - - int d = atoi(val); - if (d != 0) { - if (out) out->mnc = d; - return true; - } - - return false; -} - -/* - * Does this directory name fit the pattern of a locale dir ("en-rUS" or - * "default")? - * - * TODO: Should insist that the first two letters are lower case, and the - * second two are upper. - */ -bool AaptGroupEntry::getLocaleName(const char* fileName, - ResTable_config* out) -{ - if (strcmp(fileName, kWildcardName) == 0 - || strcmp(fileName, kDefaultLocale) == 0) { - if (out) { - out->language[0] = 0; - out->language[1] = 0; - out->country[0] = 0; - out->country[1] = 0; - } - return true; - } - - if (strlen(fileName) == 2 && isalpha(fileName[0]) && isalpha(fileName[1])) { - if (out) { - out->language[0] = fileName[0]; - out->language[1] = fileName[1]; - out->country[0] = 0; - out->country[1] = 0; - } - return true; - } - - if (strlen(fileName) == 5 && - isalpha(fileName[0]) && - isalpha(fileName[1]) && - fileName[2] == '-' && - isalpha(fileName[3]) && - isalpha(fileName[4])) { - if (out) { - out->language[0] = fileName[0]; - out->language[1] = fileName[1]; - out->country[0] = fileName[3]; - out->country[1] = fileName[4]; - } - return true; - } - - return false; -} - -bool AaptGroupEntry::getOrientationName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->orientation = out->ORIENTATION_ANY; - return true; - } else if (strcmp(name, "port") == 0) { - if (out) out->orientation = out->ORIENTATION_PORT; - return true; - } else if (strcmp(name, "land") == 0) { - if (out) out->orientation = out->ORIENTATION_LAND; - return true; - } else if (strcmp(name, "square") == 0) { - if (out) out->orientation = out->ORIENTATION_SQUARE; - return true; - } - - return false; -} - -bool AaptGroupEntry::getDensityName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->density = 0; - return true; - } - char* c = (char*)name; - while (*c >= '0' && *c <= '9') { - c++; - } - - // check that we have 'dpi' after the last digit. - if (toupper(c[0]) != 'D' || - toupper(c[1]) != 'P' || - toupper(c[2]) != 'I' || - c[3] != 0) { - return false; - } - - // temporarily replace the first letter with \0 to - // use atoi. - char tmp = c[0]; - c[0] = '\0'; - - int d = atoi(name); - c[0] = tmp; - - if (d != 0) { - if (out) out->density = d; - return true; - } - - return false; -} - -bool AaptGroupEntry::getTouchscreenName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->touchscreen = out->TOUCHSCREEN_ANY; - return true; - } else if (strcmp(name, "notouch") == 0) { - if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH; - return true; - } else if (strcmp(name, "stylus") == 0) { - if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS; - return true; - } else if (strcmp(name, "finger") == 0) { - if (out) out->touchscreen = out->TOUCHSCREEN_FINGER; - return true; - } - - return false; -} - -bool AaptGroupEntry::getKeysHiddenName(const char* name, - ResTable_config* out) -{ - uint8_t mask = 0; - uint8_t value = 0; - if (strcmp(name, kWildcardName) == 0) { - mask = out->MASK_KEYSHIDDEN; - value = out->KEYSHIDDEN_ANY; - } else if (strcmp(name, "keysexposed") == 0) { - mask = out->MASK_KEYSHIDDEN; - value = out->KEYSHIDDEN_NO; - } else if (strcmp(name, "keyshidden") == 0) { - mask = out->MASK_KEYSHIDDEN; - value = out->KEYSHIDDEN_YES; - } else if (strcmp(name, "keyssoft") == 0) { - mask = out->MASK_KEYSHIDDEN; - value = out->KEYSHIDDEN_SOFT; - } - - if (mask != 0) { - if (out) out->inputFlags = (out->inputFlags&~mask) | value; - return true; - } - - return false; -} - -bool AaptGroupEntry::getKeyboardName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->keyboard = out->KEYBOARD_ANY; - return true; - } else if (strcmp(name, "nokeys") == 0) { - if (out) out->keyboard = out->KEYBOARD_NOKEYS; - return true; - } else if (strcmp(name, "qwerty") == 0) { - if (out) out->keyboard = out->KEYBOARD_QWERTY; - return true; - } else if (strcmp(name, "12key") == 0) { - if (out) out->keyboard = out->KEYBOARD_12KEY; - return true; - } - - return false; -} - -bool AaptGroupEntry::getNavigationName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) out->navigation = out->NAVIGATION_ANY; - return true; - } else if (strcmp(name, "nonav") == 0) { - if (out) out->navigation = out->NAVIGATION_NONAV; - return true; - } else if (strcmp(name, "dpad") == 0) { - if (out) out->navigation = out->NAVIGATION_DPAD; - return true; - } else if (strcmp(name, "trackball") == 0) { - if (out) out->navigation = out->NAVIGATION_TRACKBALL; - return true; - } else if (strcmp(name, "wheel") == 0) { - if (out) out->navigation = out->NAVIGATION_WHEEL; - return true; - } - - return false; -} - -bool AaptGroupEntry::getScreenSizeName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) { - out->screenWidth = out->SCREENWIDTH_ANY; - out->screenHeight = out->SCREENHEIGHT_ANY; - } - return true; - } - - const char* x = name; - while (*x >= '0' && *x <= '9') x++; - if (x == name || *x != 'x') return false; - String8 xName(name, x-name); - x++; - - const char* y = x; - while (*y >= '0' && *y <= '9') y++; - if (y == name || *y != 0) return false; - String8 yName(x, y-x); - - uint16_t w = (uint16_t)atoi(xName.string()); - uint16_t h = (uint16_t)atoi(yName.string()); - if (w < h) { - return false; - } - - if (out) { - out->screenWidth = w; - out->screenHeight = h; - } - - return true; -} - -bool AaptGroupEntry::getVersionName(const char* name, - ResTable_config* out) -{ - if (strcmp(name, kWildcardName) == 0) { - if (out) { - out->sdkVersion = out->SDKVERSION_ANY; - out->minorVersion = out->MINORVERSION_ANY; - } - return true; - } - - if (*name != 'v') { - return false; - } - - name++; - const char* s = name; - while (*s >= '0' && *s <= '9') s++; - if (s == name || *s != 0) return false; - String8 sdkName(name, s-name); - - if (out) { - out->sdkVersion = (uint16_t)atoi(sdkName.string()); - out->minorVersion = 0; - } - - return true; -} - -int AaptGroupEntry::compare(const AaptGroupEntry& o) const -{ - int v = mcc.compare(o.mcc); - if (v == 0) v = mnc.compare(o.mnc); - if (v == 0) v = locale.compare(o.locale); - if (v == 0) v = vendor.compare(o.vendor); - if (v == 0) v = orientation.compare(o.orientation); - if (v == 0) v = density.compare(o.density); - if (v == 0) v = touchscreen.compare(o.touchscreen); - if (v == 0) v = keysHidden.compare(o.keysHidden); - if (v == 0) v = keyboard.compare(o.keyboard); - if (v == 0) v = navigation.compare(o.navigation); - if (v == 0) v = screenSize.compare(o.screenSize); - if (v == 0) v = version.compare(o.version); - return v; -} - -ResTable_config AaptGroupEntry::toParams() const -{ - ResTable_config params; - memset(¶ms, 0, sizeof(params)); - getMccName(mcc.string(), ¶ms); - getMncName(mnc.string(), ¶ms); - getLocaleName(locale.string(), ¶ms); - getOrientationName(orientation.string(), ¶ms); - getDensityName(density.string(), ¶ms); - getTouchscreenName(touchscreen.string(), ¶ms); - getKeysHiddenName(keysHidden.string(), ¶ms); - getKeyboardName(keyboard.string(), ¶ms); - getNavigationName(navigation.string(), ¶ms); - getScreenSizeName(screenSize.string(), ¶ms); - getVersionName(version.string(), ¶ms); - return params; -} - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -void* AaptFile::editData(size_t size) -{ - if (size <= mBufferSize) { - mDataSize = size; - return mData; - } - size_t allocSize = (size*3)/2; - void* buf = realloc(mData, allocSize); - if (buf == NULL) { - return NULL; - } - mData = buf; - mDataSize = size; - mBufferSize = allocSize; - return buf; -} - -void* AaptFile::editData(size_t* outSize) -{ - if (outSize) { - *outSize = mDataSize; - } - return mData; -} - -void* AaptFile::padData(size_t wordSize) -{ - const size_t extra = mDataSize%wordSize; - if (extra == 0) { - return mData; - } - - size_t initial = mDataSize; - void* data = editData(initial+(wordSize-extra)); - if (data != NULL) { - memset(((uint8_t*)data) + initial, 0, wordSize-extra); - } - return data; -} - -status_t AaptFile::writeData(const void* data, size_t size) -{ - size_t end = mDataSize; - size_t total = size + end; - void* buf = editData(total); - if (buf == NULL) { - return UNKNOWN_ERROR; - } - memcpy(((char*)buf)+end, data, size); - return NO_ERROR; -} - -void AaptFile::clearData() -{ - if (mData != NULL) free(mData); - mData = NULL; - mDataSize = 0; - mBufferSize = 0; -} - -String8 AaptFile::getPrintableSource() const -{ - if (hasData()) { - String8 name(mGroupEntry.locale.string()); - name.appendPath(mGroupEntry.vendor.string()); - name.appendPath(mPath); - name.append(" #generated"); - return name; - } - return mSourceFile; -} - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -status_t AaptGroup::addFile(const sp<AaptFile>& file) -{ - if (mFiles.indexOfKey(file->getGroupEntry()) < 0) { - file->mPath = mPath; - mFiles.add(file->getGroupEntry(), file); - return NO_ERROR; - } - - SourcePos(file->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.", - getPrintableSource().string()); - return UNKNOWN_ERROR; -} - -void AaptGroup::removeFile(size_t index) -{ - mFiles.removeItemsAt(index); -} - -void AaptGroup::print() const -{ - printf(" %s\n", getPath().string()); - const size_t N=mFiles.size(); - size_t i; - for (i=0; i<N; i++) { - sp<AaptFile> file = mFiles.valueAt(i); - const AaptGroupEntry& e = file->getGroupEntry(); - if (file->hasData()) { - printf(" Gen: (%s) %d bytes\n", e.toString().string(), - (int)file->getSize()); - } else { - printf(" Src: %s\n", file->getPrintableSource().string()); - } - } -} - -String8 AaptGroup::getPrintableSource() const -{ - if (mFiles.size() > 0) { - // Arbitrarily pull the first source file out of the list. - return mFiles.valueAt(0)->getPrintableSource(); - } - - // Should never hit this case, but to be safe... - return getPath(); - -} - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -status_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file) -{ - if (mFiles.indexOfKey(name) >= 0) { - return ALREADY_EXISTS; - } - mFiles.add(name, file); - return NO_ERROR; -} - -status_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir) -{ - if (mDirs.indexOfKey(name) >= 0) { - return ALREADY_EXISTS; - } - mDirs.add(name, dir); - return NO_ERROR; -} - -sp<AaptDir> AaptDir::makeDir(const String8& path) -{ - String8 name; - String8 remain = path; - - sp<AaptDir> subdir = this; - while (name = remain.walkPath(&remain), remain != "") { - subdir = subdir->makeDir(name); - } - - ssize_t i = subdir->mDirs.indexOfKey(name); - if (i >= 0) { - return subdir->mDirs.valueAt(i); - } - sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name)); - subdir->mDirs.add(name, dir); - return dir; -} - -void AaptDir::removeFile(const String8& name) -{ - mFiles.removeItem(name); -} - -void AaptDir::removeDir(const String8& name) -{ - mDirs.removeItem(name); -} - -status_t AaptDir::renameFile(const sp<AaptFile>& file, const String8& newName) -{ - sp<AaptGroup> origGroup; - - // Find and remove the given file with shear, brute force! - const size_t NG = mFiles.size(); - size_t i; - for (i=0; origGroup == NULL && i<NG; i++) { - sp<AaptGroup> g = mFiles.valueAt(i); - const size_t NF = g->getFiles().size(); - for (size_t j=0; j<NF; j++) { - if (g->getFiles().valueAt(j) == file) { - origGroup = g; - g->removeFile(j); - if (NF == 1) { - mFiles.removeItemsAt(i); - } - break; - } - } - } - - //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string()); - - // Place the file under its new name. - if (origGroup != NULL) { - return addLeafFile(newName, file); - } - - return NO_ERROR; -} - -status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file) -{ - sp<AaptGroup> group; - if (mFiles.indexOfKey(leafName) >= 0) { - group = mFiles.valueFor(leafName); - } else { - group = new AaptGroup(leafName, mPath.appendPathCopy(leafName)); - mFiles.add(leafName, group); - } - - return group->addFile(file); -} - -ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, - const AaptGroupEntry& kind, const String8& resType) -{ - Vector<String8> fileNames; - - { - DIR* dir = NULL; - - dir = opendir(srcDir.string()); - if (dir == NULL) { - fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); - return UNKNOWN_ERROR; - } - - /* - * Slurp the filenames out of the directory. - */ - while (1) { - struct dirent* entry; - - entry = readdir(dir); - if (entry == NULL) - break; - - if (isHidden(srcDir.string(), entry->d_name)) - continue; - - fileNames.add(String8(entry->d_name)); - } - - closedir(dir); - } - - ssize_t count = 0; - - /* - * Stash away the files and recursively descend into subdirectories. - */ - const size_t N = fileNames.size(); - size_t i; - for (i = 0; i < N; i++) { - String8 pathName(srcDir); - FileType type; - - pathName.appendPath(fileNames[i].string()); - type = getFileType(pathName.string()); - if (type == kFileTypeDirectory) { - sp<AaptDir> subdir; - bool notAdded = false; - if (mDirs.indexOfKey(fileNames[i]) >= 0) { - subdir = mDirs.valueFor(fileNames[i]); - } else { - subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i])); - notAdded = true; - } - ssize_t res = subdir->slurpFullTree(bundle, pathName, kind, - resType); - if (res < NO_ERROR) { - return res; - } - if (res > 0 && notAdded) { - mDirs.add(fileNames[i], subdir); - } - count += res; - } else if (type == kFileTypeRegular) { - sp<AaptFile> file = new AaptFile(pathName, kind, resType); - status_t err = addLeafFile(fileNames[i], file); - if (err != NO_ERROR) { - return err; - } - - count++; - - } else { - if (bundle->getVerbose()) - printf(" (ignoring non-file/dir '%s')\n", pathName.string()); - } - } - - return count; -} - -status_t AaptDir::validate() const -{ - const size_t NF = mFiles.size(); - const size_t ND = mDirs.size(); - size_t i; - for (i = 0; i < NF; i++) { - if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) { - SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( - "Invalid filename. Unable to add."); - return UNKNOWN_ERROR; - } - - size_t j; - for (j = i+1; j < NF; j++) { - if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), - mFiles.valueAt(j)->getLeaf().string()) == 0) { - SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( - "File is case-insensitive equivalent to: %s", - mFiles.valueAt(j)->getPrintableSource().string()); - return UNKNOWN_ERROR; - } - - // TODO: if ".gz", check for non-.gz; if non-, check for ".gz" - // (this is mostly caught by the "marked" stuff, below) - } - - for (j = 0; j < ND; j++) { - if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), - mDirs.valueAt(j)->getLeaf().string()) == 0) { - SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( - "File conflicts with dir from: %s", - mDirs.valueAt(j)->getPrintableSource().string()); - return UNKNOWN_ERROR; - } - } - } - - for (i = 0; i < ND; i++) { - if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) { - SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( - "Invalid directory name, unable to add."); - return UNKNOWN_ERROR; - } - - size_t j; - for (j = i+1; j < ND; j++) { - if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(), - mDirs.valueAt(j)->getLeaf().string()) == 0) { - SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( - "Directory is case-insensitive equivalent to: %s", - mDirs.valueAt(j)->getPrintableSource().string()); - return UNKNOWN_ERROR; - } - } - - status_t err = mDirs.valueAt(i)->validate(); - if (err != NO_ERROR) { - return err; - } - } - - return NO_ERROR; -} - -void AaptDir::print() const -{ - const size_t ND=getDirs().size(); - size_t i; - for (i=0; i<ND; i++) { - getDirs().valueAt(i)->print(); - } - - const size_t NF=getFiles().size(); - for (i=0; i<NF; i++) { - getFiles().valueAt(i)->print(); - } -} - -String8 AaptDir::getPrintableSource() const -{ - if (mFiles.size() > 0) { - // Arbitrarily pull the first file out of the list as the source dir. - return mFiles.valueAt(0)->getPrintableSource().getPathDir(); - } - if (mDirs.size() > 0) { - // Or arbitrarily pull the first dir out of the list as the source dir. - return mDirs.valueAt(0)->getPrintableSource().getPathDir(); - } - - // Should never hit this case, but to be safe... - return mPath; - -} - -// ========================================================================= -// ========================================================================= -// ========================================================================= - -sp<AaptFile> AaptAssets::addFile( - const String8& filePath, const AaptGroupEntry& entry, - const String8& srcDir, sp<AaptGroup>* outGroup, - const String8& resType) -{ - sp<AaptDir> dir = this; - sp<AaptGroup> group; - sp<AaptFile> file; - String8 root, remain(filePath), partialPath; - while (remain.length() > 0) { - root = remain.walkPath(&remain); - partialPath.appendPath(root); - - const String8 rootStr(root); - - if (remain.length() == 0) { - ssize_t i = dir->getFiles().indexOfKey(rootStr); - if (i >= 0) { - group = dir->getFiles().valueAt(i); - } else { - group = new AaptGroup(rootStr, filePath); - status_t res = dir->addFile(rootStr, group); - if (res != NO_ERROR) { - return NULL; - } - } - file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType); - status_t res = group->addFile(file); - if (res != NO_ERROR) { - return NULL; - } - break; - - } else { - ssize_t i = dir->getDirs().indexOfKey(rootStr); - if (i >= 0) { - dir = dir->getDirs().valueAt(i); - } else { - sp<AaptDir> subdir = new AaptDir(rootStr, partialPath); - status_t res = dir->addDir(rootStr, subdir); - if (res != NO_ERROR) { - return NULL; - } - dir = subdir; - } - } - } - - mGroupEntries.add(entry); - if (outGroup) *outGroup = group; - return file; -} - -void AaptAssets::addResource(const String8& leafName, const String8& path, - const sp<AaptFile>& file, const String8& resType) -{ - sp<AaptDir> res = AaptDir::makeDir(kResString); - String8 dirname = file->getGroupEntry().toDirName(resType); - sp<AaptDir> subdir = res->makeDir(dirname); - sp<AaptGroup> grr = new AaptGroup(leafName, path); - grr->addFile(file); - - subdir->addFile(leafName, grr); -} - - -ssize_t AaptAssets::slurpFromArgs(Bundle* bundle) -{ - int count; - int totalCount = 0; - FileType type; - const Vector<const char *>& resDirs = bundle->getResourceSourceDirs(); - const size_t dirCount =resDirs.size(); - sp<AaptAssets> current = this; - - const int N = bundle->getFileSpecCount(); - - /* - * If a package manifest was specified, include that first. - */ - if (bundle->getAndroidManifestFile() != NULL) { - // place at root of zip. - String8 srcFile(bundle->getAndroidManifestFile()); - addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(), - NULL, String8()); - totalCount++; - } - - /* - * If a directory of custom assets was supplied, slurp 'em up. - */ - if (bundle->getAssetSourceDir()) { - const char* assetDir = bundle->getAssetSourceDir(); - - FileType type = getFileType(assetDir); - if (type == kFileTypeNonexistent) { - fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDir); - return UNKNOWN_ERROR; - } - if (type != kFileTypeDirectory) { - fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir); - return UNKNOWN_ERROR; - } - - String8 assetRoot(assetDir); - sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir)); - AaptGroupEntry group; - count = assetAaptDir->slurpFullTree(bundle, assetRoot, group, - String8()); - if (count < 0) { - totalCount = count; - goto bail; - } - if (count > 0) { - mGroupEntries.add(group); - } - totalCount += count; - - if (bundle->getVerbose()) - printf("Found %d custom asset file%s in %s\n", - count, (count==1) ? "" : "s", assetDir); - } - - /* - * If a directory of resource-specific assets was supplied, slurp 'em up. - */ - for (size_t i=0; i<dirCount; i++) { - const char *res = resDirs[i]; - if (res) { - type = getFileType(res); - if (type == kFileTypeNonexistent) { - fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res); - return UNKNOWN_ERROR; - } - if (type == kFileTypeDirectory) { - if (i>0) { - sp<AaptAssets> nextOverlay = new AaptAssets(); - current->setOverlay(nextOverlay); - current = nextOverlay; - } - count = current->slurpResourceTree(bundle, String8(res)); - - if (count < 0) { - totalCount = count; - goto bail; - } - totalCount += count; - } - else { - fprintf(stderr, "ERROR: '%s' is not a directory\n", res); - return UNKNOWN_ERROR; - } - } - - } - /* - * Now do any additional raw files. - */ - for (int arg=0; arg<N; arg++) { - const char* assetDir = bundle->getFileSpecEntry(arg); - - FileType type = getFileType(assetDir); - if (type == kFileTypeNonexistent) { - fprintf(stderr, "ERROR: input directory '%s' does not exist\n", assetDir); - return UNKNOWN_ERROR; - } - if (type != kFileTypeDirectory) { - fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir); - return UNKNOWN_ERROR; - } - - String8 assetRoot(assetDir); - - if (bundle->getVerbose()) - printf("Processing raw dir '%s'\n", (const char*) assetDir); - - /* - * Do a recursive traversal of subdir tree. We don't make any - * guarantees about ordering, so we're okay with an inorder search - * using whatever order the OS happens to hand back to us. - */ - count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8()); - if (count < 0) { - /* failure; report error and remove archive */ - totalCount = count; - goto bail; - } - totalCount += count; - - if (bundle->getVerbose()) - printf("Found %d asset file%s in %s\n", - count, (count==1) ? "" : "s", assetDir); - } - - count = validate(); - if (count != NO_ERROR) { - totalCount = count; - goto bail; - } - - -bail: - return totalCount; -} - -ssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir, - const AaptGroupEntry& kind, - const String8& resType) -{ - ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType); - if (res > 0) { - mGroupEntries.add(kind); - } - - return res; -} - -ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) -{ - ssize_t err = 0; - - DIR* dir = opendir(srcDir.string()); - if (dir == NULL) { - fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); - return UNKNOWN_ERROR; - } - - status_t count = 0; - - /* - * Run through the directory, looking for dirs that match the - * expected pattern. - */ - while (1) { - struct dirent* entry = readdir(dir); - if (entry == NULL) { - break; - } - - if (isHidden(srcDir.string(), entry->d_name)) { - continue; - } - - String8 subdirName(srcDir); - subdirName.appendPath(entry->d_name); - - AaptGroupEntry group; - String8 resType; - bool b = group.initFromDirName(entry->d_name, &resType); - if (!b) { - fprintf(stderr, "invalid resource directory name: %s/%s\n", srcDir.string(), - entry->d_name); - err = -1; - continue; - } - - FileType type = getFileType(subdirName.string()); - - if (type == kFileTypeDirectory) { - sp<AaptDir> dir = makeDir(String8(entry->d_name)); - ssize_t res = dir->slurpFullTree(bundle, subdirName, group, - resType); - if (res < 0) { - count = res; - goto bail; - } - if (res > 0) { - mGroupEntries.add(group); - count += res; - } - - mDirs.add(dir); - } else { - if (bundle->getVerbose()) { - fprintf(stderr, " (ignoring file '%s')\n", subdirName.string()); - } - } - } - -bail: - closedir(dir); - dir = NULL; - - if (err != 0) { - return err; - } - return count; -} - -ssize_t -AaptAssets::slurpResourceZip(Bundle* bundle, const char* filename) -{ - int count = 0; - SortedVector<AaptGroupEntry> entries; - - ZipFile* zip = new ZipFile; - status_t err = zip->open(filename, ZipFile::kOpenReadOnly); - if (err != NO_ERROR) { - fprintf(stderr, "error opening zip file %s\n", filename); - count = err; - delete zip; - return -1; - } - - const int N = zip->getNumEntries(); - for (int i=0; i<N; i++) { - ZipEntry* entry = zip->getEntryByIndex(i); - if (entry->getDeleted()) { - continue; - } - - String8 entryName(entry->getFileName()); - - String8 dirName = entryName.getPathDir(); - sp<AaptDir> dir = dirName == "" ? this : makeDir(dirName); - - String8 resType; - AaptGroupEntry kind; - - String8 remain; - if (entryName.walkPath(&remain) == kResourceDir) { - // these are the resources, pull their type out of the directory name - kind.initFromDirName(remain.walkPath().string(), &resType); - } else { - // these are untyped and don't have an AaptGroupEntry - } - if (entries.indexOf(kind) < 0) { - entries.add(kind); - mGroupEntries.add(kind); - } - - // use the one from the zip file if they both exist. - dir->removeFile(entryName.getPathLeaf()); - - sp<AaptFile> file = new AaptFile(entryName, kind, resType); - status_t err = dir->addLeafFile(entryName.getPathLeaf(), file); - if (err != NO_ERROR) { - fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string()); - count = err; - goto bail; - } - file->setCompressionMethod(entry->getCompressionMethod()); - -#if 0 - if (entryName == "AndroidManifest.xml") { - printf("AndroidManifest.xml\n"); - } - printf("\n\nfile: %s\n", entryName.string()); -#endif - - size_t len = entry->getUncompressedLen(); - void* data = zip->uncompress(entry); - void* buf = file->editData(len); - memcpy(buf, data, len); - -#if 0 - const int OFF = 0; - const unsigned char* p = (unsigned char*)data; - const unsigned char* end = p+len; - p += OFF; - for (int i=0; i<32 && p < end; i++) { - printf("0x%03x ", i*0x10 + OFF); - for (int j=0; j<0x10 && p < end; j++) { - printf(" %02x", *p); - p++; - } - printf("\n"); - } -#endif - - free(data); - - count++; - } - -bail: - delete zip; - return count; -} - -sp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name) -{ - sp<AaptSymbols> sym = mSymbols.valueFor(name); - if (sym == NULL) { - sym = new AaptSymbols(); - mSymbols.add(name, sym); - } - return sym; -} - -status_t AaptAssets::buildIncludedResources(Bundle* bundle) -{ - if (!mHaveIncludedAssets) { - // Add in all includes. - const Vector<const char*>& incl = bundle->getPackageIncludes(); - const size_t N=incl.size(); - for (size_t i=0; i<N; i++) { - if (bundle->getVerbose()) - printf("Including resources from package: %s\n", incl[i]); - if (!mIncludedAssets.addAssetPath(String8(incl[i]), NULL)) { - fprintf(stderr, "ERROR: Asset package include '%s' not found.\n", - incl[i]); - return UNKNOWN_ERROR; - } - } - mHaveIncludedAssets = true; - } - - return NO_ERROR; -} - -status_t AaptAssets::addIncludedResources(const sp<AaptFile>& file) -{ - const ResTable& res = getIncludedResources(); - // XXX dirty! - return const_cast<ResTable&>(res).add(file->getData(), file->getSize(), NULL); -} - -const ResTable& AaptAssets::getIncludedResources() const -{ - return mIncludedAssets.getResources(false); -} - -void AaptAssets::print() const -{ - printf("Locale/Vendor pairs:\n"); - const size_t N=mGroupEntries.size(); - for (size_t i=0; i<N; i++) { - printf(" %s/%s\n", - mGroupEntries.itemAt(i).locale.string(), - mGroupEntries.itemAt(i).vendor.string()); - } - - printf("\nFiles:\n"); - AaptDir::print(); -} - -bool -valid_symbol_name(const String8& symbol) -{ - static char const * const KEYWORDS[] = { - "abstract", "assert", "boolean", "break", - "byte", "case", "catch", "char", "class", "const", "continue", - "default", "do", "double", "else", "enum", "extends", "final", - "finally", "float", "for", "goto", "if", "implements", "import", - "instanceof", "int", "interface", "long", "native", "new", "package", - "private", "protected", "public", "return", "short", "static", - "strictfp", "super", "switch", "synchronized", "this", "throw", - "throws", "transient", "try", "void", "volatile", "while", - "true", "false", "null", - NULL - }; - const char*const* k = KEYWORDS; - const char*const s = symbol.string(); - while (*k) { - if (0 == strcmp(s, *k)) { - return false; - } - k++; - } - return true; -} diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h deleted file mode 100644 index 01c8140..0000000 --- a/tools/aapt/AaptAssets.h +++ /dev/null @@ -1,519 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Information about assets being operated on. -// -#ifndef __AAPT_ASSETS_H -#define __AAPT_ASSETS_H - -#include <stdlib.h> -#include <utils/AssetManager.h> -#include <utils/KeyedVector.h> -#include <utils/String8.h> -#include <utils/ResourceTypes.h> -#include <utils/SortedVector.h> -#include <utils/String8.h> -#include <utils/Vector.h> -#include <utils/RefBase.h> -#include <utils/ZipFile.h> - -#include "Bundle.h" -#include "SourcePos.h" - -using namespace android; - -bool valid_symbol_name(const String8& str); - -enum { - AXIS_NONE = 0, - AXIS_MCC = 1, - AXIS_MNC, - AXIS_LANGUAGE, - AXIS_REGION, - AXIS_ORIENTATION, - AXIS_DENSITY, - AXIS_TOUCHSCREEN, - AXIS_KEYSHIDDEN, - AXIS_KEYBOARD, - AXIS_NAVIGATION, - AXIS_SCREENSIZE, - AXIS_VERSION -}; - -/** - * This structure contains a specific variation of a single file out - * of all the variations it can have that we can have. - */ -struct AaptGroupEntry -{ -public: - AaptGroupEntry() { } - AaptGroupEntry(const String8& _locale, const String8& _vendor) - : locale(_locale), vendor(_vendor) { } - - String8 mcc; - String8 mnc; - String8 locale; - String8 vendor; - String8 orientation; - String8 density; - String8 touchscreen; - String8 keysHidden; - String8 keyboard; - String8 navigation; - String8 screenSize; - String8 version; - - bool initFromDirName(const char* dir, String8* resType); - - static status_t parseNamePart(const String8& part, int* axis, uint32_t* value); - - static bool getMccName(const char* name, ResTable_config* out = NULL); - static bool getMncName(const char* name, ResTable_config* out = NULL); - static bool getLocaleName(const char* name, ResTable_config* out = NULL); - static bool getOrientationName(const char* name, ResTable_config* out = NULL); - static bool getDensityName(const char* name, ResTable_config* out = NULL); - static bool getTouchscreenName(const char* name, ResTable_config* out = NULL); - static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL); - static bool getKeyboardName(const char* name, ResTable_config* out = NULL); - static bool getNavigationName(const char* name, ResTable_config* out = NULL); - static bool getScreenSizeName(const char* name, ResTable_config* out = NULL); - static bool getVersionName(const char* name, ResTable_config* out = NULL); - - int compare(const AaptGroupEntry& o) const; - - ResTable_config toParams() const; - - inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; } - inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; } - inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; } - inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; } - inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; } - inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; } - - String8 toString() const; - String8 toDirName(const String8& resType) const; -}; - -inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) -{ - return lhs.compare(rhs); -} - -inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) -{ - return compare_type(lhs, rhs) < 0; -} - -class AaptGroup; - -/** - * A single asset file we know about. - */ -class AaptFile : public RefBase -{ -public: - AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry, - const String8& resType) - : mGroupEntry(groupEntry) - , mResourceType(resType) - , mSourceFile(sourceFile) - , mData(NULL) - , mDataSize(0) - , mBufferSize(0) - , mCompression(ZipEntry::kCompressStored) - { - //printf("new AaptFile created %s\n", (const char*)sourceFile); - } - virtual ~AaptFile() { } - - const String8& getPath() const { return mPath; } - const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; } - - // Data API. If there is data attached to the file, - // getSourceFile() is not used. - bool hasData() const { return mData != NULL; } - const void* getData() const { return mData; } - size_t getSize() const { return mDataSize; } - void* editData(size_t size); - void* editData(size_t* outSize = NULL); - void* padData(size_t wordSize); - status_t writeData(const void* data, size_t size); - void clearData(); - - const String8& getResourceType() const { return mResourceType; } - - // File API. If the file does not hold raw data, this is - // a full path to a file on the filesystem that holds its data. - const String8& getSourceFile() const { return mSourceFile; } - - String8 getPrintableSource() const; - - // Desired compression method, as per utils/ZipEntry.h. For example, - // no compression is ZipEntry::kCompressStored. - int getCompressionMethod() const { return mCompression; } - void setCompressionMethod(int c) { mCompression = c; } -private: - friend class AaptGroup; - - String8 mPath; - AaptGroupEntry mGroupEntry; - String8 mResourceType; - String8 mSourceFile; - void* mData; - size_t mDataSize; - size_t mBufferSize; - int mCompression; -}; - -/** - * A group of related files (the same file, with different - * vendor/locale variations). - */ -class AaptGroup : public RefBase -{ -public: - AaptGroup(const String8& leaf, const String8& path) - : mLeaf(leaf), mPath(path) { } - virtual ~AaptGroup() { } - - const String8& getLeaf() const { return mLeaf; } - - // Returns the relative path after the AaptGroupEntry dirs. - const String8& getPath() const { return mPath; } - - const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const - { return mFiles; } - - status_t addFile(const sp<AaptFile>& file); - void removeFile(size_t index); - - void print() const; - - String8 getPrintableSource() const; - -private: - String8 mLeaf; - String8 mPath; - - DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles; -}; - -/** - * A single directory of assets, which can contain for files and other - * sub-directories. - */ -class AaptDir : public RefBase -{ -public: - AaptDir(const String8& leaf, const String8& path) - : mLeaf(leaf), mPath(path) { } - virtual ~AaptDir() { } - - const String8& getLeaf() const { return mLeaf; } - - const String8& getPath() const { return mPath; } - - const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; } - const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; } - - status_t addFile(const String8& name, const sp<AaptGroup>& file); - status_t addDir(const String8& name, const sp<AaptDir>& dir); - - sp<AaptDir> makeDir(const String8& name); - - void removeFile(const String8& name); - void removeDir(const String8& name); - - status_t renameFile(const sp<AaptFile>& file, const String8& newName); - - status_t addLeafFile(const String8& leafName, - const sp<AaptFile>& file); - - virtual ssize_t slurpFullTree(Bundle* bundle, - const String8& srcDir, - const AaptGroupEntry& kind, - const String8& resType); - - /* - * Perform some sanity checks on the names of files and directories here. - * In particular: - * - Check for illegal chars in filenames. - * - Check filename length. - * - Check for presence of ".gz" and non-".gz" copies of same file. - * - Check for multiple files whose names match in a case-insensitive - * fashion (problematic for some systems). - * - * Comparing names against all other names is O(n^2). We could speed - * it up some by sorting the entries and being smarter about what we - * compare against, but I'm not expecting to have enough files in a - * single directory to make a noticeable difference in speed. - * - * Note that sorting here is not enough to guarantee that the package - * contents are sorted -- subsequent updates can rearrange things. - */ - status_t validate() const; - - void print() const; - - String8 getPrintableSource() const; - -private: - String8 mLeaf; - String8 mPath; - - DefaultKeyedVector<String8, sp<AaptGroup> > mFiles; - DefaultKeyedVector<String8, sp<AaptDir> > mDirs; -}; - -/** - * All information we know about a particular symbol. - */ -class AaptSymbolEntry -{ -public: - AaptSymbolEntry() - : isPublic(false), typeCode(TYPE_UNKNOWN) - { - } - AaptSymbolEntry(const String8& _name) - : name(_name), isPublic(false), typeCode(TYPE_UNKNOWN) - { - } - AaptSymbolEntry(const AaptSymbolEntry& o) - : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic) - , comment(o.comment), typeComment(o.typeComment) - , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal) - { - } - AaptSymbolEntry operator=(const AaptSymbolEntry& o) - { - sourcePos = o.sourcePos; - isPublic = o.isPublic; - comment = o.comment; - typeComment = o.typeComment; - typeCode = o.typeCode; - int32Val = o.int32Val; - stringVal = o.stringVal; - return *this; - } - - const String8 name; - - SourcePos sourcePos; - bool isPublic; - - String16 comment; - String16 typeComment; - - enum { - TYPE_UNKNOWN = 0, - TYPE_INT32, - TYPE_STRING - }; - - int typeCode; - - // Value. May be one of these. - int32_t int32Val; - String8 stringVal; -}; - -/** - * A group of related symbols (such as indices into a string block) - * that have been generated from the assets. - */ -class AaptSymbols : public RefBase -{ -public: - AaptSymbols() { } - virtual ~AaptSymbols() { } - - status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) { - if (!check_valid_symbol_name(name, pos, "symbol")) { - return BAD_VALUE; - } - AaptSymbolEntry& sym = edit_symbol(name, &pos); - sym.typeCode = AaptSymbolEntry::TYPE_INT32; - sym.int32Val = value; - return NO_ERROR; - } - - status_t addStringSymbol(const String8& name, const String8& value, - const SourcePos& pos) { - if (!check_valid_symbol_name(name, pos, "symbol")) { - return BAD_VALUE; - } - AaptSymbolEntry& sym = edit_symbol(name, &pos); - sym.typeCode = AaptSymbolEntry::TYPE_STRING; - sym.stringVal = value; - return NO_ERROR; - } - - status_t makeSymbolPublic(const String8& name, const SourcePos& pos) { - if (!check_valid_symbol_name(name, pos, "symbol")) { - return BAD_VALUE; - } - AaptSymbolEntry& sym = edit_symbol(name, &pos); - sym.isPublic = true; - return NO_ERROR; - } - - void appendComment(const String8& name, const String16& comment, const SourcePos& pos) { - if (comment.size() <= 0) { - return; - } - AaptSymbolEntry& sym = edit_symbol(name, &pos); - if (sym.comment.size() == 0) { - sym.comment = comment; - } else { - sym.comment.append(String16("\n")); - sym.comment.append(comment); - } - } - - void appendTypeComment(const String8& name, const String16& comment) { - if (comment.size() <= 0) { - return; - } - AaptSymbolEntry& sym = edit_symbol(name, NULL); - if (sym.typeComment.size() == 0) { - sym.typeComment = comment; - } else { - sym.typeComment.append(String16("\n")); - sym.typeComment.append(comment); - } - } - - sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) { - if (!check_valid_symbol_name(name, pos, "nested symbol")) { - return NULL; - } - - sp<AaptSymbols> sym = mNestedSymbols.valueFor(name); - if (sym == NULL) { - sym = new AaptSymbols(); - mNestedSymbols.add(name, sym); - } - - return sym; - } - - const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const - { return mSymbols; } - const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const - { return mNestedSymbols; } - - const String16& getComment(const String8& name) const - { return get_symbol(name).comment; } - const String16& getTypeComment(const String8& name) const - { return get_symbol(name).typeComment; } - -private: - bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) { - if (valid_symbol_name(symbol)) { - return true; - } - pos.error("invalid %s: '%s'\n", label, symbol.string()); - return false; - } - AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) { - ssize_t i = mSymbols.indexOfKey(symbol); - if (i < 0) { - i = mSymbols.add(symbol, AaptSymbolEntry(symbol)); - } - AaptSymbolEntry& sym = mSymbols.editValueAt(i); - if (pos != NULL && sym.sourcePos.line < 0) { - sym.sourcePos = *pos; - } - return sym; - } - const AaptSymbolEntry& get_symbol(const String8& symbol) const { - ssize_t i = mSymbols.indexOfKey(symbol); - if (i >= 0) { - return mSymbols.valueAt(i); - } - return mDefSymbol; - } - - KeyedVector<String8, AaptSymbolEntry> mSymbols; - DefaultKeyedVector<String8, sp<AaptSymbols> > mNestedSymbols; - AaptSymbolEntry mDefSymbol; -}; - -class ResourceTypeSet; - -/** - * Asset hierarchy being operated on. - */ -class AaptAssets : public AaptDir -{ -public: - AaptAssets() : AaptDir(String8(), String8()), mHaveIncludedAssets(false) { } - virtual ~AaptAssets() { } - - const String8& getPackage() const { return mPackage; } - void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; } - - const SortedVector<AaptGroupEntry>& getGroupEntries() const { return mGroupEntries; } - - sp<AaptFile> addFile(const String8& filePath, - const AaptGroupEntry& entry, - const String8& srcDir, - sp<AaptGroup>* outGroup, - const String8& resType); - - void addResource(const String8& leafName, - const String8& path, - const sp<AaptFile>& file, - const String8& resType); - - ssize_t slurpFromArgs(Bundle* bundle); - - virtual ssize_t slurpFullTree(Bundle* bundle, - const String8& srcDir, - const AaptGroupEntry& kind, - const String8& resType); - - ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir); - ssize_t slurpResourceZip(Bundle* bundle, const char* filename); - - sp<AaptSymbols> getSymbolsFor(const String8& name); - - const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; } - - String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; } - void setSymbolsPrivatePackage(const String8& pkg) { mSymbolsPrivatePackage = pkg; } - - status_t buildIncludedResources(Bundle* bundle); - status_t addIncludedResources(const sp<AaptFile>& file); - const ResTable& getIncludedResources() const; - - void print() const; - - inline const Vector<sp<AaptDir> >& resDirs() { return mDirs; } - - inline sp<AaptAssets> getOverlay() { return mOverlay; } - inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; } - - inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; } - inline void - setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { mRes = res; } - -private: - String8 mPackage; - SortedVector<AaptGroupEntry> mGroupEntries; - DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols; - String8 mSymbolsPrivatePackage; - - Vector<sp<AaptDir> > mDirs; - - bool mHaveIncludedAssets; - AssetManager mIncludedAssets; - - sp<AaptAssets> mOverlay; - KeyedVector<String8, sp<ResourceTypeSet> >* mRes; -}; - -#endif // __AAPT_ASSETS_H - diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk deleted file mode 100644 index fdc859c..0000000 --- a/tools/aapt/Android.mk +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright 2006 The Android Open Source Project -# -# Android Asset Packaging Tool -# - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - AaptAssets.cpp \ - Command.cpp \ - Main.cpp \ - Package.cpp \ - StringPool.cpp \ - XMLNode.cpp \ - ResourceTable.cpp \ - Images.cpp \ - Resource.cpp \ - SourcePos.cpp - -LOCAL_CFLAGS += -Wno-format-y2k - -LOCAL_C_INCLUDES += external/expat/lib -LOCAL_C_INCLUDES += external/libpng -LOCAL_C_INCLUDES += external/zlib -LOCAL_C_INCLUDES += build/libs/host/include - -#LOCAL_WHOLE_STATIC_LIBRARIES := -LOCAL_STATIC_LIBRARIES := \ - libhost \ - libutils \ - libcutils \ - libexpat \ - libpng - -LOCAL_LDLIBS := -lz - -ifeq ($(HOST_OS),linux) -LOCAL_LDLIBS += -lrt -endif - -ifeq ($(HOST_OS),windows) -ifeq ($(strip $(USE_CYGWIN),),) -LOCAL_LDLIBS += -lws2_32 -endif -endif - -LOCAL_MODULE := aapt - -include $(BUILD_HOST_EXECUTABLE) - diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h deleted file mode 100644 index 2d8471b..0000000 --- a/tools/aapt/Bundle.h +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// State bundle. Used to pass around stuff like command-line args. -// -#ifndef __BUNDLE_H -#define __BUNDLE_H - -#include <stdlib.h> -#include <utils.h> // android -#include <utils/String8.h> -#include <utils/Vector.h> - -/* - * Things we can do. - */ -typedef enum Command { - kCommandUnknown = 0, - kCommandVersion, - kCommandList, - kCommandDump, - kCommandAdd, - kCommandRemove, - kCommandPackage, -} Command; - -/* - * Bundle of goodies, including everything specified on the command line. - */ -class Bundle { -public: - Bundle(void) - : mCmd(kCommandUnknown), mVerbose(false), mAndroidList(false), - mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false), - mUpdate(false), mExtending(false), - mRequireLocalization(false), mPseudolocalize(false), - mCompressionMethod(0), mOutputAPKFile(NULL), - mAssetSourceDir(NULL), - mAndroidManifestFile(NULL), mPublicOutputFile(NULL), - mRClassDir(NULL), mResourceIntermediatesDir(NULL), - mArgc(0), mArgv(NULL) - {} - ~Bundle(void) {} - - /* - * Set the command value. Returns "false" if it was previously set. - */ - Command getCommand(void) const { return mCmd; } - void setCommand(Command cmd) { mCmd = cmd; } - - /* - * Command modifiers. Not all modifiers are appropriate for all - * commands. - */ - bool getVerbose(void) const { return mVerbose; } - void setVerbose(bool val) { mVerbose = val; } - bool getAndroidList(void) const { return mAndroidList; } - void setAndroidList(bool val) { mAndroidList = val; } - bool getForce(void) const { return mForce; } - void setForce(bool val) { mForce = val; } - void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; } - int getGrayscaleTolerance() { return mGrayscaleTolerance; } - bool getMakePackageDirs(void) const { return mMakePackageDirs; } - void setMakePackageDirs(bool val) { mMakePackageDirs = val; } - bool getUpdate(void) const { return mUpdate; } - void setUpdate(bool val) { mUpdate = val; } - bool getExtending(void) const { return mExtending; } - void setExtending(bool val) { mExtending = val; } - bool getRequireLocalization(void) const { return mRequireLocalization; } - void setRequireLocalization(bool val) { mRequireLocalization = val; } - bool getPseudolocalize(void) const { return mPseudolocalize; } - void setPseudolocalize(bool val) { mPseudolocalize = val; } - int getCompressionMethod(void) const { return mCompressionMethod; } - void setCompressionMethod(int val) { mCompressionMethod = val; } - const char* getOutputAPKFile() const { return mOutputAPKFile; } - void setOutputAPKFile(const char* val) { mOutputAPKFile = val; } - - /* - * Input options. - */ - const char* getAssetSourceDir() const { return mAssetSourceDir; } - void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; } - const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; } - void addResourceSourceDir(const char* dir) { mResourceSourceDirs.insertAt(dir,0); } - const char* getAndroidManifestFile() const { return mAndroidManifestFile; } - void setAndroidManifestFile(const char* file) { mAndroidManifestFile = file; } - const char* getPublicOutputFile() const { return mPublicOutputFile; } - void setPublicOutputFile(const char* file) { mPublicOutputFile = file; } - const char* getRClassDir() const { return mRClassDir; } - void setRClassDir(const char* dir) { mRClassDir = dir; } - const char* getConfigurations() const { return mConfigurations.size() > 0 ? mConfigurations.string() : NULL; } - void addConfigurations(const char* val) { if (mConfigurations.size() > 0) { mConfigurations.append(","); mConfigurations.append(val); } else { mConfigurations = val; } } - const char* getResourceIntermediatesDir() const { return mResourceIntermediatesDir; } - void setResourceIntermediatesDir(const char* dir) { mResourceIntermediatesDir = dir; } - const android::Vector<const char*>& getPackageIncludes() const { return mPackageIncludes; } - void addPackageInclude(const char* file) { mPackageIncludes.add(file); } - const android::Vector<const char*>& getJarFiles() const { return mJarFiles; } - void addJarFile(const char* file) { mJarFiles.add(file); } - const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; } - void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); } - - /* - * Set and get the file specification. - * - * Note this does NOT make a copy of argv. - */ - void setFileSpec(char* const argv[], int argc) { - mArgc = argc; - mArgv = argv; - } - int getFileSpecCount(void) const { return mArgc; } - const char* getFileSpecEntry(int idx) const { return mArgv[idx]; } - void eatArgs(int n) { - if (n > mArgc) n = mArgc; - mArgv += n; - mArgc -= n; - } - -#if 0 - /* - * Package count. Nothing to do with anything else here; this is - * just a convenient place to stuff it so we don't have to pass it - * around everywhere. - */ - int getPackageCount(void) const { return mPackageCount; } - void setPackageCount(int val) { mPackageCount = val; } -#endif - -private: - /* commands & modifiers */ - Command mCmd; - bool mVerbose; - bool mAndroidList; - bool mForce; - int mGrayscaleTolerance; - bool mMakePackageDirs; - bool mUpdate; - bool mExtending; - bool mRequireLocalization; - bool mPseudolocalize; - int mCompressionMethod; - const char* mOutputAPKFile; - const char* mAssetSourceDir; - const char* mAndroidManifestFile; - const char* mPublicOutputFile; - const char* mRClassDir; - const char* mResourceIntermediatesDir; - android::String8 mConfigurations; - android::Vector<const char*> mPackageIncludes; - android::Vector<const char*> mJarFiles; - android::Vector<const char*> mNoCompressExtensions; - android::Vector<const char*> mResourceSourceDirs; - - /* file specification */ - int mArgc; - char* const* mArgv; - -#if 0 - /* misc stuff */ - int mPackageCount; -#endif -}; - -#endif // __BUNDLE_H diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp deleted file mode 100644 index bff0423..0000000 --- a/tools/aapt/Command.cpp +++ /dev/null @@ -1,841 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Android Asset Packaging Tool main entry point. -// -#include "Main.h" -#include "Bundle.h" -#include "ResourceTable.h" -#include "XMLNode.h" - -#include <utils.h> -#include <utils/ZipFile.h> - -#include <fcntl.h> -#include <errno.h> - -using namespace android; - -/* - * Show version info. All the cool kids do it. - */ -int doVersion(Bundle* bundle) -{ - if (bundle->getFileSpecCount() != 0) - printf("(ignoring extra arguments)\n"); - printf("Android Asset Packaging Tool, v0.2\n"); - - return 0; -} - - -/* - * Open the file read only. The call fails if the file doesn't exist. - * - * Returns NULL on failure. - */ -ZipFile* openReadOnly(const char* fileName) -{ - ZipFile* zip; - status_t result; - - zip = new ZipFile; - result = zip->open(fileName, ZipFile::kOpenReadOnly); - if (result != NO_ERROR) { - if (result == NAME_NOT_FOUND) - fprintf(stderr, "ERROR: '%s' not found\n", fileName); - else if (result == PERMISSION_DENIED) - fprintf(stderr, "ERROR: '%s' access denied\n", fileName); - else - fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", - fileName); - delete zip; - return NULL; - } - - return zip; -} - -/* - * Open the file read-write. The file will be created if it doesn't - * already exist and "okayToCreate" is set. - * - * Returns NULL on failure. - */ -ZipFile* openReadWrite(const char* fileName, bool okayToCreate) -{ - ZipFile* zip = NULL; - status_t result; - int flags; - - flags = ZipFile::kOpenReadWrite; - if (okayToCreate) - flags |= ZipFile::kOpenCreate; - - zip = new ZipFile; - result = zip->open(fileName, flags); - if (result != NO_ERROR) { - delete zip; - zip = NULL; - goto bail; - } - -bail: - return zip; -} - - -/* - * Return a short string describing the compression method. - */ -const char* compressionName(int method) -{ - if (method == ZipEntry::kCompressStored) - return "Stored"; - else if (method == ZipEntry::kCompressDeflated) - return "Deflated"; - else - return "Unknown"; -} - -/* - * Return the percent reduction in size (0% == no compression). - */ -int calcPercent(long uncompressedLen, long compressedLen) -{ - if (!uncompressedLen) - return 0; - else - return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); -} - -/* - * Handle the "list" command, which can be a simple file dump or - * a verbose listing. - * - * The verbose listing closely matches the output of the Info-ZIP "unzip" - * command. - */ -int doList(Bundle* bundle) -{ - int result = 1; - ZipFile* zip = NULL; - const ZipEntry* entry; - long totalUncLen, totalCompLen; - const char* zipFileName; - - if (bundle->getFileSpecCount() != 1) { - fprintf(stderr, "ERROR: specify zip file name (only)\n"); - goto bail; - } - zipFileName = bundle->getFileSpecEntry(0); - - zip = openReadOnly(zipFileName); - if (zip == NULL) - goto bail; - - int count, i; - - if (bundle->getVerbose()) { - printf("Archive: %s\n", zipFileName); - printf( - " Length Method Size Ratio Date Time CRC-32 Name\n"); - printf( - "-------- ------ ------- ----- ---- ---- ------ ----\n"); - } - - totalUncLen = totalCompLen = 0; - - count = zip->getNumEntries(); - for (i = 0; i < count; i++) { - entry = zip->getEntryByIndex(i); - if (bundle->getVerbose()) { - char dateBuf[32]; - time_t when; - - when = entry->getModWhen(); - strftime(dateBuf, sizeof(dateBuf), "%m-%d-%y %H:%M", - localtime(&when)); - - printf("%8ld %-7.7s %7ld %3d%% %s %08lx %s\n", - (long) entry->getUncompressedLen(), - compressionName(entry->getCompressionMethod()), - (long) entry->getCompressedLen(), - calcPercent(entry->getUncompressedLen(), - entry->getCompressedLen()), - dateBuf, - entry->getCRC32(), - entry->getFileName()); - } else { - printf("%s\n", entry->getFileName()); - } - - totalUncLen += entry->getUncompressedLen(); - totalCompLen += entry->getCompressedLen(); - } - - if (bundle->getVerbose()) { - printf( - "-------- ------- --- -------\n"); - printf("%8ld %7ld %2d%% %d files\n", - totalUncLen, - totalCompLen, - calcPercent(totalUncLen, totalCompLen), - zip->getNumEntries()); - } - - if (bundle->getAndroidList()) { - AssetManager assets; - if (!assets.addAssetPath(String8(zipFileName), NULL)) { - fprintf(stderr, "ERROR: list -a failed because assets could not be loaded\n"); - goto bail; - } - - const ResTable& res = assets.getResources(false); - if (&res == NULL) { - printf("\nNo resource table found.\n"); - } else { - printf("\nResource table:\n"); - res.print(); - } - - Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml", - Asset::ACCESS_BUFFER); - if (manifestAsset == NULL) { - printf("\nNo AndroidManifest.xml found.\n"); - } else { - printf("\nAndroid manifest:\n"); - ResXMLTree tree; - tree.setTo(manifestAsset->getBuffer(true), - manifestAsset->getLength()); - printXMLBlock(&tree); - } - delete manifestAsset; - } - - result = 0; - -bail: - delete zip; - return result; -} - -static ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) -{ - size_t N = tree.getAttributeCount(); - for (size_t i=0; i<N; i++) { - if (tree.getAttributeNameResID(i) == attrRes) { - return (ssize_t)i; - } - } - return -1; -} - -static String8 getAttribute(const ResXMLTree& tree, const char* ns, - const char* attr, String8* outError) -{ - ssize_t idx = tree.indexOfAttribute(ns, attr); - if (idx < 0) { - return String8(); - } - Res_value value; - if (tree.getAttributeValue(idx, &value) != NO_ERROR) { - if (value.dataType != Res_value::TYPE_STRING) { - if (outError != NULL) *outError = "attribute is not a string value"; - return String8(); - } - } - size_t len; - const uint16_t* str = tree.getAttributeStringValue(idx, &len); - return str ? String8(str, len) : String8(); -} - -static String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) -{ - ssize_t idx = indexOfAttribute(tree, attrRes); - if (idx < 0) { - return String8(); - } - Res_value value; - if (tree.getAttributeValue(idx, &value) != NO_ERROR) { - if (value.dataType != Res_value::TYPE_STRING) { - if (outError != NULL) *outError = "attribute is not a string value"; - return String8(); - } - } - size_t len; - const uint16_t* str = tree.getAttributeStringValue(idx, &len); - return str ? String8(str, len) : String8(); -} - -static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) -{ - ssize_t idx = indexOfAttribute(tree, attrRes); - if (idx < 0) { - return -1; - } - Res_value value; - if (tree.getAttributeValue(idx, &value) != NO_ERROR) { - if (value.dataType != Res_value::TYPE_INT_DEC) { - if (outError != NULL) *outError = "attribute is not an integer value"; - return -1; - } - } - return value.data; -} - -static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, - uint32_t attrRes, String8* outError) -{ - ssize_t idx = indexOfAttribute(tree, attrRes); - if (idx < 0) { - return String8(); - } - Res_value value; - if (tree.getAttributeValue(idx, &value) != NO_ERROR) { - if (value.dataType == Res_value::TYPE_STRING) { - size_t len; - const uint16_t* str = tree.getAttributeStringValue(idx, &len); - return str ? String8(str, len) : String8(); - } - resTable->resolveReference(&value, 0); - if (value.dataType != Res_value::TYPE_STRING) { - if (outError != NULL) *outError = "attribute is not a string value"; - return String8(); - } - } - size_t len; - const Res_value* value2 = &value; - const char16_t* str = const_cast<ResTable*>(resTable)->valueToString(value2, 0, NULL, &len); - return str ? String8(str, len) : String8(); -} - -// These are attribute resource constants for the platform, as found -// in android.R.attr -enum { - NAME_ATTR = 0x01010003, - VERSION_CODE_ATTR = 0x0101021b, - VERSION_NAME_ATTR = 0x0101021c, - LABEL_ATTR = 0x01010001, - ICON_ATTR = 0x01010002, -}; - -/* - * Handle the "dump" command, to extract select data from an archive. - */ -int doDump(Bundle* bundle) -{ - status_t result = UNKNOWN_ERROR; - Asset* asset = NULL; - - if (bundle->getFileSpecCount() < 1) { - fprintf(stderr, "ERROR: no dump option specified\n"); - return 1; - } - - if (bundle->getFileSpecCount() < 2) { - fprintf(stderr, "ERROR: no dump file specified\n"); - return 1; - } - - const char* option = bundle->getFileSpecEntry(0); - const char* filename = bundle->getFileSpecEntry(1); - - AssetManager assets; - if (!assets.addAssetPath(String8(filename), NULL)) { - fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n"); - return 1; - } - - const ResTable& res = assets.getResources(false); - if (&res == NULL) { - fprintf(stderr, "ERROR: dump failed because no resource table was found\n"); - goto bail; - } - - if (strcmp("resources", option) == 0) { - res.print(); - - } else if (strcmp("xmltree", option) == 0) { - if (bundle->getFileSpecCount() < 3) { - fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); - goto bail; - } - - for (int i=2; i<bundle->getFileSpecCount(); i++) { - const char* resname = bundle->getFileSpecEntry(i); - ResXMLTree tree; - asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); - if (asset == NULL) { - fprintf(stderr, "ERROR: dump failed because resource %p found\n", resname); - goto bail; - } - - if (tree.setTo(asset->getBuffer(true), - asset->getLength()) != NO_ERROR) { - fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); - goto bail; - } - tree.restart(); - printXMLBlock(&tree); - delete asset; - asset = NULL; - } - - } else if (strcmp("xmlstrings", option) == 0) { - if (bundle->getFileSpecCount() < 3) { - fprintf(stderr, "ERROR: no dump xmltree resource file specified\n"); - goto bail; - } - - for (int i=2; i<bundle->getFileSpecCount(); i++) { - const char* resname = bundle->getFileSpecEntry(i); - ResXMLTree tree; - asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER); - if (asset == NULL) { - fprintf(stderr, "ERROR: dump failed because resource %p found\n", resname); - goto bail; - } - - if (tree.setTo(asset->getBuffer(true), - asset->getLength()) != NO_ERROR) { - fprintf(stderr, "ERROR: Resource %s is corrupt\n", resname); - goto bail; - } - printStringPool(&tree.getStrings()); - delete asset; - asset = NULL; - } - - } else { - ResXMLTree tree; - asset = assets.openNonAsset("AndroidManifest.xml", - Asset::ACCESS_BUFFER); - if (asset == NULL) { - fprintf(stderr, "ERROR: dump failed because no AndroidManifest.xml found\n"); - goto bail; - } - - if (tree.setTo(asset->getBuffer(true), - asset->getLength()) != NO_ERROR) { - fprintf(stderr, "ERROR: AndroidManifest.xml is corrupt\n"); - goto bail; - } - tree.restart(); - - if (strcmp("permissions", option) == 0) { - size_t len; - ResXMLTree::event_code_t code; - int depth = 0; - while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - depth--; - continue; - } - if (code != ResXMLTree::START_TAG) { - continue; - } - depth++; - String8 tag(tree.getElementName(&len)); - //printf("Depth %d tag %s\n", depth, tag.string()); - if (depth == 1) { - if (tag != "manifest") { - fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); - goto bail; - } - String8 pkg = getAttribute(tree, NULL, "package", NULL); - printf("package: %s\n", pkg.string()); - } else if (depth == 2 && tag == "permission") { - String8 error; - String8 name = getAttribute(tree, NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR: %s\n", error.string()); - goto bail; - } - printf("permission: %s\n", name.string()); - } else if (depth == 2 && tag == "uses-permission") { - String8 error; - String8 name = getAttribute(tree, NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR: %s\n", error.string()); - goto bail; - } - printf("uses-permission: %s\n", name.string()); - } - } - } else if (strcmp("badging", option) == 0) { - size_t len; - ResXMLTree::event_code_t code; - int depth = 0; - String8 error; - bool withinActivity = false; - bool isMainActivity = false; - bool isLauncherActivity = false; - String8 activityName; - String8 activityLabel; - String8 activityIcon; - while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - depth--; - continue; - } - if (code != ResXMLTree::START_TAG) { - continue; - } - depth++; - String8 tag(tree.getElementName(&len)); - //printf("Depth %d tag %s\n", depth, tag.string()); - if (depth == 1) { - if (tag != "manifest") { - fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n"); - goto bail; - } - String8 pkg = getAttribute(tree, NULL, "package", NULL); - printf("package: name='%s' ", pkg.string()); - int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); - goto bail; - } - if (versionCode > 0) { - printf("versionCode='%d' ", versionCode); - } else { - printf("versionCode='' "); - } - String8 versionName = getAttribute(tree, VERSION_NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); - goto bail; - } - printf("versionName='%s'\n", versionName.string()); - } else if (depth == 2 && tag == "application") { - String8 label = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string()); - goto bail; - } - printf("application: label='%s' ", label.string()); - - String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); - goto bail; - } - printf("icon='%s'\n", icon.string()); - } else if (depth == 3 && tag == "activity") { - withinActivity = true; - //printf("LOG: withinActivity==true\n"); - - activityName = getAttribute(tree, NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); - goto bail; - } - - activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string()); - goto bail; - } - - activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); - goto bail; - } - } else if (depth == 5 && withinActivity) { - if (tag == "action") { - //printf("LOG: action tag\n"); - String8 action = getAttribute(tree, NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); - goto bail; - } - if (action == "android.intent.action.MAIN") { - isMainActivity = true; - //printf("LOG: isMainActivity==true\n"); - } - } else if (tag == "category") { - String8 category = getAttribute(tree, NAME_ATTR, &error); - if (error != "") { - fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string()); - goto bail; - } - if (category == "android.intent.category.LAUNCHER") { - isLauncherActivity = true; - //printf("LOG: isLauncherActivity==true\n"); - } - } - } - - if (depth < 3) { - //if (withinActivity) printf("LOG: withinActivity==false\n"); - withinActivity = false; - } - - if (depth < 5) { - //if (isMainActivity) printf("LOG: isMainActivity==false\n"); - //if (isLauncherActivity) printf("LOG: isLauncherActivity==false\n"); - isMainActivity = false; - isLauncherActivity = false; - } - - if (withinActivity && isMainActivity && isLauncherActivity) { - printf("launchable activity: name='%s' label='%s' icon='%s'\n", - activityName.string(), activityLabel.string(), - activityIcon.string()); - } - } - printf("locales:"); - Vector<String8> locales; - res.getLocales(&locales); - const size_t N = locales.size(); - for (size_t i=0; i<N; i++) { - const char* localeStr = locales[i].string(); - if (localeStr == NULL || strlen(localeStr) == 0) { - localeStr = "--_--"; - } - printf(" '%s'", localeStr); - } - printf("\n"); - } else if (strcmp("configurations", option) == 0) { - Vector<ResTable_config> configs; - res.getConfigurations(&configs); - const size_t N = configs.size(); - for (size_t i=0; i<N; i++) { - printf("%s\n", configs[i].toString().string()); - } - } else { - fprintf(stderr, "ERROR: unknown dump option '%s'\n", option); - goto bail; - } - } - - result = NO_ERROR; - -bail: - if (asset) { - delete asset; - } - return (result != NO_ERROR); -} - - -/* - * Handle the "add" command, which wants to add files to a new or - * pre-existing archive. - */ -int doAdd(Bundle* bundle) -{ - ZipFile* zip = NULL; - status_t result = UNKNOWN_ERROR; - const char* zipFileName; - - if (bundle->getUpdate()) { - /* avoid confusion */ - fprintf(stderr, "ERROR: can't use '-u' with add\n"); - goto bail; - } - - if (bundle->getFileSpecCount() < 1) { - fprintf(stderr, "ERROR: must specify zip file name\n"); - goto bail; - } - zipFileName = bundle->getFileSpecEntry(0); - - if (bundle->getFileSpecCount() < 2) { - fprintf(stderr, "NOTE: nothing to do\n"); - goto bail; - } - - zip = openReadWrite(zipFileName, true); - if (zip == NULL) { - fprintf(stderr, "ERROR: failed opening/creating '%s' as Zip file\n", zipFileName); - goto bail; - } - - for (int i = 1; i < bundle->getFileSpecCount(); i++) { - const char* fileName = bundle->getFileSpecEntry(i); - - if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) { - printf(" '%s'... (from gzip)\n", fileName); - result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL); - } else { - printf(" '%s'...\n", fileName); - result = zip->add(fileName, bundle->getCompressionMethod(), NULL); - } - if (result != NO_ERROR) { - fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); - if (result == NAME_NOT_FOUND) - fprintf(stderr, ": file not found\n"); - else if (result == ALREADY_EXISTS) - fprintf(stderr, ": already exists in archive\n"); - else - fprintf(stderr, "\n"); - goto bail; - } - } - - result = NO_ERROR; - -bail: - delete zip; - return (result != NO_ERROR); -} - - -/* - * Delete files from an existing archive. - */ -int doRemove(Bundle* bundle) -{ - ZipFile* zip = NULL; - status_t result = UNKNOWN_ERROR; - const char* zipFileName; - - if (bundle->getFileSpecCount() < 1) { - fprintf(stderr, "ERROR: must specify zip file name\n"); - goto bail; - } - zipFileName = bundle->getFileSpecEntry(0); - - if (bundle->getFileSpecCount() < 2) { - fprintf(stderr, "NOTE: nothing to do\n"); - goto bail; - } - - zip = openReadWrite(zipFileName, false); - if (zip == NULL) { - fprintf(stderr, "ERROR: failed opening Zip archive '%s'\n", - zipFileName); - goto bail; - } - - for (int i = 1; i < bundle->getFileSpecCount(); i++) { - const char* fileName = bundle->getFileSpecEntry(i); - ZipEntry* entry; - - entry = zip->getEntryByName(fileName); - if (entry == NULL) { - printf(" '%s' NOT FOUND\n", fileName); - continue; - } - - result = zip->remove(entry); - - if (result != NO_ERROR) { - fprintf(stderr, "Unable to delete '%s' from '%s'\n", - bundle->getFileSpecEntry(i), zipFileName); - goto bail; - } - } - - /* update the archive */ - zip->flush(); - -bail: - delete zip; - return (result != NO_ERROR); -} - - -/* - * Package up an asset directory and associated application files. - */ -int doPackage(Bundle* bundle) -{ - const char* outputAPKFile; - int retVal = 1; - status_t err; - sp<AaptAssets> assets; - int N; - - // -c zz_ZZ means do pseudolocalization - ResourceFilter filter; - err = filter.parse(bundle->getConfigurations()); - if (err != NO_ERROR) { - goto bail; - } - if (filter.containsPseudo()) { - bundle->setPseudolocalize(true); - } - - N = bundle->getFileSpecCount(); - if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 - && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) { - fprintf(stderr, "ERROR: no input files\n"); - goto bail; - } - - outputAPKFile = bundle->getOutputAPKFile(); - - // Make sure the filenames provided exist and are of the appropriate type. - if (outputAPKFile) { - FileType type; - type = getFileType(outputAPKFile); - if (type != kFileTypeNonexistent && type != kFileTypeRegular) { - fprintf(stderr, - "ERROR: output file '%s' exists but is not regular file\n", - outputAPKFile); - goto bail; - } - } - - // Load the assets. - assets = new AaptAssets(); - err = assets->slurpFromArgs(bundle); - if (err < 0) { - goto bail; - } - - if (bundle->getVerbose()) { - assets->print(); - } - - // If they asked for any files that need to be compiled, do so. - if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) { - err = buildResources(bundle, assets); - if (err != 0) { - goto bail; - } - } - - // At this point we've read everything and processed everything. From here - // on out it's just writing output files. - if (SourcePos::hasErrors()) { - goto bail; - } - - // Write out R.java constants - if (assets->getPackage() == assets->getSymbolsPrivatePackage()) { - err = writeResourceSymbols(bundle, assets, assets->getPackage(), true); - if (err < 0) { - goto bail; - } - } else { - err = writeResourceSymbols(bundle, assets, assets->getPackage(), false); - if (err < 0) { - goto bail; - } - err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true); - if (err < 0) { - goto bail; - } - } - - // Write the apk - if (outputAPKFile) { - err = writeAPK(bundle, assets, String8(outputAPKFile)); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputAPKFile); - goto bail; - } - } - - retVal = 0; -bail: - if (SourcePos::hasErrors()) { - SourcePos::printErrors(stderr); - } - return retVal; -} diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp deleted file mode 100644 index 4c776fb..0000000 --- a/tools/aapt/Images.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#define PNG_INTERNAL - -#include "Images.h" - -#include <utils/ResourceTypes.h> -#include <utils/ByteOrder.h> - -#include <png.h> - -#define NOISY(x) //x - -static void -png_write_aapt_file(png_structp png_ptr, png_bytep data, png_size_t length) -{ - status_t err = ((AaptFile*)png_ptr->io_ptr)->writeData(data, length); - if (err != NO_ERROR) { - png_error(png_ptr, "Write Error"); - } -} - - -static void -png_flush_aapt_file(png_structp png_ptr) -{ -} - -// This holds an image as 8bpp RGBA. -struct image_info -{ - image_info() : rows(NULL), is9Patch(false), allocRows(NULL) { } - ~image_info() { - if (rows && rows != allocRows) { - free(rows); - } - if (allocRows) { - for (int i=0; i<(int)allocHeight; i++) { - free(allocRows[i]); - } - free(allocRows); - } - } - - png_uint_32 width; - png_uint_32 height; - png_bytepp rows; - - // 9-patch info. - bool is9Patch; - Res_png_9patch info9Patch; - - png_uint_32 allocHeight; - png_bytepp allocRows; -}; - -static void read_png(const char* imageName, - png_structp read_ptr, png_infop read_info, - image_info* outImageInfo) -{ - int color_type; - int bit_depth, interlace_type, compression_type; - int i; - - png_read_info(read_ptr, read_info); - - png_get_IHDR(read_ptr, read_info, &outImageInfo->width, - &outImageInfo->height, &bit_depth, &color_type, - &interlace_type, &compression_type, NULL); - - //printf("Image %s:\n", imageName); - //printf("color_type=%d, bit_depth=%d, interlace_type=%d, compression_type=%d\n", - // color_type, bit_depth, interlace_type, compression_type); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(read_ptr); - - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_gray_1_2_4_to_8(read_ptr); - - if (png_get_valid(read_ptr, read_info, PNG_INFO_tRNS)) { - //printf("Has PNG_INFO_tRNS!\n"); - png_set_tRNS_to_alpha(read_ptr); - } - - if (bit_depth == 16) - png_set_strip_16(read_ptr); - - if ((color_type&PNG_COLOR_MASK_ALPHA) == 0) - png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER); - - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(read_ptr); - - png_read_update_info(read_ptr, read_info); - - outImageInfo->rows = (png_bytepp)malloc( - outImageInfo->height * png_sizeof(png_bytep)); - outImageInfo->allocHeight = outImageInfo->height; - outImageInfo->allocRows = outImageInfo->rows; - - png_set_rows(read_ptr, read_info, outImageInfo->rows); - - for (i = 0; i < (int)outImageInfo->height; i++) - { - outImageInfo->rows[i] = (png_bytep) - malloc(png_get_rowbytes(read_ptr, read_info)); - } - - png_read_image(read_ptr, outImageInfo->rows); - - png_read_end(read_ptr, read_info); - - NOISY(printf("Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n", - imageName, - (int)outImageInfo->width, (int)outImageInfo->height, - bit_depth, color_type, - interlace_type, compression_type)); - - png_get_IHDR(read_ptr, read_info, &outImageInfo->width, - &outImageInfo->height, &bit_depth, &color_type, - &interlace_type, &compression_type, NULL); -} - -static bool is_tick(png_bytep p, bool transparent, const char** outError) -{ - if (transparent) { - if (p[3] == 0) { - return false; - } - if (p[3] != 0xff) { - *outError = "Frame pixels must be either solid or transparent (not intermediate alphas)"; - return false; - } - if (p[0] != 0 || p[1] != 0 || p[2] != 0) { - *outError = "Ticks in transparent frame must be black"; - } - return true; - } - - if (p[3] != 0xFF) { - *outError = "White frame must be a solid color (no alpha)"; - } - if (p[0] == 0xFF && p[1] == 0xFF && p[2] == 0xFF) { - return false; - } - if (p[0] != 0 || p[1] != 0 || p[2] != 0) { - *outError = "Ticks in white frame must be black"; - return false; - } - return true; -} - -enum { - TICK_START, - TICK_INSIDE_1, - TICK_OUTSIDE_1 -}; - -static status_t get_horizontal_ticks( - png_bytep row, int width, bool transparent, bool required, - int32_t* outLeft, int32_t* outRight, const char** outError, - uint8_t* outDivs, bool multipleAllowed) -{ - int i; - *outLeft = *outRight = -1; - int state = TICK_START; - bool found = false; - - for (i=1; i<width-1; i++) { - if (is_tick(row+i*4, transparent, outError)) { - if (state == TICK_START || - (state == TICK_OUTSIDE_1 && multipleAllowed)) { - *outLeft = i-1; - *outRight = width-2; - found = true; - if (outDivs != NULL) { - *outDivs += 2; - } - state = TICK_INSIDE_1; - } else if (state == TICK_OUTSIDE_1) { - *outError = "Can't have more than one marked region along edge"; - *outLeft = i; - return UNKNOWN_ERROR; - } - } else if (*outError == NULL) { - if (state == TICK_INSIDE_1) { - // We're done with this div. Move on to the next. - *outRight = i-1; - outRight += 2; - outLeft += 2; - state = TICK_OUTSIDE_1; - } - } else { - *outLeft = i; - return UNKNOWN_ERROR; - } - } - - if (required && !found) { - *outError = "No marked region found along edge"; - *outLeft = -1; - return UNKNOWN_ERROR; - } - - return NO_ERROR; -} - -static status_t get_vertical_ticks( - png_bytepp rows, int offset, int height, bool transparent, bool required, - int32_t* outTop, int32_t* outBottom, const char** outError, - uint8_t* outDivs, bool multipleAllowed) -{ - int i; - *outTop = *outBottom = -1; - int state = TICK_START; - bool found = false; - - for (i=1; i<height-1; i++) { - if (is_tick(rows[i]+offset, transparent, outError)) { - if (state == TICK_START || - (state == TICK_OUTSIDE_1 && multipleAllowed)) { - *outTop = i-1; - *outBottom = height-2; - found = true; - if (outDivs != NULL) { - *outDivs += 2; - } - state = TICK_INSIDE_1; - } else if (state == TICK_OUTSIDE_1) { - *outError = "Can't have more than one marked region along edge"; - *outTop = i; - return UNKNOWN_ERROR; - } - } else if (*outError == NULL) { - if (state == TICK_INSIDE_1) { - // We're done with this div. Move on to the next. - *outBottom = i-1; - outTop += 2; - outBottom += 2; - state = TICK_OUTSIDE_1; - } - } else { - *outTop = i; - return UNKNOWN_ERROR; - } - } - - if (required && !found) { - *outError = "No marked region found along edge"; - *outTop = -1; - return UNKNOWN_ERROR; - } - - return NO_ERROR; -} - -static uint32_t get_color( - png_bytepp rows, int left, int top, int right, int bottom) -{ - png_bytep color = rows[top] + left*4; - - if (left > right || top > bottom) { - return Res_png_9patch::TRANSPARENT_COLOR; - } - - while (top <= bottom) { - for (int i = left; i <= right; i++) { - png_bytep p = rows[top]+i*4; - if (color[3] == 0) { - if (p[3] != 0) { - return Res_png_9patch::NO_COLOR; - } - } else if (p[0] != color[0] || p[1] != color[1] - || p[2] != color[2] || p[3] != color[3]) { - return Res_png_9patch::NO_COLOR; - } - } - top++; - } - - if (color[3] == 0) { - return Res_png_9patch::TRANSPARENT_COLOR; - } - return (color[3]<<24) | (color[0]<<16) | (color[1]<<8) | color[2]; -} - -static void select_patch( - int which, int front, int back, int size, int* start, int* end) -{ - switch (which) { - case 0: - *start = 0; - *end = front-1; - break; - case 1: - *start = front; - *end = back-1; - break; - case 2: - *start = back; - *end = size-1; - break; - } -} - -static uint32_t get_color(image_info* image, int hpatch, int vpatch) -{ - int left, right, top, bottom; - select_patch( - hpatch, image->info9Patch.xDivs[0], image->info9Patch.xDivs[1], - image->width, &left, &right); - select_patch( - vpatch, image->info9Patch.yDivs[0], image->info9Patch.yDivs[1], - image->height, &top, &bottom); - //printf("Selecting h=%d v=%d: (%d,%d)-(%d,%d)\n", - // hpatch, vpatch, left, top, right, bottom); - const uint32_t c = get_color(image->rows, left, top, right, bottom); - NOISY(printf("Color in (%d,%d)-(%d,%d): #%08x\n", left, top, right, bottom, c)); - return c; -} - -static status_t do_9patch(const char* imageName, image_info* image) -{ - image->is9Patch = true; - - int W = image->width; - int H = image->height; - int i, j; - - int maxSizeXDivs = (W / 2 + 1) * sizeof(int32_t); - int maxSizeYDivs = (H / 2 + 1) * sizeof(int32_t); - int32_t* xDivs = (int32_t*) malloc(maxSizeXDivs); - int32_t* yDivs = (int32_t*) malloc(maxSizeYDivs); - uint8_t numXDivs = 0; - uint8_t numYDivs = 0; - int8_t numColors; - int numRows; - int numCols; - int top; - int left; - int right; - int bottom; - memset(xDivs, -1, maxSizeXDivs); - memset(yDivs, -1, maxSizeYDivs); - image->info9Patch.paddingLeft = image->info9Patch.paddingRight = - image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1; - - png_bytep p = image->rows[0]; - bool transparent = p[3] == 0; - bool hasColor = false; - - const char* errorMsg = NULL; - int errorPixel = -1; - const char* errorEdge = ""; - - int colorIndex = 0; - - // Validate size... - if (W < 3 || H < 3) { - errorMsg = "Image must be at least 3x3 (1x1 without frame) pixels"; - goto getout; - } - - // Validate frame... - if (!transparent && - (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) { - errorMsg = "Must have one-pixel frame that is either transparent or white"; - goto getout; - } - - // Find left and right of sizing areas... - if (get_horizontal_ticks(p, W, transparent, true, &xDivs[0], - &xDivs[1], &errorMsg, &numXDivs, true) != NO_ERROR) { - errorPixel = xDivs[0]; - errorEdge = "top"; - goto getout; - } - - // Find top and bottom of sizing areas... - if (get_vertical_ticks(image->rows, 0, H, transparent, true, &yDivs[0], - &yDivs[1], &errorMsg, &numYDivs, true) != NO_ERROR) { - errorPixel = yDivs[0]; - errorEdge = "left"; - goto getout; - } - - // Find left and right of padding area... - if (get_horizontal_ticks(image->rows[H-1], W, transparent, false, &image->info9Patch.paddingLeft, - &image->info9Patch.paddingRight, &errorMsg, NULL, false) != NO_ERROR) { - errorPixel = image->info9Patch.paddingLeft; - errorEdge = "bottom"; - goto getout; - } - - // Find top and bottom of padding area... - if (get_vertical_ticks(image->rows, (W-1)*4, H, transparent, false, &image->info9Patch.paddingTop, - &image->info9Patch.paddingBottom, &errorMsg, NULL, false) != NO_ERROR) { - errorPixel = image->info9Patch.paddingTop; - errorEdge = "right"; - goto getout; - } - - // Copy patch data into image - image->info9Patch.numXDivs = numXDivs; - image->info9Patch.numYDivs = numYDivs; - image->info9Patch.xDivs = xDivs; - image->info9Patch.yDivs = yDivs; - - // If padding is not yet specified, take values from size. - if (image->info9Patch.paddingLeft < 0) { - image->info9Patch.paddingLeft = xDivs[0]; - image->info9Patch.paddingRight = W - 2 - xDivs[1]; - } else { - // Adjust value to be correct! - image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight; - } - if (image->info9Patch.paddingTop < 0) { - image->info9Patch.paddingTop = yDivs[0]; - image->info9Patch.paddingBottom = H - 2 - yDivs[1]; - } else { - // Adjust value to be correct! - image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom; - } - - NOISY(printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName, - image->info9Patch.xDivs[0], image->info9Patch.xDivs[1], - image->info9Patch.yDivs[0], image->info9Patch.yDivs[1])); - NOISY(printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName, - image->info9Patch.paddingLeft, image->info9Patch.paddingRight, - image->info9Patch.paddingTop, image->info9Patch.paddingBottom)); - - // Remove frame from image. - image->rows = (png_bytepp)malloc((H-2) * png_sizeof(png_bytep)); - for (i=0; i<(H-2); i++) { - image->rows[i] = image->allocRows[i+1]; - memmove(image->rows[i], image->rows[i]+4, (W-2)*4); - } - image->width -= 2; - W = image->width; - image->height -= 2; - H = image->height; - - // Figure out the number of rows and columns in the N-patch - numCols = numXDivs + 1; - if (xDivs[0] == 0) { // Column 1 is strechable - numCols--; - } - if (xDivs[numXDivs - 1] == W) { - numCols--; - } - numRows = numYDivs + 1; - if (yDivs[0] == 0) { // Row 1 is strechable - numRows--; - } - if (yDivs[numYDivs - 1] == H) { - numRows--; - } - numColors = numRows * numCols; - image->info9Patch.numColors = numColors; - image->info9Patch.colors = (uint32_t*)malloc(numColors * sizeof(uint32_t)); - - // Fill in color information for each patch. - - uint32_t c; - top = 0; - - // The first row always starts with the top being at y=0 and the bottom - // being either yDivs[1] (if yDivs[0]=0) of yDivs[0]. In the former case - // the first row is stretchable along the Y axis, otherwise it is fixed. - // The last row always ends with the bottom being bitmap.height and the top - // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or - // yDivs[numYDivs-1]. In the former case the last row is stretchable along - // the Y axis, otherwise it is fixed. - // - // The first and last columns are similarly treated with respect to the X - // axis. - // - // The above is to help explain some of the special casing that goes on the - // code below. - - // The initial yDiv and whether the first row is considered stretchable or - // not depends on whether yDiv[0] was zero or not. - for (j = (yDivs[0] == 0 ? 1 : 0); - j <= numYDivs && top < H; - j++) { - if (j == numYDivs) { - bottom = H; - } else { - bottom = yDivs[j]; - } - left = 0; - // The initial xDiv and whether the first column is considered - // stretchable or not depends on whether xDiv[0] was zero or not. - for (i = xDivs[0] == 0 ? 1 : 0; - i <= numXDivs && left < W; - i++) { - if (i == numXDivs) { - right = W; - } else { - right = xDivs[i]; - } - c = get_color(image->rows, left, top, right - 1, bottom - 1); - image->info9Patch.colors[colorIndex++] = c; - NOISY(if (c != Res_png_9patch::NO_COLOR) hasColor = true); - left = right; - } - top = bottom; - } - - assert(colorIndex == numColors); - - for (i=0; i<numColors; i++) { - if (hasColor) { - if (i == 0) printf("Colors in %s:\n ", imageName); - printf(" #%08x", image->info9Patch.colors[i]); - if (i == numColors - 1) printf("\n"); - } - } - - image->is9Patch = true; - image->info9Patch.deviceToFile(); - -getout: - if (errorMsg) { - fprintf(stderr, - "ERROR: 9-patch image %s malformed.\n" - " %s.\n", imageName, errorMsg); - if (errorPixel >= 0) { - fprintf(stderr, - " Found at pixel #%d along %s edge.\n", errorPixel, errorEdge); - } else { - fprintf(stderr, - " Found along %s edge.\n", errorEdge); - } - return UNKNOWN_ERROR; - } - return NO_ERROR; -} - -static void checkNinePatchSerialization(Res_png_9patch* inPatch, void * data) -{ - if (sizeof(void*) != sizeof(int32_t)) { - // can't deserialize on a non-32 bit system - return; - } - size_t patchSize = inPatch->serializedSize(); - void * newData = malloc(patchSize); - memcpy(newData, data, patchSize); - Res_png_9patch* outPatch = inPatch->deserialize(newData); - // deserialization is done in place, so outPatch == newData - assert(outPatch == newData); - assert(outPatch->numXDivs == inPatch->numXDivs); - assert(outPatch->numYDivs == inPatch->numYDivs); - assert(outPatch->paddingLeft == inPatch->paddingLeft); - assert(outPatch->paddingRight == inPatch->paddingRight); - assert(outPatch->paddingTop == inPatch->paddingTop); - assert(outPatch->paddingBottom == inPatch->paddingBottom); - for (int i = 0; i < outPatch->numXDivs; i++) { - assert(outPatch->xDivs[i] == inPatch->xDivs[i]); - } - for (int i = 0; i < outPatch->numYDivs; i++) { - assert(outPatch->yDivs[i] == inPatch->yDivs[i]); - } - for (int i = 0; i < outPatch->numColors; i++) { - assert(outPatch->colors[i] == inPatch->colors[i]); - } - free(newData); -} - -static bool patch_equals(Res_png_9patch& patch1, Res_png_9patch& patch2) { - if (!(patch1.numXDivs == patch2.numXDivs && - patch1.numYDivs == patch2.numYDivs && - patch1.numColors == patch2.numColors && - patch1.paddingLeft == patch2.paddingLeft && - patch1.paddingRight == patch2.paddingRight && - patch1.paddingTop == patch2.paddingTop && - patch1.paddingBottom == patch2.paddingBottom)) { - return false; - } - for (int i = 0; i < patch1.numColors; i++) { - if (patch1.colors[i] != patch2.colors[i]) { - return false; - } - } - for (int i = 0; i < patch1.numXDivs; i++) { - if (patch1.xDivs[i] != patch2.xDivs[i]) { - return false; - } - } - for (int i = 0; i < patch1.numYDivs; i++) { - if (patch1.yDivs[i] != patch2.yDivs[i]) { - return false; - } - } - return true; -} - -static void dump_image(int w, int h, png_bytepp rows, int color_type) -{ - int i, j, rr, gg, bb, aa; - - int bpp; - if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY) { - bpp = 1; - } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - bpp = 2; - } else if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - // We use a padding byte even when there is no alpha - bpp = 4; - } else { - printf("Unknown color type %d.\n", color_type); - } - - for (j = 0; j < h; j++) { - png_bytep row = rows[j]; - for (i = 0; i < w; i++) { - rr = row[0]; - gg = row[1]; - bb = row[2]; - aa = row[3]; - row += bpp; - - if (i == 0) { - printf("Row %d:", j); - } - switch (bpp) { - case 1: - printf(" (%d)", rr); - break; - case 2: - printf(" (%d %d", rr, gg); - break; - case 3: - printf(" (%d %d %d)", rr, gg, bb); - break; - case 4: - printf(" (%d %d %d %d)", rr, gg, bb, aa); - break; - } - if (i == (w - 1)) { - NOISY(printf("\n")); - } - } - } -} - -#define MAX(a,b) ((a)>(b)?(a):(b)) -#define ABS(a) ((a)<0?-(a):(a)) - -static void analyze_image(const char *imageName, image_info &imageInfo, int grayscaleTolerance, - png_colorp rgbPalette, png_bytep alphaPalette, - int *paletteEntries, bool *hasTransparency, int *colorType, - png_bytepp outRows) -{ - int w = imageInfo.width; - int h = imageInfo.height; - int i, j, rr, gg, bb, aa, idx; - uint32_t colors[256], col; - int num_colors = 0; - int maxGrayDeviation = 0; - - bool isOpaque = true; - bool isPalette = true; - bool isGrayscale = true; - - // Scan the entire image and determine if: - // 1. Every pixel has R == G == B (grayscale) - // 2. Every pixel has A == 255 (opaque) - // 3. There are no more than 256 distinct RGBA colors - - // NOISY(printf("Initial image data:\n")); - // dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA); - - for (j = 0; j < h; j++) { - png_bytep row = imageInfo.rows[j]; - png_bytep out = outRows[j]; - for (i = 0; i < w; i++) { - rr = *row++; - gg = *row++; - bb = *row++; - aa = *row++; - - int odev = maxGrayDeviation; - maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation); - maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation); - maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation); - if (maxGrayDeviation > odev) { - NOISY(printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n", - maxGrayDeviation, i, j, rr, gg, bb, aa)); - } - - // Check if image is really grayscale - if (isGrayscale) { - if (rr != gg || rr != bb) { - NOISY(printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n", - i, j, rr, gg, bb, aa)); - isGrayscale = false; - } - } - - // Check if image is really opaque - if (isOpaque) { - if (aa != 0xff) { - NOISY(printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n", - i, j, rr, gg, bb, aa)); - isOpaque = false; - } - } - - // Check if image is really <= 256 colors - if (isPalette) { - col = (uint32_t) ((rr << 24) | (gg << 16) | (bb << 8) | aa); - bool match = false; - for (idx = 0; idx < num_colors; idx++) { - if (colors[idx] == col) { - match = true; - break; - } - } - - // Write the palette index for the pixel to outRows optimistically - // We might overwrite it later if we decide to encode as gray or - // gray + alpha - *out++ = idx; - if (!match) { - if (num_colors == 256) { - NOISY(printf("Found 257th color at %d, %d\n", i, j)); - isPalette = false; - } else { - colors[num_colors++] = col; - } - } - } - } - } - - *paletteEntries = 0; - *hasTransparency = !isOpaque; - int bpp = isOpaque ? 3 : 4; - int paletteSize = w * h + bpp * num_colors; - - NOISY(printf("isGrayscale = %s\n", isGrayscale ? "true" : "false")); - NOISY(printf("isOpaque = %s\n", isOpaque ? "true" : "false")); - NOISY(printf("isPalette = %s\n", isPalette ? "true" : "false")); - NOISY(printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n", - paletteSize, 2 * w * h, bpp * w * h)); - NOISY(printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation, grayscaleTolerance)); - - // Choose the best color type for the image. - // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel - // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct combinations - // is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA - // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is sufficiently - // small, otherwise use COLOR_TYPE_RGB{_ALPHA} - if (isGrayscale) { - if (isOpaque) { - *colorType = PNG_COLOR_TYPE_GRAY; // 1 byte/pixel - } else { - // Use a simple heuristic to determine whether using a palette will - // save space versus using gray + alpha for each pixel. - // This doesn't take into account chunk overhead, filtering, LZ - // compression, etc. - if (isPalette && (paletteSize < 2 * w * h)) { - *colorType = PNG_COLOR_TYPE_PALETTE; // 1 byte/pixel + 4 bytes/color - } else { - *colorType = PNG_COLOR_TYPE_GRAY_ALPHA; // 2 bytes per pixel - } - } - } else if (isPalette && (paletteSize < bpp * w * h)) { - *colorType = PNG_COLOR_TYPE_PALETTE; - } else { - if (maxGrayDeviation <= grayscaleTolerance) { - printf("%s: forcing image to gray (max deviation = %d)\n", imageName, maxGrayDeviation); - *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA; - } else { - *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA; - } - } - - // Perform postprocessing of the image or palette data based on the final - // color type chosen - - if (*colorType == PNG_COLOR_TYPE_PALETTE) { - // Create separate RGB and Alpha palettes and set the number of colors - *paletteEntries = num_colors; - - // Create the RGB and alpha palettes - for (int idx = 0; idx < num_colors; idx++) { - col = colors[idx]; - rgbPalette[idx].red = (png_byte) ((col >> 24) & 0xff); - rgbPalette[idx].green = (png_byte) ((col >> 16) & 0xff); - rgbPalette[idx].blue = (png_byte) ((col >> 8) & 0xff); - alphaPalette[idx] = (png_byte) (col & 0xff); - } - } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) { - // If the image is gray or gray + alpha, compact the pixels into outRows - for (j = 0; j < h; j++) { - png_bytep row = imageInfo.rows[j]; - png_bytep out = outRows[j]; - for (i = 0; i < w; i++) { - rr = *row++; - gg = *row++; - bb = *row++; - aa = *row++; - - if (isGrayscale) { - *out++ = rr; - } else { - *out++ = (png_byte) (rr * 0.2126f + gg * 0.7152f + bb * 0.0722f); - } - if (!isOpaque) { - *out++ = aa; - } - } - } - } -} - - -static void write_png(const char* imageName, - png_structp write_ptr, png_infop write_info, - image_info& imageInfo, int grayscaleTolerance) -{ - bool optimize = true; - png_uint_32 width, height; - int color_type; - int bit_depth, interlace_type, compression_type; - int i; - - png_unknown_chunk unknowns[1]; - - png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * png_sizeof(png_bytep)); - if (outRows == (png_bytepp) 0) { - printf("Can't allocate output buffer!\n"); - exit(1); - } - for (i = 0; i < (int) imageInfo.height; i++) { - outRows[i] = (png_bytep) malloc(2 * (int) imageInfo.width); - if (outRows[i] == (png_bytep) 0) { - printf("Can't allocate output buffer!\n"); - exit(1); - } - } - - png_set_compression_level(write_ptr, Z_BEST_COMPRESSION); - - NOISY(printf("Writing image %s: w = %d, h = %d\n", imageName, - (int) imageInfo.width, (int) imageInfo.height)); - - png_color rgbPalette[256]; - png_byte alphaPalette[256]; - bool hasTransparency; - int paletteEntries; - - analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette, - &paletteEntries, &hasTransparency, &color_type, outRows); - switch (color_type) { - case PNG_COLOR_TYPE_PALETTE: - NOISY(printf("Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\n", - imageName, paletteEntries, - hasTransparency ? " (with alpha)" : "")); - break; - case PNG_COLOR_TYPE_GRAY: - NOISY(printf("Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\n", imageName)); - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - NOISY(printf("Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\n", imageName)); - break; - case PNG_COLOR_TYPE_RGB: - NOISY(printf("Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\n", imageName)); - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - NOISY(printf("Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\n", imageName)); - break; - } - - png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height, - 8, color_type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_PLTE(write_ptr, write_info, rgbPalette, paletteEntries); - if (hasTransparency) { - png_set_tRNS(write_ptr, write_info, alphaPalette, paletteEntries, (png_color_16p) 0); - } - png_set_filter(write_ptr, 0, PNG_NO_FILTERS); - } else { - png_set_filter(write_ptr, 0, PNG_ALL_FILTERS); - } - - if (imageInfo.is9Patch) { - NOISY(printf("Adding 9-patch info...\n")); - strcpy((char*)unknowns[0].name, "npTc"); - unknowns[0].data = (png_byte*)imageInfo.info9Patch.serialize(); - unknowns[0].size = imageInfo.info9Patch.serializedSize(); - // TODO: remove the check below when everything works - checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[0].data); - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - (png_byte*)"npTc", 1); - png_set_unknown_chunks(write_ptr, write_info, unknowns, 1); - // XXX I can't get this to work without forcibly changing - // the location to what I want... which apparently is supposed - // to be a private API, but everything else I have tried results - // in the location being set to what I -last- wrote so I never - // get written. :p - png_set_unknown_chunk_location(write_ptr, write_info, 0, PNG_HAVE_PLTE); - } - - png_write_info(write_ptr, write_info); - - png_bytepp rows; - if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_set_filler(write_ptr, 0, PNG_FILLER_AFTER); - rows = imageInfo.rows; - } else { - rows = outRows; - } - png_write_image(write_ptr, rows); - -// NOISY(printf("Final image data:\n")); -// dump_image(imageInfo.width, imageInfo.height, rows, color_type); - - png_write_end(write_ptr, write_info); - - for (i = 0; i < (int) imageInfo.height; i++) { - free(outRows[i]); - } - free(outRows); - - png_get_IHDR(write_ptr, write_info, &width, &height, - &bit_depth, &color_type, &interlace_type, - &compression_type, NULL); - - NOISY(printf("Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n", - (int)width, (int)height, bit_depth, color_type, interlace_type, - compression_type)); -} - -status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets, - const sp<AaptFile>& file, String8* outNewLeafName) -{ - String8 ext(file->getPath().getPathExtension()); - - // We currently only process PNG images. - if (strcmp(ext.string(), ".png") != 0) { - return NO_ERROR; - } - - // Example of renaming a file: - //*outNewLeafName = file->getPath().getBasePath().getFileName(); - //outNewLeafName->append(".nupng"); - - String8 printableName(file->getPrintableSource()); - - png_structp read_ptr = NULL; - png_infop read_info = NULL; - FILE* fp; - - image_info imageInfo; - - png_structp write_ptr = NULL; - png_infop write_info = NULL; - - status_t error = UNKNOWN_ERROR; - - const size_t nameLen = file->getPath().length(); - - fp = fopen(file->getSourceFile().string(), "rb"); - if (fp == NULL) { - fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.string()); - goto bail; - } - - read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL, - (png_error_ptr)NULL); - if (!read_ptr) { - goto bail; - } - - read_info = png_create_info_struct(read_ptr); - if (!read_info) { - goto bail; - } - - if (setjmp(png_jmpbuf(read_ptr))) { - goto bail; - } - - png_init_io(read_ptr, fp); - - read_png(printableName.string(), read_ptr, read_info, &imageInfo); - - if (nameLen > 6) { - const char* name = file->getPath().string(); - if (name[nameLen-5] == '9' && name[nameLen-6] == '.') { - if (do_9patch(printableName.string(), &imageInfo) != NO_ERROR) { - goto bail; - } - } - } - - write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL, - (png_error_ptr)NULL); - if (!write_ptr) - { - goto bail; - } - - write_info = png_create_info_struct(write_ptr); - if (!write_info) - { - goto bail; - } - - png_set_write_fn(write_ptr, (void*)file.get(), - png_write_aapt_file, png_flush_aapt_file); - - if (setjmp(png_jmpbuf(write_ptr))) - { - goto bail; - } - - write_png(printableName.string(), write_ptr, write_info, imageInfo, - bundle->getGrayscaleTolerance()); - - error = NO_ERROR; - - if (bundle->getVerbose()) { - fseek(fp, 0, SEEK_END); - size_t oldSize = (size_t)ftell(fp); - size_t newSize = file->getSize(); - float factor = ((float)newSize)/oldSize; - int percent = (int)(factor*100); - printf(" (processed image %s: %d%% size of source)\n", printableName.string(), percent); - } - -bail: - if (read_ptr) { - png_destroy_read_struct(&read_ptr, &read_info, (png_infopp)NULL); - } - if (fp) { - fclose(fp); - } - if (write_ptr) { - png_destroy_write_struct(&write_ptr, &write_info); - } - - if (error != NO_ERROR) { - fprintf(stderr, "ERROR: Failure processing PNG image %s\n", - file->getPrintableSource().string()); - } - return error; -} - - - -status_t postProcessImage(const sp<AaptAssets>& assets, - ResourceTable* table, const sp<AaptFile>& file) -{ - String8 ext(file->getPath().getPathExtension()); - - // At this point, now that we have all the resource data, all we need to - // do is compile XML files. - if (strcmp(ext.string(), ".xml") == 0) { - return compileXmlFile(assets, file, table); - } - - return NO_ERROR; -} diff --git a/tools/aapt/Images.h b/tools/aapt/Images.h deleted file mode 100644 index 168e22f..0000000 --- a/tools/aapt/Images.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#ifndef IMAGES_H -#define IMAGES_H - -#include "ResourceTable.h" - -status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets, - const sp<AaptFile>& file, String8* outNewLeafName); - -status_t postProcessImage(const sp<AaptAssets>& assets, - ResourceTable* table, const sp<AaptFile>& file); - -#endif diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp deleted file mode 100644 index 71b1a3c..0000000 --- a/tools/aapt/Main.cpp +++ /dev/null @@ -1,369 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Android Asset Packaging Tool main entry point. -// -#include "Main.h" -#include "Bundle.h" - -#include <utils.h> -#include <utils/ZipFile.h> - -#include <stdlib.h> -#include <getopt.h> -#include <assert.h> - -using namespace android; - -static const char* gProgName = "aapt"; - -/* - * When running under Cygwin on Windows, this will convert slash-based - * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons - * fail later as they use back-slash separators under Windows. - * - * This operates in-place on the path string. - */ -void convertPath(char *path) { - if (path != NULL && OS_PATH_SEPARATOR != '/') { - for (; *path; path++) { - if (*path == '/') { - *path = OS_PATH_SEPARATOR; - } - } - } -} - -/* - * Print usage info. - */ -void usage(void) -{ - fprintf(stderr, "Android Asset Packaging Tool\n\n"); - fprintf(stderr, "Usage:\n"); - fprintf(stderr, - " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n" - " List contents of Zip-compatible archive.\n\n", gProgName); - fprintf(stderr, - " %s d[ump] WHAT file.{apk} [asset [asset ...]]\n" - " badging Print the label and icon for the app declared in APK.\n" - " permissions Print the permissions from the APK.\n" - " resources Print the resource table from the APK.\n" - " configurations Print the configurations in the APK.\n" - " xmltree Print the compiled xmls in the given assets.\n" - " xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName); - fprintf(stderr, - " %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n" - " [-0 extension [-0 extension ...]] \\\n" - " [-g tolerance] \\\n" - " [-j jarfile] \\\n" - " [-I base-package [-I base-package ...]] \\\n" - " [-A asset-source-dir] [-P public-definitions-file] \\\n" - " [-S resource-sources [-S resource-sources ...]] " - " [-F apk-file] [-J R-file-dir] \\\n" - " [raw-files-dir [raw-files-dir] ...]\n" - "\n" - " Package the android resources. It will read assets and resources that are\n" - " supplied with the -M -A -S or raw-files-dir arguments. The -J -P -F and -R\n" - " options control which files are output.\n\n" - , gProgName); - fprintf(stderr, - " %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\n" - " Delete specified files from Zip-compatible archive.\n\n", - gProgName); - fprintf(stderr, - " %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\n" - " Add specified files to Zip-compatible archive.\n\n", gProgName); - fprintf(stderr, - " %s v[ersion]\n" - " Print program version.\n\n", gProgName); - fprintf(stderr, - " Modifiers:\n" - " -a print Android-specific data (resources, manifest) when listing\n" - " -c specify which configurations to include. The default is all\n" - " configurations. The value of the parameter should be a comma\n" - " separated list of configuration values. Locales should be specified\n" - " as either a language or language-region pair. Some examples:\n" - " en\n" - " port,en\n" - " port,land,en_US\n" - " If you put the special locale, zz_ZZ on the list, it will perform\n" - " pseudolocalization on the default locale, modifying all of the\n" - " strings so you can look for strings that missed the\n" - " internationalization process. For example:\n" - " port,land,zz_ZZ\n" - " -d one or more device assets to include, separated by commas\n" - " -f force overwrite of existing files\n" - " -g specify a pixel tolerance to force images to grayscale, default 0\n" - " -j specify a jar or zip file containing classes to include\n" - " -m make package directories under location specified by -J\n" -#if 0 - " -p pseudolocalize the default configuration\n" -#endif - " -u update existing packages (add new, replace older, remove deleted files)\n" - " -v verbose output\n" - " -x create extending (non-application) resource IDs\n" - " -z require localization of resource attributes marked with\n" - " localization=\"suggested\"\n" - " -A additional directory in which to find raw asset files\n" - " -F specify the apk file to output\n" - " -I add an existing package to base include set\n" - " -J specify where to output R.java resource constant definitions\n" - " -M specify full path to AndroidManifest.xml to include in zip\n" - " -P specify where to output public resource definitions\n" - " -S directory in which to find resources. Multiple directories will be scanned" - " and the first match found (left to right) will take precedence." - " -0 specifies an additional extension for which such files will not\n" - " be stored compressed in the .apk. An empty string means to not\n" - " compress any files at all.\n"); -} - -/* - * Dispatch the command. - */ -int handleCommand(Bundle* bundle) -{ - //printf("--- command %d (verbose=%d force=%d):\n", - // bundle->getCommand(), bundle->getVerbose(), bundle->getForce()); - //for (int i = 0; i < bundle->getFileSpecCount(); i++) - // printf(" %d: '%s'\n", i, bundle->getFileSpecEntry(i)); - - switch (bundle->getCommand()) { - case kCommandVersion: return doVersion(bundle); - case kCommandList: return doList(bundle); - case kCommandDump: return doDump(bundle); - case kCommandAdd: return doAdd(bundle); - case kCommandRemove: return doRemove(bundle); - case kCommandPackage: return doPackage(bundle); - default: - fprintf(stderr, "%s: requested command not yet supported\n", gProgName); - return 1; - } -} - -/* - * Parse args. - */ -int main(int argc, char* const argv[]) -{ - char *prog = argv[0]; - Bundle bundle; - bool wantUsage = false; - int result = 1; // pessimistically assume an error. - int tolerance = 0; - - /* default to compression */ - bundle.setCompressionMethod(ZipEntry::kCompressDeflated); - - if (argc < 2) { - wantUsage = true; - goto bail; - } - - if (argv[1][0] == 'v') - bundle.setCommand(kCommandVersion); - else if (argv[1][0] == 'd') - bundle.setCommand(kCommandDump); - else if (argv[1][0] == 'l') - bundle.setCommand(kCommandList); - else if (argv[1][0] == 'a') - bundle.setCommand(kCommandAdd); - else if (argv[1][0] == 'r') - bundle.setCommand(kCommandRemove); - else if (argv[1][0] == 'p') - bundle.setCommand(kCommandPackage); - else { - fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]); - wantUsage = true; - goto bail; - } - argc -= 2; - argv += 2; - - /* - * Pull out flags. We support "-fv" and "-f -v". - */ - while (argc && argv[0][0] == '-') { - /* flag(s) found */ - const char* cp = argv[0] +1; - - while (*cp != '\0') { - switch (*cp) { - case 'v': - bundle.setVerbose(true); - break; - case 'a': - bundle.setAndroidList(true); - break; - case 'c': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-c' option\n"); - wantUsage = true; - goto bail; - } - bundle.addConfigurations(argv[0]); - break; - case 'f': - bundle.setForce(true); - break; - case 'g': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-g' option\n"); - wantUsage = true; - goto bail; - } - tolerance = atoi(argv[0]); - bundle.setGrayscaleTolerance(tolerance); - printf("%s: Images with deviation <= %d will be forced to grayscale.\n", prog, tolerance); - break; - case 'm': - bundle.setMakePackageDirs(true); - break; -#if 0 - case 'p': - bundle.setPseudolocalize(true); - break; -#endif - case 'u': - bundle.setUpdate(true); - break; - case 'x': - bundle.setExtending(true); - break; - case 'z': - bundle.setRequireLocalization(true); - break; - case 'j': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-j' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.addJarFile(argv[0]); - break; - case 'A': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-A' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.setAssetSourceDir(argv[0]); - break; - case 'I': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-I' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.addPackageInclude(argv[0]); - break; - case 'F': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-F' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.setOutputAPKFile(argv[0]); - break; - case 'J': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-J' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.setRClassDir(argv[0]); - break; - case 'M': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-M' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.setAndroidManifestFile(argv[0]); - break; - case 'P': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-P' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.setPublicOutputFile(argv[0]); - break; - case 'S': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-S' option\n"); - wantUsage = true; - goto bail; - } - convertPath(argv[0]); - bundle.addResourceSourceDir(argv[0]); - break; - case '0': - argc--; - argv++; - if (!argc) { - fprintf(stderr, "ERROR: No argument supplied for '-e' option\n"); - wantUsage = true; - goto bail; - } - if (argv[0][0] != 0) { - bundle.addNoCompressExtension(argv[0]); - } else { - bundle.setCompressionMethod(ZipEntry::kCompressStored); - } - break; - default: - fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp); - wantUsage = true; - goto bail; - } - - cp++; - } - argc--; - argv++; - } - - /* - * We're past the flags. The rest all goes straight in. - */ - bundle.setFileSpec(argv, argc); - - result = handleCommand(&bundle); - -bail: - if (wantUsage) { - usage(); - result = 2; - } - - //printf("--> returning %d\n", result); - return result; -} diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h deleted file mode 100644 index 65c0a8a..0000000 --- a/tools/aapt/Main.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Some global defines that don't really merit their own header. -// -#ifndef __MAIN_H -#define __MAIN_H - -#include <utils.h> -#include "Bundle.h" -#include "AaptAssets.h" -#include <utils/ZipFile.h> - -extern int doVersion(Bundle* bundle); -extern int doList(Bundle* bundle); -extern int doDump(Bundle* bundle); -extern int doAdd(Bundle* bundle); -extern int doRemove(Bundle* bundle); -extern int doPackage(Bundle* bundle); - -extern int calcPercent(long uncompressedLen, long compressedLen); - -extern android::status_t writeAPK(Bundle* bundle, - const sp<AaptAssets>& assets, - const android::String8& outputFile); - -extern android::status_t buildResources(Bundle* bundle, - const sp<AaptAssets>& assets); - -extern android::status_t writeResourceSymbols(Bundle* bundle, - const sp<AaptAssets>& assets, const String8& pkgName, bool includePrivate); - -extern bool isValidResourceType(const String8& type); - -ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptAssets>& assets); - -extern status_t filterResources(Bundle* bundle, const sp<AaptAssets>& assets); - -int dumpResources(Bundle* bundle); - -#endif // __MAIN_H diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp deleted file mode 100644 index eb7d6f5..0000000 --- a/tools/aapt/Package.cpp +++ /dev/null @@ -1,464 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Package assets into Zip files. -// -#include "Main.h" -#include "AaptAssets.h" -#include "ResourceTable.h" - -#include <utils.h> -#include <utils/ZipFile.h> - -#include <sys/types.h> -#include <dirent.h> -#include <ctype.h> -#include <errno.h> - -using namespace android; - -static const char* kExcludeExtension = ".EXCLUDE"; - -/* these formats are already compressed, or don't compress well */ -static const char* kNoCompressExt[] = { - ".jpg", ".jpeg", ".png", ".gif", - ".wav", ".mp2", ".mp3", ".ogg", ".aac", - ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", - ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", - ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", - ".amr", ".awb", ".wma", ".wmv" -}; - -/* fwd decls, so I can write this downward */ -ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptAssets>& assets); -ssize_t processAssets(Bundle* bundle, ZipFile* zip, - const sp<AaptDir>& dir, const AaptGroupEntry& ge); -bool processFile(Bundle* bundle, ZipFile* zip, - const sp<AaptGroup>& group, const sp<AaptFile>& file); -bool okayToCompress(Bundle* bundle, const String8& pathName); -ssize_t processJarFiles(Bundle* bundle, ZipFile* zip); - -/* - * The directory hierarchy looks like this: - * "outputDir" and "assetRoot" are existing directories. - * - * On success, "bundle->numPackages" will be the number of Zip packages - * we created. - */ -status_t writeAPK(Bundle* bundle, const sp<AaptAssets>& assets, - const String8& outputFile) -{ - status_t result = NO_ERROR; - ZipFile* zip = NULL; - int count; - - //bundle->setPackageCount(0); - - /* - * Prep the Zip archive. - * - * If the file already exists, fail unless "update" or "force" is set. - * If "update" is set, update the contents of the existing archive. - * Else, if "force" is set, remove the existing archive. - */ - FileType fileType = getFileType(outputFile.string()); - if (fileType == kFileTypeNonexistent) { - // okay, create it below - } else if (fileType == kFileTypeRegular) { - if (bundle->getUpdate()) { - // okay, open it below - } else if (bundle->getForce()) { - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.string(), - strerror(errno)); - goto bail; - } - } else { - fprintf(stderr, "ERROR: '%s' exists (use '-f' to force overwrite)\n", - outputFile.string()); - goto bail; - } - } else { - fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.string()); - goto bail; - } - - if (bundle->getVerbose()) { - printf("%s '%s'\n", (fileType == kFileTypeNonexistent) ? "Creating" : "Opening", - outputFile.string()); - } - - status_t status; - zip = new ZipFile; - status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate); - if (status != NO_ERROR) { - fprintf(stderr, "ERROR: unable to open '%s' as Zip file for writing\n", - outputFile.string()); - goto bail; - } - - if (bundle->getVerbose()) { - printf("Writing all files...\n"); - } - - count = processAssets(bundle, zip, assets); - if (count < 0) { - fprintf(stderr, "ERROR: unable to process assets while packaging '%s'\n", - outputFile.string()); - result = count; - goto bail; - } - - if (bundle->getVerbose()) { - printf("Generated %d file%s\n", count, (count==1) ? "" : "s"); - } - - count = processJarFiles(bundle, zip); - if (count < 0) { - fprintf(stderr, "ERROR: unable to process jar files while packaging '%s'\n", - outputFile.string()); - result = count; - goto bail; - } - - if (bundle->getVerbose()) - printf("Included %d file%s from jar/zip files.\n", count, (count==1) ? "" : "s"); - - result = NO_ERROR; - - /* - * Check for cruft. We set the "marked" flag on all entries we created - * or decided not to update. If the entry isn't already slated for - * deletion, remove it now. - */ - { - if (bundle->getVerbose()) - printf("Checking for deleted files\n"); - int i, removed = 0; - for (i = 0; i < zip->getNumEntries(); i++) { - ZipEntry* entry = zip->getEntryByIndex(i); - - if (!entry->getMarked() && entry->getDeleted()) { - if (bundle->getVerbose()) { - printf(" (removing crufty '%s')\n", - entry->getFileName()); - } - zip->remove(entry); - removed++; - } - } - if (bundle->getVerbose() && removed > 0) - printf("Removed %d file%s\n", removed, (removed==1) ? "" : "s"); - } - - /* tell Zip lib to process deletions and other pending changes */ - result = zip->flush(); - if (result != NO_ERROR) { - fprintf(stderr, "ERROR: Zip flush failed, archive may be hosed\n"); - goto bail; - } - - /* anything here? */ - if (zip->getNumEntries() == 0) { - if (bundle->getVerbose()) { - printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().string()); - } - delete zip; // close the file so we can remove it in Win32 - zip = NULL; - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "WARNING: could not unlink '%s'\n", outputFile.string()); - } - } - - assert(result == NO_ERROR); - -bail: - delete zip; // must close before remove in Win32 - if (result != NO_ERROR) { - if (bundle->getVerbose()) { - printf("Removing %s due to earlier failures\n", outputFile.string()); - } - if (unlink(outputFile.string()) != 0) { - fprintf(stderr, "WARNING: could not unlink '%s'\n", outputFile.string()); - } - } - - if (result == NO_ERROR && bundle->getVerbose()) - printf("Done!\n"); - return result; -} - -ssize_t processAssets(Bundle* bundle, ZipFile* zip, - const sp<AaptAssets>& assets) -{ - ResourceFilter filter; - status_t status = filter.parse(bundle->getConfigurations()); - if (status != NO_ERROR) { - return -1; - } - - ssize_t count = 0; - - const size_t N = assets->getGroupEntries().size(); - for (size_t i=0; i<N; i++) { - const AaptGroupEntry& ge = assets->getGroupEntries()[i]; - if (!filter.match(ge.toParams())) { - continue; - } - ssize_t res = processAssets(bundle, zip, assets, ge); - if (res < 0) { - return res; - } - count += res; - } - - return count; -} - -ssize_t processAssets(Bundle* bundle, ZipFile* zip, - const sp<AaptDir>& dir, const AaptGroupEntry& ge) -{ - ssize_t count = 0; - - const size_t ND = dir->getDirs().size(); - size_t i; - for (i=0; i<ND; i++) { - ssize_t res = processAssets(bundle, zip, dir->getDirs().valueAt(i), ge); - if (res < 0) { - return res; - } - count += res; - } - - const size_t NF = dir->getFiles().size(); - for (i=0; i<NF; i++) { - sp<AaptGroup> gp = dir->getFiles().valueAt(i); - ssize_t fi = gp->getFiles().indexOfKey(ge); - if (fi >= 0) { - sp<AaptFile> fl = gp->getFiles().valueAt(fi); - if (!processFile(bundle, zip, gp, fl)) { - return UNKNOWN_ERROR; - } - count++; - } - } - - return count; -} - -/* - * Process a regular file, adding it to the archive if appropriate. - * - * If we're in "update" mode, and the file already exists in the archive, - * delete the existing entry before adding the new one. - */ -bool processFile(Bundle* bundle, ZipFile* zip, - const sp<AaptGroup>& group, const sp<AaptFile>& file) -{ - const bool hasData = file->hasData(); - - String8 storageName(group->getPath()); - storageName.convertToResPath(); - ZipEntry* entry; - bool fromGzip = false; - status_t result; - - /* - * See if the filename ends in ".EXCLUDE". We can't use - * String8::getPathExtension() because the length of what it considers - * to be an extension is capped. - * - * The Asset Manager doesn't check for ".EXCLUDE" in Zip archives, - * so there's no value in adding them (and it makes life easier on - * the AssetManager lib if we don't). - * - * NOTE: this restriction has been removed. If you're in this code, you - * should clean this up, but I'm in here getting rid of Path Name, and I - * don't want to make other potentially breaking changes --joeo - */ - int fileNameLen = storageName.length(); - int excludeExtensionLen = strlen(kExcludeExtension); - if (fileNameLen > excludeExtensionLen - && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen), - kExcludeExtension))) { - fprintf(stderr, "WARNING: '%s' not added to Zip\n", storageName.string()); - return true; - } - - if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) { - fromGzip = true; - storageName = storageName.getBasePath(); - } - - if (bundle->getUpdate()) { - entry = zip->getEntryByName(storageName.string()); - if (entry != NULL) { - /* file already exists in archive; there can be only one */ - if (entry->getMarked()) { - fprintf(stderr, - "ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n", - file->getPrintableSource().string()); - return false; - } - if (!hasData) { - const String8& srcName = file->getSourceFile(); - time_t fileModWhen; - fileModWhen = getFileModDate(srcName.string()); - if (fileModWhen == (time_t) -1) { // file existence tested earlier, - return false; // not expecting an error here - } - - if (fileModWhen > entry->getModWhen()) { - // mark as deleted so add() will succeed - if (bundle->getVerbose()) { - printf(" (removing old '%s')\n", storageName.string()); - } - - zip->remove(entry); - } else { - // version in archive is newer - if (bundle->getVerbose()) { - printf(" (not updating '%s')\n", storageName.string()); - } - entry->setMarked(true); - return true; - } - } else { - // Generated files are always replaced. - zip->remove(entry); - } - } - } - - //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE); - - if (fromGzip) { - result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry); - } else if (!hasData) { - /* don't compress certain files, e.g. PNGs */ - int compressionMethod = bundle->getCompressionMethod(); - if (!okayToCompress(bundle, storageName)) { - compressionMethod = ZipEntry::kCompressStored; - } - result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod, - &entry); - } else { - result = zip->add(file->getData(), file->getSize(), storageName.string(), - file->getCompressionMethod(), &entry); - } - if (result == NO_ERROR) { - if (bundle->getVerbose()) { - printf(" '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : ""); - if (entry->getCompressionMethod() == ZipEntry::kCompressStored) { - printf(" (not compressed)\n"); - } else { - printf(" (compressed %d%%)\n", calcPercent(entry->getUncompressedLen(), - entry->getCompressedLen())); - } - } - entry->setMarked(true); - } else { - if (result == ALREADY_EXISTS) { - fprintf(stderr, " Unable to add '%s': file already in archive (try '-u'?)\n", - file->getPrintableSource().string()); - } else { - fprintf(stderr, " Unable to add '%s': Zip add failed\n", - file->getPrintableSource().string()); - } - return false; - } - - return true; -} - -/* - * Determine whether or not we want to try to compress this file based - * on the file extension. - */ -bool okayToCompress(Bundle* bundle, const String8& pathName) -{ - String8 ext = pathName.getPathExtension(); - int i; - - if (ext.length() == 0) - return true; - - for (i = 0; i < NELEM(kNoCompressExt); i++) { - if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0) - return false; - } - - const android::Vector<const char*>& others(bundle->getNoCompressExtensions()); - for (i = 0; i < (int)others.size(); i++) { - const char* str = others[i]; - int pos = pathName.length() - strlen(str); - if (pos < 0) { - continue; - } - const char* path = pathName.string(); - if (strcasecmp(path + pos, str) == 0) { - return false; - } - } - - return true; -} - -bool endsWith(const char* haystack, const char* needle) -{ - size_t a = strlen(haystack); - size_t b = strlen(needle); - if (a < b) return false; - return strcasecmp(haystack+(a-b), needle) == 0; -} - -ssize_t processJarFile(ZipFile* jar, ZipFile* out) -{ - status_t err; - size_t N = jar->getNumEntries(); - size_t count = 0; - for (size_t i=0; i<N; i++) { - ZipEntry* entry = jar->getEntryByIndex(i); - const char* storageName = entry->getFileName(); - if (endsWith(storageName, ".class")) { - int compressionMethod = entry->getCompressionMethod(); - size_t size = entry->getUncompressedLen(); - const void* data = jar->uncompress(entry); - if (data == NULL) { - fprintf(stderr, "ERROR: unable to uncompress entry '%s'\n", - storageName); - return -1; - } - out->add(data, size, storageName, compressionMethod, NULL); - free((void*)data); - } - count++; - } - return count; -} - -ssize_t processJarFiles(Bundle* bundle, ZipFile* zip) -{ - ssize_t err; - ssize_t count = 0; - const android::Vector<const char*>& jars = bundle->getJarFiles(); - - size_t N = jars.size(); - for (size_t i=0; i<N; i++) { - ZipFile jar; - err = jar.open(jars[i], ZipFile::kOpenReadOnly); - if (err != 0) { - fprintf(stderr, "ERROR: unable to open '%s' as a zip file: %zd\n", - jars[i], err); - return err; - } - err += processJarFile(&jar, zip); - if (err < 0) { - fprintf(stderr, "ERROR: unable to process '%s'\n", jars[i]); - return err; - } - count += err; - } - - return count; -} diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp deleted file mode 100644 index b2bd9ff..0000000 --- a/tools/aapt/Resource.cpp +++ /dev/null @@ -1,1524 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// -#include "Main.h" -#include "AaptAssets.h" -#include "StringPool.h" -#include "XMLNode.h" -#include "ResourceTable.h" -#include "Images.h" - -#define NOISY(x) // x - -// ========================================================================== -// ========================================================================== -// ========================================================================== - -class PackageInfo -{ -public: - PackageInfo() - { - } - ~PackageInfo() - { - } - - status_t parsePackage(const sp<AaptGroup>& grp); -}; - -// ========================================================================== -// ========================================================================== -// ========================================================================== - -static String8 parseResourceName(const String8& leaf) -{ - const char* firstDot = strchr(leaf.string(), '.'); - const char* str = leaf.string(); - - if (firstDot) { - return String8(str, firstDot-str); - } else { - return String8(str); - } -} - -class ResourceTypeSet : public RefBase, - public KeyedVector<String8,sp<AaptGroup> > -{ -public: - ResourceTypeSet(); -}; - -ResourceTypeSet::ResourceTypeSet() - :RefBase(), - KeyedVector<String8,sp<AaptGroup> >() -{ -} - -class ResourceDirIterator -{ -public: - ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType) - : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0) - { - } - - inline const sp<AaptGroup>& getGroup() const { return mGroup; } - inline const sp<AaptFile>& getFile() const { return mFile; } - - inline const String8& getBaseName() const { return mBaseName; } - inline const String8& getLeafName() const { return mLeafName; } - inline String8 getPath() const { return mPath; } - inline const ResTable_config& getParams() const { return mParams; } - - enum { - EOD = 1 - }; - - ssize_t next() - { - while (true) { - sp<AaptGroup> group; - sp<AaptFile> file; - - // Try to get next file in this current group. - if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) { - group = mGroup; - file = group->getFiles().valueAt(mGroupPos++); - - // Try to get the next group/file in this directory - } else if (mSetPos < mSet->size()) { - mGroup = group = mSet->valueAt(mSetPos++); - if (group->getFiles().size() < 1) { - continue; - } - file = group->getFiles().valueAt(0); - mGroupPos = 1; - - // All done! - } else { - return EOD; - } - - mFile = file; - - String8 leaf(group->getLeaf()); - mLeafName = String8(leaf); - mParams = file->getGroupEntry().toParams(); - NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d density=%d touch=%d key=%d inp=%d nav=%d\n", - group->getPath().string(), mParams.mcc, mParams.mnc, - mParams.language[0] ? mParams.language[0] : '-', - mParams.language[1] ? mParams.language[1] : '-', - mParams.country[0] ? mParams.country[0] : '-', - mParams.country[1] ? mParams.country[1] : '-', - mParams.orientation, - mParams.density, mParams.touchscreen, mParams.keyboard, - mParams.inputFlags, mParams.navigation)); - mPath = "res"; - mPath.appendPath(file->getGroupEntry().toDirName(mResType)); - mPath.appendPath(leaf); - mBaseName = parseResourceName(leaf); - if (mBaseName == "") { - fprintf(stderr, "Error: malformed resource filename %s\n", - file->getPrintableSource().string()); - return UNKNOWN_ERROR; - } - - NOISY(printf("file name=%s\n", mBaseName.string())); - - return NO_ERROR; - } - } - -private: - String8 mResType; - - const sp<ResourceTypeSet> mSet; - size_t mSetPos; - - sp<AaptGroup> mGroup; - size_t mGroupPos; - - sp<AaptFile> mFile; - String8 mBaseName; - String8 mLeafName; - String8 mPath; - ResTable_config mParams; -}; - -// ========================================================================== -// ========================================================================== -// ========================================================================== - -bool isValidResourceType(const String8& type) -{ - return type == "anim" || type == "drawable" || type == "layout" - || type == "values" || type == "xml" || type == "raw" - || type == "color" || type == "menu"; -} - -static sp<AaptFile> getResourceFile(const sp<AaptAssets>& assets, bool makeIfNecessary=true) -{ - sp<AaptGroup> group = assets->getFiles().valueFor(String8("resources.arsc")); - sp<AaptFile> file; - if (group != NULL) { - file = group->getFiles().valueFor(AaptGroupEntry()); - if (file != NULL) { - return file; - } - } - - if (!makeIfNecessary) { - return NULL; - } - return assets->addFile(String8("resources.arsc"), AaptGroupEntry(), String8(), - NULL, String8()); -} - -static status_t parsePackage(const sp<AaptAssets>& assets, const sp<AaptGroup>& grp) -{ - if (grp->getFiles().size() != 1) { - fprintf(stderr, "WARNING: Multiple AndroidManifest.xml files found, using %s\n", - grp->getFiles().valueAt(0)->getPrintableSource().string()); - } - - sp<AaptFile> file = grp->getFiles().valueAt(0); - - ResXMLTree block; - status_t err = parseXMLResource(file, &block); - if (err != NO_ERROR) { - return err; - } - //printXMLBlock(&block); - - ResXMLTree::event_code_t code; - while ((code=block.next()) != ResXMLTree::START_TAG - && code != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - } - - size_t len; - if (code != ResXMLTree::START_TAG) { - fprintf(stderr, "%s:%d: No start tag found\n", - file->getPrintableSource().string(), block.getLineNumber()); - return UNKNOWN_ERROR; - } - if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) { - fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n", - file->getPrintableSource().string(), block.getLineNumber(), - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - - ssize_t nameIndex = block.indexOfAttribute(NULL, "package"); - if (nameIndex < 0) { - fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n", - file->getPrintableSource().string(), block.getLineNumber()); - return UNKNOWN_ERROR; - } - - assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len))); - - return NO_ERROR; -} - -// ========================================================================== -// ========================================================================== -// ========================================================================== - -static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets, - ResourceTable* table, - const sp<ResourceTypeSet>& set, - const char* resType) -{ - String8 type8(resType); - String16 type16(resType); - - bool hasErrors = false; - - ResourceDirIterator it(set, String8(resType)); - ssize_t res; - while ((res=it.next()) == NO_ERROR) { - if (bundle->getVerbose()) { - printf(" (new resource id %s from %s)\n", - it.getBaseName().string(), it.getFile()->getPrintableSource().string()); - } - String16 baseName(it.getBaseName()); - const char16_t* str = baseName.string(); - const char16_t* const end = str + baseName.size(); - while (str < end) { - if (!((*str >= 'a' && *str <= 'z') - || (*str >= '0' && *str <= '9') - || *str == '_' || *str == '.')) { - fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n", - it.getPath().string()); - hasErrors = true; - } - str++; - } - String8 resPath = it.getPath(); - resPath.convertToResPath(); - table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()), - type16, - baseName, - String16(resPath), - NULL, - &it.getParams()); - assets->addResource(it.getLeafName(), resPath, it.getFile(), type8); - } - - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -static status_t preProcessImages(Bundle* bundle, const sp<AaptAssets>& assets, - const sp<ResourceTypeSet>& set) -{ - ResourceDirIterator it(set, String8("drawable")); - Vector<sp<AaptFile> > newNameFiles; - Vector<String8> newNamePaths; - ssize_t res; - while ((res=it.next()) == NO_ERROR) { - res = preProcessImage(bundle, assets, it.getFile(), NULL); - if (res != NO_ERROR) { - return res; - } - } - - return NO_ERROR; -} - -status_t postProcessImages(const sp<AaptAssets>& assets, - ResourceTable* table, - const sp<ResourceTypeSet>& set) -{ - ResourceDirIterator it(set, String8("drawable")); - ssize_t res; - while ((res=it.next()) == NO_ERROR) { - res = postProcessImage(assets, table, it.getFile()); - if (res != NO_ERROR) { - return res; - } - } - - return res < NO_ERROR ? res : (status_t)NO_ERROR; -} - -static void collect_files(const sp<AaptDir>& dir, - KeyedVector<String8, sp<ResourceTypeSet> >* resources) -{ - const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles(); - int N = groups.size(); - for (int i=0; i<N; i++) { - String8 leafName = groups.keyAt(i); - const sp<AaptGroup>& group = groups.valueAt(i); - - const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files - = group->getFiles(); - - if (files.size() == 0) { - continue; - } - - String8 resType = files.valueAt(0)->getResourceType(); - - ssize_t index = resources->indexOfKey(resType); - - if (index < 0) { - sp<ResourceTypeSet> set = new ResourceTypeSet(); - set->add(leafName, group); - resources->add(resType, set); - } else { - sp<ResourceTypeSet> set = resources->valueAt(index); - index = set->indexOfKey(leafName); - if (index < 0) { - set->add(leafName, group); - } else { - sp<AaptGroup> existingGroup = set->valueAt(index); - int M = files.size(); - for (int j=0; j<M; j++) { - existingGroup->addFile(files.valueAt(j)); - } - } - } - } -} - -static void collect_files(const sp<AaptAssets>& ass, - KeyedVector<String8, sp<ResourceTypeSet> >* resources) -{ - const Vector<sp<AaptDir> >& dirs = ass->resDirs(); - int N = dirs.size(); - - for (int i=0; i<N; i++) { - sp<AaptDir> d = dirs.itemAt(i); - collect_files(d, resources); - - // don't try to include the res dir - ass->removeDir(d->getLeaf()); - } -} - -enum { - ATTR_OKAY = -1, - ATTR_NOT_FOUND = -2, - ATTR_LEADING_SPACES = -3, - ATTR_TRAILING_SPACES = -4 -}; -static int validateAttr(const String8& path, const ResXMLParser& parser, - const char* ns, const char* attr, const char* validChars, bool required) -{ - size_t len; - - ssize_t index = parser.indexOfAttribute(ns, attr); - const uint16_t* str; - if (index >= 0 && (str=parser.getAttributeStringValue(index, &len)) != NULL) { - if (validChars) { - for (size_t i=0; i<len; i++) { - uint16_t c = str[i]; - const char* p = validChars; - bool okay = false; - while (*p) { - if (c == *p) { - okay = true; - break; - } - p++; - } - if (!okay) { - fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr, (char)str[i]); - return (int)i; - } - } - } - if (*str == ' ') { - fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); - return ATTR_LEADING_SPACES; - } - if (str[len-1] == ' ') { - fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); - return ATTR_TRAILING_SPACES; - } - return ATTR_OKAY; - } - if (required) { - fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n", - path.string(), parser.getLineNumber(), - String8(parser.getElementName(&len)).string(), attr); - return ATTR_NOT_FOUND; - } - return ATTR_OKAY; -} - -static void checkForIds(const String8& path, ResXMLParser& parser) -{ - ResXMLTree::event_code_t code; - while ((code=parser.next()) != ResXMLTree::END_DOCUMENT - && code > ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::START_TAG) { - ssize_t index = parser.indexOfAttribute(NULL, "id"); - if (index >= 0) { - fprintf(stderr, "%s:%d: WARNING: found plain 'id' attribute; did you mean the new 'android:id' name?\n", - path.string(), parser.getLineNumber()); - } - } - } -} - -static void applyFileOverlay(const sp<AaptAssets>& assets, - const sp<ResourceTypeSet>& baseSet, - const char *resType) -{ - // Replace any base level files in this category with any found from the overlay - // Also add any found only in the overlay. - sp<AaptAssets> overlay = assets->getOverlay(); - String8 resTypeString(resType); - - // work through the linked list of overlays - while (overlay.get()) { - KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources(); - - // get the overlay resources of the requested type - ssize_t index = overlayRes->indexOfKey(resTypeString); - if (index >= 0) { - sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index); - - // for each of the resources, check for a match in the previously built - // non-overlay "baseset". - size_t overlayCount = overlaySet->size(); - for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) { - size_t baseIndex = baseSet->indexOfKey(overlaySet->keyAt(overlayIndex)); - if (baseIndex != UNKNOWN_ERROR) { - // look for same flavor. For a given file (strings.xml, for example) - // there may be a locale specific or other flavors - we want to match - // the same flavor. - sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex); - sp<AaptGroup> baseGroup = baseSet->valueAt(baseIndex); - - DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles = - baseGroup->getFiles(); - DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = - overlayGroup->getFiles(); - size_t overlayGroupSize = overlayFiles.size(); - for (size_t overlayGroupIndex = 0; - overlayGroupIndex<overlayGroupSize; - overlayGroupIndex++) { - size_t baseFileIndex = - baseFiles.indexOfKey(overlayFiles.keyAt(overlayGroupIndex)); - if(baseFileIndex < UNKNOWN_ERROR) { - baseGroup->removeFile(baseFileIndex); - } else { - // didn't find a match fall through and add it.. - } - baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex)); - } - } else { - // this group doesn't exist (a file that's only in the overlay) - // add it - baseSet->add(overlaySet->keyAt(overlayIndex), - overlaySet->valueAt(overlayIndex)); - } - } - // this overlay didn't have resources for this type - } - // try next overlay - overlay = overlay->getOverlay(); - } - return; -} - -#define ASSIGN_IT(n) \ - do { \ - ssize_t index = resources->indexOfKey(String8(#n)); \ - if (index >= 0) { \ - n ## s = resources->valueAt(index); \ - } \ - } while (0) - -status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) -{ - // First, look for a package file to parse. This is required to - // be able to generate the resource information. - sp<AaptGroup> androidManifestFile = - assets->getFiles().valueFor(String8("AndroidManifest.xml")); - if (androidManifestFile == NULL) { - fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n"); - return UNKNOWN_ERROR; - } - - status_t err = parsePackage(assets, androidManifestFile); - if (err != NO_ERROR) { - return err; - } - - NOISY(printf("Creating resources for package %s\n", - assets->getPackage().string())); - - ResourceTable table(bundle, String16(assets->getPackage())); - err = table.addIncludedResources(bundle, assets); - if (err != NO_ERROR) { - return err; - } - - NOISY(printf("Found %d included resource packages\n", (int)table.size())); - - // -------------------------------------------------------------- - // First, gather all resource information. - // -------------------------------------------------------------- - - // resType -> leafName -> group - KeyedVector<String8, sp<ResourceTypeSet> > *resources = - new KeyedVector<String8, sp<ResourceTypeSet> >; - collect_files(assets, resources); - - sp<ResourceTypeSet> drawables; - sp<ResourceTypeSet> layouts; - sp<ResourceTypeSet> anims; - sp<ResourceTypeSet> xmls; - sp<ResourceTypeSet> raws; - sp<ResourceTypeSet> colors; - sp<ResourceTypeSet> menus; - - ASSIGN_IT(drawable); - ASSIGN_IT(layout); - ASSIGN_IT(anim); - ASSIGN_IT(xml); - ASSIGN_IT(raw); - ASSIGN_IT(color); - ASSIGN_IT(menu); - - assets->setResources(resources); - // now go through any resource overlays and collect their files - sp<AaptAssets> current = assets->getOverlay(); - while(current.get()) { - KeyedVector<String8, sp<ResourceTypeSet> > *resources = - new KeyedVector<String8, sp<ResourceTypeSet> >; - current->setResources(resources); - collect_files(current, resources); - current = current->getOverlay(); - } - // apply the overlay files to the base set - applyFileOverlay(assets, drawables, "drawable"); - applyFileOverlay(assets, layouts, "layout"); - applyFileOverlay(assets, anims, "anim"); - applyFileOverlay(assets, xmls, "xml"); - applyFileOverlay(assets, raws, "raw"); - applyFileOverlay(assets, colors, "color"); - applyFileOverlay(assets, menus, "menu"); - - bool hasErrors = false; - - if (drawables != NULL) { - err = preProcessImages(bundle, assets, drawables); - if (err == NO_ERROR) { - err = makeFileResources(bundle, assets, &table, drawables, "drawable"); - if (err != NO_ERROR) { - hasErrors = true; - } - } else { - hasErrors = true; - } - } - - if (layouts != NULL) { - err = makeFileResources(bundle, assets, &table, layouts, "layout"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (anims != NULL) { - err = makeFileResources(bundle, assets, &table, anims, "anim"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (xmls != NULL) { - err = makeFileResources(bundle, assets, &table, xmls, "xml"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (raws != NULL) { - err = makeFileResources(bundle, assets, &table, raws, "raw"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - // compile resources - current = assets; - while(current.get()) { - KeyedVector<String8, sp<ResourceTypeSet> > *resources = - current->getResources(); - - ssize_t index = resources->indexOfKey(String8("values")); - if (index >= 0) { - ResourceDirIterator it(resources->valueAt(index), String8("values")); - ssize_t res; - while ((res=it.next()) == NO_ERROR) { - sp<AaptFile> file = it.getFile(); - res = compileResourceFile(bundle, assets, file, it.getParams(), - (current!=assets), &table); - if (res != NO_ERROR) { - hasErrors = true; - } - } - } - current = current->getOverlay(); - } - - if (colors != NULL) { - err = makeFileResources(bundle, assets, &table, colors, "color"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (menus != NULL) { - err = makeFileResources(bundle, assets, &table, menus, "menu"); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - // -------------------------------------------------------------------- - // Assignment of resource IDs and initial generation of resource table. - // -------------------------------------------------------------------- - - if (table.hasResources()) { - sp<AaptFile> resFile(getResourceFile(assets)); - if (resFile == NULL) { - fprintf(stderr, "Error: unable to generate entry for resource data\n"); - return UNKNOWN_ERROR; - } - - err = table.assignResourceIds(); - if (err < NO_ERROR) { - return err; - } - } - - // -------------------------------------------------------------- - // Finally, we can now we can compile XML files, which may reference - // resources. - // -------------------------------------------------------------- - - if (layouts != NULL) { - ResourceDirIterator it(layouts, String8("layout")); - while ((err=it.next()) == NO_ERROR) { - String8 src = it.getFile()->getPrintableSource(); - err = compileXmlFile(assets, it.getFile(), &table); - if (err == NO_ERROR) { - ResXMLTree block; - block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); - checkForIds(src, block); - } else { - hasErrors = true; - } - } - - if (err < NO_ERROR) { - hasErrors = true; - } - err = NO_ERROR; - } - - if (anims != NULL) { - ResourceDirIterator it(anims, String8("anim")); - while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (err < NO_ERROR) { - hasErrors = true; - } - err = NO_ERROR; - } - - if (xmls != NULL) { - ResourceDirIterator it(xmls, String8("xml")); - while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (err < NO_ERROR) { - hasErrors = true; - } - err = NO_ERROR; - } - - if (drawables != NULL) { - err = postProcessImages(assets, &table, drawables); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (colors != NULL) { - ResourceDirIterator it(colors, String8("color")); - while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - if (err < NO_ERROR) { - hasErrors = true; - } - err = NO_ERROR; - } - - if (menus != NULL) { - ResourceDirIterator it(menus, String8("menu")); - while ((err=it.next()) == NO_ERROR) { - String8 src = it.getFile()->getPrintableSource(); - err = compileXmlFile(assets, it.getFile(), &table); - if (err != NO_ERROR) { - hasErrors = true; - } - ResXMLTree block; - block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); - checkForIds(src, block); - } - - if (err < NO_ERROR) { - hasErrors = true; - } - err = NO_ERROR; - } - - const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0)); - String8 manifestPath(manifestFile->getPrintableSource()); - - // Perform a basic validation of the manifest file. This time we - // parse it with the comments intact, so that we can use them to - // generate java docs... so we are not going to write this one - // back out to the final manifest data. - err = compileXmlFile(assets, manifestFile, &table, - XML_COMPILE_ASSIGN_ATTRIBUTE_IDS - | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES); - if (err < NO_ERROR) { - return err; - } - ResXMLTree block; - block.setTo(manifestFile->getData(), manifestFile->getSize(), true); - String16 manifest16("manifest"); - String16 permission16("permission"); - String16 permission_group16("permission-group"); - String16 uses_permission16("uses-permission"); - String16 instrumentation16("instrumentation"); - String16 application16("application"); - String16 provider16("provider"); - String16 service16("service"); - String16 receiver16("receiver"); - String16 activity16("activity"); - String16 action16("action"); - String16 category16("category"); - String16 data16("scheme"); - const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789"; - const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; - const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$"; - const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:"; - const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;"; - const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+"; - const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-"; - ResXMLTree::event_code_t code; - sp<AaptSymbols> permissionSymbols; - sp<AaptSymbols> permissionGroupSymbols; - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code > ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::START_TAG) { - size_t len; - if (block.getElementNamespace(&len) != NULL) { - continue; - } - if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) { - if (validateAttr(manifestPath, block, NULL, "package", - packageIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0 - || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) { - const bool isGroup = strcmp16(block.getElementName(&len), - permission_group16.string()) == 0; - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - isGroup ? packageIdentCharsWithTheStupid - : packageIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - SourcePos srcPos(manifestPath, block.getLineNumber()); - sp<AaptSymbols> syms; - if (!isGroup) { - syms = permissionSymbols; - if (syms == NULL) { - sp<AaptSymbols> symbols = - assets->getSymbolsFor(String8("Manifest")); - syms = permissionSymbols = symbols->addNestedSymbol( - String8("permission"), srcPos); - } - } else { - syms = permissionGroupSymbols; - if (syms == NULL) { - sp<AaptSymbols> symbols = - assets->getSymbolsFor(String8("Manifest")); - syms = permissionGroupSymbols = symbols->addNestedSymbol( - String8("permission_group"), srcPos); - } - } - size_t len; - ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name"); - const uint16_t* id = block.getAttributeStringValue(index, &len); - if (id == NULL) { - fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", - manifestPath.string(), block.getLineNumber(), - String8(block.getElementName(&len)).string()); - hasErrors = true; - break; - } - String8 idStr(id); - char* p = idStr.lockBuffer(idStr.size()); - char* e = p + idStr.size(); - bool begins_with_digit = true; // init to true so an empty string fails - while (e > p) { - e--; - if (*e >= '0' && *e <= '9') { - begins_with_digit = true; - continue; - } - if ((*e >= 'a' && *e <= 'z') || - (*e >= 'A' && *e <= 'Z') || - (*e == '_')) { - begins_with_digit = false; - continue; - } - if (isGroup && (*e == '-')) { - *e = '_'; - begins_with_digit = false; - continue; - } - e++; - break; - } - idStr.unlockBuffer(); - // verify that we stopped because we hit a period or - // the beginning of the string, and that the - // identifier didn't begin with a digit. - if (begins_with_digit || (e != p && *(e-1) != '.')) { - fprintf(stderr, - "%s:%d: Permission name <%s> is not a valid Java symbol\n", - manifestPath.string(), block.getLineNumber(), idStr.string()); - hasErrors = true; - } - syms->addStringSymbol(String8(e), idStr, srcPos); - const uint16_t* cmt = block.getComment(&len); - if (cmt != NULL && *cmt != 0) { - //printf("Comment of %s: %s\n", String8(e).string(), - // String8(cmt).string()); - syms->appendComment(String8(e), String16(cmt), srcPos); - } else { - //printf("No comment for %s\n", String8(e).string()); - } - syms->makeSymbolPublic(String8(e), srcPos); - } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) { - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - packageIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) { - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - classIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "targetPackage", - packageIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) { - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - classIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "permission", - packageIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "process", - processIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "taskAffinity", - processIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) { - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - classIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "authorities", - authoritiesIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "permission", - packageIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "process", - processIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), service16.string()) == 0 - || strcmp16(block.getElementName(&len), receiver16.string()) == 0 - || strcmp16(block.getElementName(&len), activity16.string()) == 0) { - if (validateAttr(manifestPath, block, RESOURCES_ANDROID_NAMESPACE, "name", - classIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "permission", - packageIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "process", - processIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "taskAffinity", - processIdentChars, false) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), action16.string()) == 0 - || strcmp16(block.getElementName(&len), category16.string()) == 0) { - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "name", - packageIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) { - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "mimeType", - typeIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - if (validateAttr(manifestPath, block, - RESOURCES_ANDROID_NAMESPACE, "scheme", - schemeIdentChars, true) != ATTR_OKAY) { - hasErrors = true; - } - } - } - } - - if (table.validateLocalizations()) { - hasErrors = true; - } - - if (hasErrors) { - return UNKNOWN_ERROR; - } - - // Generate final compiled manifest file. - manifestFile->clearData(); - err = compileXmlFile(assets, manifestFile, &table); - if (err < NO_ERROR) { - return err; - } - - //block.restart(); - //printXMLBlock(&block); - - // -------------------------------------------------------------- - // Generate the final resource table. - // Re-flatten because we may have added new resource IDs - // -------------------------------------------------------------- - - if (table.hasResources()) { - sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); - err = table.addSymbols(symbols); - if (err < NO_ERROR) { - return err; - } - - sp<AaptFile> resFile(getResourceFile(assets)); - if (resFile == NULL) { - fprintf(stderr, "Error: unable to generate entry for resource data\n"); - return UNKNOWN_ERROR; - } - - err = table.flatten(bundle, resFile); - if (err < NO_ERROR) { - return err; - } - - if (bundle->getPublicOutputFile()) { - FILE* fp = fopen(bundle->getPublicOutputFile(), "w+"); - if (fp == NULL) { - fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n", - (const char*)bundle->getPublicOutputFile(), strerror(errno)); - return UNKNOWN_ERROR; - } - if (bundle->getVerbose()) { - printf(" Writing public definitions to %s.\n", bundle->getPublicOutputFile()); - } - table.writePublicDefinitions(String16(assets->getPackage()), fp); - } - - NOISY( - ResTable rt; - rt.add(resFile->getData(), resFile->getSize(), NULL); - printf("Generated resources:\n"); - rt.print(); - ) - - // These resources are now considered to be a part of the included - // resources, for others to reference. - err = assets->addIncludedResources(resFile); - if (err < NO_ERROR) { - fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n"); - return err; - } - } - - return err; -} - -static const char* getIndentSpace(int indent) -{ -static const char whitespace[] = -" "; - - return whitespace + sizeof(whitespace) - 1 - indent*4; -} - -static status_t fixupSymbol(String16* inoutSymbol) -{ - inoutSymbol->replaceAll('.', '_'); - inoutSymbol->replaceAll(':', '_'); - return NO_ERROR; -} - -static String16 getAttributeComment(const sp<AaptAssets>& assets, - const String8& name, - String16* outTypeComment = NULL) -{ - sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R")); - if (asym != NULL) { - //printf("Got R symbols!\n"); - asym = asym->getNestedSymbols().valueFor(String8("attr")); - if (asym != NULL) { - //printf("Got attrs symbols! comment %s=%s\n", - // name.string(), String8(asym->getComment(name)).string()); - if (outTypeComment != NULL) { - *outTypeComment = asym->getTypeComment(name); - } - return asym->getComment(name); - } - } - return String16(); -} - -static status_t writeLayoutClasses( - FILE* fp, const sp<AaptAssets>& assets, - const sp<AaptSymbols>& symbols, int indent, bool includePrivate) -{ - const char* indentStr = getIndentSpace(indent); - if (!includePrivate) { - fprintf(fp, "%s/** @doconly */\n", indentStr); - } - fprintf(fp, "%spublic static final class styleable {\n", indentStr); - indent++; - - String16 attr16("attr"); - String16 package16(assets->getPackage()); - - indentStr = getIndentSpace(indent); - bool hasErrors = false; - - size_t i; - size_t N = symbols->getNestedSymbols().size(); - for (i=0; i<N; i++) { - sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); - String16 nclassName16(symbols->getNestedSymbols().keyAt(i)); - String8 realClassName(nclassName16); - if (fixupSymbol(&nclassName16) != NO_ERROR) { - hasErrors = true; - } - String8 nclassName(nclassName16); - - SortedVector<uint32_t> idents; - Vector<uint32_t> origOrder; - Vector<bool> publicFlags; - - size_t a; - size_t NA = nsymbols->getSymbols().size(); - for (a=0; a<NA; a++) { - const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a)); - int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32 - ? sym.int32Val : 0; - bool isPublic = true; - if (code == 0) { - String16 name16(sym.name); - uint32_t typeSpecFlags; - code = assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); - if (code == 0) { - fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n", - nclassName.string(), sym.name.string()); - hasErrors = true; - } - isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; - } - idents.add(code); - origOrder.add(code); - publicFlags.add(isPublic); - } - - NA = idents.size(); - - String16 comment = symbols->getComment(realClassName); - fprintf(fp, "%s/** ", indentStr); - if (comment.size() > 0) { - fprintf(fp, "%s\n", String8(comment).string()); - } else { - fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string()); - } - bool hasTable = false; - for (a=0; a<NA; a++) { - ssize_t pos = idents.indexOf(origOrder.itemAt(a)); - if (pos >= 0) { - if (!hasTable) { - hasTable = true; - fprintf(fp, - "%s <p>Includes the following attributes:</p>\n" - "%s <table border=\"2\" width=\"85%%\" align=\"center\" frame=\"hsides\" rules=\"all\" cellpadding=\"5\">\n" - "%s <colgroup align=\"left\" />\n" - "%s <colgroup align=\"left\" />\n" - "%s <tr><th>Attribute<th>Summary</tr>\n", - indentStr, - indentStr, - indentStr, - indentStr, - indentStr); - } - const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); - if (!publicFlags.itemAt(a) && !includePrivate) { - continue; - } - String8 name8(sym.name); - String16 comment(sym.comment); - if (comment.size() <= 0) { - comment = getAttributeComment(assets, name8); - } - if (comment.size() > 0) { - const char16_t* p = comment.string(); - while (*p != 0 && *p != '.') { - if (*p == '{') { - while (*p != 0 && *p != '}') { - p++; - } - } else { - p++; - } - } - if (*p == '.') { - p++; - } - comment = String16(comment.string(), p-comment.string()); - } - String16 name(name8); - fixupSymbol(&name); - fprintf(fp, "%s <tr><th><code>{@link #%s_%s %s:%s}</code><td>%s</tr>\n", - indentStr, nclassName.string(), - String8(name).string(), - assets->getPackage().string(), - String8(name).string(), - String8(comment).string()); - } - } - if (hasTable) { - fprintf(fp, "%s </table>\n", indentStr); - } - for (a=0; a<NA; a++) { - ssize_t pos = idents.indexOf(origOrder.itemAt(a)); - if (pos >= 0) { - const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); - if (!publicFlags.itemAt(a) && !includePrivate) { - continue; - } - String16 name(sym.name); - fixupSymbol(&name); - fprintf(fp, "%s @see #%s_%s\n", - indentStr, nclassName.string(), - String8(name).string()); - } - } - fprintf(fp, "%s */\n", getIndentSpace(indent)); - - fprintf(fp, - "%spublic static final int[] %s = {\n" - "%s", - indentStr, nclassName.string(), - getIndentSpace(indent+1)); - - for (a=0; a<NA; a++) { - if (a != 0) { - if ((a&3) == 0) { - fprintf(fp, ",\n%s", getIndentSpace(indent+1)); - } else { - fprintf(fp, ", "); - } - } - fprintf(fp, "0x%08x", idents[a]); - } - - fprintf(fp, "\n%s};\n", indentStr); - - for (a=0; a<NA; a++) { - ssize_t pos = idents.indexOf(origOrder.itemAt(a)); - if (pos >= 0) { - const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a); - if (!publicFlags.itemAt(a) && !includePrivate) { - continue; - } - String8 name8(sym.name); - String16 comment(sym.comment); - String16 typeComment; - if (comment.size() <= 0) { - comment = getAttributeComment(assets, name8, &typeComment); - } else { - getAttributeComment(assets, name8, &typeComment); - } - String16 name(name8); - if (fixupSymbol(&name) != NO_ERROR) { - hasErrors = true; - } - - uint32_t typeSpecFlags = 0; - String16 name16(sym.name); - assets->getIncludedResources().identifierForName( - name16.string(), name16.size(), - attr16.string(), attr16.size(), - package16.string(), package16.size(), &typeSpecFlags); - //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(), - // String8(attr16).string(), String8(name16).string(), typeSpecFlags); - const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0; - - fprintf(fp, "%s/**\n", indentStr); - if (comment.size() > 0) { - fprintf(fp, "%s <p>\n%s @attr description\n", indentStr, indentStr); - fprintf(fp, "%s %s\n", indentStr, String8(comment).string()); - } else { - fprintf(fp, - "%s <p>This symbol is the offset where the {@link %s.R.attr#%s}\n" - "%s attribute's value can be found in the {@link #%s} array.\n", - indentStr, - pub ? assets->getPackage().string() - : assets->getSymbolsPrivatePackage().string(), - String8(name).string(), - indentStr, nclassName.string()); - } - if (typeComment.size() > 0) { - fprintf(fp, "\n\n%s %s\n", indentStr, String8(typeComment).string()); - } - if (comment.size() > 0) { - if (pub) { - fprintf(fp, - "%s <p>This corresponds to the global attribute" - "%s resource symbol {@link %s.R.attr#%s}.\n", - indentStr, indentStr, - assets->getPackage().string(), - String8(name).string()); - } else { - fprintf(fp, - "%s <p>This is a private symbol.\n", indentStr); - } - } - fprintf(fp, "%s @attr name %s:%s\n", indentStr, - "android", String8(name).string()); - fprintf(fp, "%s*/\n", indentStr); - fprintf(fp, - "%spublic static final int %s_%s = %d;\n", - indentStr, nclassName.string(), - String8(name).string(), (int)pos); - } - } - } - - indent--; - fprintf(fp, "%s};\n", getIndentSpace(indent)); - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -static status_t writeSymbolClass( - FILE* fp, const sp<AaptAssets>& assets, bool includePrivate, - const sp<AaptSymbols>& symbols, const String8& className, int indent) -{ - fprintf(fp, "%spublic %sfinal class %s {\n", - getIndentSpace(indent), - indent != 0 ? "static " : "", className.string()); - indent++; - - size_t i; - status_t err = NO_ERROR; - - size_t N = symbols->getSymbols().size(); - for (i=0; i<N; i++) { - const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); - if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { - continue; - } - if (!includePrivate && !sym.isPublic) { - continue; - } - String16 name(sym.name); - String8 realName(name); - if (fixupSymbol(&name) != NO_ERROR) { - return UNKNOWN_ERROR; - } - String16 comment(sym.comment); - bool haveComment = false; - if (comment.size() > 0) { - haveComment = true; - fprintf(fp, - "%s/** %s\n", - getIndentSpace(indent), String8(comment).string()); - } else if (sym.isPublic && !includePrivate) { - sym.sourcePos.warning("No comment for public symbol %s:%s/%s", - assets->getPackage().string(), className.string(), - String8(sym.name).string()); - } - String16 typeComment(sym.typeComment); - if (typeComment.size() > 0) { - if (!haveComment) { - haveComment = true; - fprintf(fp, - "%s/** %s\n", - getIndentSpace(indent), String8(typeComment).string()); - } else { - fprintf(fp, - "%s %s\n", - getIndentSpace(indent), String8(typeComment).string()); - } - } - if (haveComment) { - fprintf(fp,"%s */\n", getIndentSpace(indent)); - } - fprintf(fp, "%spublic static final int %s=0x%08x;\n", - getIndentSpace(indent), - String8(name).string(), (int)sym.int32Val); - } - - for (i=0; i<N; i++) { - const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i); - if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) { - continue; - } - if (!includePrivate && !sym.isPublic) { - continue; - } - String16 name(sym.name); - if (fixupSymbol(&name) != NO_ERROR) { - return UNKNOWN_ERROR; - } - String16 comment(sym.comment); - if (comment.size() > 0) { - fprintf(fp, - "%s/** %s\n" - "%s */\n", - getIndentSpace(indent), String8(comment).string(), - getIndentSpace(indent)); - } else if (sym.isPublic && !includePrivate) { - sym.sourcePos.warning("No comment for public symbol %s:%s/%s", - assets->getPackage().string(), className.string(), - String8(sym.name).string()); - } - fprintf(fp, "%spublic static final String %s=\"%s\";\n", - getIndentSpace(indent), - String8(name).string(), sym.stringVal.string()); - } - - sp<AaptSymbols> styleableSymbols; - - N = symbols->getNestedSymbols().size(); - for (i=0; i<N; i++) { - sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i); - String8 nclassName(symbols->getNestedSymbols().keyAt(i)); - if (nclassName == "styleable") { - styleableSymbols = nsymbols; - } else { - err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent); - } - if (err != NO_ERROR) { - return err; - } - } - - if (styleableSymbols != NULL) { - err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate); - if (err != NO_ERROR) { - return err; - } - } - - indent--; - fprintf(fp, "%s}\n", getIndentSpace(indent)); - return NO_ERROR; -} - -status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, - const String8& package, bool includePrivate) -{ - if (!bundle->getRClassDir()) { - return NO_ERROR; - } - - const size_t N = assets->getSymbols().size(); - for (size_t i=0; i<N; i++) { - sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i); - String8 className(assets->getSymbols().keyAt(i)); - String8 dest(bundle->getRClassDir()); - if (bundle->getMakePackageDirs()) { - String8 pkg(package); - const char* last = pkg.string(); - const char* s = last-1; - do { - s++; - if (s > last && (*s == '.' || *s == 0)) { - String8 part(last, s-last); - dest.appendPath(part); -#ifdef HAVE_MS_C_RUNTIME - _mkdir(dest.string()); -#else - mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); -#endif - last = s+1; - } - } while (*s); - } - dest.appendPath(className); - dest.append(".java"); - FILE* fp = fopen(dest.string(), "w+"); - if (fp == NULL) { - fprintf(stderr, "ERROR: Unable to open class file %s: %s\n", - dest.string(), strerror(errno)); - return UNKNOWN_ERROR; - } - if (bundle->getVerbose()) { - printf(" Writing symbols for class %s.\n", className.string()); - } - - fprintf(fp, - "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" - " *\n" - " * This class was automatically generated by the\n" - " * aapt tool from the resource data it found. It\n" - " * should not be modified by hand.\n" - " */\n" - "\n" - "package %s;\n\n", package.string()); - - status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0); - if (err != NO_ERROR) { - return err; - } - fclose(fp); - } - - return NO_ERROR; -} diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp deleted file mode 100644 index 6f71a1e..0000000 --- a/tools/aapt/ResourceTable.cpp +++ /dev/null @@ -1,3491 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#include "ResourceTable.h" - -#include "XMLNode.h" - -#include <utils/ByteOrder.h> -#include <utils/ResourceTypes.h> -#include <stdarg.h> - -#define NOISY(x) //x - -status_t compileXmlFile(const sp<AaptAssets>& assets, - const sp<AaptFile>& target, - ResourceTable* table, - int options) -{ - sp<XMLNode> root = XMLNode::parse(target); - if (root == NULL) { - return UNKNOWN_ERROR; - } - if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { - root->removeWhitespace(true, NULL); - } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { - root->removeWhitespace(false, NULL); - } - - bool hasErrors = false; - - if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { - status_t err = root->assignResourceIds(assets, table); - if (err != NO_ERROR) { - hasErrors = true; - } - } - - status_t err = root->parseValues(assets, table); - if (err != NO_ERROR) { - hasErrors = true; - } - - if (hasErrors) { - return UNKNOWN_ERROR; - } - - NOISY(printf("Input XML Resource:\n")); - NOISY(root->print()); - err = root->flatten(target, - (options&XML_COMPILE_STRIP_COMMENTS) != 0, - (options&XML_COMPILE_STRIP_RAW_VALUES) != 0); - if (err != NO_ERROR) { - return err; - } - - NOISY(printf("Output XML Resource:\n")); - NOISY(ResXMLTree tree; - tree.setTo(target->getData(), target->getSize()); - printXMLBlock(&tree)); - - target->setCompressionMethod(ZipEntry::kCompressDeflated); - - return err; -} - -#undef NOISY -#define NOISY(x) //x - -struct flag_entry -{ - const char16_t* name; - size_t nameLen; - uint32_t value; - const char* description; -}; - -static const char16_t referenceArray[] = - { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' }; -static const char16_t stringArray[] = - { 's', 't', 'r', 'i', 'n', 'g' }; -static const char16_t integerArray[] = - { 'i', 'n', 't', 'e', 'g', 'e', 'r' }; -static const char16_t booleanArray[] = - { 'b', 'o', 'o', 'l', 'e', 'a', 'n' }; -static const char16_t colorArray[] = - { 'c', 'o', 'l', 'o', 'r' }; -static const char16_t floatArray[] = - { 'f', 'l', 'o', 'a', 't' }; -static const char16_t dimensionArray[] = - { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' }; -static const char16_t fractionArray[] = - { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' }; -static const char16_t enumArray[] = - { 'e', 'n', 'u', 'm' }; -static const char16_t flagsArray[] = - { 'f', 'l', 'a', 'g', 's' }; - -static const flag_entry gFormatFlags[] = { - { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE, - "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n" - "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."}, - { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING, - "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." }, - { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER, - "an integer value, such as \"<code>100</code>\"." }, - { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN, - "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." }, - { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR, - "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n" - "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." }, - { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT, - "a floating point value, such as \"<code>1.2</code>\"."}, - { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION, - "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n" - "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n" - "in (inches), mm (millimeters)." }, - { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION, - "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n" - "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n" - "some parent container." }, - { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL }, - { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL }, - { NULL, 0, 0, NULL } -}; - -static const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' }; - -static const flag_entry l10nRequiredFlags[] = { - { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL }, - { NULL, 0, 0, NULL } -}; - -static const char16_t nulStr[] = { 0 }; - -static uint32_t parse_flags(const char16_t* str, size_t len, - const flag_entry* flags, bool* outError = NULL) -{ - while (len > 0 && isspace(*str)) { - str++; - len--; - } - while (len > 0 && isspace(str[len-1])) { - len--; - } - - const char16_t* const end = str + len; - uint32_t value = 0; - - while (str < end) { - const char16_t* div = str; - while (div < end && *div != '|') { - div++; - } - - const flag_entry* cur = flags; - while (cur->name) { - if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) { - value |= cur->value; - break; - } - cur++; - } - - if (!cur->name) { - if (outError) *outError = true; - return 0; - } - - str = div < end ? div+1 : div; - } - - if (outError) *outError = false; - return value; -} - -static String16 mayOrMust(int type, int flags) -{ - if ((type&(~flags)) == 0) { - return String16("<p>Must"); - } - - return String16("<p>May"); -} - -static void appendTypeInfo(ResourceTable* outTable, const String16& pkg, - const String16& typeName, const String16& ident, int type, - const flag_entry* flags) -{ - bool hadType = false; - while (flags->name) { - if ((type&flags->value) != 0 && flags->description != NULL) { - String16 fullMsg(mayOrMust(type, flags->value)); - fullMsg.append(String16(" be ")); - fullMsg.append(String16(flags->description)); - outTable->appendTypeComment(pkg, typeName, ident, fullMsg); - hadType = true; - } - flags++; - } - if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) { - outTable->appendTypeComment(pkg, typeName, ident, - String16("<p>This may also be a reference to a resource (in the form\n" - "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n" - "theme attribute (in the form\n" - "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n" - "containing a value of this type.")); - } -} - -struct PendingAttribute -{ - const String16 myPackage; - const SourcePos sourcePos; - const bool appendComment; - int32_t type; - String16 ident; - String16 comment; - bool hasErrors; - bool added; - - PendingAttribute(String16 _package, const sp<AaptFile>& in, - ResXMLTree& block, bool _appendComment) - : myPackage(_package) - , sourcePos(in->getPrintableSource(), block.getLineNumber()) - , appendComment(_appendComment) - , type(ResTable_map::TYPE_ANY) - , hasErrors(false) - , added(false) - { - } - - status_t createIfNeeded(ResourceTable* outTable) - { - if (added || hasErrors) { - return NO_ERROR; - } - added = true; - - String16 attr16("attr"); - - if (outTable->hasBagOrEntry(myPackage, attr16, ident)) { - sourcePos.error("Attribute \"%s\" has already been defined\n", - String8(ident).string()); - hasErrors = true; - return UNKNOWN_ERROR; - } - - char numberStr[16]; - sprintf(numberStr, "%d", type); - status_t err = outTable->addBag(sourcePos, myPackage, - attr16, ident, String16(""), - String16("^type"), - String16(numberStr), NULL, NULL); - if (err != NO_ERROR) { - hasErrors = true; - return err; - } - outTable->appendComment(myPackage, attr16, ident, comment, appendComment); - //printf("Attribute %s comment: %s\n", String8(ident).string(), - // String8(comment).string()); - return err; - } -}; - -static status_t compileAttribute(const sp<AaptFile>& in, - ResXMLTree& block, - const String16& myPackage, - ResourceTable* outTable, - String16* outIdent = NULL, - bool inStyleable = false) -{ - PendingAttribute attr(myPackage, in, block, inStyleable); - - const String16 attr16("attr"); - const String16 id16("id"); - - // Attribute type constants. - const String16 enum16("enum"); - const String16 flag16("flag"); - - ResXMLTree::event_code_t code; - size_t len; - status_t err; - - ssize_t identIdx = block.indexOfAttribute(NULL, "name"); - if (identIdx >= 0) { - attr.ident = String16(block.getAttributeStringValue(identIdx, &len)); - if (outIdent) { - *outIdent = attr.ident; - } - } else { - attr.sourcePos.error("A 'name' attribute is required for <attr>\n"); - attr.hasErrors = true; - } - - attr.comment = String16( - block.getComment(&len) ? block.getComment(&len) : nulStr); - - ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); - if (typeIdx >= 0) { - String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); - attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); - if (attr.type == 0) { - attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", - String8(typeStr).string()); - attr.hasErrors = true; - } - attr.createIfNeeded(outTable); - } else if (!inStyleable) { - // Attribute definitions outside of styleables always define the - // attribute as a generic value. - attr.createIfNeeded(outTable); - } - - //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); - - ssize_t minIdx = block.indexOfAttribute(NULL, "min"); - if (minIdx >= 0) { - String16 val = String16(block.getAttributeStringValue(minIdx, &len)); - if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { - attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", - String8(val).string()); - attr.hasErrors = true; - } - attr.createIfNeeded(outTable); - if (!attr.hasErrors) { - err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, - String16(""), String16("^min"), String16(val), NULL, NULL); - if (err != NO_ERROR) { - attr.hasErrors = true; - } - } - } - - ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); - if (maxIdx >= 0) { - String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); - if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { - attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", - String8(val).string()); - attr.hasErrors = true; - } - attr.createIfNeeded(outTable); - if (!attr.hasErrors) { - err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, - String16(""), String16("^max"), String16(val), NULL, NULL); - attr.hasErrors = true; - } - } - - if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) { - attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n"); - attr.hasErrors = true; - } - - ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization"); - if (l10nIdx >= 0) { - const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len); - bool error; - uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); - if (error) { - attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", - String8(str).string()); - attr.hasErrors = true; - } - attr.createIfNeeded(outTable); - if (!attr.hasErrors) { - char buf[10]; - sprintf(buf, "%d", l10n_required); - err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, - String16(""), String16("^l10n"), String16(buf), NULL, NULL); - if (err != NO_ERROR) { - attr.hasErrors = true; - } - } - } - - String16 enumOrFlagsComment; - - while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::START_TAG) { - uint32_t localType = 0; - if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { - localType = ResTable_map::TYPE_ENUM; - } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { - localType = ResTable_map::TYPE_FLAGS; - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - - attr.createIfNeeded(outTable); - - if (attr.type == ResTable_map::TYPE_ANY) { - // No type was explicitly stated, so supplying enum tags - // implicitly creates an enum or flag. - attr.type = 0; - } - - if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) { - // Wasn't originally specified as an enum, so update its type. - attr.type |= localType; - if (!attr.hasErrors) { - char numberStr[16]; - sprintf(numberStr, "%d", attr.type); - err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), - myPackage, attr16, attr.ident, String16(""), - String16("^type"), String16(numberStr), NULL, NULL, true); - if (err != NO_ERROR) { - attr.hasErrors = true; - } - } - } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) { - if (localType == ResTable_map::TYPE_ENUM) { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("<enum> attribute can not be used inside a flags format\n"); - attr.hasErrors = true; - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("<flag> attribute can not be used inside a enum format\n"); - attr.hasErrors = true; - } - } - - String16 itemIdent; - ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); - if (itemIdentIdx >= 0) { - itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("A 'name' attribute is required for <enum> or <flag>\n"); - attr.hasErrors = true; - } - - String16 value; - ssize_t valueIdx = block.indexOfAttribute(NULL, "value"); - if (valueIdx >= 0) { - value = String16(block.getAttributeStringValue(valueIdx, &len)); - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("A 'value' attribute is required for <enum> or <flag>\n"); - attr.hasErrors = true; - } - if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("Tag <enum> or <flag> 'value' attribute must be a number," - " not \"%s\"\n", - String8(value).string()); - attr.hasErrors = true; - } - - // Make sure an id is defined for this enum/flag identifier... - if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) { - err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), - myPackage, id16, itemIdent, String16(), NULL); - if (err != NO_ERROR) { - attr.hasErrors = true; - } - } - - if (!attr.hasErrors) { - if (enumOrFlagsComment.size() == 0) { - enumOrFlagsComment.append(mayOrMust(attr.type, - ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)); - enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM) - ? String16(" be one of the following constant values.") - : String16(" be one or more (separated by '|') of the following constant values.")); - enumOrFlagsComment.append(String16("</p>\n<table border=\"2\" width=\"85%\" align=\"center\" frame=\"hsides\" rules=\"all\" cellpadding=\"5\">\n" - "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<tr><th>Constant<th>Value<th>Description</tr>")); - } - - enumOrFlagsComment.append(String16("\n<tr><th><code>")); - enumOrFlagsComment.append(itemIdent); - enumOrFlagsComment.append(String16("</code><td>")); - enumOrFlagsComment.append(value); - enumOrFlagsComment.append(String16("<td>")); - if (block.getComment(&len)) { - enumOrFlagsComment.append(String16(block.getComment(&len))); - } - enumOrFlagsComment.append(String16("</tr>")); - - err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), - myPackage, - attr16, attr.ident, String16(""), - itemIdent, value, NULL, NULL, false, true); - if (err != NO_ERROR) { - attr.hasErrors = true; - } - } - } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { - break; - } - if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { - if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("Found tag </%s> where </enum> is expected\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - } else { - if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()) - .error("Found tag </%s> where </flag> is expected\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - } - } - } - - if (!attr.hasErrors && attr.added) { - appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags); - } - - if (!attr.hasErrors && enumOrFlagsComment.size() > 0) { - enumOrFlagsComment.append(String16("\n</table>")); - outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment); - } - - - return NO_ERROR; -} - -bool localeIsDefined(const ResTable_config& config) -{ - return config.locale == 0; -} - -status_t parseAndAddBag(Bundle* bundle, - const sp<AaptFile>& in, - ResXMLTree* block, - const ResTable_config& config, - const String16& myPackage, - const String16& curType, - const String16& ident, - const String16& parentIdent, - const String16& itemIdent, - int32_t curFormat, - bool pseudolocalize, - const bool overwrite, - ResourceTable* outTable) -{ - status_t err; - const String16 item16("item"); - - String16 str; - Vector<StringPool::entry_style_span> spans; - err = parseStyledString(bundle, in->getPrintableSource().string(), - block, item16, &str, &spans, - pseudolocalize); - if (err != NO_ERROR) { - return err; - } - - NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d " - " pid=%s, bag=%s, id=%s: %s\n", - config.language[0], config.language[1], - config.country[0], config.country[1], - config.orientation, config.density, - String8(parentIdent).string(), - String8(ident).string(), - String8(itemIdent).string(), - String8(str).string())); - - err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), - myPackage, curType, ident, parentIdent, itemIdent, str, - &spans, &config, overwrite, false, curFormat); - return err; -} - - -status_t parseAndAddEntry(Bundle* bundle, - const sp<AaptFile>& in, - ResXMLTree* block, - const ResTable_config& config, - const String16& myPackage, - const String16& curType, - const String16& ident, - const String16& curTag, - bool curIsStyled, - int32_t curFormat, - bool pseudolocalize, - const bool overwrite, - ResourceTable* outTable) -{ - status_t err; - - String16 str; - Vector<StringPool::entry_style_span> spans; - err = parseStyledString(bundle, in->getPrintableSource().string(), block, - curTag, &str, curIsStyled ? &spans : NULL, - pseudolocalize); - - if (err < NO_ERROR) { - return err; - } - - NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n", - config.language[0], config.language[1], - config.country[0], config.country[1], - config.orientation, config.density, - String8(ident).string(), String8(str).string())); - - err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), - myPackage, curType, ident, str, &spans, &config, - false, curFormat, overwrite); - - return err; -} - -status_t compileResourceFile(Bundle* bundle, - const sp<AaptAssets>& assets, - const sp<AaptFile>& in, - const ResTable_config& defParams, - const bool overwrite, - ResourceTable* outTable) -{ - ResXMLTree block; - status_t err = parseXMLResource(in, &block, false, true); - if (err != NO_ERROR) { - return err; - } - - // Top-level tag. - const String16 resources16("resources"); - - // Identifier declaration tags. - const String16 declare_styleable16("declare-styleable"); - const String16 attr16("attr"); - - // Data creation organizational tags. - const String16 string16("string"); - const String16 drawable16("drawable"); - const String16 color16("color"); - const String16 bool16("bool"); - const String16 integer16("integer"); - const String16 dimen16("dimen"); - const String16 fraction16("fraction"); - const String16 style16("style"); - const String16 plurals16("plurals"); - const String16 array16("array"); - const String16 string_array16("string-array"); - const String16 integer_array16("integer-array"); - const String16 public16("public"); - const String16 private_symbols16("private-symbols"); - const String16 skip16("skip"); - const String16 eat_comment16("eat-comment"); - - // Data creation tags. - const String16 bag16("bag"); - const String16 item16("item"); - - // Attribute type constants. - const String16 enum16("enum"); - - // plural values - const String16 other16("other"); - const String16 quantityOther16("^other"); - const String16 zero16("zero"); - const String16 quantityZero16("^zero"); - const String16 one16("one"); - const String16 quantityOne16("^one"); - const String16 two16("two"); - const String16 quantityTwo16("^two"); - const String16 few16("few"); - const String16 quantityFew16("^few"); - const String16 many16("many"); - const String16 quantityMany16("^many"); - - // useful attribute names and special values - const String16 name16("name"); - const String16 translatable16("translatable"); - const String16 false16("false"); - - const String16 myPackage(assets->getPackage()); - - bool hasErrors = false; - - uint32_t nextPublicId = 0; - - ResXMLTree::event_code_t code; - do { - code = block.next(); - } while (code == ResXMLTree::START_NAMESPACE); - - size_t len; - if (code != ResXMLTree::START_TAG) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "No start tag found\n"); - return UNKNOWN_ERROR; - } - if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - - ResTable_config curParams(defParams); - - ResTable_config pseudoParams(curParams); - pseudoParams.language[0] = 'z'; - pseudoParams.language[1] = 'z'; - pseudoParams.country[0] = 'Z'; - pseudoParams.country[1] = 'Z'; - - while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::START_TAG) { - const String16* curTag = NULL; - String16 curType; - int32_t curFormat = ResTable_map::TYPE_ANY; - bool curIsBag = false; - bool curIsStyled = false; - bool curIsPseudolocalizable = false; - bool localHasErrors = false; - - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { - break; - } - } - } - continue; - - } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { - break; - } - } - } - continue; - - } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { - SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); - - String16 type; - ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); - if (typeIdx < 0) { - srcPos.error("A 'type' attribute is required for <public>\n"); - hasErrors = localHasErrors = true; - } - type = String16(block.getAttributeStringValue(typeIdx, &len)); - - String16 name; - ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); - if (nameIdx < 0) { - srcPos.error("A 'name' attribute is required for <public>\n"); - hasErrors = localHasErrors = true; - } - name = String16(block.getAttributeStringValue(nameIdx, &len)); - - uint32_t ident = 0; - ssize_t identIdx = block.indexOfAttribute(NULL, "id"); - if (identIdx >= 0) { - const char16_t* identStr = block.getAttributeStringValue(identIdx, &len); - Res_value identValue; - if (!ResTable::stringToInt(identStr, len, &identValue)) { - srcPos.error("Given 'id' attribute is not an integer: %s\n", - String8(block.getAttributeStringValue(identIdx, &len)).string()); - hasErrors = localHasErrors = true; - } else { - ident = identValue.data; - nextPublicId = ident+1; - } - } else if (nextPublicId == 0) { - srcPos.error("No 'id' attribute supplied <public>," - " and no previous id defined in this file.\n"); - hasErrors = localHasErrors = true; - } else if (!localHasErrors) { - ident = nextPublicId; - nextPublicId++; - } - - if (!localHasErrors) { - err = outTable->addPublic(srcPos, myPackage, type, name, ident); - if (err < NO_ERROR) { - hasErrors = localHasErrors = true; - } - } - if (!localHasErrors) { - sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); - if (symbols != NULL) { - symbols = symbols->addNestedSymbol(String8(type), srcPos); - } - if (symbols != NULL) { - symbols->makeSymbolPublic(String8(name), srcPos); - String16 comment( - block.getComment(&len) ? block.getComment(&len) : nulStr); - symbols->appendComment(String8(name), comment, srcPos); - } else { - srcPos.error("Unable to create symbols!\n"); - hasErrors = localHasErrors = true; - } - } - - while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), public16.string()) == 0) { - break; - } - } - } - continue; - - } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { - String16 pkg; - ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); - if (pkgIdx < 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'package' attribute is required for <private-symbols>\n"); - hasErrors = localHasErrors = true; - } - pkg = String16(block.getAttributeStringValue(pkgIdx, &len)); - if (!localHasErrors) { - assets->setSymbolsPrivatePackage(String8(pkg)); - } - - while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { - break; - } - } - } - continue; - - } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { - SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); - - String16 ident; - ssize_t identIdx = block.indexOfAttribute(NULL, "name"); - if (identIdx < 0) { - srcPos.error("A 'name' attribute is required for <declare-styleable>\n"); - hasErrors = localHasErrors = true; - } - ident = String16(block.getAttributeStringValue(identIdx, &len)); - - sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); - if (!localHasErrors) { - if (symbols != NULL) { - symbols = symbols->addNestedSymbol(String8("styleable"), srcPos); - } - sp<AaptSymbols> styleSymbols = symbols; - if (symbols != NULL) { - symbols = symbols->addNestedSymbol(String8(ident), srcPos); - } - if (symbols == NULL) { - srcPos.error("Unable to create symbols!\n"); - return UNKNOWN_ERROR; - } - - String16 comment( - block.getComment(&len) ? block.getComment(&len) : nulStr); - styleSymbols->appendComment(String8(ident), comment, srcPos); - } else { - symbols = NULL; - } - - while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::START_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { - break; - } - } - } - continue; - } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { - break; - } - } - } - continue; - } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - - String16 comment( - block.getComment(&len) ? block.getComment(&len) : nulStr); - String16 itemIdent; - err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true); - if (err != NO_ERROR) { - hasErrors = localHasErrors = true; - } - - if (symbols != NULL) { - SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); - symbols->addSymbol(String8(itemIdent), 0, srcPos); - symbols->appendComment(String8(itemIdent), comment, srcPos); - //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), - // String8(comment).string()); - } - } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { - break; - } - - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Found tag </%s> where </attr> is expected\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - } - continue; - - } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { - err = compileAttribute(in, block, myPackage, outTable, NULL); - if (err != NO_ERROR) { - hasErrors = true; - } - continue; - - } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { - curTag = &item16; - ssize_t attri = block.indexOfAttribute(NULL, "type"); - if (attri >= 0) { - curType = String16(block.getAttributeStringValue(attri, &len)); - ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); - if (formatIdx >= 0) { - String16 formatStr = String16(block.getAttributeStringValue( - formatIdx, &len)); - curFormat = parse_flags(formatStr.string(), formatStr.size(), - gFormatFlags); - if (curFormat == 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Tag <item> 'format' attribute value \"%s\" not valid\n", - String8(formatStr).string()); - hasErrors = localHasErrors = true; - } - } - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'type' attribute is required for <item>\n"); - hasErrors = localHasErrors = true; - } - curIsStyled = true; - } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { - // Note the existence and locale of every string we process - char rawLocale[16]; - curParams.getLocale(rawLocale); - String8 locale(rawLocale); - String16 name; - String16 translatable; - - size_t n = block.getAttributeCount(); - for (size_t i = 0; i < n; i++) { - size_t length; - const uint16_t* attr = block.getAttributeName(i, &length); - if (strcmp16(attr, name16.string()) == 0) { - name.setTo(block.getAttributeStringValue(i, &length)); - } else if (strcmp16(attr, translatable16.string()) == 0) { - translatable.setTo(block.getAttributeStringValue(i, &length)); - } - } - - if (name.size() > 0) { - if (translatable == false16) { - // Untranslatable strings must only exist in the default [empty] locale - if (locale.size() > 0) { - fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists" - " in locale '%s'\n", String8(name).string(), - bundle->getResourceSourceDirs()[0], - locale.string()); - // hasErrors = localHasErrors = true; - } else { - // Intentionally empty block: - // - // Don't add untranslatable strings to the localization table; that - // way if we later see localizations of them, they'll be flagged as - // having no default translation. - } - } else { - outTable->addLocalization(name, locale); - } - } - - curTag = &string16; - curType = string16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; - curIsStyled = true; - curIsPseudolocalizable = true; - } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { - curTag = &drawable16; - curType = drawable16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; - } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { - curTag = &color16; - curType = color16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; - } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { - curTag = &bool16; - curType = bool16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; - } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { - curTag = &integer16; - curType = integer16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; - } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { - curTag = &dimen16; - curType = dimen16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; - } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { - curTag = &fraction16; - curType = fraction16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; - } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { - curTag = &bag16; - curIsBag = true; - ssize_t attri = block.indexOfAttribute(NULL, "type"); - if (attri >= 0) { - curType = String16(block.getAttributeStringValue(attri, &len)); - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'type' attribute is required for <bag>\n"); - hasErrors = localHasErrors = true; - } - } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { - curTag = &style16; - curType = style16; - curIsBag = true; - } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { - curTag = &plurals16; - curType = plurals16; - curIsBag = true; - } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { - curTag = &array16; - curType = array16; - curIsBag = true; - ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); - if (formatIdx >= 0) { - String16 formatStr = String16(block.getAttributeStringValue( - formatIdx, &len)); - curFormat = parse_flags(formatStr.string(), formatStr.size(), - gFormatFlags); - if (curFormat == 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Tag <array> 'format' attribute value \"%s\" not valid\n", - String8(formatStr).string()); - hasErrors = localHasErrors = true; - } - } - } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { - curTag = &string_array16; - curType = array16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; - curIsBag = true; - curIsPseudolocalizable = true; - } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { - curTag = &integer_array16; - curType = array16; - curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; - curIsBag = true; - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Found tag %s where item is expected\n", - String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - - String16 ident; - ssize_t identIdx = block.indexOfAttribute(NULL, "name"); - if (identIdx >= 0) { - ident = String16(block.getAttributeStringValue(identIdx, &len)); - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'name' attribute is required for <%s>\n", - String8(*curTag).string()); - hasErrors = localHasErrors = true; - } - - String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); - - if (curIsBag) { - // Figure out the parent of this bag... - String16 parentIdent; - ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent"); - if (parentIdentIdx >= 0) { - parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len)); - } else { - ssize_t sep = ident.findLast('.'); - if (sep >= 0) { - parentIdent.setTo(ident, sep); - } - } - - if (!localHasErrors) { - err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), - myPackage, curType, ident, parentIdent, &curParams); - if (err != NO_ERROR) { - hasErrors = localHasErrors = true; - } - } - - ssize_t elmIndex = 0; - char elmIndexStr[14]; - while ((code=block.next()) != ResXMLTree::END_DOCUMENT - && code != ResXMLTree::BAD_DOCUMENT) { - - if (code == ResXMLTree::START_TAG) { - if (strcmp16(block.getElementName(&len), item16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Tag <%s> can not appear inside <%s>, only <item>\n", - String8(block.getElementName(&len)).string(), - String8(*curTag).string()); - return UNKNOWN_ERROR; - } - - String16 itemIdent; - if (curType == array16) { - sprintf(elmIndexStr, "^index_%d", (int)elmIndex++); - itemIdent = String16(elmIndexStr); - } else if (curType == plurals16) { - ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity"); - if (itemIdentIdx >= 0) { - String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len)); - if (quantity16 == other16) { - itemIdent = quantityOther16; - } - else if (quantity16 == zero16) { - itemIdent = quantityZero16; - } - else if (quantity16 == one16) { - itemIdent = quantityOne16; - } - else if (quantity16 == two16) { - itemIdent = quantityTwo16; - } - else if (quantity16 == few16) { - itemIdent = quantityFew16; - } - else if (quantity16 == many16) { - itemIdent = quantityMany16; - } - else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Illegal 'quantity' attribute is <item> inside <plurals>\n"); - hasErrors = localHasErrors = true; - } - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'quantity' attribute is required for <item> inside <plurals>\n"); - hasErrors = localHasErrors = true; - } - } else { - ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); - if (itemIdentIdx >= 0) { - itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); - } else { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "A 'name' attribute is required for <item>\n"); - hasErrors = localHasErrors = true; - } - } - - ResXMLParser::ResXMLPosition parserPosition; - block.getPosition(&parserPosition); - - err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, - ident, parentIdent, itemIdent, curFormat, - false, overwrite, outTable); - if (err == NO_ERROR) { - if (curIsPseudolocalizable && localeIsDefined(curParams) - && bundle->getPseudolocalize()) { - // pseudolocalize here -#if 1 - block.setPosition(parserPosition); - err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, - curType, ident, parentIdent, itemIdent, curFormat, true, - overwrite, outTable); -#endif - } - } - if (err != NO_ERROR) { - hasErrors = localHasErrors = true; - } - } else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Found tag </%s> where </%s> is expected\n", - String8(block.getElementName(&len)).string(), - String8(*curTag).string()); - return UNKNOWN_ERROR; - } - break; - } - } - } else { - ResXMLParser::ResXMLPosition parserPosition; - block.getPosition(&parserPosition); - - err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, - *curTag, curIsStyled, curFormat, false, overwrite, outTable); - - if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? - hasErrors = localHasErrors = true; - } - else if (err == NO_ERROR) { - if (curIsPseudolocalizable && localeIsDefined(curParams) - && bundle->getPseudolocalize()) { - // pseudolocalize here - block.setPosition(parserPosition); - err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, - ident, *curTag, curIsStyled, curFormat, true, false, outTable); - if (err != NO_ERROR) { - hasErrors = localHasErrors = true; - } - } - } - } - -#if 0 - if (comment.size() > 0) { - printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), - String8(curType).string(), String8(ident).string(), - String8(comment).string()); - } -#endif - if (!localHasErrors) { - outTable->appendComment(myPackage, curType, ident, comment, false); - } - } - else if (code == ResXMLTree::END_TAG) { - if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); - return UNKNOWN_ERROR; - } - } - else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) { - } - else if (code == ResXMLTree::TEXT) { - if (isWhitespace(block.getText(&len))) { - continue; - } - SourcePos(in->getPrintableSource(), block.getLineNumber()).error( - "Found text \"%s\" where item tag is expected\n", - String8(block.getText(&len)).string()); - return UNKNOWN_ERROR; - } - } - - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage) - : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false), - mIsAppPackage(!bundle->getExtending()), - mNumLocal(0), - mBundle(bundle) -{ -} - -status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets) -{ - status_t err = assets->buildIncludedResources(bundle); - if (err != NO_ERROR) { - return err; - } - - // For future reference to included resources. - mAssets = assets; - - const ResTable& incl = assets->getIncludedResources(); - - // Retrieve all the packages. - const size_t N = incl.getBasePackageCount(); - for (size_t phase=0; phase<2; phase++) { - for (size_t i=0; i<N; i++) { - String16 name(incl.getBasePackageName(i)); - uint32_t id = incl.getBasePackageId(i); - // First time through: only add base packages (id - // is not 0); second time through add the other - // packages. - if (phase != 0) { - if (id != 0) { - // Skip base packages -- already one. - id = 0; - } else { - // Assign a dynamic id. - id = mNextPackageId; - } - } else if (id != 0) { - if (id == 127) { - if (mHaveAppPackage) { - fprintf(stderr, "Included resource have two application packages!\n"); - return UNKNOWN_ERROR; - } - mHaveAppPackage = true; - } - if (mNextPackageId > id) { - fprintf(stderr, "Included base package ID %d already in use!\n", id); - return UNKNOWN_ERROR; - } - } - if (id != 0) { - NOISY(printf("Including package %s with ID=%d\n", - String8(name).string(), id)); - sp<Package> p = new Package(name, id); - mPackages.add(name, p); - mOrderedPackages.add(p); - - if (id >= mNextPackageId) { - mNextPackageId = id+1; - } - } - } - } - - // Every resource table always has one first entry, the bag attributes. - const SourcePos unknown(String8("????"), 0); - sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown); - - return NO_ERROR; -} - -status_t ResourceTable::addPublic(const SourcePos& sourcePos, - const String16& package, - const String16& type, - const String16& name, - const uint32_t ident) -{ - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); - if (rid != 0) { - sourcePos.error("Error declaring public resource %s/%s for included package %s\n", - String8(type).string(), String8(name).string(), - String8(package).string()); - return UNKNOWN_ERROR; - } - - sp<Type> t = getType(package, type, sourcePos); - if (t == NULL) { - return UNKNOWN_ERROR; - } - return t->addPublic(sourcePos, name, ident); -} - -status_t ResourceTable::addEntry(const SourcePos& sourcePos, - const String16& package, - const String16& type, - const String16& name, - const String16& value, - const Vector<StringPool::entry_style_span>* style, - const ResTable_config* params, - const bool doSetIndex, - const int32_t format, - const bool overwrite) -{ - // Check for adding entries in other packages... for now we do - // nothing. We need to do the right thing here to support skinning. - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); - if (rid != 0) { - return NO_ERROR; - } - -#if 0 - if (name == String16("left")) { - printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n", - sourcePos.file.string(), sourcePos.line, String8(type).string(), - String8(value).string()); - } -#endif - - sp<Entry> e = getEntry(package, type, name, sourcePos, params, doSetIndex); - if (e == NULL) { - return UNKNOWN_ERROR; - } - status_t err = e->setItem(sourcePos, value, style, format, overwrite); - if (err == NO_ERROR) { - mNumLocal++; - } - return err; -} - -status_t ResourceTable::startBag(const SourcePos& sourcePos, - const String16& package, - const String16& type, - const String16& name, - const String16& bagParent, - const ResTable_config* params, - bool replace, bool isId) -{ - // Check for adding entries in other packages... for now we do - // nothing. We need to do the right thing here to support skinning. - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); - if (rid != 0) { - return NO_ERROR; - } - -#if 0 - if (name == String16("left")) { - printf("Adding bag left: file=%s, line=%d, type=%s\n", - sourcePos.file.striing(), sourcePos.line, String8(type).string()); - } -#endif - - sp<Entry> e = getEntry(package, type, name, sourcePos, params); - if (e == NULL) { - return UNKNOWN_ERROR; - } - - // If a parent is explicitly specified, set it. - if (bagParent.size() > 0) { - String16 curPar = e->getParent(); - if (curPar.size() > 0 && curPar != bagParent) { - sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n", - String8(e->getParent()).string(), - String8(bagParent).string()); - return UNKNOWN_ERROR; - } - e->setParent(bagParent); - } - - return e->makeItABag(sourcePos); -} - -status_t ResourceTable::addBag(const SourcePos& sourcePos, - const String16& package, - const String16& type, - const String16& name, - const String16& bagParent, - const String16& bagKey, - const String16& value, - const Vector<StringPool::entry_style_span>* style, - const ResTable_config* params, - bool replace, bool isId, const int32_t format) -{ - // Check for adding entries in other packages... for now we do - // nothing. We need to do the right thing here to support skinning. - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); - if (rid != 0) { - return NO_ERROR; - } - -#if 0 - if (name == String16("left")) { - printf("Adding bag left: file=%s, line=%d, type=%s\n", - sourcePos.file.striing(), sourcePos.line, String8(type).string()); - } -#endif - - sp<Entry> e = getEntry(package, type, name, sourcePos, params); - if (e == NULL) { - return UNKNOWN_ERROR; - } - - // If a parent is explicitly specified, set it. - if (bagParent.size() > 0) { - String16 curPar = e->getParent(); - if (curPar.size() > 0 && curPar != bagParent) { - sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n", - String8(e->getParent()).string(), - String8(bagParent).string()); - return UNKNOWN_ERROR; - } - e->setParent(bagParent); - } - - const bool first = e->getBag().indexOfKey(bagKey) < 0; - status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format); - if (err == NO_ERROR && first) { - mNumLocal++; - } - return err; -} - -bool ResourceTable::hasBagOrEntry(const String16& package, - const String16& type, - const String16& name) const -{ - // First look for this in the included resources... - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size()); - if (rid != 0) { - return true; - } - - sp<Package> p = mPackages.valueFor(package); - if (p != NULL) { - sp<Type> t = p->getTypes().valueFor(type); - if (t != NULL) { - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c != NULL) return true; - } - } - - return false; -} - -bool ResourceTable::hasBagOrEntry(const String16& ref, - const String16* defType, - const String16* defPackage) -{ - String16 package, type, name; - if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, - defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { - return false; - } - return hasBagOrEntry(package, type, name); -} - -bool ResourceTable::appendComment(const String16& package, - const String16& type, - const String16& name, - const String16& comment, - bool onlyIfEmpty) -{ - if (comment.size() <= 0) { - return true; - } - - sp<Package> p = mPackages.valueFor(package); - if (p != NULL) { - sp<Type> t = p->getTypes().valueFor(type); - if (t != NULL) { - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c != NULL) { - c->appendComment(comment, onlyIfEmpty); - return true; - } - } - } - return false; -} - -bool ResourceTable::appendTypeComment(const String16& package, - const String16& type, - const String16& name, - const String16& comment) -{ - if (comment.size() <= 0) { - return true; - } - - sp<Package> p = mPackages.valueFor(package); - if (p != NULL) { - sp<Type> t = p->getTypes().valueFor(type); - if (t != NULL) { - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c != NULL) { - c->appendTypeComment(comment); - return true; - } - } - } - return false; -} - -size_t ResourceTable::size() const { - return mPackages.size(); -} - -size_t ResourceTable::numLocalResources() const { - return mNumLocal; -} - -bool ResourceTable::hasResources() const { - return mNumLocal > 0; -} - -sp<AaptFile> ResourceTable::flatten(Bundle* bundle) -{ - sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); - status_t err = flatten(bundle, data); - return err == NO_ERROR ? data : NULL; -} - -inline uint32_t ResourceTable::getResId(const sp<Package>& p, - const sp<Type>& t, - uint32_t nameId) -{ - return makeResId(p->getAssignedId(), t->getIndex(), nameId); -} - -uint32_t ResourceTable::getResId(const String16& package, - const String16& type, - const String16& name, - bool onlyPublic) const -{ - sp<Package> p = mPackages.valueFor(package); - if (p == NULL) return 0; - - // First look for this in the included resources... - uint32_t specFlags = 0; - uint32_t rid = mAssets->getIncludedResources() - .identifierForName(name.string(), name.size(), - type.string(), type.size(), - package.string(), package.size(), - &specFlags); - if (rid != 0) { - if (onlyPublic) { - if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { - return 0; - } - } - - if (Res_INTERNALID(rid)) { - return rid; - } - return Res_MAKEID(p->getAssignedId()-1, - Res_GETTYPE(rid), - Res_GETENTRY(rid)); - } - - sp<Type> t = p->getTypes().valueFor(type); - if (t == NULL) return 0; - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c == NULL) return 0; - int32_t ei = c->getEntryIndex(); - if (ei < 0) return 0; - return getResId(p, t, ei); -} - -uint32_t ResourceTable::getResId(const String16& ref, - const String16* defType, - const String16* defPackage, - const char** outErrorMsg, - bool onlyPublic) const -{ - String16 package, type, name; - if (!ResTable::expandResourceRef( - ref.string(), ref.size(), &package, &type, &name, - defType, defPackage ? defPackage:&mAssetsPackage, - outErrorMsg)) { - NOISY(printf("Expanding resource: ref=%s\n", - String8(ref).string())); - NOISY(printf("Expanding resource: defType=%s\n", - defType ? String8(*defType).string() : "NULL")); - NOISY(printf("Expanding resource: defPackage=%s\n", - defPackage ? String8(*defPackage).string() : "NULL")); - NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string())); - NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", - String8(package).string(), String8(type).string(), - String8(name).string())); - return 0; - } - uint32_t res = getResId(package, type, name, onlyPublic); - NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", - String8(package).string(), String8(type).string(), - String8(name).string(), res)); - if (res == 0) { - if (outErrorMsg) - *outErrorMsg = "No resource found that matches the given name"; - } - return res; -} - -bool ResourceTable::isValidResourceName(const String16& s) -{ - const char16_t* p = s.string(); - bool first = true; - while (*p) { - if ((*p >= 'a' && *p <= 'z') - || (*p >= 'A' && *p <= 'Z') - || *p == '_' - || (!first && *p >= '0' && *p <= '9')) { - first = false; - p++; - continue; - } - return false; - } - return true; -} - -bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, - const String16& str, - bool preserveSpaces, bool coerceType, - uint32_t attrID, - const Vector<StringPool::entry_style_span>* style, - String16* outStr, void* accessorCookie, - uint32_t attrType) -{ - String16 finalStr; - - bool res = true; - if (style == NULL || style->size() == 0) { - // Text is not styled so it can be any type... let's figure it out. - res = mAssets->getIncludedResources() - .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, - coerceType, attrID, NULL, &mAssetsPackage, this, - accessorCookie, attrType); - } else { - // Styled text can only be a string, and while collecting the style - // information we have already processed that string! - outValue->size = sizeof(Res_value); - outValue->res0 = 0; - outValue->dataType = outValue->TYPE_STRING; - outValue->data = 0; - finalStr = str; - } - - if (!res) { - return false; - } - - if (outValue->dataType == outValue->TYPE_STRING) { - // Should do better merging styles. - if (pool) { - if (style != NULL && style->size() > 0) { - outValue->data = pool->add(finalStr, *style); - } else { - outValue->data = pool->add(finalStr, true); - } - } else { - // Caller will fill this in later. - outValue->data = 0; - } - - if (outStr) { - *outStr = finalStr; - } - - } - - return true; -} - -uint32_t ResourceTable::getCustomResource( - const String16& package, const String16& type, const String16& name) const -{ - //printf("getCustomResource: %s %s %s\n", String8(package).string(), - // String8(type).string(), String8(name).string()); - sp<Package> p = mPackages.valueFor(package); - if (p == NULL) return 0; - sp<Type> t = p->getTypes().valueFor(type); - if (t == NULL) return 0; - sp<ConfigList> c = t->getConfigs().valueFor(name); - if (c == NULL) return 0; - int32_t ei = c->getEntryIndex(); - if (ei < 0) return 0; - return getResId(p, t, ei); -} - -uint32_t ResourceTable::getCustomResourceWithCreation( - const String16& package, const String16& type, const String16& name, - const bool createIfNotFound) -{ - uint32_t resId = getCustomResource(package, type, name); - if (resId != 0 || !createIfNotFound) { - return resId; - } - String16 value("false"); - - status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true); - if (status == NO_ERROR) { - resId = getResId(package, type, name); - return resId; - } - return 0; -} - -uint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const -{ - return origPackage; -} - -bool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) -{ - //printf("getAttributeType #%08x\n", attrID); - Res_value value; - if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { - //printf("getAttributeType #%08x (%s): #%08x\n", attrID, - // String8(getEntry(attrID)->getName()).string(), value.data); - *outType = value.data; - return true; - } - return false; -} - -bool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin) -{ - //printf("getAttributeMin #%08x\n", attrID); - Res_value value; - if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) { - *outMin = value.data; - return true; - } - return false; -} - -bool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax) -{ - //printf("getAttributeMax #%08x\n", attrID); - Res_value value; - if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) { - *outMax = value.data; - return true; - } - return false; -} - -uint32_t ResourceTable::getAttributeL10N(uint32_t attrID) -{ - //printf("getAttributeL10N #%08x\n", attrID); - Res_value value; - if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) { - return value.data; - } - return ResTable_map::L10N_NOT_REQUIRED; -} - -bool ResourceTable::getLocalizationSetting() -{ - return mBundle->getRequireLocalization(); -} - -void ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) -{ - if (accessorCookie != NULL && fmt != NULL) { - AccessorCookie* ac = (AccessorCookie*)accessorCookie; - int retval=0; - char buf[1024]; - va_list ap; - va_start(ap, fmt); - retval = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", - buf, ac->attr.string(), ac->value.string()); - } -} - -bool ResourceTable::getAttributeKeys( - uint32_t attrID, Vector<String16>* outKeys) -{ - sp<const Entry> e = getEntry(attrID); - if (e != NULL) { - const size_t N = e->getBag().size(); - for (size_t i=0; i<N; i++) { - const String16& key = e->getBag().keyAt(i); - if (key.size() > 0 && key.string()[0] != '^') { - outKeys->add(key); - } - } - return true; - } - return false; -} - -bool ResourceTable::getAttributeEnum( - uint32_t attrID, const char16_t* name, size_t nameLen, - Res_value* outValue) -{ - //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); - String16 nameStr(name, nameLen); - sp<const Entry> e = getEntry(attrID); - if (e != NULL) { - const size_t N = e->getBag().size(); - for (size_t i=0; i<N; i++) { - //printf("Comparing %s to %s\n", String8(name, nameLen).string(), - // String8(e->getBag().keyAt(i)).string()); - if (e->getBag().keyAt(i) == nameStr) { - return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); - } - } - } - return false; -} - -bool ResourceTable::getAttributeFlags( - uint32_t attrID, const char16_t* name, size_t nameLen, - Res_value* outValue) -{ - outValue->dataType = Res_value::TYPE_INT_HEX; - outValue->data = 0; - - //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); - String16 nameStr(name, nameLen); - sp<const Entry> e = getEntry(attrID); - if (e != NULL) { - const size_t N = e->getBag().size(); - - const char16_t* end = name + nameLen; - const char16_t* pos = name; - bool failed = false; - while (pos < end && !failed) { - const char16_t* start = pos; - end++; - while (pos < end && *pos != '|') { - pos++; - } - - String16 nameStr(start, pos-start); - size_t i; - for (i=0; i<N; i++) { - //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), - // String8(e->getBag().keyAt(i)).string()); - if (e->getBag().keyAt(i) == nameStr) { - Res_value val; - bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); - if (!got) { - return false; - } - //printf("Got value: 0x%08x\n", val.data); - outValue->data |= val.data; - break; - } - } - - if (i >= N) { - // Didn't find this flag identifier. - return false; - } - if (pos < end) { - pos++; - } - } - - return true; - } - return false; -} - -status_t ResourceTable::assignResourceIds() -{ - const size_t N = mOrderedPackages.size(); - size_t pi; - status_t firstError = NO_ERROR; - - // First generate all bag attributes and assign indices. - for (pi=0; pi<N; pi++) { - sp<Package> p = mOrderedPackages.itemAt(pi); - if (p == NULL || p->getTypes().size() == 0) { - // Empty, skip! - continue; - } - - status_t err = p->applyPublicTypeOrder(); - if (err != NO_ERROR && firstError == NO_ERROR) { - firstError = err; - } - - // Generate attributes... - const size_t N = p->getOrderedTypes().size(); - size_t ti; - for (ti=0; ti<N; ti++) { - sp<Type> t = p->getOrderedTypes().itemAt(ti); - if (t == NULL) { - continue; - } - const size_t N = t->getOrderedConfigs().size(); - for (size_t ci=0; ci<N; ci++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); - if (c == NULL) { - continue; - } - const size_t N = c->getEntries().size(); - for (size_t ei=0; ei<N; ei++) { - sp<Entry> e = c->getEntries().valueAt(ei); - if (e == NULL) { - continue; - } - status_t err = e->generateAttributes(this, p->getName()); - if (err != NO_ERROR && firstError == NO_ERROR) { - firstError = err; - } - } - } - } - - const SourcePos unknown(String8("????"), 0); - sp<Type> attr = p->getType(String16("attr"), unknown); - - // Assign indices... - for (ti=0; ti<N; ti++) { - sp<Type> t = p->getOrderedTypes().itemAt(ti); - if (t == NULL) { - continue; - } - err = t->applyPublicEntryOrder(); - if (err != NO_ERROR && firstError == NO_ERROR) { - firstError = err; - } - - const size_t N = t->getOrderedConfigs().size(); - t->setIndex(ti+1); - - LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t, - "First type is not attr!"); - - for (size_t ei=0; ei<N; ei++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei); - if (c == NULL) { - continue; - } - c->setEntryIndex(ei); - } - } - - // Assign resource IDs to keys in bags... - for (ti=0; ti<N; ti++) { - sp<Type> t = p->getOrderedTypes().itemAt(ti); - if (t == NULL) { - continue; - } - const size_t N = t->getOrderedConfigs().size(); - for (size_t ci=0; ci<N; ci++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); - //printf("Ordered config #%d: %p\n", ci, c.get()); - const size_t N = c->getEntries().size(); - for (size_t ei=0; ei<N; ei++) { - sp<Entry> e = c->getEntries().valueAt(ei); - if (e == NULL) { - continue; - } - status_t err = e->assignResourceIds(this, p->getName()); - if (err != NO_ERROR && firstError == NO_ERROR) { - firstError = err; - } - } - } - } - } - return firstError; -} - -status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { - const size_t N = mOrderedPackages.size(); - size_t pi; - - for (pi=0; pi<N; pi++) { - sp<Package> p = mOrderedPackages.itemAt(pi); - if (p->getTypes().size() == 0) { - // Empty, skip! - continue; - } - - const size_t N = p->getOrderedTypes().size(); - size_t ti; - - for (ti=0; ti<N; ti++) { - sp<Type> t = p->getOrderedTypes().itemAt(ti); - if (t == NULL) { - continue; - } - const size_t N = t->getOrderedConfigs().size(); - sp<AaptSymbols> typeSymbols; - typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); - for (size_t ci=0; ci<N; ci++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); - if (c == NULL) { - continue; - } - uint32_t rid = getResId(p, t, ci); - if (rid == 0) { - return UNKNOWN_ERROR; - } - if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) { - typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos()); - - String16 comment(c->getComment()); - typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); - //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(), - // String8(comment).string()); - comment = c->getTypeComment(); - typeSymbols->appendTypeComment(String8(c->getName()), comment); - } else { -#if 0 - printf("**** NO MATCH: 0x%08x vs 0x%08x\n", - Res_GETPACKAGE(rid), p->getAssignedId()); -#endif - } - } - } - } - return NO_ERROR; -} - - -void -ResourceTable::addLocalization(const String16& name, const String8& locale) -{ - mLocalizations[name].insert(locale); -} - - -/*! - * Flag various sorts of localization problems. '+' indicates checks already implemented; - * '-' indicates checks that will be implemented in the future. - * - * + A localized string for which no default-locale version exists => warning - * + A string for which no version in an explicitly-requested locale exists => warning - * + A localized translation of an translateable="false" string => warning - * - A localized string not provided in every locale used by the table - */ -status_t -ResourceTable::validateLocalizations(void) -{ - status_t err = NO_ERROR; - const String8 defaultLocale; - - // For all strings... - for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin(); - nameIter != mLocalizations.end(); - nameIter++) { - const set<String8>& configSet = nameIter->second; // naming convenience - - // Look for strings with no default localization - if (configSet.count(defaultLocale) == 0) { - fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:", - String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]); - for (set<String8>::iterator locales = configSet.begin(); - locales != configSet.end(); - locales++) { - fprintf(stdout, " %s", (*locales).string()); - } - fprintf(stdout, "\n"); - // !!! TODO: throw an error here in some circumstances - } - - // Check that all requested localizations are present for this string - if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) { - const char* allConfigs = mBundle->getConfigurations(); - const char* start = allConfigs; - const char* comma; - - do { - String8 config; - comma = strchr(start, ','); - if (comma != NULL) { - config.setTo(start, comma - start); - start = comma + 1; - } else { - config.setTo(start); - } - - // don't bother with the pseudolocale "zz_ZZ" - if (config != "zz_ZZ") { - if (configSet.find(config) == configSet.end()) { - // okay, no specific localization found. it's possible that we are - // requiring a specific regional localization [e.g. de_DE] but there is an - // available string in the generic language localization [e.g. de]; - // consider that string to have fulfilled the localization requirement. - String8 region(config.string(), 2); - if (configSet.find(region) == configSet.end()) { - if (configSet.count(defaultLocale) == 0) { - fprintf(stdout, "aapt: error: " - "*** string '%s' has no default or required localization " - "for '%s' in %s\n", - String8(nameIter->first).string(), - config.string(), - mBundle->getResourceSourceDirs()[0]); - err = UNKNOWN_ERROR; - } - } - } - } - } while (comma != NULL); - } - } - - return err; -} - - -status_t -ResourceFilter::parse(const char* arg) -{ - if (arg == NULL) { - return 0; - } - - const char* p = arg; - const char* q; - - while (true) { - q = strchr(p, ','); - if (q == NULL) { - q = p + strlen(p); - } - - String8 part(p, q-p); - - if (part == "zz_ZZ") { - mContainsPseudo = true; - } - int axis; - uint32_t value; - if (AaptGroupEntry::parseNamePart(part, &axis, &value)) { - fprintf(stderr, "Invalid configuration: %s\n", arg); - fprintf(stderr, " "); - for (int i=0; i<p-arg; i++) { - fprintf(stderr, " "); - } - for (int i=0; i<q-p; i++) { - fprintf(stderr, "^"); - } - fprintf(stderr, "\n"); - return 1; - } - - ssize_t index = mData.indexOfKey(axis); - if (index < 0) { - mData.add(axis, SortedVector<uint32_t>()); - } - SortedVector<uint32_t>& sv = mData.editValueFor(axis); - sv.add(value); - // if it's a locale with a region, also match an unmodified locale of the - // same language - if (axis == AXIS_LANGUAGE) { - if (value & 0xffff0000) { - sv.add(value & 0x0000ffff); - } - } - p = q; - if (!*p) break; - p++; - } - - return NO_ERROR; -} - -bool -ResourceFilter::match(int axis, uint32_t value) -{ - if (value == 0) { - // they didn't specify anything so take everything - return true; - } - ssize_t index = mData.indexOfKey(axis); - if (index < 0) { - // we didn't request anything on this axis so take everything - return true; - } - const SortedVector<uint32_t>& sv = mData.valueAt(index); - return sv.indexOf(value) >= 0; -} - -bool -ResourceFilter::match(const ResTable_config& config) -{ - if (config.locale) { - uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16) - | (config.language[1] << 8) | (config.language[0]); - if (!match(AXIS_LANGUAGE, locale)) { - return false; - } - } - if (!match(AXIS_ORIENTATION, config.orientation)) { - return false; - } - if (!match(AXIS_DENSITY, config.density)) { - return false; - } - if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) { - return false; - } - if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) { - return false; - } - if (!match(AXIS_KEYBOARD, config.keyboard)) { - return false; - } - if (!match(AXIS_NAVIGATION, config.navigation)) { - return false; - } - if (!match(AXIS_SCREENSIZE, config.screenSize)) { - return false; - } - if (!match(AXIS_VERSION, config.version)) { - return false; - } - return true; -} - -status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) -{ - ResourceFilter filter; - status_t err = filter.parse(bundle->getConfigurations()); - if (err != NO_ERROR) { - return err; - } - - const size_t N = mOrderedPackages.size(); - size_t pi; - - // Iterate through all data, collecting all values (strings, - // references, etc). - StringPool valueStrings; - for (pi=0; pi<N; pi++) { - sp<Package> p = mOrderedPackages.itemAt(pi); - if (p->getTypes().size() == 0) { - // Empty, skip! - continue; - } - - StringPool typeStrings; - StringPool keyStrings; - - const size_t N = p->getOrderedTypes().size(); - for (size_t ti=0; ti<N; ti++) { - sp<Type> t = p->getOrderedTypes().itemAt(ti); - if (t == NULL) { - typeStrings.add(String16("<empty>"), false); - continue; - } - typeStrings.add(t->getName(), false); - - const size_t N = t->getOrderedConfigs().size(); - for (size_t ci=0; ci<N; ci++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); - if (c == NULL) { - continue; - } - const size_t N = c->getEntries().size(); - for (size_t ei=0; ei<N; ei++) { - ConfigDescription config = c->getEntries().keyAt(ei); - if (!filter.match(config)) { - continue; - } - sp<Entry> e = c->getEntries().valueAt(ei); - if (e == NULL) { - continue; - } - e->setNameIndex(keyStrings.add(e->getName(), true)); - status_t err = e->prepareFlatten(&valueStrings, this); - if (err != NO_ERROR) { - return err; - } - } - } - } - - p->setTypeStrings(typeStrings.createStringBlock()); - p->setKeyStrings(keyStrings.createStringBlock()); - } - - ssize_t strAmt = 0; - - // Now build the array of package chunks. - Vector<sp<AaptFile> > flatPackages; - for (pi=0; pi<N; pi++) { - sp<Package> p = mOrderedPackages.itemAt(pi); - if (p->getTypes().size() == 0) { - // Empty, skip! - continue; - } - - const size_t N = p->getTypeStrings().size(); - - const size_t baseSize = sizeof(ResTable_package); - - // Start the package data. - sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); - ResTable_package* header = (ResTable_package*)data->editData(baseSize); - if (header == NULL) { - fprintf(stderr, "ERROR: out of memory creating ResTable_package\n"); - return NO_MEMORY; - } - memset(header, 0, sizeof(*header)); - header->header.type = htods(RES_TABLE_PACKAGE_TYPE); - header->header.headerSize = htods(sizeof(*header)); - header->id = htodl(p->getAssignedId()); - strcpy16_htod(header->name, p->getName().string()); - - // Write the string blocks. - const size_t typeStringsStart = data->getSize(); - sp<AaptFile> strFile = p->getTypeStringsData(); - ssize_t amt = data->writeData(strFile->getData(), strFile->getSize()); - #if PRINT_STRING_METRICS - fprintf(stderr, "**** type strings: %d\n", amt); - #endif - strAmt += amt; - if (amt < 0) { - return amt; - } - const size_t keyStringsStart = data->getSize(); - strFile = p->getKeyStringsData(); - amt = data->writeData(strFile->getData(), strFile->getSize()); - #if PRINT_STRING_METRICS - fprintf(stderr, "**** key strings: %d\n", amt); - #endif - strAmt += amt; - if (amt < 0) { - return amt; - } - - // Build the type chunks inside of this package. - for (size_t ti=0; ti<N; ti++) { - // Retrieve them in the same order as the type string block. - size_t len; - String16 typeName(p->getTypeStrings().stringAt(ti, &len)); - sp<Type> t = p->getTypes().valueFor(typeName); - LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), - "Type name %s not found", - String8(typeName).string()); - - const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; - - // First write the typeSpec chunk, containing information about - // each resource entry in this type. - { - const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N; - const size_t typeSpecStart = data->getSize(); - ResTable_typeSpec* tsHeader = (ResTable_typeSpec*) - (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart); - if (tsHeader == NULL) { - fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n"); - return NO_MEMORY; - } - memset(tsHeader, 0, sizeof(*tsHeader)); - tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE); - tsHeader->header.headerSize = htods(sizeof(*tsHeader)); - tsHeader->header.size = htodl(typeSpecSize); - tsHeader->id = ti+1; - tsHeader->entryCount = htodl(N); - - uint32_t* typeSpecFlags = (uint32_t*) - (((uint8_t*)data->editData()) - + typeSpecStart + sizeof(ResTable_typeSpec)); - memset(typeSpecFlags, 0, sizeof(uint32_t)*N); - - for (size_t ei=0; ei<N; ei++) { - sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); - if (cl->getPublic()) { - typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); - } - const size_t CN = cl->getEntries().size(); - for (size_t ci=0; ci<CN; ci++) { - if (!filter.match(cl->getEntries().keyAt(ci))) { - continue; - } - for (size_t cj=ci+1; cj<CN; cj++) { - if (!filter.match(cl->getEntries().keyAt(cj))) { - continue; - } - typeSpecFlags[ei] |= htodl( - cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj))); - } - } - } - } - - // We need to write one type chunk for each configuration for - // which we have entries in this type. - const size_t NC = t->getUniqueConfigs().size(); - - const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; - - for (size_t ci=0; ci<NC; ci++) { - ConfigDescription config = t->getUniqueConfigs().itemAt(ci); - - NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", - ti+1, - config.mcc, config.mnc, - config.language[0] ? config.language[0] : '-', - config.language[1] ? config.language[1] : '-', - config.country[0] ? config.country[0] : '-', - config.country[1] ? config.country[1] : '-', - config.orientation, - config.touchscreen, - config.density, - config.keyboard, - config.inputFlags, - config.navigation, - config.screenWidth, - config.screenHeight)); - - if (!filter.match(config)) { - continue; - } - - const size_t typeStart = data->getSize(); - - ResTable_type* tHeader = (ResTable_type*) - (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart); - if (tHeader == NULL) { - fprintf(stderr, "ERROR: out of memory creating ResTable_type\n"); - return NO_MEMORY; - } - - memset(tHeader, 0, sizeof(*tHeader)); - tHeader->header.type = htods(RES_TABLE_TYPE_TYPE); - tHeader->header.headerSize = htods(sizeof(*tHeader)); - tHeader->id = ti+1; - tHeader->entryCount = htodl(N); - tHeader->entriesStart = htodl(typeSize); - tHeader->config = config; - NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", - ti+1, - tHeader->config.mcc, tHeader->config.mnc, - tHeader->config.language[0] ? tHeader->config.language[0] : '-', - tHeader->config.language[1] ? tHeader->config.language[1] : '-', - tHeader->config.country[0] ? tHeader->config.country[0] : '-', - tHeader->config.country[1] ? tHeader->config.country[1] : '-', - tHeader->config.orientation, - tHeader->config.touchscreen, - tHeader->config.density, - tHeader->config.keyboard, - tHeader->config.inputFlags, - tHeader->config.navigation, - tHeader->config.screenWidth, - tHeader->config.screenHeight)); - tHeader->config.swapHtoD(); - - // Build the entries inside of this type. - for (size_t ei=0; ei<N; ei++) { - sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); - sp<Entry> e = cl->getEntries().valueFor(config); - - // Set the offset for this entry in its type. - uint32_t* index = (uint32_t*) - (((uint8_t*)data->editData()) - + typeStart + sizeof(ResTable_type)); - if (e != NULL) { - index[ei] = htodl(data->getSize()-typeStart-typeSize); - - // Create the entry. - ssize_t amt = e->flatten(bundle, data, cl->getPublic()); - if (amt < 0) { - return amt; - } - } else { - index[ei] = htodl(ResTable_type::NO_ENTRY); - } - } - - // Fill in the rest of the type information. - tHeader = (ResTable_type*) - (((uint8_t*)data->editData()) + typeStart); - tHeader->header.size = htodl(data->getSize()-typeStart); - } - } - - // Fill in the rest of the package information. - header = (ResTable_package*)data->editData(); - header->header.size = htodl(data->getSize()); - header->typeStrings = htodl(typeStringsStart); - header->lastPublicType = htodl(p->getTypeStrings().size()); - header->keyStrings = htodl(keyStringsStart); - header->lastPublicKey = htodl(p->getKeyStrings().size()); - - flatPackages.add(data); - } - - // And now write out the final chunks. - const size_t dataStart = dest->getSize(); - - { - // blah - ResTable_header header; - memset(&header, 0, sizeof(header)); - header.header.type = htods(RES_TABLE_TYPE); - header.header.headerSize = htods(sizeof(header)); - header.packageCount = htodl(flatPackages.size()); - status_t err = dest->writeData(&header, sizeof(header)); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating ResTable_header\n"); - return err; - } - } - - ssize_t strStart = dest->getSize(); - err = valueStrings.writeStringBlock(dest); - if (err != NO_ERROR) { - return err; - } - - ssize_t amt = (dest->getSize()-strStart); - strAmt += amt; - #if PRINT_STRING_METRICS - fprintf(stderr, "**** value strings: %d\n", amt); - fprintf(stderr, "**** total strings: %d\n", strAmt); - #endif - - for (pi=0; pi<flatPackages.size(); pi++) { - err = dest->writeData(flatPackages[pi]->getData(), - flatPackages[pi]->getSize()); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n"); - return err; - } - } - - ResTable_header* header = (ResTable_header*) - (((uint8_t*)dest->getData()) + dataStart); - header->header.size = htodl(dest->getSize() - dataStart); - - NOISY(aout << "Resource table:" - << HexDump(dest->getData(), dest->getSize()) << endl); - - #if PRINT_STRING_METRICS - fprintf(stderr, "**** total resource table size: %d / %d%% strings\n", - dest->getSize(), (strAmt*100)/dest->getSize()); - #endif - - return NO_ERROR; -} - -void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) -{ - fprintf(fp, - "<!-- This file contains <public> resource definitions for all\n" - " resources that were generated from the source data. -->\n" - "\n" - "<resources>\n"); - - writePublicDefinitions(package, fp, true); - writePublicDefinitions(package, fp, false); - - fprintf(fp, - "\n" - "</resources>\n"); -} - -void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub) -{ - bool didHeader = false; - - sp<Package> pkg = mPackages.valueFor(package); - if (pkg != NULL) { - const size_t NT = pkg->getOrderedTypes().size(); - for (size_t i=0; i<NT; i++) { - sp<Type> t = pkg->getOrderedTypes().itemAt(i); - if (t == NULL) { - continue; - } - - bool didType = false; - - const size_t NC = t->getOrderedConfigs().size(); - for (size_t j=0; j<NC; j++) { - sp<ConfigList> c = t->getOrderedConfigs().itemAt(j); - if (c == NULL) { - continue; - } - - if (c->getPublic() != pub) { - continue; - } - - if (!didType) { - fprintf(fp, "\n"); - didType = true; - } - if (!didHeader) { - if (pub) { - fprintf(fp," <!-- PUBLIC SECTION. These resources have been declared public.\n"); - fprintf(fp," Changes to these definitions will break binary compatibility. -->\n\n"); - } else { - fprintf(fp," <!-- PRIVATE SECTION. These resources have not been declared public.\n"); - fprintf(fp," You can make them public my moving these lines into a file in res/values. -->\n\n"); - } - didHeader = true; - } - if (!pub) { - const size_t NE = c->getEntries().size(); - for (size_t k=0; k<NE; k++) { - const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); - if (pos.file != "") { - fprintf(fp," <!-- Declared at %s:%d -->\n", - pos.file.string(), pos.line); - } - } - } - fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", - String8(t->getName()).string(), - String8(c->getName()).string(), - getResId(pkg, t, c->getEntryIndex())); - } - } - } -} - -ResourceTable::Item::Item(const SourcePos& _sourcePos, - bool _isId, - const String16& _value, - const Vector<StringPool::entry_style_span>* _style, - int32_t _format) - : sourcePos(_sourcePos) - , isId(_isId) - , value(_value) - , format(_format) - , bagKeyId(0) - , evaluating(false) -{ - if (_style) { - style = *_style; - } -} - -status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) -{ - if (mType == TYPE_BAG) { - return NO_ERROR; - } - if (mType == TYPE_UNKNOWN) { - mType = TYPE_BAG; - return NO_ERROR; - } - sourcePos.error("Resource entry %s is already defined as a single item.\n" - "%s:%d: Originally defined here.\n", - String8(mName).string(), - mItem.sourcePos.file.string(), mItem.sourcePos.line); - return UNKNOWN_ERROR; -} - -status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, - const String16& value, - const Vector<StringPool::entry_style_span>* style, - int32_t format, - const bool overwrite) -{ - Item item(sourcePos, false, value, style); - - if (mType == TYPE_BAG) { - const Item& item(mBag.valueAt(0)); - sourcePos.error("Resource entry %s is already defined as a bag.\n" - "%s:%d: Originally defined here.\n", - String8(mName).string(), - item.sourcePos.file.string(), item.sourcePos.line); - return UNKNOWN_ERROR; - } - if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { - sourcePos.error("Resource entry %s is already defined.\n" - "%s:%d: Originally defined here.\n", - String8(mName).string(), - mItem.sourcePos.file.string(), mItem.sourcePos.line); - return UNKNOWN_ERROR; - } - - mType = TYPE_ITEM; - mItem = item; - mItemFormat = format; - return NO_ERROR; -} - -status_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, - const String16& key, const String16& value, - const Vector<StringPool::entry_style_span>* style, - bool replace, bool isId, int32_t format) -{ - status_t err = makeItABag(sourcePos); - if (err != NO_ERROR) { - return err; - } - - Item item(sourcePos, isId, value, style, format); - - // XXX NOTE: there is an error if you try to have a bag with two keys, - // one an attr and one an id, with the same name. Not something we - // currently ever have to worry about. - ssize_t origKey = mBag.indexOfKey(key); - if (origKey >= 0) { - if (!replace) { - const Item& item(mBag.valueAt(origKey)); - sourcePos.error("Resource entry %s already has bag item %s.\n" - "%s:%d: Originally defined here.\n", - String8(mName).string(), String8(key).string(), - item.sourcePos.file.string(), item.sourcePos.line); - return UNKNOWN_ERROR; - } - //printf("Replacing %s with %s\n", - // String8(mBag.valueFor(key).value).string(), String8(value).string()); - mBag.replaceValueFor(key, item); - } - - mBag.add(key, item); - return NO_ERROR; -} - -status_t ResourceTable::Entry::generateAttributes(ResourceTable* table, - const String16& package) -{ - const String16 attr16("attr"); - const String16 id16("id"); - const size_t N = mBag.size(); - for (size_t i=0; i<N; i++) { - const String16& key = mBag.keyAt(i); - const Item& it = mBag.valueAt(i); - if (it.isId) { - if (!table->hasBagOrEntry(key, &id16, &package)) { - String16 value("false"); - status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, - id16, key, value); - if (err != NO_ERROR) { - return err; - } - } - } else if (!table->hasBagOrEntry(key, &attr16, &package)) { - -#if 1 -// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", -// String8(key).string()); -// const Item& item(mBag.valueAt(i)); -// fprintf(stderr, "Referenced from file %s line %d\n", -// item.sourcePos.file.string(), item.sourcePos.line); -// return UNKNOWN_ERROR; -#else - char numberStr[16]; - sprintf(numberStr, "%d", ResTable_map::TYPE_ANY); - status_t err = table->addBag(SourcePos("<generated>", 0), package, - attr16, key, String16(""), - String16("^type"), - String16(numberStr), NULL, NULL); - if (err != NO_ERROR) { - return err; - } -#endif - } - } - return NO_ERROR; -} - -status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, - const String16& package) -{ - bool hasErrors = false; - - if (mType == TYPE_BAG) { - const char* errorMsg; - const String16 style16("style"); - const String16 attr16("attr"); - const String16 id16("id"); - mParentId = 0; - if (mParent.size() > 0) { - mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); - if (mParentId == 0) { - mPos.error("Error retrieving parent for item: %s '%s'.\n", - errorMsg, String8(mParent).string()); - hasErrors = true; - } - } - const size_t N = mBag.size(); - for (size_t i=0; i<N; i++) { - const String16& key = mBag.keyAt(i); - Item& it = mBag.editValueAt(i); - it.bagKeyId = table->getResId(key, - it.isId ? &id16 : &attr16, NULL, &errorMsg); - //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); - if (it.bagKeyId == 0) { - it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, - String8(it.isId ? id16 : attr16).string(), - String8(key).string()); - hasErrors = true; - } - } - } - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table) -{ - if (mType == TYPE_ITEM) { - Item& it = mItem; - AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value)); - if (!table->stringToValue(&it.parsedValue, strings, - it.value, false, true, 0, - &it.style, NULL, &ac, mItemFormat)) { - return UNKNOWN_ERROR; - } - } else if (mType == TYPE_BAG) { - const size_t N = mBag.size(); - for (size_t i=0; i<N; i++) { - const String16& key = mBag.keyAt(i); - Item& it = mBag.editValueAt(i); - AccessorCookie ac(it.sourcePos, String8(key), String8(it.value)); - if (!table->stringToValue(&it.parsedValue, strings, - it.value, false, true, it.bagKeyId, - &it.style, NULL, &ac, it.format)) { - return UNKNOWN_ERROR; - } - } - } else { - mPos.error("Error: entry %s is not a single item or a bag.\n", - String8(mName).string()); - return UNKNOWN_ERROR; - } - return NO_ERROR; -} - -ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic) -{ - size_t amt = 0; - ResTable_entry header; - memset(&header, 0, sizeof(header)); - header.size = htods(sizeof(header)); - const type ty = this != NULL ? mType : TYPE_ITEM; - if (this != NULL) { - if (ty == TYPE_BAG) { - header.flags |= htods(header.FLAG_COMPLEX); - } - if (isPublic) { - header.flags |= htods(header.FLAG_PUBLIC); - } - header.key.index = htodl(mNameIndex); - } - if (ty != TYPE_BAG) { - status_t err = data->writeData(&header, sizeof(header)); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); - return err; - } - - const Item& it = mItem; - Res_value par; - memset(&par, 0, sizeof(par)); - par.size = htods(it.parsedValue.size); - par.dataType = it.parsedValue.dataType; - par.res0 = it.parsedValue.res0; - par.data = htodl(it.parsedValue.data); - #if 0 - printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", - String8(mName).string(), it.parsedValue.dataType, - it.parsedValue.data, par.res0); - #endif - err = data->writeData(&par, it.parsedValue.size); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating Res_value\n"); - return err; - } - amt += it.parsedValue.size; - } else { - size_t N = mBag.size(); - size_t i; - // Create correct ordering of items. - KeyedVector<uint32_t, const Item*> items; - for (i=0; i<N; i++) { - const Item& it = mBag.valueAt(i); - items.add(it.bagKeyId, &it); - } - N = items.size(); - - ResTable_map_entry mapHeader; - memcpy(&mapHeader, &header, sizeof(header)); - mapHeader.size = htods(sizeof(mapHeader)); - mapHeader.parent.ident = htodl(mParentId); - mapHeader.count = htodl(N); - status_t err = data->writeData(&mapHeader, sizeof(mapHeader)); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); - return err; - } - - for (i=0; i<N; i++) { - const Item& it = *items.valueAt(i); - ResTable_map map; - map.name.ident = htodl(it.bagKeyId); - map.value.size = htods(it.parsedValue.size); - map.value.dataType = it.parsedValue.dataType; - map.value.res0 = it.parsedValue.res0; - map.value.data = htodl(it.parsedValue.data); - err = data->writeData(&map, sizeof(map)); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: out of memory creating Res_value\n"); - return err; - } - amt += sizeof(map); - } - } - return amt; -} - -void ResourceTable::ConfigList::appendComment(const String16& comment, - bool onlyIfEmpty) -{ - if (comment.size() <= 0) { - return; - } - if (onlyIfEmpty && mComment.size() > 0) { - return; - } - if (mComment.size() > 0) { - mComment.append(String16("\n")); - } - mComment.append(comment); -} - -void ResourceTable::ConfigList::appendTypeComment(const String16& comment) -{ - if (comment.size() <= 0) { - return; - } - if (mTypeComment.size() > 0) { - mTypeComment.append(String16("\n")); - } - mTypeComment.append(comment); -} - -status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, - const String16& name, - const uint32_t ident) -{ - #if 0 - int32_t entryIdx = Res_GETENTRY(ident); - if (entryIdx < 0) { - sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", - String8(mName).string(), String8(name).string(), ident); - return UNKNOWN_ERROR; - } - #endif - - int32_t typeIdx = Res_GETTYPE(ident); - if (typeIdx >= 0) { - typeIdx++; - if (mPublicIndex > 0 && mPublicIndex != typeIdx) { - sourcePos.error("Public resource %s/%s has conflicting type codes for its" - " public identifiers (0x%x vs 0x%x).\n", - String8(mName).string(), String8(name).string(), - mPublicIndex, typeIdx); - return UNKNOWN_ERROR; - } - mPublicIndex = typeIdx; - } - - if (mFirstPublicSourcePos == NULL) { - mFirstPublicSourcePos = new SourcePos(sourcePos); - } - - if (mPublic.indexOfKey(name) < 0) { - mPublic.add(name, Public(sourcePos, String16(), ident)); - } else { - Public& p = mPublic.editValueFor(name); - if (p.ident != ident) { - sourcePos.error("Public resource %s/%s has conflicting public identifiers" - " (0x%08x vs 0x%08x).\n" - "%s:%d: Originally defined here.\n", - String8(mName).string(), String8(name).string(), p.ident, ident, - p.sourcePos.file.string(), p.sourcePos.line); - return UNKNOWN_ERROR; - } - } - - return NO_ERROR; -} - -sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, - const SourcePos& sourcePos, - const ResTable_config* config, - bool doSetIndex) -{ - int pos = -1; - sp<ConfigList> c = mConfigs.valueFor(entry); - if (c == NULL) { - c = new ConfigList(entry, sourcePos); - mConfigs.add(entry, c); - pos = (int)mOrderedConfigs.size(); - mOrderedConfigs.add(c); - if (doSetIndex) { - c->setEntryIndex(pos); - } - } - - ConfigDescription cdesc; - if (config) cdesc = *config; - - sp<Entry> e = c->getEntries().valueFor(cdesc); - if (e == NULL) { - if (config != NULL) { - NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", - sourcePos.file.string(), sourcePos.line, - config->mcc, config->mnc, - config->language[0] ? config->language[0] : '-', - config->language[1] ? config->language[1] : '-', - config->country[0] ? config->country[0] : '-', - config->country[1] ? config->country[1] : '-', - config->orientation, - config->touchscreen, - config->density, - config->keyboard, - config->inputFlags, - config->navigation, - config->screenWidth, - config->screenHeight)); - } else { - NOISY(printf("New entry at %s:%d: NULL config\n", - sourcePos.file.string(), sourcePos.line)); - } - e = new Entry(entry, sourcePos); - c->addEntry(cdesc, e); - /* - if (doSetIndex) { - if (pos < 0) { - for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) { - if (mOrderedConfigs[pos] == c) { - break; - } - } - if (pos >= (int)mOrderedConfigs.size()) { - sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry"); - return NULL; - } - } - e->setEntryIndex(pos); - } - */ - } - - mUniqueConfigs.add(cdesc); - - return e; -} - -status_t ResourceTable::Type::applyPublicEntryOrder() -{ - size_t N = mOrderedConfigs.size(); - Vector<sp<ConfigList> > origOrder(mOrderedConfigs); - bool hasError = false; - - size_t i; - for (i=0; i<N; i++) { - mOrderedConfigs.replaceAt(NULL, i); - } - - const size_t NP = mPublic.size(); - //printf("Ordering %d configs from %d public defs\n", N, NP); - size_t j; - for (j=0; j<NP; j++) { - const String16& name = mPublic.keyAt(j); - const Public& p = mPublic.valueAt(j); - int32_t idx = Res_GETENTRY(p.ident); - //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", - // String8(mName).string(), String8(name).string(), p.ident, N); - bool found = false; - for (i=0; i<N; i++) { - sp<ConfigList> e = origOrder.itemAt(i); - //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); - if (e->getName() == name) { - if (idx >= (int32_t)mOrderedConfigs.size()) { - p.sourcePos.error("Public entry identifier 0x%x entry index " - "is larger than available symbols (index %d, total symbols %d).\n", - p.ident, idx, mOrderedConfigs.size()); - hasError = true; - } else if (mOrderedConfigs.itemAt(idx) == NULL) { - e->setPublic(true); - e->setPublicSourcePos(p.sourcePos); - mOrderedConfigs.replaceAt(e, idx); - origOrder.removeAt(i); - N--; - found = true; - break; - } else { - sp<ConfigList> oe = mOrderedConfigs.itemAt(idx); - - p.sourcePos.error("Multiple entry names declared for public entry" - " identifier 0x%x in type %s (%s vs %s).\n" - "%s:%d: Originally defined here.", - idx+1, String8(mName).string(), - String8(oe->getName()).string(), - String8(name).string(), - oe->getPublicSourcePos().file.string(), - oe->getPublicSourcePos().line); - hasError = true; - } - } - } - - if (!found) { - p.sourcePos.error("Public symbol %s/%s declared here is not defined.", - String8(mName).string(), String8(name).string()); - hasError = true; - } - } - - //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size()); - - if (N != origOrder.size()) { - printf("Internal error: remaining private symbol count mismatch\n"); - N = origOrder.size(); - } - - j = 0; - for (i=0; i<N; i++) { - sp<ConfigList> e = origOrder.itemAt(i); - // There will always be enough room for the remaining entries. - while (mOrderedConfigs.itemAt(j) != NULL) { - j++; - } - mOrderedConfigs.replaceAt(e, j); - j++; - } - - return hasError ? UNKNOWN_ERROR : NO_ERROR; -} - -ResourceTable::Package::Package(const String16& name, ssize_t includedId) - : mName(name), mIncludedId(includedId), - mTypeStringsMapping(0xffffffff), - mKeyStringsMapping(0xffffffff) -{ -} - -sp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type, - const SourcePos& sourcePos, - bool doSetIndex) -{ - sp<Type> t = mTypes.valueFor(type); - if (t == NULL) { - t = new Type(type, sourcePos); - mTypes.add(type, t); - mOrderedTypes.add(t); - if (doSetIndex) { - // For some reason the type's index is set to one plus the index - // in the mOrderedTypes list, rather than just the index. - t->setIndex(mOrderedTypes.size()); - } - } - return t; -} - -status_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data) -{ - mTypeStringsData = data; - status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: Type string data is corrupt!\n"); - } - return err; -} - -status_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data) -{ - mKeyStringsData = data; - status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: Key string data is corrupt!\n"); - } - return err; -} - -status_t ResourceTable::Package::setStrings(const sp<AaptFile>& data, - ResStringPool* strings, - DefaultKeyedVector<String16, uint32_t>* mappings) -{ - if (data->getData() == NULL) { - return UNKNOWN_ERROR; - } - - NOISY(aout << "Setting restable string pool: " - << HexDump(data->getData(), data->getSize()) << endl); - - status_t err = strings->setTo(data->getData(), data->getSize()); - if (err == NO_ERROR) { - const size_t N = strings->size(); - for (size_t i=0; i<N; i++) { - size_t len; - mappings->add(String16(strings->stringAt(i, &len)), i); - } - } - return err; -} - -status_t ResourceTable::Package::applyPublicTypeOrder() -{ - size_t N = mOrderedTypes.size(); - Vector<sp<Type> > origOrder(mOrderedTypes); - - size_t i; - for (i=0; i<N; i++) { - mOrderedTypes.replaceAt(NULL, i); - } - - for (i=0; i<N; i++) { - sp<Type> t = origOrder.itemAt(i); - int32_t idx = t->getPublicIndex(); - if (idx > 0) { - idx--; - while (idx >= (int32_t)mOrderedTypes.size()) { - mOrderedTypes.add(); - } - if (mOrderedTypes.itemAt(idx) != NULL) { - sp<Type> ot = mOrderedTypes.itemAt(idx); - t->getFirstPublicSourcePos().error("Multiple type names declared for public type" - " identifier 0x%x (%s vs %s).\n" - "%s:%d: Originally defined here.", - idx, String8(ot->getName()).string(), - String8(t->getName()).string(), - ot->getFirstPublicSourcePos().file.string(), - ot->getFirstPublicSourcePos().line); - return UNKNOWN_ERROR; - } - mOrderedTypes.replaceAt(t, idx); - origOrder.removeAt(i); - i--; - N--; - } - } - - size_t j=0; - for (i=0; i<N; i++) { - sp<Type> t = origOrder.itemAt(i); - // There will always be enough room for the remaining types. - while (mOrderedTypes.itemAt(j) != NULL) { - j++; - } - mOrderedTypes.replaceAt(t, j); - } - - return NO_ERROR; -} - -sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) -{ - sp<Package> p = mPackages.valueFor(package); - if (p == NULL) { - if (mIsAppPackage) { - if (mHaveAppPackage) { - fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n" - "Use -x to create extended resources.\n"); - return NULL; - } - mHaveAppPackage = true; - p = new Package(package, 127); - } else { - p = new Package(package, mNextPackageId); - } - //printf("*** NEW PACKAGE: \"%s\" id=%d\n", - // String8(package).string(), p->getAssignedId()); - mPackages.add(package, p); - mOrderedPackages.add(p); - mNextPackageId++; - } - return p; -} - -sp<ResourceTable::Type> ResourceTable::getType(const String16& package, - const String16& type, - const SourcePos& sourcePos, - bool doSetIndex) -{ - sp<Package> p = getPackage(package); - if (p == NULL) { - return NULL; - } - return p->getType(type, sourcePos, doSetIndex); -} - -sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, - const String16& type, - const String16& name, - const SourcePos& sourcePos, - const ResTable_config* config, - bool doSetIndex) -{ - sp<Type> t = getType(package, type, sourcePos, doSetIndex); - if (t == NULL) { - return NULL; - } - return t->getEntry(name, sourcePos, config, doSetIndex); -} - -sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, - const ResTable_config* config) const -{ - int pid = Res_GETPACKAGE(resID)+1; - const size_t N = mOrderedPackages.size(); - size_t i; - sp<Package> p; - for (i=0; i<N; i++) { - sp<Package> check = mOrderedPackages[i]; - if (check->getAssignedId() == pid) { - p = check; - break; - } - - } - if (p == NULL) { - fprintf(stderr, "WARNING: Package not found for resource #%08x\n", resID); - return NULL; - } - - int tid = Res_GETTYPE(resID); - if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) { - fprintf(stderr, "WARNING: Type not found for resource #%08x\n", resID); - return NULL; - } - sp<Type> t = p->getOrderedTypes()[tid]; - - int eid = Res_GETENTRY(resID); - if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) { - fprintf(stderr, "WARNING: Entry not found for resource #%08x\n", resID); - return NULL; - } - - sp<ConfigList> c = t->getOrderedConfigs()[eid]; - if (c == NULL) { - fprintf(stderr, "WARNING: Entry not found for resource #%08x\n", resID); - return NULL; - } - - ConfigDescription cdesc; - if (config) cdesc = *config; - sp<Entry> e = c->getEntries().valueFor(cdesc); - if (c == NULL) { - fprintf(stderr, "WARNING: Entry configuration not found for resource #%08x\n", resID); - return NULL; - } - - return e; -} - -const ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const -{ - sp<const Entry> e = getEntry(resID); - if (e == NULL) { - return NULL; - } - - const size_t N = e->getBag().size(); - for (size_t i=0; i<N; i++) { - const Item& it = e->getBag().valueAt(i); - if (it.bagKeyId == 0) { - fprintf(stderr, "WARNING: ID not yet assigned to '%s' in bag '%s'\n", - String8(e->getName()).string(), - String8(e->getBag().keyAt(i)).string()); - } - if (it.bagKeyId == attrID) { - return ⁢ - } - } - - return NULL; -} - -bool ResourceTable::getItemValue( - uint32_t resID, uint32_t attrID, Res_value* outValue) -{ - const Item* item = getItem(resID, attrID); - - bool res = false; - if (item != NULL) { - if (item->evaluating) { - sp<const Entry> e = getEntry(resID); - const size_t N = e->getBag().size(); - size_t i; - for (i=0; i<N; i++) { - if (&e->getBag().valueAt(i) == item) { - break; - } - } - fprintf(stderr, "WARNING: Circular reference detected in key '%s' of bag '%s'\n", - String8(e->getName()).string(), - String8(e->getBag().keyAt(i)).string()); - return false; - } - item->evaluating = true; - res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId); - NOISY( - if (res) { - printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", - resID, attrID, String8(getEntry(resID)->getName()).string(), - outValue->dataType, outValue->data); - } else { - printf("getItemValue of #%08x[#%08x]: failed\n", - resID, attrID); - } - ); - item->evaluating = false; - } - return res; -} diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h deleted file mode 100644 index e8fbd9b..0000000 --- a/tools/aapt/ResourceTable.h +++ /dev/null @@ -1,534 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#ifndef RESOURCE_TABLE_H -#define RESOURCE_TABLE_H - -#include "StringPool.h" -#include "SourcePos.h" - -#include <set> -#include <map> - -using namespace std; - -class ResourceTable; - -enum { - XML_COMPILE_STRIP_COMMENTS = 1<<0, - XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1, - XML_COMPILE_COMPACT_WHITESPACE = 1<<2, - XML_COMPILE_STRIP_WHITESPACE = 1<<3, - XML_COMPILE_STRIP_RAW_VALUES = 1<<4, - - XML_COMPILE_STANDARD_RESOURCE = - XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS - | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES -}; - -status_t compileXmlFile(const sp<AaptAssets>& assets, - const sp<AaptFile>& target, - ResourceTable* table, - int options = XML_COMPILE_STANDARD_RESOURCE); - -status_t compileResourceFile(Bundle* bundle, - const sp<AaptAssets>& assets, - const sp<AaptFile>& in, - const ResTable_config& defParams, - const bool overwrite, - ResourceTable* outTable); - -struct AccessorCookie -{ - SourcePos sourcePos; - String8 attr; - String8 value; - - AccessorCookie(const SourcePos&p, const String8& a, const String8& v) - :sourcePos(p), - attr(a), - value(v) - { - } -}; - -class ResourceTable : public ResTable::Accessor -{ -public: - class Package; - class Type; - class Entry; - - ResourceTable(Bundle* bundle, const String16& assetsPackage); - - status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets); - - status_t addPublic(const SourcePos& pos, - const String16& package, - const String16& type, - const String16& name, - const uint32_t ident); - - status_t addEntry(const SourcePos& pos, - const String16& package, - const String16& type, - const String16& name, - const String16& value, - const Vector<StringPool::entry_style_span>* style = NULL, - const ResTable_config* params = NULL, - const bool doSetIndex = false, - const int32_t format = ResTable_map::TYPE_ANY, - const bool overwrite = false); - - status_t startBag(const SourcePos& pos, - const String16& package, - const String16& type, - const String16& name, - const String16& bagParent, - const ResTable_config* params = NULL, - bool replace = false, - bool isId = false); - - status_t addBag(const SourcePos& pos, - const String16& package, - const String16& type, - const String16& name, - const String16& bagParent, - const String16& bagKey, - const String16& value, - const Vector<StringPool::entry_style_span>* style = NULL, - const ResTable_config* params = NULL, - bool replace = false, - bool isId = false, - const int32_t format = ResTable_map::TYPE_ANY); - - bool hasBagOrEntry(const String16& package, - const String16& type, - const String16& name) const; - - bool hasBagOrEntry(const String16& ref, - const String16* defType = NULL, - const String16* defPackage = NULL); - - bool appendComment(const String16& package, - const String16& type, - const String16& name, - const String16& comment, - bool onlyIfEmpty = false); - - bool appendTypeComment(const String16& package, - const String16& type, - const String16& name, - const String16& comment); - - size_t size() const; - size_t numLocalResources() const; - bool hasResources() const; - - sp<AaptFile> flatten(Bundle*); - - static inline uint32_t makeResId(uint32_t packageId, - uint32_t typeId, - uint32_t nameId) - { - return nameId | (typeId<<16) | (packageId<<24); - } - - static inline uint32_t getResId(const sp<Package>& p, - const sp<Type>& t, - uint32_t nameId); - - uint32_t getResId(const String16& package, - const String16& type, - const String16& name, - bool onlyPublic = false) const; - - uint32_t getResId(const String16& ref, - const String16* defType = NULL, - const String16* defPackage = NULL, - const char** outErrorMsg = NULL, - bool onlyPublic = false) const; - - static bool isValidResourceName(const String16& s); - - bool stringToValue(Res_value* outValue, StringPool* pool, - const String16& str, - bool preserveSpaces, bool coerceType, - uint32_t attrID, - const Vector<StringPool::entry_style_span>* style = NULL, - String16* outStr = NULL, void* accessorCookie = NULL, - uint32_t attrType = ResTable_map::TYPE_ANY); - - status_t assignResourceIds(); - status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL); - void addLocalization(const String16& name, const String8& locale); - status_t validateLocalizations(void); - - status_t flatten(Bundle*, const sp<AaptFile>& dest); - - void writePublicDefinitions(const String16& package, FILE* fp); - - virtual uint32_t getCustomResource(const String16& package, - const String16& type, - const String16& name) const; - virtual uint32_t getCustomResourceWithCreation(const String16& package, - const String16& type, - const String16& name, - const bool createIfNeeded); - virtual uint32_t getRemappedPackage(uint32_t origPackage) const; - virtual bool getAttributeType(uint32_t attrID, uint32_t* outType); - virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin); - virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax); - virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys); - virtual bool getAttributeEnum(uint32_t attrID, - const char16_t* name, size_t nameLen, - Res_value* outValue); - virtual bool getAttributeFlags(uint32_t attrID, - const char16_t* name, size_t nameLen, - Res_value* outValue); - virtual uint32_t getAttributeL10N(uint32_t attrID); - - virtual bool getLocalizationSetting(); - virtual void reportError(void* accessorCookie, const char* fmt, ...); - - void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; } - - class Item { - public: - Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false) - { memset(&parsedValue, 0, sizeof(parsedValue)); } - Item(const SourcePos& pos, - bool _isId, - const String16& _value, - const Vector<StringPool::entry_style_span>* _style = NULL, - int32_t format = ResTable_map::TYPE_ANY); - Item(const Item& o) : sourcePos(o.sourcePos), - isId(o.isId), value(o.value), style(o.style), - format(o.format), bagKeyId(o.bagKeyId), evaluating(false) { - memset(&parsedValue, 0, sizeof(parsedValue)); - } - ~Item() { } - - Item& operator=(const Item& o) { - sourcePos = o.sourcePos; - isId = o.isId; - value = o.value; - style = o.style; - format = o.format; - bagKeyId = o.bagKeyId; - parsedValue = o.parsedValue; - return *this; - } - - SourcePos sourcePos; - mutable bool isId; - String16 value; - Vector<StringPool::entry_style_span> style; - int32_t format; - uint32_t bagKeyId; - mutable bool evaluating; - Res_value parsedValue; - }; - - class Entry : public RefBase { - public: - Entry(const String16& name, const SourcePos& pos) - : mName(name), mType(TYPE_UNKNOWN), - mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos) - { } - virtual ~Entry() { } - - enum type { - TYPE_UNKNOWN = 0, - TYPE_ITEM, - TYPE_BAG - }; - - String16 getName() const { return mName; } - type getType() const { return mType; } - - void setParent(const String16& parent) { mParent = parent; } - String16 getParent() const { return mParent; } - - status_t makeItABag(const SourcePos& sourcePos); - - status_t setItem(const SourcePos& pos, - const String16& value, - const Vector<StringPool::entry_style_span>* style = NULL, - int32_t format = ResTable_map::TYPE_ANY, - const bool overwrite = false); - - status_t addToBag(const SourcePos& pos, - const String16& key, const String16& value, - const Vector<StringPool::entry_style_span>* style = NULL, - bool replace=false, bool isId = false, - int32_t format = ResTable_map::TYPE_ANY); - - // Index of the entry's name string in the key pool. - int32_t getNameIndex() const { return mNameIndex; } - void setNameIndex(int32_t index) { mNameIndex = index; } - - const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; } - const KeyedVector<String16, Item>& getBag() const { return mBag; } - - status_t generateAttributes(ResourceTable* table, - const String16& package); - - status_t assignResourceIds(ResourceTable* table, - const String16& package); - - status_t prepareFlatten(StringPool* strings, ResourceTable* table); - - ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic); - - const SourcePos& getPos() const { return mPos; } - - private: - String16 mName; - String16 mParent; - type mType; - Item mItem; - int32_t mItemFormat; - KeyedVector<String16, Item> mBag; - int32_t mNameIndex; - uint32_t mParentId; - SourcePos mPos; - }; - - struct ConfigDescription : public ResTable_config { - ConfigDescription() { - memset(this, 0, sizeof(*this)); - size = sizeof(ResTable_config); - } - ConfigDescription(const ResTable_config&o) { - *static_cast<ResTable_config*>(this) = o; - size = sizeof(ResTable_config); - } - ConfigDescription(const ConfigDescription&o) { - *static_cast<ResTable_config*>(this) = o; - } - - ConfigDescription& operator=(const ResTable_config& o) { - *static_cast<ResTable_config*>(this) = o; - size = sizeof(ResTable_config); - return *this; - } - ConfigDescription& operator=(const ConfigDescription& o) { - *static_cast<ResTable_config*>(this) = o; - return *this; - } - - inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; } - inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; } - inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; } - inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; } - inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; } - inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; } - }; - - class ConfigList : public RefBase { - public: - ConfigList(const String16& name, const SourcePos& pos) - : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { } - virtual ~ConfigList() { } - - String16 getName() const { return mName; } - const SourcePos& getPos() const { return mPos; } - - void appendComment(const String16& comment, bool onlyIfEmpty = false); - const String16& getComment() const { return mComment; } - - void appendTypeComment(const String16& comment); - const String16& getTypeComment() const { return mTypeComment; } - - // Index of this entry in its Type. - int32_t getEntryIndex() const { return mEntryIndex; } - void setEntryIndex(int32_t index) { mEntryIndex = index; } - - void setPublic(bool pub) { mPublic = pub; } - bool getPublic() const { return mPublic; } - void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; } - const SourcePos& getPublicSourcePos() { return mPublicSourcePos; } - - void addEntry(const ResTable_config& config, const sp<Entry>& entry) { - mEntries.add(config, entry); - } - - const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; } - private: - const String16 mName; - const SourcePos mPos; - String16 mComment; - String16 mTypeComment; - bool mPublic; - SourcePos mPublicSourcePos; - int32_t mEntryIndex; - DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries; - }; - - class Public { - public: - Public() : sourcePos(), ident(0) { } - Public(const SourcePos& pos, - const String16& _comment, - uint32_t _ident) - : sourcePos(pos), - comment(_comment), ident(_ident) { } - Public(const Public& o) : sourcePos(o.sourcePos), - comment(o.comment), ident(o.ident) { } - ~Public() { } - - Public& operator=(const Public& o) { - sourcePos = o.sourcePos; - comment = o.comment; - ident = o.ident; - return *this; - } - - SourcePos sourcePos; - String16 comment; - uint32_t ident; - }; - - class Type : public RefBase { - public: - Type(const String16& name, const SourcePos& pos) - : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos) - { } - virtual ~Type() { delete mFirstPublicSourcePos; } - - status_t addPublic(const SourcePos& pos, - const String16& name, - const uint32_t ident); - - String16 getName() const { return mName; } - sp<Entry> getEntry(const String16& entry, - const SourcePos& pos, - const ResTable_config* config = NULL, - bool doSetIndex = false); - - const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } - - int32_t getPublicIndex() const { return mPublicIndex; } - - int32_t getIndex() const { return mIndex; } - void setIndex(int32_t index) { mIndex = index; } - - status_t applyPublicEntryOrder(); - - const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; } - - const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; } - const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; } - - const SourcePos& getPos() const { return mPos; } - private: - String16 mName; - SourcePos* mFirstPublicSourcePos; - DefaultKeyedVector<String16, Public> mPublic; - SortedVector<ConfigDescription> mUniqueConfigs; - DefaultKeyedVector<String16, sp<ConfigList> > mConfigs; - Vector<sp<ConfigList> > mOrderedConfigs; - int32_t mPublicIndex; - int32_t mIndex; - SourcePos mPos; - }; - - class Package : public RefBase { - public: - Package(const String16& name, ssize_t includedId=-1); - virtual ~Package() { } - - String16 getName() const { return mName; } - sp<Type> getType(const String16& type, - const SourcePos& pos, - bool doSetIndex = false); - - ssize_t getAssignedId() const { return mIncludedId; } - - const ResStringPool& getTypeStrings() const { return mTypeStrings; } - uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); } - const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; } - status_t setTypeStrings(const sp<AaptFile>& data); - - const ResStringPool& getKeyStrings() const { return mKeyStrings; } - uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); } - const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; } - status_t setKeyStrings(const sp<AaptFile>& data); - - status_t applyPublicTypeOrder(); - - const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; } - const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; } - - private: - status_t setStrings(const sp<AaptFile>& data, - ResStringPool* strings, - DefaultKeyedVector<String16, uint32_t>* mappings); - - const String16 mName; - const ssize_t mIncludedId; - DefaultKeyedVector<String16, sp<Type> > mTypes; - Vector<sp<Type> > mOrderedTypes; - sp<AaptFile> mTypeStringsData; - sp<AaptFile> mKeyStringsData; - ResStringPool mTypeStrings; - ResStringPool mKeyStrings; - DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping; - DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping; - }; - -private: - void writePublicDefinitions(const String16& package, FILE* fp, bool pub); - sp<Package> getPackage(const String16& package); - sp<Type> getType(const String16& package, - const String16& type, - const SourcePos& pos, - bool doSetIndex = false); - sp<Entry> getEntry(const String16& package, - const String16& type, - const String16& name, - const SourcePos& pos, - const ResTable_config* config = NULL, - bool doSetIndex = false); - sp<const Entry> getEntry(uint32_t resID, - const ResTable_config* config = NULL) const; - const Item* getItem(uint32_t resID, uint32_t attrID) const; - bool getItemValue(uint32_t resID, uint32_t attrID, - Res_value* outValue); - - - String16 mAssetsPackage; - sp<AaptAssets> mAssets; - DefaultKeyedVector<String16, sp<Package> > mPackages; - Vector<sp<Package> > mOrderedPackages; - uint32_t mNextPackageId; - bool mHaveAppPackage; - bool mIsAppPackage; - size_t mNumLocal; - SourcePos mCurrentXmlPos; - Bundle* mBundle; - - // key = string resource name, value = set of locales in which that name is defined - map<String16, set<String8> > mLocalizations; -}; - -class ResourceFilter -{ -public: - ResourceFilter() : mData(), mContainsPseudo(false) {} - status_t parse(const char* arg); - bool match(int axis, uint32_t value); - bool match(const ResTable_config& config); - inline bool containsPseudo() { return mContainsPseudo; } - -private: - KeyedVector<int,SortedVector<uint32_t> > mData; - bool mContainsPseudo; -}; - - -#endif diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp deleted file mode 100644 index 2761d18..0000000 --- a/tools/aapt/SourcePos.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "SourcePos.h" - -#include <stdarg.h> -#include <vector> - -using namespace std; - - -// ErrorPos -// ============================================================================= -struct ErrorPos -{ - String8 file; - int line; - String8 error; - bool fatal; - - ErrorPos(); - ErrorPos(const ErrorPos& that); - ErrorPos(const String8& file, int line, const String8& error, bool fatal); - ~ErrorPos(); - bool operator<(const ErrorPos& rhs) const; - bool operator==(const ErrorPos& rhs) const; - ErrorPos& operator=(const ErrorPos& rhs); - - void print(FILE* to) const; -}; - -static vector<ErrorPos> g_errors; - -ErrorPos::ErrorPos() - :line(-1), fatal(false) -{ -} - -ErrorPos::ErrorPos(const ErrorPos& that) - :file(that.file), - line(that.line), - error(that.error), - fatal(that.fatal) -{ -} - -ErrorPos::ErrorPos(const String8& f, int l, const String8& e, bool fat) - :file(f), - line(l), - error(e), - fatal(fat) -{ -} - -ErrorPos::~ErrorPos() -{ -} - -bool -ErrorPos::operator<(const ErrorPos& rhs) const -{ - if (this->file < rhs.file) return true; - if (this->file == rhs.file) { - if (this->line < rhs.line) return true; - if (this->line == rhs.line) { - if (this->error < rhs.error) return true; - } - } - return false; -} - -bool -ErrorPos::operator==(const ErrorPos& rhs) const -{ - return this->file == rhs.file - && this->line == rhs.line - && this->error == rhs.error; -} - -ErrorPos& -ErrorPos::operator=(const ErrorPos& rhs) -{ - this->file = rhs.file; - this->line = rhs.line; - this->error = rhs.error; - return *this; -} - -void -ErrorPos::print(FILE* to) const -{ - const char* type = fatal ? "ERROR" : "WARNING"; - - if (this->line >= 0) { - fprintf(to, "%s:%d: %s %s\n", this->file.string(), this->line, type, this->error.string()); - } else { - fprintf(to, "%s: %s %s\n", this->file.string(), type, this->error.string()); - } -} - -// SourcePos -// ============================================================================= -SourcePos::SourcePos(const String8& f, int l) - : file(f), line(l) -{ -} - -SourcePos::SourcePos(const SourcePos& that) - : file(that.file), line(that.line) -{ -} - -SourcePos::SourcePos() - : file("???", 0), line(-1) -{ -} - -SourcePos::~SourcePos() -{ -} - -int -SourcePos::error(const char* fmt, ...) const -{ - int retval=0; - char buf[1024]; - va_list ap; - va_start(ap, fmt); - retval = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - char* p = buf + retval - 1; - while (p > buf && *p == '\n') { - *p = '\0'; - p--; - } - g_errors.push_back(ErrorPos(this->file, this->line, String8(buf), true)); - return retval; -} - -int -SourcePos::warning(const char* fmt, ...) const -{ - int retval=0; - char buf[1024]; - va_list ap; - va_start(ap, fmt); - retval = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - char* p = buf + retval - 1; - while (p > buf && *p == '\n') { - *p = '\0'; - p--; - } - ErrorPos(this->file, this->line, String8(buf), false).print(stderr); - return retval; -} - -bool -SourcePos::hasErrors() -{ - return g_errors.size() > 0; -} - -void -SourcePos::printErrors(FILE* to) -{ - vector<ErrorPos>::const_iterator it; - for (it=g_errors.begin(); it!=g_errors.end(); it++) { - it->print(to); - } -} - - - diff --git a/tools/aapt/SourcePos.h b/tools/aapt/SourcePos.h deleted file mode 100644 index 33f72a9..0000000 --- a/tools/aapt/SourcePos.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SOURCEPOS_H -#define SOURCEPOS_H - -#include <utils/String8.h> -#include <stdio.h> - -using namespace android; - -class SourcePos -{ -public: - String8 file; - int line; - - SourcePos(const String8& f, int l); - SourcePos(const SourcePos& that); - SourcePos(); - ~SourcePos(); - - int error(const char* fmt, ...) const; - int warning(const char* fmt, ...) const; - - static bool hasErrors(); - static void printErrors(FILE* to); -}; - - -#endif // SOURCEPOS_H diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp deleted file mode 100644 index 878d3b1..0000000 --- a/tools/aapt/StringPool.cpp +++ /dev/null @@ -1,369 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#include "StringPool.h" - -#include <utils/ByteOrder.h> - -#define NOISY(x) //x - -void strcpy16_htod(uint16_t* dst, const uint16_t* src) -{ - while (*src) { - char16_t s = htods(*src); - *dst++ = s; - src++; - } - *dst = 0; -} - -void printStringPool(const ResStringPool* pool) -{ - const size_t NS = pool->size(); - for (size_t s=0; s<NS; s++) { - size_t len; - printf("String #%d: %s\n", s, - String8(pool->stringAt(s, &len)).string()); - } -} - -StringPool::StringPool(bool sorted) - : mSorted(sorted), mValues(-1), mIdents(-1) -{ -} - -ssize_t StringPool::add(const String16& value, bool mergeDuplicates) -{ - return add(String16(), value, mergeDuplicates); -} - -ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans) -{ - ssize_t res = add(String16(), value, false); - if (res >= 0) { - addStyleSpans(res, spans); - } - return res; -} - -ssize_t StringPool::add(const String16& ident, const String16& value, - bool mergeDuplicates) -{ - if (ident.size() > 0) { - ssize_t idx = mIdents.valueFor(ident); - if (idx >= 0) { - fprintf(stderr, "ERROR: Duplicate string identifier %s\n", - String8(mEntries[idx].value).string()); - return UNKNOWN_ERROR; - } - } - - ssize_t vidx = mValues.indexOfKey(value); - ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1; - ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1; - if (eidx < 0) { - eidx = mEntries.add(entry(value)); - if (eidx < 0) { - fprintf(stderr, "Failure adding string %s\n", String8(value).string()); - return eidx; - } - } - - const bool first = vidx < 0; - if (first || !mergeDuplicates) { - pos = mEntryArray.add(eidx); - if (first) { - vidx = mValues.add(value, pos); - const size_t N = mEntryArrayToValues.size(); - for (size_t i=0; i<N; i++) { - size_t& e = mEntryArrayToValues.editItemAt(i); - if ((ssize_t)e >= vidx) { - e++; - } - } - } - mEntryArrayToValues.add(vidx); - if (!mSorted) { - entry& ent = mEntries.editItemAt(eidx); - ent.indices.add(pos); - } - } - - if (ident.size() > 0) { - mIdents.add(ident, vidx); - } - - NOISY(printf("Adding string %s to pool: pos=%d eidx=%d vidx=%d\n", - String8(value).string(), pos, eidx, vidx)); - - return pos; -} - -status_t StringPool::addStyleSpan(size_t idx, const String16& name, - uint32_t start, uint32_t end) -{ - entry_style_span span; - span.name = name; - span.span.firstChar = start; - span.span.lastChar = end; - return addStyleSpan(idx, span); -} - -status_t StringPool::addStyleSpans(size_t idx, const Vector<entry_style_span>& spans) -{ - const size_t N=spans.size(); - for (size_t i=0; i<N; i++) { - status_t err = addStyleSpan(idx, spans[i]); - if (err != NO_ERROR) { - return err; - } - } - return NO_ERROR; -} - -status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span) -{ - LOG_ALWAYS_FATAL_IF(mSorted, "Can't use styles with sorted string pools."); - - // Place blank entries in the span array up to this index. - while (mEntryStyleArray.size() <= idx) { - mEntryStyleArray.add(); - } - - entry_style& style = mEntryStyleArray.editItemAt(idx); - style.spans.add(span); - return NO_ERROR; -} - -size_t StringPool::size() const -{ - return mSorted ? mValues.size() : mEntryArray.size(); -} - -const StringPool::entry& StringPool::entryAt(size_t idx) const -{ - if (!mSorted) { - return mEntries[mEntryArray[idx]]; - } else { - return mEntries[mEntryArray[mValues.valueAt(idx)]]; - } -} - -size_t StringPool::countIdentifiers() const -{ - return mIdents.size(); -} - -sp<AaptFile> StringPool::createStringBlock() -{ - sp<AaptFile> pool = new AaptFile(String8(), AaptGroupEntry(), - String8()); - status_t err = writeStringBlock(pool); - return err == NO_ERROR ? pool : NULL; -} - -status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) -{ - // Allow appending. Sorry this is a little wacky. - if (pool->getSize() > 0) { - sp<AaptFile> block = createStringBlock(); - if (block == NULL) { - return UNKNOWN_ERROR; - } - ssize_t res = pool->writeData(block->getData(), block->getSize()); - return (res >= 0) ? (status_t)NO_ERROR : res; - } - - // First we need to add all style span names to the string pool. - // We do this now (instead of when the span is added) so that these - // will appear at the end of the pool, not disrupting the order - // our client placed their own strings in it. - - const size_t STYLES = mEntryStyleArray.size(); - size_t i; - - for (i=0; i<STYLES; i++) { - entry_style& style = mEntryStyleArray.editItemAt(i); - const size_t N = style.spans.size(); - for (size_t i=0; i<N; i++) { - entry_style_span& span = style.spans.editItemAt(i); - ssize_t idx = add(span.name, true); - if (idx < 0) { - fprintf(stderr, "Error adding span for style tag '%s'\n", - String8(span.name).string()); - return idx; - } - span.span.name.index = (uint32_t)idx; - } - } - - const size_t ENTRIES = size(); - - // Now build the pool of unique strings. - - const size_t STRINGS = mEntries.size(); - const size_t preSize = sizeof(ResStringPool_header) - + (sizeof(uint32_t)*ENTRIES) - + (sizeof(uint32_t)*STYLES); - if (pool->editData(preSize) == NULL) { - fprintf(stderr, "ERROR: Out of memory for string pool\n"); - return NO_MEMORY; - } - - size_t strPos = 0; - for (i=0; i<STRINGS; i++) { - entry& ent = mEntries.editItemAt(i); - const size_t strSize = (ent.value.size()); - const size_t lenSize = strSize > 0x7fff ? sizeof(uint32_t) : sizeof(uint16_t); - const size_t totalSize = lenSize + ((strSize+1)*sizeof(uint16_t)); - - ent.offset = strPos; - uint16_t* dat = (uint16_t*)pool->editData(preSize + strPos + totalSize); - if (dat == NULL) { - fprintf(stderr, "ERROR: Out of memory for string pool\n"); - return NO_MEMORY; - } - dat += (preSize+strPos)/sizeof(uint16_t); - if (lenSize > sizeof(uint16_t)) { - *dat = htods(0x8000 | ((strSize>>16)&0x7ffff)); - dat++; - } - *dat++ = htods(strSize); - strcpy16_htod(dat, ent.value); - - strPos += lenSize + (strSize+1)*sizeof(uint16_t); - } - - // Pad ending string position up to a uint32_t boundary. - - if (strPos&0x3) { - size_t padPos = ((strPos+3)&~0x3); - uint8_t* dat = (uint8_t*)pool->editData(preSize + padPos); - if (dat == NULL) { - fprintf(stderr, "ERROR: Out of memory padding string pool\n"); - return NO_MEMORY; - } - memset(dat+preSize+strPos, 0, padPos-strPos); - strPos = padPos; - } - - // Build the pool of style spans. - - size_t styPos = strPos; - for (i=0; i<STYLES; i++) { - entry_style& ent = mEntryStyleArray.editItemAt(i); - const size_t N = ent.spans.size(); - const size_t totalSize = (N*sizeof(ResStringPool_span)) - + sizeof(ResStringPool_ref); - - ent.offset = styPos-strPos; - uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + totalSize); - if (dat == NULL) { - fprintf(stderr, "ERROR: Out of memory for string styles\n"); - return NO_MEMORY; - } - ResStringPool_span* span = (ResStringPool_span*)(dat+preSize+styPos); - for (size_t i=0; i<N; i++) { - span->name.index = htodl(ent.spans[i].span.name.index); - span->firstChar = htodl(ent.spans[i].span.firstChar); - span->lastChar = htodl(ent.spans[i].span.lastChar); - span++; - } - span->name.index = htodl(ResStringPool_span::END); - - styPos += totalSize; - } - - if (STYLES > 0) { - // Add full terminator at the end (when reading we validate that - // the end of the pool is fully terminated to simplify error - // checking). - size_t extra = sizeof(ResStringPool_span)-sizeof(ResStringPool_ref); - uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + extra); - if (dat == NULL) { - fprintf(stderr, "ERROR: Out of memory for string styles\n"); - return NO_MEMORY; - } - uint32_t* p = (uint32_t*)(dat+preSize+styPos); - while (extra > 0) { - *p++ = htodl(ResStringPool_span::END); - extra -= sizeof(uint32_t); - } - styPos += extra; - } - - // Write header. - - ResStringPool_header* header = - (ResStringPool_header*)pool->padData(sizeof(uint32_t)); - if (header == NULL) { - fprintf(stderr, "ERROR: Out of memory for string pool\n"); - return NO_MEMORY; - } - memset(header, 0, sizeof(*header)); - header->header.type = htods(RES_STRING_POOL_TYPE); - header->header.headerSize = htods(sizeof(*header)); - header->header.size = htodl(pool->getSize()); - header->stringCount = htodl(ENTRIES); - header->styleCount = htodl(STYLES); - if (mSorted) { - header->flags |= htodl(ResStringPool_header::SORTED_FLAG); - } - header->stringsStart = htodl(preSize); - header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0); - - // Write string index array. - - uint32_t* index = (uint32_t*)(header+1); - if (mSorted) { - for (i=0; i<ENTRIES; i++) { - entry& ent = const_cast<entry&>(entryAt(i)); - ent.indices.clear(); - ent.indices.add(i); - *index++ = htodl(ent.offset); - } - } else { - for (i=0; i<ENTRIES; i++) { - entry& ent = mEntries.editItemAt(mEntryArray[i]); - *index++ = htodl(ent.offset); - NOISY(printf("Writing entry #%d: \"%s\" ent=%d off=%d\n", i, - String8(ent.value).string(), - mEntryArray[i], ent.offset)); - } - } - - // Write style index array. - - if (mSorted) { - for (i=0; i<STYLES; i++) { - LOG_ALWAYS_FATAL("Shouldn't be here!"); - } - } else { - for (i=0; i<STYLES; i++) { - *index++ = htodl(mEntryStyleArray[i].offset); - } - } - - return NO_ERROR; -} - -ssize_t StringPool::offsetForString(const String16& val) const -{ - const Vector<size_t>* indices = offsetsForString(val); - ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1; - NOISY(printf("Offset for string %s: %d (%s)\n", String8(val).string(), res, - res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8())); - return res; -} - -const Vector<size_t>* StringPool::offsetsForString(const String16& val) const -{ - ssize_t pos = mValues.valueFor(val); - if (pos < 0) { - return NULL; - } - return &mEntries[mEntryArray[pos]].indices; -} diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h deleted file mode 100644 index 9082b37..0000000 --- a/tools/aapt/StringPool.h +++ /dev/null @@ -1,148 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#ifndef STRING_POOL_H -#define STRING_POOL_H - -#include "Main.h" -#include "AaptAssets.h" - -#include <utils/ResourceTypes.h> -#include <utils/String16.h> -#include <utils/TextOutput.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <ctype.h> -#include <errno.h> - -#include <expat.h> - -using namespace android; - -#define PRINT_STRING_METRICS 0 - -void strcpy16_htod(uint16_t* dst, const uint16_t* src); - -void printStringPool(const ResStringPool* pool); - -/** - * The StringPool class is used as an intermediate representation for - * generating the string pool resource data structure that can be parsed with - * ResStringPool in include/utils/ResourceTypes.h. - */ -class StringPool -{ -public: - struct entry { - entry() : offset(0) { } - entry(const String16& _value) : value(_value), offset(0) { } - entry(const entry& o) : value(o.value), offset(o.offset), indices(o.indices) { } - - String16 value; - size_t offset; - Vector<size_t> indices; - }; - - struct entry_style_span { - String16 name; - ResStringPool_span span; - }; - - struct entry_style { - entry_style() : offset(0) { } - - entry_style(const entry_style& o) : offset(o.offset), spans(o.spans) { } - - size_t offset; - Vector<entry_style_span> spans; - }; - - /** - * If 'sorted' is true, then the final strings in the resource data - * structure will be generated in sorted order. This allow for fast - * lookup with ResStringPool::indexOfString() (O(log n)), at the expense - * of support for styled string entries (which requires the same string - * be included multiple times in the pool). - */ - explicit StringPool(bool sorted = false); - - /** - * Add a new string to the pool. If mergeDuplicates is true, thenif - * the string already exists the existing entry for it will be used; - * otherwise, or if the value doesn't already exist, a new entry is - * created. - * - * Returns the index in the entry array of the new string entry. Note that - * if this string pool is sorted, the returned index will not be valid - * when the pool is finally written. - */ - ssize_t add(const String16& value, bool mergeDuplicates = false); - - ssize_t add(const String16& value, const Vector<entry_style_span>& spans); - - ssize_t add(const String16& ident, const String16& value, - bool mergeDuplicates = false); - - status_t addStyleSpan(size_t idx, const String16& name, - uint32_t start, uint32_t end); - status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans); - status_t addStyleSpan(size_t idx, const entry_style_span& span); - - size_t size() const; - - const entry& entryAt(size_t idx) const; - - size_t countIdentifiers() const; - - sp<AaptFile> createStringBlock(); - - status_t writeStringBlock(const sp<AaptFile>& pool); - - /** - * Find out an offset in the pool for a particular string. If the string - * pool is sorted, this can not be called until after createStringBlock() - * or writeStringBlock() has been called - * (which determines the offsets). In the case of a string that appears - * multiple times in the pool, the first offset will be returned. Returns - * -1 if the string does not exist. - */ - ssize_t offsetForString(const String16& val) const; - - /** - * Find all of the offsets in the pool for a particular string. If the - * string pool is sorted, this can not be called until after - * createStringBlock() or writeStringBlock() has been called - * (which determines the offsets). Returns NULL if the string does not exist. - */ - const Vector<size_t>* offsetsForString(const String16& val) const; - -private: - const bool mSorted; - // Raw array of unique strings, in some arbitrary order. - Vector<entry> mEntries; - // Array of indices into mEntries, in the order they were - // added to the pool. This can be different than mEntries - // if the same string was added multiple times (it will appear - // once in mEntries, with multiple occurrences in this array). - Vector<size_t> mEntryArray; - // Optional style span information associated with each index of - // mEntryArray. - Vector<entry_style> mEntryStyleArray; - // Mapping from indices in mEntryArray to indices in mValues. - Vector<size_t> mEntryArrayToValues; - // Unique set of all the strings added to the pool, mapped to - // the first index of mEntryArray where the value was added. - DefaultKeyedVector<String16, ssize_t> mValues; - // Unique set of all (optional) identifiers of strings in the - // pool, mapping to indices in mEntries. - DefaultKeyedVector<String16, ssize_t> mIdents; - -}; - -#endif - diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp deleted file mode 100644 index d476567..0000000 --- a/tools/aapt/XMLNode.cpp +++ /dev/null @@ -1,1295 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#include "XMLNode.h" -#include "ResourceTable.h" - -#include <host/pseudolocalize.h> -#include <utils/ByteOrder.h> -#include <errno.h> -#include <string.h> - -#ifndef HAVE_MS_C_RUNTIME -#define O_BINARY 0 -#endif - -#define NOISY(x) //x -#define NOISY_PARSE(x) //x - -const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/"; -const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"; -const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/"; - -const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2"; -const char* const ALLOWED_XLIFF_ELEMENTS[] = { - "bpt", - "ept", - "it", - "ph", - "g", - "bx", - "ex", - "x" - }; - -bool isWhitespace(const char16_t* str) -{ - while (*str != 0 && *str < 128 && isspace(*str)) { - str++; - } - return *str == 0; -} - -static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE); -static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE); - -String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic) -{ - //printf("%s starts with %s?\n", String8(namespaceUri).string(), - // String8(RESOURCES_PREFIX).string()); - size_t prefixSize; - bool isPublic = true; - if (namespaceUri.startsWith(RESOURCES_PREFIX)) { - prefixSize = RESOURCES_PREFIX.size(); - } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) { - isPublic = false; - prefixSize = RESOURCES_PRV_PREFIX.size(); - } else { - if (outIsPublic) *outIsPublic = isPublic; // = true - return String16(); - } - - //printf("YES!\n"); - //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string()); - if (outIsPublic) *outIsPublic = isPublic; - return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize); -} - -status_t parseStyledString(Bundle* bundle, - const char* fileName, - ResXMLTree* inXml, - const String16& endTag, - String16* outString, - Vector<StringPool::entry_style_span>* outSpans, - bool pseudolocalize) -{ - Vector<StringPool::entry_style_span> spanStack; - String16 curString; - String16 rawString; - const char* errorMsg; - int xliffDepth = 0; - bool firstTime = true; - - size_t len; - ResXMLTree::event_code_t code; - while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - - if (code == ResXMLTree::TEXT) { - String16 text(inXml->getText(&len)); - if (firstTime && text.size() > 0) { - firstTime = false; - if (text.string()[0] == '@') { - // If this is a resource reference, don't do the pseudoloc. - pseudolocalize = false; - } - } - if (xliffDepth == 0 && pseudolocalize) { - std::string orig(String8(text).string()); - std::string pseudo = pseudolocalize_string(orig); - curString.append(String16(String8(pseudo.c_str()))); - } else { - curString.append(text); - } - } else if (code == ResXMLTree::START_TAG) { - const String16 element16(inXml->getElementName(&len)); - const String8 element8(element16); - - size_t nslen; - const uint16_t* ns = inXml->getElementNamespace(&nslen); - if (ns == NULL) { - ns = (const uint16_t*)"\0\0"; - nslen = 0; - } - const String8 nspace(String16(ns, nslen)); - if (nspace == XLIFF_XMLNS) { - const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]); - for (int i=0; i<N; i++) { - if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) { - xliffDepth++; - // in this case, treat it like it was just text, in other words, do nothing - // here and silently drop this element - goto moveon; - } - } - { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Found unsupported XLIFF tag <%s>\n", - element8.string()); - return UNKNOWN_ERROR; - } -moveon: - continue; - } - - if (outSpans == NULL) { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Found style tag <%s> where styles are not allowed\n", element8.string()); - return UNKNOWN_ERROR; - } - - if (!ResTable::collectString(outString, curString.string(), - curString.size(), false, &errorMsg, true)) { - SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", - errorMsg, String8(curString).string()); - return UNKNOWN_ERROR; - } - rawString.append(curString); - curString = String16(); - - StringPool::entry_style_span span; - span.name = element16; - for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) { - span.name.append(String16(";")); - const char16_t* str = inXml->getAttributeName(ai, &len); - span.name.append(str, len); - span.name.append(String16("=")); - str = inXml->getAttributeStringValue(ai, &len); - span.name.append(str, len); - } - //printf("Span: %s\n", String8(span.name).string()); - span.span.firstChar = span.span.lastChar = outString->size(); - spanStack.push(span); - - } else if (code == ResXMLTree::END_TAG) { - size_t nslen; - const uint16_t* ns = inXml->getElementNamespace(&nslen); - if (ns == NULL) { - ns = (const uint16_t*)"\0\0"; - nslen = 0; - } - const String8 nspace(String16(ns, nslen)); - if (nspace == XLIFF_XMLNS) { - xliffDepth--; - continue; - } - if (!ResTable::collectString(outString, curString.string(), - curString.size(), false, &errorMsg, true)) { - SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", - errorMsg, String8(curString).string()); - return UNKNOWN_ERROR; - } - rawString.append(curString); - curString = String16(); - - if (spanStack.size() == 0) { - if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Found tag %s where <%s> close is expected\n", - String8(inXml->getElementName(&len)).string(), - String8(endTag).string()); - return UNKNOWN_ERROR; - } - break; - } - StringPool::entry_style_span span = spanStack.top(); - String16 spanTag; - ssize_t semi = span.name.findFirst(';'); - if (semi >= 0) { - spanTag.setTo(span.name.string(), semi); - } else { - spanTag.setTo(span.name); - } - if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Found close tag %s where close tag %s is expected\n", - String8(inXml->getElementName(&len)).string(), - String8(spanTag).string()); - return UNKNOWN_ERROR; - } - bool empty = true; - if (outString->size() > 0) { - span.span.lastChar = outString->size()-1; - if (span.span.lastChar >= span.span.firstChar) { - empty = false; - outSpans->add(span); - } - } - spanStack.pop(); - - if (empty) { - fprintf(stderr, "%s:%d: WARNING: empty '%s' span found in text '%s'\n", - fileName, inXml->getLineNumber(), - String8(spanTag).string(), String8(*outString).string()); - - } - } else if (code == ResXMLTree::START_NAMESPACE) { - // nothing - } - } - - if (code == ResXMLTree::BAD_DOCUMENT) { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "Error parsing XML\n"); - } - - if (outSpans != NULL && outSpans->size() > 0) { - if (curString.size() > 0) { - if (!ResTable::collectString(outString, curString.string(), - curString.size(), false, &errorMsg, true)) { - SourcePos(String8(fileName), inXml->getLineNumber()).error( - "%s (in %s)\n", - errorMsg, String8(curString).string()); - return UNKNOWN_ERROR; - } - } - } else { - // There is no style information, so string processing will happen - // later as part of the overall type conversion. Return to the - // client the raw unprocessed text. - rawString.append(curString); - outString->setTo(rawString); - } - - return NO_ERROR; -} - -struct namespace_entry { - String8 prefix; - String8 uri; -}; - -static String8 make_prefix(int depth) -{ - String8 prefix; - int i; - for (i=0; i<depth; i++) { - prefix.append(" "); - } - return prefix; -} - -static String8 build_namespace(const Vector<namespace_entry>& namespaces, - const uint16_t* ns) -{ - String8 str; - if (ns != NULL) { - str = String8(ns); - const size_t N = namespaces.size(); - for (size_t i=0; i<N; i++) { - const namespace_entry& ne = namespaces.itemAt(i); - if (ne.uri == str) { - str = ne.prefix; - break; - } - } - str.append(":"); - } - return str; -} - -void printXMLBlock(ResXMLTree* block) -{ - block->restart(); - - Vector<namespace_entry> namespaces; - - ResXMLTree::event_code_t code; - int depth = 0; - while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - String8 prefix = make_prefix(depth); - int i; - if (code == ResXMLTree::START_TAG) { - size_t len; - const uint16_t* ns16 = block->getElementNamespace(&len); - String8 elemNs = build_namespace(namespaces, ns16); - const uint16_t* com16 = block->getComment(&len); - if (com16) { - printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string()); - } - printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(), - String8(block->getElementName(&len)).string(), - block->getLineNumber()); - int N = block->getAttributeCount(); - depth++; - prefix = make_prefix(depth); - for (i=0; i<N; i++) { - uint32_t res = block->getAttributeNameResID(i); - ns16 = block->getAttributeNamespace(i, &len); - String8 ns = build_namespace(namespaces, ns16); - String8 name(block->getAttributeName(i, &len)); - printf("%sA: ", prefix.string()); - if (res) { - printf("%s%s(0x%08x)", ns.string(), name.string(), res); - } else { - printf("%s%s", ns.string(), name.string()); - } - Res_value value; - block->getAttributeValue(i, &value); - if (value.dataType == Res_value::TYPE_NULL) { - printf("=(null)"); - } else if (value.dataType == Res_value::TYPE_REFERENCE) { - printf("=@0x%x", (int)value.data); - } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) { - printf("=?0x%x", (int)value.data); - } else if (value.dataType == Res_value::TYPE_STRING) { - printf("=\"%s\"", - String8(block->getAttributeStringValue(i, &len)).string()); - } else { - printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data); - } - const char16_t* val = block->getAttributeStringValue(i, &len); - if (val != NULL) { - printf(" (Raw: \"%s\")", String8(val).string()); - } - printf("\n"); - } - } else if (code == ResXMLTree::END_TAG) { - depth--; - } else if (code == ResXMLTree::START_NAMESPACE) { - namespace_entry ns; - size_t len; - const uint16_t* prefix16 = block->getNamespacePrefix(&len); - if (prefix16) { - ns.prefix = String8(prefix16); - } else { - ns.prefix = "<DEF>"; - } - ns.uri = String8(block->getNamespaceUri(&len)); - namespaces.push(ns); - printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(), - ns.uri.string()); - depth++; - } else if (code == ResXMLTree::END_NAMESPACE) { - depth--; - const namespace_entry& ns = namespaces.top(); - size_t len; - const uint16_t* prefix16 = block->getNamespacePrefix(&len); - String8 pr; - if (prefix16) { - pr = String8(prefix16); - } else { - pr = "<DEF>"; - } - if (ns.prefix != pr) { - prefix = make_prefix(depth); - printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n", - prefix.string(), pr.string(), ns.prefix.string()); - } - String8 uri = String8(block->getNamespaceUri(&len)); - if (ns.uri != uri) { - prefix = make_prefix(depth); - printf("%s *** BAD END NS URI: found=%s, expected=%s\n", - prefix.string(), uri.string(), ns.uri.string()); - } - namespaces.pop(); - } else if (code == ResXMLTree::TEXT) { - size_t len; - printf("%sC: \"%s\"\n", prefix.string(), String8(block->getText(&len)).string()); - } - } - - block->restart(); -} - -status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree, - bool stripAll, bool keepComments, - const char** cDataTags) -{ - sp<XMLNode> root = XMLNode::parse(file); - if (root == NULL) { - return UNKNOWN_ERROR; - } - root->removeWhitespace(stripAll, cDataTags); - - NOISY(printf("Input XML from %s:\n", (const char*)file->getPrintableSource())); - NOISY(root->print()); - sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8()); - status_t err = root->flatten(rsc, !keepComments, false); - if (err != NO_ERROR) { - return err; - } - err = outTree->setTo(rsc->getData(), rsc->getSize(), true); - if (err != NO_ERROR) { - return err; - } - - NOISY(printf("Output XML:\n")); - NOISY(printXMLBlock(outTree)); - - return NO_ERROR; -} - -sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file) -{ - char buf[16384]; - int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY); - if (fd < 0) { - SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s", - strerror(errno)); - return NULL; - } - - XML_Parser parser = XML_ParserCreateNS(NULL, 1); - ParseState state; - state.filename = file->getPrintableSource(); - state.parser = parser; - XML_SetUserData(parser, &state); - XML_SetElementHandler(parser, startElement, endElement); - XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace); - XML_SetCharacterDataHandler(parser, characterData); - XML_SetCommentHandler(parser, commentData); - - ssize_t len; - bool done; - do { - len = read(fd, buf, sizeof(buf)); - done = len < (ssize_t)sizeof(buf); - if (len < 0) { - SourcePos(file->getSourceFile(), -1).error("Error reading file: %s\n", strerror(errno)); - close(fd); - return NULL; - } - if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { - SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error( - "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser))); - close(fd); - return NULL; - } - } while (!done); - - XML_ParserFree(parser); - if (state.root == NULL) { - SourcePos(file->getSourceFile(), -1).error("No XML data generated when parsing"); - } - close(fd); - return state.root; -} - -XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace) - : mNextAttributeIndex(0x80000000) - , mFilename(filename) - , mStartLineNumber(0) - , mEndLineNumber(0) -{ - if (isNamespace) { - mNamespacePrefix = s1; - mNamespaceUri = s2; - } else { - mNamespaceUri = s1; - mElementName = s2; - } -} - -XMLNode::XMLNode(const String8& filename) - : mFilename(filename) -{ -} - -XMLNode::type XMLNode::getType() const -{ - if (mElementName.size() != 0) { - return TYPE_ELEMENT; - } - if (mNamespaceUri.size() != 0) { - return TYPE_NAMESPACE; - } - return TYPE_CDATA; -} - -const String16& XMLNode::getNamespacePrefix() const -{ - return mNamespacePrefix; -} - -const String16& XMLNode::getNamespaceUri() const -{ - return mNamespaceUri; -} - -const String16& XMLNode::getElementNamespace() const -{ - return mNamespaceUri; -} - -const String16& XMLNode::getElementName() const -{ - return mElementName; -} - -const Vector<sp<XMLNode> >& XMLNode::getChildren() const -{ - return mChildren; -} - -const Vector<XMLNode::attribute_entry>& - XMLNode::getAttributes() const -{ - return mAttributes; -} - -const String16& XMLNode::getCData() const -{ - return mChars; -} - -const String16& XMLNode::getComment() const -{ - return mComment; -} - -int32_t XMLNode::getStartLineNumber() const -{ - return mStartLineNumber; -} - -int32_t XMLNode::getEndLineNumber() const -{ - return mEndLineNumber; -} - -status_t XMLNode::addChild(const sp<XMLNode>& child) -{ - if (getType() == TYPE_CDATA) { - SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node."); - return UNKNOWN_ERROR; - } - //printf("Adding child %p to parent %p\n", child.get(), this); - mChildren.add(child); - return NO_ERROR; -} - -status_t XMLNode::addAttribute(const String16& ns, const String16& name, - const String16& value) -{ - if (getType() == TYPE_CDATA) { - SourcePos(mFilename, getStartLineNumber()).error("Child to CDATA node."); - return UNKNOWN_ERROR; - } - attribute_entry e; - e.index = mNextAttributeIndex++; - e.ns = ns; - e.name = name; - e.string = value; - mAttributes.add(e); - mAttributeOrder.add(e.index, mAttributes.size()-1); - return NO_ERROR; -} - -void XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId) -{ - attribute_entry& e = mAttributes.editItemAt(attrIdx); - if (e.nameResId) { - mAttributeOrder.removeItem(e.nameResId); - } else { - mAttributeOrder.removeItem(e.index); - } - NOISY(printf("Elem %s %s=\"%s\": set res id = 0x%08x\n", - String8(getElementName()).string(), - String8(mAttributes.itemAt(attrIdx).name).string(), - String8(mAttributes.itemAt(attrIdx).string).string(), - resId)); - mAttributes.editItemAt(attrIdx).nameResId = resId; - mAttributeOrder.add(resId, attrIdx); -} - -status_t XMLNode::appendChars(const String16& chars) -{ - if (getType() != TYPE_CDATA) { - SourcePos(mFilename, getStartLineNumber()).error("Adding characters to element node."); - return UNKNOWN_ERROR; - } - mChars.append(chars); - return NO_ERROR; -} - -status_t XMLNode::appendComment(const String16& comment) -{ - if (mComment.size() > 0) { - mComment.append(String16("\n")); - } - mComment.append(comment); - return NO_ERROR; -} - -void XMLNode::setStartLineNumber(int32_t line) -{ - mStartLineNumber = line; -} - -void XMLNode::setEndLineNumber(int32_t line) -{ - mEndLineNumber = line; -} - -void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags) -{ - //printf("Removing whitespace in %s\n", String8(mElementName).string()); - size_t N = mChildren.size(); - if (cDataTags) { - String8 tag(mElementName); - const char** p = cDataTags; - while (*p) { - if (tag == *p) { - stripAll = false; - break; - } - } - } - for (size_t i=0; i<N; i++) { - sp<XMLNode> node = mChildren.itemAt(i); - if (node->getType() == TYPE_CDATA) { - // This is a CDATA node... - const char16_t* p = node->mChars.string(); - while (*p != 0 && *p < 128 && isspace(*p)) { - p++; - } - //printf("Space ends at %d in \"%s\"\n", - // (int)(p-node->mChars.string()), - // String8(node->mChars).string()); - if (*p == 0) { - if (stripAll) { - // Remove this node! - mChildren.removeAt(i); - N--; - i--; - } else { - node->mChars = String16(" "); - } - } else { - // Compact leading/trailing whitespace. - const char16_t* e = node->mChars.string()+node->mChars.size()-1; - while (e > p && *e < 128 && isspace(*e)) { - e--; - } - if (p > node->mChars.string()) { - p--; - } - if (e < (node->mChars.string()+node->mChars.size()-1)) { - e++; - } - if (p > node->mChars.string() || - e < (node->mChars.string()+node->mChars.size()-1)) { - String16 tmp(p, e-p+1); - node->mChars = tmp; - } - } - } else { - node->removeWhitespace(stripAll, cDataTags); - } - } -} - -status_t XMLNode::parseValues(const sp<AaptAssets>& assets, - ResourceTable* table) -{ - bool hasErrors = false; - - if (getType() == TYPE_ELEMENT) { - const size_t N = mAttributes.size(); - String16 defPackage(assets->getPackage()); - for (size_t i=0; i<N; i++) { - attribute_entry& e = mAttributes.editItemAt(i); - AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name), - String8(e.string)); - table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber())); - if (!assets->getIncludedResources() - .stringToValue(&e.value, &e.string, - e.string.string(), e.string.size(), true, true, - e.nameResId, NULL, &defPackage, table, &ac)) { - hasErrors = true; - } - NOISY(printf("Attr %s: type=0x%x, str=%s\n", - String8(e.name).string(), e.value.dataType, - String8(e.string).string())); - } - } - const size_t N = mChildren.size(); - for (size_t i=0; i<N; i++) { - status_t err = mChildren.itemAt(i)->parseValues(assets, table); - if (err != NO_ERROR) { - hasErrors = true; - } - } - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets, - const ResourceTable* table) -{ - bool hasErrors = false; - - if (getType() == TYPE_ELEMENT) { - String16 attr("attr"); - const char* errorMsg; - const size_t N = mAttributes.size(); - for (size_t i=0; i<N; i++) { - const attribute_entry& e = mAttributes.itemAt(i); - if (e.ns.size() <= 0) continue; - bool nsIsPublic; - String16 pkg(getNamespaceResourcePackage(e.ns, &nsIsPublic)); - NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n", - String8(getElementName()).string(), - String8(e.name).string(), - String8(e.string).string(), - String8(e.ns).string(), - (nsIsPublic) ? "public" : "private", - String8(pkg).string())); - if (pkg.size() <= 0) continue; - uint32_t res = table != NULL - ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic) - : assets->getIncludedResources(). - identifierForName(e.name.string(), e.name.size(), - attr.string(), attr.size(), - pkg.string(), pkg.size()); - if (res != 0) { - NOISY(printf("XML attribute name %s: resid=0x%08x\n", - String8(e.name).string(), res)); - setAttributeResID(i, res); - } else { - SourcePos(mFilename, getStartLineNumber()).error( - "No resource identifier found for attribute '%s' in package '%s'\n", - String8(e.name).string(), String8(pkg).string()); - hasErrors = true; - } - } - } - const size_t N = mChildren.size(); - for (size_t i=0; i<N; i++) { - status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table); - if (err < NO_ERROR) { - hasErrors = true; - } - } - - return hasErrors ? UNKNOWN_ERROR : NO_ERROR; -} - -status_t XMLNode::flatten(const sp<AaptFile>& dest, - bool stripComments, bool stripRawValues) const -{ - StringPool strings; - Vector<uint32_t> resids; - - // First collect just the strings for attribute names that have a - // resource ID assigned to them. This ensures that the resource ID - // array is compact, and makes it easier to deal with attribute names - // in different namespaces (and thus with different resource IDs). - collect_resid_strings(&strings, &resids); - - // Next collect all remainibng strings. - collect_strings(&strings, &resids, stripComments, stripRawValues); - -#if 0 // No longer compiles - NOISY(printf("Found strings:\n"); - const size_t N = strings.size(); - for (size_t i=0; i<N; i++) { - printf("%s\n", String8(strings.entryAt(i).string).string()); - } - ); -#endif - - sp<AaptFile> stringPool = strings.createStringBlock(); - NOISY(aout << "String pool:" - << HexDump(stringPool->getData(), stringPool->getSize()) << endl); - - ResXMLTree_header header; - memset(&header, 0, sizeof(header)); - header.header.type = htods(RES_XML_TYPE); - header.header.headerSize = htods(sizeof(header)); - - const size_t basePos = dest->getSize(); - dest->writeData(&header, sizeof(header)); - dest->writeData(stringPool->getData(), stringPool->getSize()); - - // If we have resource IDs, write them. - if (resids.size() > 0) { - const size_t resIdsPos = dest->getSize(); - const size_t resIdsSize = - sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size()); - ResChunk_header* idsHeader = (ResChunk_header*) - (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos); - idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE); - idsHeader->headerSize = htods(sizeof(*idsHeader)); - idsHeader->size = htodl(resIdsSize); - uint32_t* ids = (uint32_t*)(idsHeader+1); - for (size_t i=0; i<resids.size(); i++) { - *ids++ = htodl(resids[i]); - } - } - - flatten_node(strings, dest, stripComments, stripRawValues); - - void* data = dest->editData(); - ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos); - size_t size = dest->getSize()-basePos; - hd->header.size = htodl(dest->getSize()-basePos); - - NOISY(aout << "XML resource:" - << HexDump(dest->getData(), dest->getSize()) << endl); - - #if PRINT_STRING_METRICS - fprintf(stderr, "**** total xml size: %d / %d%% strings (in %s)\n", - dest->getSize(), (stringPool->getSize()*100)/dest->getSize(), - dest->getPath().string()); - #endif - - return NO_ERROR; -} - -void XMLNode::print(int indent) -{ - String8 prefix; - int i; - for (i=0; i<indent; i++) { - prefix.append(" "); - } - if (getType() == TYPE_ELEMENT) { - String8 elemNs(getNamespaceUri()); - if (elemNs.size() > 0) { - elemNs.append(":"); - } - printf("%s E: %s%s", prefix.string(), - elemNs.string(), String8(getElementName()).string()); - int N = mAttributes.size(); - for (i=0; i<N; i++) { - ssize_t idx = mAttributeOrder.valueAt(i); - if (i == 0) { - printf(" / "); - } else { - printf(", "); - } - const attribute_entry& attr = mAttributes.itemAt(idx); - String8 attrNs(attr.ns); - if (attrNs.size() > 0) { - attrNs.append(":"); - } - if (attr.nameResId) { - printf("%s%s(0x%08x)", attrNs.string(), - String8(attr.name).string(), attr.nameResId); - } else { - printf("%s%s", attrNs.string(), String8(attr.name).string()); - } - printf("=%s", String8(attr.string).string()); - } - printf("\n"); - } else if (getType() == TYPE_NAMESPACE) { - printf("%s N: %s=%s\n", prefix.string(), - getNamespacePrefix().size() > 0 - ? String8(getNamespacePrefix()).string() : "<DEF>", - String8(getNamespaceUri()).string()); - } else { - printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string()); - } - int N = mChildren.size(); - for (i=0; i<N; i++) { - mChildren.itemAt(i)->print(indent+1); - } -} - -static void splitName(const char* name, String16* outNs, String16* outName) -{ - const char* p = name; - while (*p != 0 && *p != 1) { - p++; - } - if (*p == 0) { - *outNs = String16(); - *outName = String16(name); - } else { - *outNs = String16(name, (p-name)); - *outName = String16(p+1); - } -} - -void XMLCALL -XMLNode::startNamespace(void *userData, const char *prefix, const char *uri) -{ - NOISY_PARSE(printf("Start Namespace: %s %s\n", prefix, uri)); - ParseState* st = (ParseState*)userData; - sp<XMLNode> node = XMLNode::newNamespace(st->filename, - String16(prefix != NULL ? prefix : ""), String16(uri)); - node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); - if (st->stack.size() > 0) { - st->stack.itemAt(st->stack.size()-1)->addChild(node); - } else { - st->root = node; - } - st->stack.push(node); -} - -void XMLCALL -XMLNode::startElement(void *userData, const char *name, const char **atts) -{ - NOISY_PARSE(printf("Start Element: %s\n", name)); - ParseState* st = (ParseState*)userData; - String16 ns16, name16; - splitName(name, &ns16, &name16); - sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16); - node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); - if (st->pendingComment.size() > 0) { - node->appendComment(st->pendingComment); - st->pendingComment = String16(); - } - if (st->stack.size() > 0) { - st->stack.itemAt(st->stack.size()-1)->addChild(node); - } else { - st->root = node; - } - st->stack.push(node); - - for (int i = 0; atts[i]; i += 2) { - splitName(atts[i], &ns16, &name16); - node->addAttribute(ns16, name16, String16(atts[i+1])); - } -} - -void XMLCALL -XMLNode::characterData(void *userData, const XML_Char *s, int len) -{ - NOISY_PARSE(printf("CDATA: \"%s\"\n", String8(s, len).string())); - ParseState* st = (ParseState*)userData; - sp<XMLNode> node = NULL; - if (st->stack.size() == 0) { - return; - } - sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1); - if (parent != NULL && parent->getChildren().size() > 0) { - node = parent->getChildren()[parent->getChildren().size()-1]; - if (node->getType() != TYPE_CDATA) { - // Last node is not CDATA, need to make a new node. - node = NULL; - } - } - - if (node == NULL) { - node = XMLNode::newCData(st->filename); - node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); - parent->addChild(node); - } - - node->appendChars(String16(s, len)); -} - -void XMLCALL -XMLNode::endElement(void *userData, const char *name) -{ - NOISY_PARSE(printf("End Element: %s\n", name)); - ParseState* st = (ParseState*)userData; - sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1); - node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser)); - if (st->pendingComment.size() > 0) { - node->appendComment(st->pendingComment); - st->pendingComment = String16(); - } - String16 ns16, name16; - splitName(name, &ns16, &name16); - LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16 - || node->getElementName() != name16, - "Bad end element %s", name); - st->stack.pop(); -} - -void XMLCALL -XMLNode::endNamespace(void *userData, const char *prefix) -{ - const char* nonNullPrefix = prefix != NULL ? prefix : ""; - NOISY_PARSE(printf("End Namespace: %s\n", prefix)); - ParseState* st = (ParseState*)userData; - sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1); - node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser)); - LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix), - "Bad end namespace %s", prefix); - st->stack.pop(); -} - -void XMLCALL -XMLNode::commentData(void *userData, const char *comment) -{ - NOISY_PARSE(printf("Comment: %s\n", comment)); - ParseState* st = (ParseState*)userData; - if (st->pendingComment.size() > 0) { - st->pendingComment.append(String16("\n")); - } - st->pendingComment.append(String16(comment)); -} - -status_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds, - bool stripComments, bool stripRawValues) const -{ - collect_attr_strings(dest, outResIds, true); - - int i; - if (mNamespacePrefix.size() > 0) { - dest->add(mNamespacePrefix, true); - } - if (mNamespaceUri.size() > 0) { - dest->add(mNamespaceUri, true); - } - if (mElementName.size() > 0) { - dest->add(mElementName, true); - } - - if (!stripComments && mComment.size() > 0) { - dest->add(mComment, true); - } - - const int NA = mAttributes.size(); - - for (i=0; i<NA; i++) { - const attribute_entry& ae = mAttributes.itemAt(i); - if (ae.ns.size() > 0) { - dest->add(ae.ns, true); - } - if (!stripRawValues || ae.needStringValue()) { - dest->add(ae.string, true); - } - /* - if (ae.value.dataType == Res_value::TYPE_NULL - || ae.value.dataType == Res_value::TYPE_STRING) { - dest->add(ae.string, true); - } - */ - } - - if (mElementName.size() == 0) { - // If not an element, include the CDATA, even if it is empty. - dest->add(mChars, true); - } - - const int NC = mChildren.size(); - - for (i=0; i<NC; i++) { - mChildren.itemAt(i)->collect_strings(dest, outResIds, - stripComments, stripRawValues); - } - - return NO_ERROR; -} - -status_t XMLNode::collect_attr_strings(StringPool* outPool, - Vector<uint32_t>* outResIds, bool allAttrs) const { - const int NA = mAttributes.size(); - - for (int i=0; i<NA; i++) { - const attribute_entry& attr = mAttributes.itemAt(i); - uint32_t id = attr.nameResId; - if (id || allAttrs) { - // See if we have already assigned this resource ID to a pooled - // string... - const Vector<size_t>* indices = outPool->offsetsForString(attr.name); - ssize_t idx = -1; - if (indices != NULL) { - const int NJ = indices->size(); - const size_t NR = outResIds->size(); - for (int j=0; j<NJ; j++) { - size_t strIdx = indices->itemAt(j); - if (strIdx >= NR) { - if (id == 0) { - // We don't need to assign a resource ID for this one. - idx = strIdx; - break; - } - // Just ignore strings that are out of range of - // the currently assigned resource IDs... we add - // strings as we assign the first ID. - } else if (outResIds->itemAt(strIdx) == id) { - idx = strIdx; - break; - } - } - } - if (idx < 0) { - idx = outPool->add(attr.name); - NOISY(printf("Adding attr %s (resid 0x%08x) to pool: idx=%d\n", - String8(attr.name).string(), id, idx)); - if (id != 0) { - while ((ssize_t)outResIds->size() <= idx) { - outResIds->add(0); - } - outResIds->replaceAt(id, idx); - } - } - attr.namePoolIdx = idx; - NOISY(printf("String %s offset=0x%08x\n", - String8(attr.name).string(), idx)); - } - } - - return NO_ERROR; -} - -status_t XMLNode::collect_resid_strings(StringPool* outPool, - Vector<uint32_t>* outResIds) const -{ - collect_attr_strings(outPool, outResIds, false); - - const int NC = mChildren.size(); - - for (int i=0; i<NC; i++) { - mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds); - } - - return NO_ERROR; -} - -status_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest, - bool stripComments, bool stripRawValues) const -{ - ResXMLTree_node node; - ResXMLTree_cdataExt cdataExt; - ResXMLTree_namespaceExt namespaceExt; - ResXMLTree_attrExt attrExt; - const void* extData = NULL; - size_t extSize = 0; - ResXMLTree_attribute attr; - - const size_t NA = mAttributes.size(); - const size_t NC = mChildren.size(); - size_t i; - - LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), "Attributes messed up!"); - - const String16 id16("id"); - const String16 class16("class"); - const String16 style16("style"); - - const type type = getType(); - - memset(&node, 0, sizeof(node)); - memset(&attr, 0, sizeof(attr)); - node.header.headerSize = htods(sizeof(node)); - node.lineNumber = htodl(getStartLineNumber()); - if (!stripComments) { - node.comment.index = htodl( - mComment.size() > 0 ? strings.offsetForString(mComment) : -1); - //if (mComment.size() > 0) { - // printf("Flattening comment: %s\n", String8(mComment).string()); - //} - } else { - node.comment.index = htodl((uint32_t)-1); - } - if (type == TYPE_ELEMENT) { - node.header.type = htods(RES_XML_START_ELEMENT_TYPE); - extData = &attrExt; - extSize = sizeof(attrExt); - memset(&attrExt, 0, sizeof(attrExt)); - if (mNamespaceUri.size() > 0) { - attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri)); - } else { - attrExt.ns.index = htodl((uint32_t)-1); - } - attrExt.name.index = htodl(strings.offsetForString(mElementName)); - attrExt.attributeStart = htods(sizeof(attrExt)); - attrExt.attributeSize = htods(sizeof(attr)); - attrExt.attributeCount = htods(NA); - attrExt.idIndex = htods(0); - attrExt.classIndex = htods(0); - attrExt.styleIndex = htods(0); - for (i=0; i<NA; i++) { - ssize_t idx = mAttributeOrder.valueAt(i); - const attribute_entry& ae = mAttributes.itemAt(idx); - if (ae.ns.size() == 0) { - if (ae.name == id16) { - attrExt.idIndex = htods(i+1); - } else if (ae.name == class16) { - attrExt.classIndex = htods(i+1); - } else if (ae.name == style16) { - attrExt.styleIndex = htods(i+1); - } - } - } - } else if (type == TYPE_NAMESPACE) { - node.header.type = htods(RES_XML_START_NAMESPACE_TYPE); - extData = &namespaceExt; - extSize = sizeof(namespaceExt); - memset(&namespaceExt, 0, sizeof(namespaceExt)); - if (mNamespacePrefix.size() > 0) { - namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix)); - } else { - namespaceExt.prefix.index = htodl((uint32_t)-1); - } - namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix)); - namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri)); - LOG_ALWAYS_FATAL_IF(NA != 0, "Namespace nodes can't have attributes!"); - } else if (type == TYPE_CDATA) { - node.header.type = htods(RES_XML_CDATA_TYPE); - extData = &cdataExt; - extSize = sizeof(cdataExt); - memset(&cdataExt, 0, sizeof(cdataExt)); - cdataExt.data.index = htodl(strings.offsetForString(mChars)); - cdataExt.typedData.size = htods(sizeof(cdataExt.typedData)); - cdataExt.typedData.res0 = 0; - cdataExt.typedData.dataType = mCharsValue.dataType; - cdataExt.typedData.data = htodl(mCharsValue.data); - LOG_ALWAYS_FATAL_IF(NA != 0, "CDATA nodes can't have attributes!"); - } - - node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA)); - - dest->writeData(&node, sizeof(node)); - if (extSize > 0) { - dest->writeData(extData, extSize); - } - - for (i=0; i<NA; i++) { - ssize_t idx = mAttributeOrder.valueAt(i); - const attribute_entry& ae = mAttributes.itemAt(idx); - if (ae.ns.size() > 0) { - attr.ns.index = htodl(strings.offsetForString(ae.ns)); - } else { - attr.ns.index = htodl((uint32_t)-1); - } - attr.name.index = htodl(ae.namePoolIdx); - - if (!stripRawValues || ae.needStringValue()) { - attr.rawValue.index = htodl(strings.offsetForString(ae.string)); - } else { - attr.rawValue.index = htodl((uint32_t)-1); - } - attr.typedValue.size = htods(sizeof(attr.typedValue)); - if (ae.value.dataType == Res_value::TYPE_NULL - || ae.value.dataType == Res_value::TYPE_STRING) { - attr.typedValue.res0 = 0; - attr.typedValue.dataType = Res_value::TYPE_STRING; - attr.typedValue.data = htodl(strings.offsetForString(ae.string)); - } else { - attr.typedValue.res0 = 0; - attr.typedValue.dataType = ae.value.dataType; - attr.typedValue.data = htodl(ae.value.data); - } - dest->writeData(&attr, sizeof(attr)); - } - - for (i=0; i<NC; i++) { - status_t err = mChildren.itemAt(i)->flatten_node(strings, dest, - stripComments, stripRawValues); - if (err != NO_ERROR) { - return err; - } - } - - if (type == TYPE_ELEMENT) { - ResXMLTree_endElementExt endElementExt; - memset(&endElementExt, 0, sizeof(endElementExt)); - node.header.type = htods(RES_XML_END_ELEMENT_TYPE); - node.header.size = htodl(sizeof(node)+sizeof(endElementExt)); - node.lineNumber = htodl(getEndLineNumber()); - node.comment.index = htodl((uint32_t)-1); - endElementExt.ns.index = attrExt.ns.index; - endElementExt.name.index = attrExt.name.index; - dest->writeData(&node, sizeof(node)); - dest->writeData(&endElementExt, sizeof(endElementExt)); - } else if (type == TYPE_NAMESPACE) { - node.header.type = htods(RES_XML_END_NAMESPACE_TYPE); - node.lineNumber = htodl(getEndLineNumber()); - node.comment.index = htodl((uint32_t)-1); - node.header.size = htodl(sizeof(node)+extSize); - dest->writeData(&node, sizeof(node)); - dest->writeData(extData, extSize); - } - - return NO_ERROR; -} diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h deleted file mode 100644 index 86548a2..0000000 --- a/tools/aapt/XMLNode.h +++ /dev/null @@ -1,184 +0,0 @@ -// -// Copyright 2006 The Android Open Source Project -// -// Build resource files from raw assets. -// - -#ifndef XML_NODE_H -#define XML_NODE_H - -#include "StringPool.h" -#include "ResourceTable.h" - -class XMLNode; - -extern const char* const RESOURCES_ROOT_NAMESPACE; -extern const char* const RESOURCES_ANDROID_NAMESPACE; - -bool isWhitespace(const char16_t* str); - -String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic = NULL); - -status_t parseStyledString(Bundle* bundle, - const char* fileName, - ResXMLTree* inXml, - const String16& endTag, - String16* outString, - Vector<StringPool::entry_style_span>* outSpans, - bool isPseudolocalizable); - -void printXMLBlock(ResXMLTree* block); - -status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree, - bool stripAll=true, bool keepComments=false, - const char** cDataTags=NULL); - -class XMLNode : public RefBase -{ -public: - static sp<XMLNode> parse(const sp<AaptFile>& file); - - static inline - sp<XMLNode> newNamespace(const String8& filename, const String16& prefix, const String16& uri) { - return new XMLNode(filename, prefix, uri, true); - } - - static inline - sp<XMLNode> newElement(const String8& filename, const String16& ns, const String16& name) { - return new XMLNode(filename, ns, name, false); - } - - static inline - sp<XMLNode> newCData(const String8& filename) { - return new XMLNode(filename); - } - - enum type { - TYPE_NAMESPACE, - TYPE_ELEMENT, - TYPE_CDATA - }; - - type getType() const; - - const String16& getNamespacePrefix() const; - const String16& getNamespaceUri() const; - - const String16& getElementNamespace() const; - const String16& getElementName() const; - const Vector<sp<XMLNode> >& getChildren() const; - - struct attribute_entry { - attribute_entry() : index(~(uint32_t)0), nameResId(0) - { - value.dataType = Res_value::TYPE_NULL; - } - - bool needStringValue() const { - return nameResId == 0 - || value.dataType == Res_value::TYPE_NULL - || value.dataType == Res_value::TYPE_STRING; - } - - String16 ns; - String16 name; - String16 string; - Res_value value; - uint32_t index; - uint32_t nameResId; - mutable uint32_t namePoolIdx; - }; - - const Vector<attribute_entry>& getAttributes() const; - - const String16& getCData() const; - - const String16& getComment() const; - - int32_t getStartLineNumber() const; - int32_t getEndLineNumber() const; - - status_t addChild(const sp<XMLNode>& child); - - status_t addAttribute(const String16& ns, const String16& name, - const String16& value); - - void setAttributeResID(size_t attrIdx, uint32_t resId); - - status_t appendChars(const String16& chars); - - status_t appendComment(const String16& comment); - - void setStartLineNumber(int32_t line); - void setEndLineNumber(int32_t line); - - void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL); - - status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table); - - status_t assignResourceIds(const sp<AaptAssets>& assets, - const ResourceTable* table = NULL); - - status_t flatten(const sp<AaptFile>& dest, bool stripComments, - bool stripRawValues) const; - - void print(int indent=0); - -private: - struct ParseState - { - String8 filename; - XML_Parser parser; - sp<XMLNode> root; - Vector<sp<XMLNode> > stack; - String16 pendingComment; - }; - - static void XMLCALL - startNamespace(void *userData, const char *prefix, const char *uri); - static void XMLCALL - startElement(void *userData, const char *name, const char **atts); - static void XMLCALL - characterData(void *userData, const XML_Char *s, int len); - static void XMLCALL - endElement(void *userData, const char *name); - static void XMLCALL - endNamespace(void *userData, const char *prefix); - - static void XMLCALL - commentData(void *userData, const char *comment); - - // Creating an element node. - XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace); - - // Creating a CDATA node. - XMLNode(const String8& filename); - - status_t collect_strings(StringPool* dest, Vector<uint32_t>* outResIds, - bool stripComments, bool stripRawValues) const; - - status_t collect_attr_strings(StringPool* outPool, - Vector<uint32_t>* outResIds, bool allAttrs) const; - - status_t collect_resid_strings(StringPool* outPool, - Vector<uint32_t>* outResIds) const; - - status_t flatten_node(const StringPool& strings, const sp<AaptFile>& dest, - bool stripComments, bool stripRawValues) const; - - String16 mNamespacePrefix; - String16 mNamespaceUri; - String16 mElementName; - Vector<sp<XMLNode> > mChildren; - Vector<attribute_entry> mAttributes; - KeyedVector<uint32_t, uint32_t> mAttributeOrder; - uint32_t mNextAttributeIndex; - String16 mChars; - Res_value mCharsValue; - String16 mComment; - String8 mFilename; - int32_t mStartLineNumber; - int32_t mEndLineNumber; -}; - -#endif diff --git a/tools/aapt/printapk.cpp b/tools/aapt/printapk.cpp deleted file mode 100644 index 4cf73d8..0000000 --- a/tools/aapt/printapk.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include <utils/ResourceTypes.h> -#include <utils/String8.h> -#include <utils/String16.h> -#include <zipfile/zipfile.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> - -using namespace android; - -static int -usage() -{ - fprintf(stderr, - "usage: apk APKFILE\n" - "\n" - "APKFILE an android packge file produced by aapt.\n" - ); - return 1; -} - - -int -main(int argc, char** argv) -{ - const char* filename; - int fd; - ssize_t amt; - off_t size; - void* buf; - zipfile_t zip; - zipentry_t entry; - void* cookie; - void* resfile; - int bufsize; - int err; - - if (argc != 2) { - return usage(); - } - - filename = argv[1]; - fd = open(filename, O_RDONLY); - if (fd == -1) { - fprintf(stderr, "apk: couldn't open file for read: %s\n", filename); - return 1; - } - - size = lseek(fd, 0, SEEK_END); - amt = lseek(fd, 0, SEEK_SET); - - if (size < 0 || amt < 0) { - fprintf(stderr, "apk: error determining file size: %s\n", filename); - return 1; - } - - buf = malloc(size); - if (buf == NULL) { - fprintf(stderr, "apk: file too big: %s\n", filename); - return 1; - } - - amt = read(fd, buf, size); - if (amt != size) { - fprintf(stderr, "apk: error reading file: %s\n", filename); - return 1; - } - - close(fd); - - zip = init_zipfile(buf, size); - if (zip == NULL) { - fprintf(stderr, "apk: file doesn't seem to be a zip file: %s\n", - filename); - return 1; - } - - printf("files:\n"); - cookie = NULL; - while ((entry = iterate_zipfile(zip, &cookie))) { - char* name = get_zipentry_name(entry); - printf(" %s\n", name); - free(name); - } - - entry = lookup_zipentry(zip, "resources.arsc"); - if (entry != NULL) { - size = get_zipentry_size(entry); - bufsize = size + (size / 1000) + 1; - resfile = malloc(bufsize); - - err = decompress_zipentry(entry, resfile, bufsize); - if (err != 0) { - fprintf(stderr, "apk: error decompressing resources.arsc"); - return 1; - } - - ResTable res(resfile, size, resfile); - res.print(); -#if 0 - size_t tableCount = res.getTableCount(); - printf("Tables: %d\n", (int)tableCount); - for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) { - const ResStringPool* strings = res.getTableStringBlock(tableIndex); - size_t stringCount = strings->size(); - for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) { - size_t len; - const char16_t* ch = strings->stringAt(stringIndex, &len); - String8 s(String16(ch, len)); - printf(" [%3d] %s\n", (int)stringIndex, s.string()); - } - } - - size_t basePackageCount = res.getBasePackageCount(); - printf("Base Packages: %d\n", (int)basePackageCount); - for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) { - const char16_t* ch = res.getBasePackageName(bpIndex); - String8 s = String8(String16(ch)); - printf(" [%3d] %s\n", (int)bpIndex, s.string()); - } -#endif - } - - - return 0; -} diff --git a/tools/aapt/tests/plurals/AndroidManifest.xml b/tools/aapt/tests/plurals/AndroidManifest.xml deleted file mode 100644 index c721dee..0000000 --- a/tools/aapt/tests/plurals/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.aapt.test.plurals"> - -</manifest> diff --git a/tools/aapt/tests/plurals/res/values/strings.xml b/tools/aapt/tests/plurals/res/values/strings.xml deleted file mode 100644 index 1c1fc19..0000000 --- a/tools/aapt/tests/plurals/res/values/strings.xml +++ /dev/null @@ -1,7 +0,0 @@ -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="ok">OK</string> - <plurals name="a_plural"> - <item quantity="one">A dog</item> - <item quantity="other">Some dogs</item> - </plurals> -</resources> diff --git a/tools/aapt/tests/plurals/run.sh b/tools/aapt/tests/plurals/run.sh deleted file mode 100755 index 4d39e10..0000000 --- a/tools/aapt/tests/plurals/run.sh +++ /dev/null @@ -1,16 +0,0 @@ -TEST_DIR=tools/aapt/tests/plurals -TEST_OUT_DIR=out/plurals_test - -rm -rf $TEST_OUT_DIR -mkdir -p $TEST_OUT_DIR -mkdir -p $TEST_OUT_DIR/java - -#gdb --args \ -aapt package -v -x -m -z -J $TEST_OUT_DIR/java -M $TEST_DIR/AndroidManifest.xml \ - -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \ - -P $TEST_OUT_DIR/public_resources.xml \ - -S $TEST_DIR/res - -echo -echo "==================== FILES CREATED ==================== " -find $TEST_OUT_DIR -type f diff --git a/tools/aidl/AST.cpp b/tools/aidl/AST.cpp deleted file mode 100755 index 91802a9..0000000 --- a/tools/aidl/AST.cpp +++ /dev/null @@ -1,867 +0,0 @@ -#include "AST.h" -#include "Type.h" - -void -WriteModifiers(FILE* to, int mod, int mask) -{ - int m = mod & mask; - - if ((m & SCOPE_MASK) == PUBLIC) { - fprintf(to, "public "); - } - else if ((m & SCOPE_MASK) == PRIVATE) { - fprintf(to, "private "); - } - else if ((m & SCOPE_MASK) == PROTECTED) { - fprintf(to, "protected "); - } - - if (m & STATIC) { - fprintf(to, "static "); - } - - if (m & FINAL) { - fprintf(to, "final "); - } - - if (m & ABSTRACT) { - fprintf(to, "abstract "); - } -} - -void -WriteArgumentList(FILE* to, const vector<Expression*>& arguments) -{ - size_t N = arguments.size(); - for (size_t i=0; i<N; i++) { - arguments[i]->Write(to); - if (i != N-1) { - fprintf(to, ", "); - } - } -} - -ClassElement::ClassElement() -{ -} - -ClassElement::~ClassElement() -{ -} - -Field::Field() - :ClassElement(), - modifiers(0), - variable(NULL) -{ -} - -Field::Field(int m, Variable* v) - :ClassElement(), - modifiers(m), - variable(v) -{ -} - -Field::~Field() -{ -} - -void -Field::GatherTypes(set<Type*>* types) const -{ - types->insert(this->variable->type); -} - -void -Field::Write(FILE* to) -{ - if (this->comment.length() != 0) { - fprintf(to, "%s\n", this->comment.c_str()); - } - WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL); - fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(), - this->variable->name.c_str()); - if (this->value.length() != 0) { - fprintf(to, " = %s", this->value.c_str()); - } - fprintf(to, ";\n"); -} - -Expression::~Expression() -{ -} - -LiteralExpression::LiteralExpression(const string& v) - :value(v) -{ -} - -LiteralExpression::~LiteralExpression() -{ -} - -void -LiteralExpression::Write(FILE* to) -{ - fprintf(to, "%s", this->value.c_str()); -} - -Variable::Variable() - :type(NULL), - name(), - dimension(0) -{ -} - -Variable::Variable(Type* t, const string& n) - :type(t), - name(n), - dimension(0) -{ -} - -Variable::Variable(Type* t, const string& n, int d) - :type(t), - name(n), - dimension(d) -{ -} - -Variable::~Variable() -{ -} - -void -Variable::GatherTypes(set<Type*>* types) const -{ - types->insert(this->type); -} - -void -Variable::WriteDeclaration(FILE* to) -{ - string dim; - for (int i=0; i<this->dimension; i++) { - dim += "[]"; - } - fprintf(to, "%s%s %s", this->type->QualifiedName().c_str(), dim.c_str(), - this->name.c_str()); -} - -void -Variable::Write(FILE* to) -{ - fprintf(to, "%s", name.c_str()); -} - -FieldVariable::FieldVariable(Expression* o, const string& n) - :object(o), - clazz(NULL), - name(n) -{ -} - -FieldVariable::FieldVariable(Type* c, const string& n) - :object(NULL), - clazz(c), - name(n) -{ -} - -FieldVariable::~FieldVariable() -{ -} - -void -FieldVariable::Write(FILE* to) -{ - if (this->object != NULL) { - this->object->Write(to); - } - else if (this->clazz != NULL) { - fprintf(to, "%s", this->clazz->QualifiedName().c_str()); - } - fprintf(to, ".%s", name.c_str()); -} - - -Statement::~Statement() -{ -} - -StatementBlock::StatementBlock() -{ -} - -StatementBlock::~StatementBlock() -{ -} - -void -StatementBlock::Write(FILE* to) -{ - fprintf(to, "{\n"); - int N = this->statements.size(); - for (int i=0; i<N; i++) { - this->statements[i]->Write(to); - } - fprintf(to, "}\n"); -} - -void -StatementBlock::Add(Statement* statement) -{ - this->statements.push_back(statement); -} - -void -StatementBlock::Add(Expression* expression) -{ - this->statements.push_back(new ExpressionStatement(expression)); -} - -ExpressionStatement::ExpressionStatement(Expression* e) - :expression(e) -{ -} - -ExpressionStatement::~ExpressionStatement() -{ -} - -void -ExpressionStatement::Write(FILE* to) -{ - this->expression->Write(to); - fprintf(to, ";\n"); -} - -Assignment::Assignment(Variable* l, Expression* r) - :lvalue(l), - rvalue(r), - cast(NULL) -{ -} - -Assignment::Assignment(Variable* l, Expression* r, Type* c) - :lvalue(l), - rvalue(r), - cast(c) -{ -} - -Assignment::~Assignment() -{ -} - -void -Assignment::Write(FILE* to) -{ - this->lvalue->Write(to); - fprintf(to, " = "); - if (this->cast != NULL) { - fprintf(to, "(%s)", this->cast->QualifiedName().c_str()); - } - this->rvalue->Write(to); -} - -MethodCall::MethodCall(const string& n) - :obj(NULL), - clazz(NULL), - name(n) -{ -} - -MethodCall::MethodCall(Expression* o, const string& n) - :obj(o), - clazz(NULL), - name(n) -{ -} - -MethodCall::MethodCall(Type* t, const string& n) - :obj(NULL), - clazz(t), - name(n) -{ -} - -MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...) - :obj(o), - clazz(NULL), - name(n) -{ - va_list args; - va_start(args, argc); - init(argc, args); - va_end(args); -} - -MethodCall::MethodCall(Type* t, const string& n, int argc = 0, ...) - :obj(NULL), - clazz(t), - name(n) -{ - va_list args; - va_start(args, argc); - init(argc, args); - va_end(args); -} - -MethodCall::~MethodCall() -{ -} - -void -MethodCall::init(int n, va_list args) -{ - for (int i=0; i<n; i++) { - Expression* expression = (Expression*)va_arg(args, void*); - this->arguments.push_back(expression); - } -} - -void -MethodCall::Write(FILE* to) -{ - if (this->obj != NULL) { - this->obj->Write(to); - fprintf(to, "."); - } - else if (this->clazz != NULL) { - fprintf(to, "%s.", this->clazz->QualifiedName().c_str()); - } - fprintf(to, "%s(", this->name.c_str()); - WriteArgumentList(to, this->arguments); - fprintf(to, ")"); -} - -Comparison::Comparison(Expression* l, const string& o, Expression* r) - :lvalue(l), - op(o), - rvalue(r) -{ -} - -Comparison::~Comparison() -{ -} - -void -Comparison::Write(FILE* to) -{ - fprintf(to, "("); - this->lvalue->Write(to); - fprintf(to, "%s", this->op.c_str()); - this->rvalue->Write(to); - fprintf(to, ")"); -} - -NewExpression::NewExpression(Type* t) - :type(t) -{ -} - -NewExpression::~NewExpression() -{ -} - -void -NewExpression::Write(FILE* to) -{ - fprintf(to, "new %s(", this->type->InstantiableName().c_str()); - WriteArgumentList(to, this->arguments); - fprintf(to, ")"); -} - -NewArrayExpression::NewArrayExpression(Type* t, Expression* s) - :type(t), - size(s) -{ -} - -NewArrayExpression::~NewArrayExpression() -{ -} - -void -NewArrayExpression::Write(FILE* to) -{ - fprintf(to, "new %s[", this->type->QualifiedName().c_str()); - size->Write(to); - fprintf(to, "]"); -} - -Ternary::Ternary() - :condition(NULL), - ifpart(NULL), - elsepart(NULL) -{ -} - -Ternary::Ternary(Expression* a, Expression* b, Expression* c) - :condition(a), - ifpart(b), - elsepart(c) -{ -} - -Ternary::~Ternary() -{ -} - -void -Ternary::Write(FILE* to) -{ - fprintf(to, "(("); - this->condition->Write(to); - fprintf(to, ")?("); - this->ifpart->Write(to); - fprintf(to, "):("); - this->elsepart->Write(to); - fprintf(to, "))"); -} - -Cast::Cast() - :type(NULL), - expression(NULL) -{ -} - -Cast::Cast(Type* t, Expression* e) - :type(t), - expression(e) -{ -} - -Cast::~Cast() -{ -} - -void -Cast::Write(FILE* to) -{ - fprintf(to, "((%s)", this->type->QualifiedName().c_str()); - expression->Write(to); - fprintf(to, ")"); -} - -VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c) - :lvalue(l), - cast(c), - rvalue(r) -{ -} - -VariableDeclaration::VariableDeclaration(Variable* l) - :lvalue(l), - cast(NULL), - rvalue(NULL) -{ -} - -VariableDeclaration::~VariableDeclaration() -{ -} - -void -VariableDeclaration::Write(FILE* to) -{ - this->lvalue->WriteDeclaration(to); - if (this->rvalue != NULL) { - fprintf(to, " = "); - if (this->cast != NULL) { - fprintf(to, "(%s)", this->cast->QualifiedName().c_str()); - } - this->rvalue->Write(to); - } - fprintf(to, ";\n"); -} - -IfStatement::IfStatement() - :expression(NULL), - statements(new StatementBlock), - elseif(NULL) -{ -} - -IfStatement::~IfStatement() -{ -} - -void -IfStatement::Write(FILE* to) -{ - if (this->expression != NULL) { - fprintf(to, "if ("); - this->expression->Write(to); - fprintf(to, ") "); - } - this->statements->Write(to); - if (this->elseif != NULL) { - fprintf(to, "else "); - this->elseif->Write(to); - } -} - -ReturnStatement::ReturnStatement(Expression* e) - :expression(e) -{ -} - -ReturnStatement::~ReturnStatement() -{ -} - -void -ReturnStatement::Write(FILE* to) -{ - fprintf(to, "return "); - this->expression->Write(to); - fprintf(to, ";\n"); -} - -TryStatement::TryStatement() - :statements(new StatementBlock) -{ -} - -TryStatement::~TryStatement() -{ -} - -void -TryStatement::Write(FILE* to) -{ - fprintf(to, "try "); - this->statements->Write(to); -} - -CatchStatement::CatchStatement(Variable* e) - :statements(new StatementBlock), - exception(e) -{ -} - -CatchStatement::~CatchStatement() -{ -} - -void -CatchStatement::Write(FILE* to) -{ - fprintf(to, "catch "); - if (this->exception != NULL) { - fprintf(to, "("); - this->exception->WriteDeclaration(to); - fprintf(to, ") "); - } - this->statements->Write(to); -} - -FinallyStatement::FinallyStatement() - :statements(new StatementBlock) -{ -} - -FinallyStatement::~FinallyStatement() -{ -} - -void -FinallyStatement::Write(FILE* to) -{ - fprintf(to, "finally "); - this->statements->Write(to); -} - -Case::Case() - :statements(new StatementBlock) -{ -} - -Case::Case(const string& c) - :statements(new StatementBlock) -{ - cases.push_back(c); -} - -Case::~Case() -{ -} - -void -Case::Write(FILE* to) -{ - int N = this->cases.size(); - if (N > 0) { - for (int i=0; i<N; i++) { - string s = this->cases[i]; - if (s.length() != 0) { - fprintf(to, "case %s:\n", s.c_str()); - } else { - fprintf(to, "default:\n"); - } - } - } else { - fprintf(to, "default:\n"); - } - statements->Write(to); -} - -SwitchStatement::SwitchStatement(Expression* e) - :expression(e) -{ -} - -SwitchStatement::~SwitchStatement() -{ -} - -void -SwitchStatement::Write(FILE* to) -{ - fprintf(to, "switch ("); - this->expression->Write(to); - fprintf(to, ")\n{\n"); - int N = this->cases.size(); - for (int i=0; i<N; i++) { - this->cases[i]->Write(to); - } - fprintf(to, "}\n"); -} - -Method::Method() - :ClassElement(), - modifiers(0), - returnType(NULL), // (NULL means constructor) - returnTypeDimension(0), - statements(NULL) -{ -} - -Method::~Method() -{ -} - -void -Method::GatherTypes(set<Type*>* types) const -{ - size_t N, i; - - if (this->returnType) { - types->insert(this->returnType); - } - - N = this->parameters.size(); - for (i=0; i<N; i++) { - this->parameters[i]->GatherTypes(types); - } - - N = this->exceptions.size(); - for (i=0; i<N; i++) { - types->insert(this->exceptions[i]); - } -} - -void -Method::Write(FILE* to) -{ - size_t N, i; - - if (this->comment.length() != 0) { - fprintf(to, "%s\n", this->comment.c_str()); - } - - WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL); - - if (this->returnType != NULL) { - string dim; - for (i=0; i<this->returnTypeDimension; i++) { - dim += "[]"; - } - fprintf(to, "%s%s ", this->returnType->QualifiedName().c_str(), - dim.c_str()); - } - - fprintf(to, "%s(", this->name.c_str()); - - N = this->parameters.size(); - for (i=0; i<N; i++) { - this->parameters[i]->WriteDeclaration(to); - if (i != N-1) { - fprintf(to, ", "); - } - } - - fprintf(to, ")"); - - N = this->exceptions.size(); - for (i=0; i<N; i++) { - if (i == 0) { - fprintf(to, " throws "); - } else { - fprintf(to, ", "); - } - fprintf(to, "%s", this->exceptions[i]->QualifiedName().c_str()); - } - - if (this->statements == NULL) { - fprintf(to, ";\n"); - } else { - fprintf(to, "\n"); - this->statements->Write(to); - } -} - -Class::Class() - :modifiers(0), - what(CLASS), - type(NULL), - extends(NULL) -{ -} - -Class::~Class() -{ -} - -void -Class::GatherTypes(set<Type*>* types) const -{ - int N, i; - - types->insert(this->type); - if (this->extends != NULL) { - types->insert(this->extends); - } - - N = this->interfaces.size(); - for (i=0; i<N; i++) { - types->insert(this->interfaces[i]); - } - - N = this->elements.size(); - for (i=0; i<N; i++) { - this->elements[i]->GatherTypes(types); - } -} - -void -Class::Write(FILE* to) -{ - size_t N, i; - - if (this->comment.length() != 0) { - fprintf(to, "%s\n", this->comment.c_str()); - } - - WriteModifiers(to, this->modifiers, ALL_MODIFIERS); - - if (this->what == Class::CLASS) { - fprintf(to, "class "); - } else { - fprintf(to, "interface "); - } - - string name = this->type->Name(); - size_t pos = name.rfind('.'); - if (pos != string::npos) { - name = name.c_str() + pos + 1; - } - - fprintf(to, "%s", name.c_str()); - - if (this->extends != NULL) { - fprintf(to, " extends %s", this->extends->QualifiedName().c_str()); - } - - N = this->interfaces.size(); - if (N != 0) { - if (this->what == Class::CLASS) { - fprintf(to, " implements"); - } else { - fprintf(to, " extends"); - } - for (i=0; i<N; i++) { - fprintf(to, " %s", this->interfaces[i]->QualifiedName().c_str()); - } - } - - fprintf(to, "\n"); - fprintf(to, "{\n"); - - N = this->elements.size(); - for (i=0; i<N; i++) { - this->elements[i]->Write(to); - } - - fprintf(to, "}\n"); - -} - -Document::Document() -{ -} - -Document::~Document() -{ -} - -static string -escape_backslashes(const string& str) -{ - string result; - const size_t I=str.length(); - for (size_t i=0; i<I; i++) { - char c = str[i]; - if (c == '\\') { - result += "\\\\"; - } else { - result += c; - } - } - return result; -} - -void -Document::Write(FILE* to) -{ - size_t N, i; - - if (this->comment.length() != 0) { - fprintf(to, "%s\n", this->comment.c_str()); - } - fprintf(to, "/*\n" - " * This file is auto-generated. DO NOT MODIFY.\n" - " * Original file: %s\n" - " */\n", escape_backslashes(this->originalSrc).c_str()); - if (this->package.length() != 0) { - fprintf(to, "package %s;\n", this->package.c_str()); - } - - // gather the types for the import statements - set<Type*> types; - N = this->classes.size(); - for (i=0; i<N; i++) { - Class* c = this->classes[i]; - c->GatherTypes(&types); - } - - set<Type*>::iterator it; - for (it=types.begin(); it!=types.end(); it++) { - Type* t = *it; - string pkg = t->Package(); - if (pkg.length() != 0 && pkg != this->package) { - fprintf(to, "import %s;\n", t->ImportType().c_str()); - } - } - - N = this->classes.size(); - for (i=0; i<N; i++) { - Class* c = this->classes[i]; - c->Write(to); - } -} - diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h deleted file mode 100755 index 1dedd04..0000000 --- a/tools/aidl/AST.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef AIDL_AST_H -#define AIDL_AST_H - -#include <string> -#include <vector> -#include <set> -#include <stdarg.h> - -using namespace std; - -class Type; - -enum { - PACKAGE_PRIVATE = 0x00000000, - PUBLIC = 0x00000001, - PRIVATE = 0x00000002, - PROTECTED = 0x00000003, - SCOPE_MASK = 0x00000003, - - STATIC = 0x00000010, - FINAL = 0x00000020, - ABSTRACT = 0x00000040, - - ALL_MODIFIERS = 0xffffffff -}; - -// Write the modifiers that are set in both mod and mask -void WriteModifiers(FILE* to, int mod, int mask); - -struct ClassElement -{ - ClassElement(); - virtual ~ClassElement(); - - virtual void GatherTypes(set<Type*>* types) const = 0; - virtual void Write(FILE* to) = 0; -}; - -struct Expression -{ - virtual ~Expression(); - virtual void Write(FILE* to) = 0; -}; - -struct LiteralExpression : public Expression -{ - string value; - - LiteralExpression(const string& value); - virtual ~LiteralExpression(); - virtual void Write(FILE* to); -}; - -struct Variable : public Expression -{ - Type* type; - string name; - int dimension; - - Variable(); - Variable(Type* type, const string& name); - Variable(Type* type, const string& name, int dimension); - virtual ~Variable(); - - virtual void GatherTypes(set<Type*>* types) const; - void WriteDeclaration(FILE* to); - void Write(FILE* to); -}; - -struct FieldVariable : public Expression -{ - Expression* object; - Type* clazz; - string name; - - FieldVariable(Expression* object, const string& name); - FieldVariable(Type* clazz, const string& name); - virtual ~FieldVariable(); - - void Write(FILE* to); -}; - -struct Field : public ClassElement -{ - string comment; - int modifiers; - Variable *variable; - string value; - - Field(); - Field(int modifiers, Variable* variable); - virtual ~Field(); - - virtual void GatherTypes(set<Type*>* types) const; - virtual void Write(FILE* to); -}; - -struct Statement -{ - virtual ~Statement(); - virtual void Write(FILE* to) = 0; -}; - -struct StatementBlock -{ - vector<Statement*> statements; - - StatementBlock(); - virtual ~StatementBlock(); - virtual void Write(FILE* to); - - void Add(Statement* statement); - void Add(Expression* expression); -}; - -struct ExpressionStatement : public Statement -{ - Expression* expression; - - ExpressionStatement(Expression* expression); - virtual ~ExpressionStatement(); - virtual void Write(FILE* to); -}; - -struct Assignment : public Expression -{ - Variable* lvalue; - Expression* rvalue; - Type* cast; - - Assignment(Variable* lvalue, Expression* rvalue); - Assignment(Variable* lvalue, Expression* rvalue, Type* cast); - virtual ~Assignment(); - virtual void Write(FILE* to); -}; - -struct MethodCall : public Expression -{ - Expression* obj; - Type* clazz; - string name; - vector<Expression*> arguments; - vector<string> exceptions; - - MethodCall(const string& name); - MethodCall(Expression* obj, const string& name); - MethodCall(Type* clazz, const string& name); - MethodCall(Expression* obj, const string& name, int argc, ...); - MethodCall(Type* clazz, const string& name, int argc, ...); - virtual ~MethodCall(); - virtual void Write(FILE* to); - -private: - void init(int n, va_list args); -}; - -struct Comparison : public Expression -{ - Expression* lvalue; - string op; - Expression* rvalue; - - Comparison(Expression* lvalue, const string& op, Expression* rvalue); - virtual ~Comparison(); - virtual void Write(FILE* to); -}; - -struct NewExpression : public Expression -{ - Type* type; - vector<Expression*> arguments; - - NewExpression(Type* type); - virtual ~NewExpression(); - virtual void Write(FILE* to); -}; - -struct NewArrayExpression : public Expression -{ - Type* type; - Expression* size; - - NewArrayExpression(Type* type, Expression* size); - virtual ~NewArrayExpression(); - virtual void Write(FILE* to); -}; - -struct Ternary : public Expression -{ - Expression* condition; - Expression* ifpart; - Expression* elsepart; - - Ternary(); - Ternary(Expression* condition, Expression* ifpart, Expression* elsepart); - virtual ~Ternary(); - virtual void Write(FILE* to); -}; - -struct Cast : public Expression -{ - Type* type; - Expression* expression; - - Cast(); - Cast(Type* type, Expression* expression); - virtual ~Cast(); - virtual void Write(FILE* to); -}; - -struct VariableDeclaration : public Statement -{ - Variable* lvalue; - Type* cast; - Expression* rvalue; - - VariableDeclaration(Variable* lvalue); - VariableDeclaration(Variable* lvalue, Expression* rvalue, Type* cast = NULL); - virtual ~VariableDeclaration(); - virtual void Write(FILE* to); -}; - -struct IfStatement : public Statement -{ - Expression* expression; - StatementBlock* statements; - IfStatement* elseif; - - IfStatement(); - virtual ~IfStatement(); - virtual void Write(FILE* to); -}; - -struct ReturnStatement : public Statement -{ - Expression* expression; - - ReturnStatement(Expression* expression); - virtual ~ReturnStatement(); - virtual void Write(FILE* to); -}; - -struct TryStatement : public Statement -{ - StatementBlock* statements; - - TryStatement(); - virtual ~TryStatement(); - virtual void Write(FILE* to); -}; - -struct CatchStatement : public Statement -{ - StatementBlock* statements; - Variable* exception; - - CatchStatement(Variable* exception); - virtual ~CatchStatement(); - virtual void Write(FILE* to); -}; - -struct FinallyStatement : public Statement -{ - StatementBlock* statements; - - FinallyStatement(); - virtual ~FinallyStatement(); - virtual void Write(FILE* to); -}; - -struct Case -{ - vector<string> cases; - StatementBlock* statements; - - Case(); - Case(const string& c); - virtual ~Case(); - virtual void Write(FILE* to); -}; - -struct SwitchStatement : public Statement -{ - Expression* expression; - vector<Case*> cases; - - SwitchStatement(Expression* expression); - virtual ~SwitchStatement(); - virtual void Write(FILE* to); -}; - -struct Method : public ClassElement -{ - string comment; - int modifiers; - Type* returnType; - size_t returnTypeDimension; - string name; - vector<Variable*> parameters; - vector<Type*> exceptions; - StatementBlock* statements; - - Method(); - virtual ~Method(); - - virtual void GatherTypes(set<Type*>* types) const; - virtual void Write(FILE* to); -}; - -struct Class : public ClassElement -{ - enum { - CLASS, - INTERFACE - }; - - string comment; - int modifiers; - int what; // CLASS or INTERFACE - Type* type; - Type* extends; - vector<Type*> interfaces; - vector<ClassElement*> elements; - - Class(); - virtual ~Class(); - - virtual void GatherTypes(set<Type*>* types) const; - virtual void Write(FILE* to); -}; - -struct Document -{ - string comment; - string package; - string originalSrc; - set<Type*> imports; - vector<Class*> classes; - - Document(); - virtual ~Document(); - - virtual void Write(FILE* to); -}; - -#endif // AIDL_AST_H diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk deleted file mode 100644 index 944aeb6..0000000 --- a/tools/aidl/Android.mk +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2007 The Android Open Source Project -# -# Copies files into the directory structure described by a manifest - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - aidl_language_l.l \ - aidl_language_y.y \ - aidl.cpp \ - aidl_language.cpp \ - options.cpp \ - search_path.cpp \ - AST.cpp \ - Type.cpp \ - generate_java.cpp - -LOCAL_CFLAGS := -g -LOCAL_MODULE := aidl - -include $(BUILD_HOST_EXECUTABLE) - - diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp deleted file mode 100755 index a44072d..0000000 --- a/tools/aidl/Type.cpp +++ /dev/null @@ -1,1228 +0,0 @@ -#include "Type.h" - -Namespace NAMES; - -Type* VOID_TYPE; -Type* BOOLEAN_TYPE; -Type* BYTE_TYPE; -Type* CHAR_TYPE; -Type* INT_TYPE; -Type* LONG_TYPE; -Type* FLOAT_TYPE; -Type* DOUBLE_TYPE; -Type* STRING_TYPE; -Type* CHAR_SEQUENCE_TYPE; -Type* TEXT_UTILS_TYPE; -Type* REMOTE_EXCEPTION_TYPE; -Type* RUNTIME_EXCEPTION_TYPE; -Type* IBINDER_TYPE; -Type* IINTERFACE_TYPE; -Type* BINDER_NATIVE_TYPE; -Type* BINDER_PROXY_TYPE; -Type* PARCEL_TYPE; -Type* PARCELABLE_INTERFACE_TYPE; -Type* MAP_TYPE; -Type* LIST_TYPE; -Type* CLASSLOADER_TYPE; - -Expression* NULL_VALUE; -Expression* THIS_VALUE; -Expression* SUPER_VALUE; -Expression* TRUE_VALUE; -Expression* FALSE_VALUE; - -void -register_base_types() -{ - VOID_TYPE = new BasicType("void", "XXX", "XXX", "XXX", "XXX", "XXX"); - NAMES.Add(VOID_TYPE); - - BOOLEAN_TYPE = new BooleanType(); - NAMES.Add(BOOLEAN_TYPE); - - BYTE_TYPE = new BasicType("byte", "writeByte", "readByte", - "writeByteArray", "createByteArray", "readByteArray"); - NAMES.Add(BYTE_TYPE); - - CHAR_TYPE = new CharType(); - NAMES.Add(CHAR_TYPE); - - INT_TYPE = new BasicType("int", "writeInt", "readInt", - "writeIntArray", "createIntArray", "readIntArray"); - NAMES.Add(INT_TYPE); - - LONG_TYPE = new BasicType("long", "writeLong", "readLong", - "writeLongArray", "createLongArray", "readLongArray"); - NAMES.Add(LONG_TYPE); - - FLOAT_TYPE = new BasicType("float", "writeFloat", "readFloat", - "writeFloatArray", "createFloatArray", "readFloatArray"); - NAMES.Add(FLOAT_TYPE); - - DOUBLE_TYPE = new BasicType("double", "writeDouble", "readDouble", - "writeDoubleArray", "createDoubleArray", "readDoubleArray"); - NAMES.Add(DOUBLE_TYPE); - - STRING_TYPE = new StringType(); - NAMES.Add(STRING_TYPE); - - CHAR_SEQUENCE_TYPE = new CharSequenceType(); - NAMES.Add(CHAR_SEQUENCE_TYPE); - - MAP_TYPE = new MapType(); - NAMES.Add(MAP_TYPE); - - LIST_TYPE = new ListType(); - NAMES.Add(LIST_TYPE); - - TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", - Type::BUILT_IN, false, false); - NAMES.Add(TEXT_UTILS_TYPE); - - REMOTE_EXCEPTION_TYPE = new RemoteExceptionType(); - NAMES.Add(REMOTE_EXCEPTION_TYPE); - - RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType(); - NAMES.Add(RUNTIME_EXCEPTION_TYPE); - - IBINDER_TYPE = new IBinderType(); - NAMES.Add(IBINDER_TYPE); - - IINTERFACE_TYPE = new IInterfaceType(); - NAMES.Add(IINTERFACE_TYPE); - - BINDER_NATIVE_TYPE = new BinderType(); - NAMES.Add(BINDER_NATIVE_TYPE); - - BINDER_PROXY_TYPE = new BinderProxyType(); - NAMES.Add(BINDER_PROXY_TYPE); - - PARCEL_TYPE = new ParcelType(); - NAMES.Add(PARCEL_TYPE); - - PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType(); - NAMES.Add(PARCELABLE_INTERFACE_TYPE); - - CLASSLOADER_TYPE = new ClassLoaderType(); - NAMES.Add(CLASSLOADER_TYPE); - - NULL_VALUE = new LiteralExpression("null"); - THIS_VALUE = new LiteralExpression("this"); - SUPER_VALUE = new LiteralExpression("super"); - TRUE_VALUE = new LiteralExpression("true"); - FALSE_VALUE = new LiteralExpression("false"); - - NAMES.AddGenericType("java.util", "List", 1); - NAMES.AddGenericType("java.util", "Map", 2); -} - -static Type* -make_generic_type(const string& package, const string& name, - const vector<Type*>& args) -{ - if (package == "java.util" && name == "List") { - return new GenericListType("java.util", "List", args); - } - return NULL; - //return new GenericType(package, name, args); -} - -// ================================================================ - -Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut) - :m_package(), - m_name(name), - m_declFile(""), - m_declLine(-1), - m_kind(kind), - m_canWriteToParcel(canWriteToParcel), - m_canBeOut(canBeOut) -{ - m_qualifiedName = name; -} - -Type::Type(const string& package, const string& name, - int kind, bool canWriteToParcel, bool canBeOut, - const string& declFile, int declLine) - :m_package(package), - m_name(name), - m_declFile(declFile), - m_declLine(declLine), - m_kind(kind), - m_canWriteToParcel(canWriteToParcel), - m_canBeOut(canBeOut) -{ - if (package.length() > 0) { - m_qualifiedName = package; - m_qualifiedName += '.'; - } - m_qualifiedName += name; -} - -Type::~Type() -{ -} - -bool -Type::CanBeArray() const -{ - return false; -} - -string -Type::ImportType() const -{ - return m_qualifiedName; -} - -string -Type::CreatorName() const -{ - return ""; -} - -string -Type::InstantiableName() const -{ - return QualifiedName(); -} - - -void -Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* WriteToParcel error " - + m_qualifiedName + " */")); -} - -void -Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* CreateFromParcel error " - + m_qualifiedName + " */")); -} - -void -Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* ReadFromParcel error " - + m_qualifiedName + " */")); -} - -void -Type::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* WriteArrayToParcel error " - + m_qualifiedName + " */")); -} - -void -Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* CreateArrayFromParcel error " - + m_qualifiedName + " */")); -} - -void -Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", - __FILE__, __LINE__, m_qualifiedName.c_str()); - addTo->Add(new LiteralExpression("/* ReadArrayFromParcel error " - + m_qualifiedName + " */")); -} - -void -Type::SetQualifiedName(const string& qualified) -{ - m_qualifiedName = qualified; -} - -Expression* -Type::BuildWriteToParcelFlags(int flags) -{ - if (flags == 0) { - return new LiteralExpression("0"); - } - if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0) { - return new FieldVariable(PARCELABLE_INTERFACE_TYPE, - "PARCELABLE_WRITE_RETURN_VALUE"); - } - return new LiteralExpression("0"); -} - -// ================================================================ - -BasicType::BasicType(const string& name, const string& marshallMethod, - const string& unmarshallMethod, - const string& writeArray, const string& createArray, - const string& readArray) - :Type(name, BUILT_IN, true, false), - m_marshallMethod(marshallMethod), - m_unmarshallMethod(unmarshallMethod), - m_writeArrayMethod(writeArray), - m_createArrayMethod(createArray), - m_readArrayMethod(readArray) -{ -} - -void -BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, m_marshallMethod, 1, v)); -} - -void -BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod))); -} - -bool -BasicType::CanBeArray() const -{ - return true; -} - -void -BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, m_writeArrayMethod, 1, v)); -} - -void -BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod))); -} - -void -BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v)); -} - - -// ================================================================ - -BooleanType::BooleanType() - :Type("boolean", BUILT_IN, true, false) -{ -} - -void -BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeInt", 1, - new Ternary(v, new LiteralExpression("1"), - new LiteralExpression("0")))); -} - -void -BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"), - "!=", new MethodCall(parcel, "readInt")))); -} - -bool -BooleanType::CanBeArray() const -{ - return true; -} - -void -BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v)); -} - -void -BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray"))); -} - -void -BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v)); -} - - -// ================================================================ - -CharType::CharType() - :Type("char", BUILT_IN, true, false) -{ -} - -void -CharType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeInt", 1, - new Cast(INT_TYPE, v))); -} - -void -CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this)); -} - -bool -CharType::CanBeArray() const -{ - return true; -} - -void -CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v)); -} - -void -CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray"))); -} - -void -CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new MethodCall(parcel, "readCharArray", 1, v)); -} - -// ================================================================ - -StringType::StringType() - :Type("java.lang", "String", BUILT_IN, true, false) -{ -} - -string -StringType::CreatorName() const -{ - return "android.os.Parcel.STRING_CREATOR"; -} - -void -StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeString", 1, v)); -} - -void -StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "readString"))); -} - -bool -StringType::CanBeArray() const -{ - return true; -} - -void -StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v)); -} - -void -StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray"))); -} - -void -StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new MethodCall(parcel, "readStringArray", 1, v)); -} - -// ================================================================ - -CharSequenceType::CharSequenceType() - :Type("java.lang", "CharSequence", BUILT_IN, true, false) -{ -} - -string -CharSequenceType::CreatorName() const -{ - return "android.os.Parcel.STRING_CREATOR"; -} - -void -CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - // if (v != null) { - // parcel.writeInt(1); - // v.writeToParcel(parcel); - // } else { - // parcel.writeInt(0); - // } - IfStatement* elsepart = new IfStatement(); - elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1, - new LiteralExpression("0"))); - IfStatement* ifpart = new IfStatement; - ifpart->expression = new Comparison(v, "!=", NULL_VALUE); - ifpart->elseif = elsepart; - ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1, - new LiteralExpression("1"))); - ifpart->statements->Add(new MethodCall(TEXT_UTILS_TYPE, "writeToParcel", - 3, v, parcel, BuildWriteToParcelFlags(flags))); - - addTo->Add(ifpart); -} - -void -CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - // if (0 != parcel.readInt()) { - // v = TextUtils.createFromParcel(parcel) - // } else { - // v = null; - // } - IfStatement* elsepart = new IfStatement(); - elsepart->statements->Add(new Assignment(v, NULL_VALUE)); - - IfStatement* ifpart = new IfStatement(); - ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", - new MethodCall(parcel, "readInt")); - ifpart->elseif = elsepart; - ifpart->statements->Add(new Assignment(v, - new MethodCall(TEXT_UTILS_TYPE, - "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel))); - - addTo->Add(ifpart); -} - - -// ================================================================ - -RemoteExceptionType::RemoteExceptionType() - :Type("android.os", "RemoteException", BUILT_IN, false, false) -{ -} - -void -RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -// ================================================================ - -RuntimeExceptionType::RuntimeExceptionType() - :Type("java.lang", "RuntimeException", BUILT_IN, false, false) -{ -} - -void -RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - - -// ================================================================ - -IBinderType::IBinderType() - :Type("android.os", "IBinder", BUILT_IN, true, false) -{ -} - -void -IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v)); -} - -void -IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder"))); -} - -void -IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v)); -} - -void -IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray"))); -} - -void -IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v)); -} - - -// ================================================================ - -IInterfaceType::IInterfaceType() - :Type("android.os", "IInterface", BUILT_IN, false, false) -{ -} - -void -IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - - -// ================================================================ - -BinderType::BinderType() - :Type("android.os", "Binder", BUILT_IN, false, false) -{ -} - -void -BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - - -// ================================================================ - -BinderProxyType::BinderProxyType() - :Type("android.os", "BinderProxy", BUILT_IN, false, false) -{ -} - -void -BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - - -// ================================================================ - -ParcelType::ParcelType() - :Type("android.os", "Parcel", BUILT_IN, false, false) -{ -} - -void -ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -// ================================================================ - -ParcelableInterfaceType::ParcelableInterfaceType() - :Type("android.os", "Parcelable", BUILT_IN, false, false) -{ -} - -void -ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -void -ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__); -} - -// ================================================================ - -MapType::MapType() - :Type("java.util", "Map", BUILT_IN, true, true) -{ -} - -void -MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeMap", 1, v)); -} - -void -MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); - addTo->Add(new VariableDeclaration(cl, - new LiteralExpression("this.getClass().getClassLoader()"), - CLASSLOADER_TYPE)); - addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, cl))); -} - -void -MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); - addTo->Add(new VariableDeclaration(cl, - new LiteralExpression("this.getClass().getClassLoader()"), - CLASSLOADER_TYPE)); - addTo->Add(new MethodCall(parcel, "readMap", 2, v, cl)); -} - - -// ================================================================ - -ListType::ListType() - :Type("java.util", "List", BUILT_IN, true, true) -{ -} - -string -ListType::InstantiableName() const -{ - return "java.util.ArrayList"; -} - -void -ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeList", 1, v)); -} - -void -ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); - addTo->Add(new VariableDeclaration(cl, - new LiteralExpression("this.getClass().getClassLoader()"), - CLASSLOADER_TYPE)); - addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, cl))); -} - -void -ListType::ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - Variable *cl = new Variable(CLASSLOADER_TYPE, "cl"); - addTo->Add(new VariableDeclaration(cl, - new LiteralExpression("this.getClass().getClassLoader()"), - CLASSLOADER_TYPE)); - addTo->Add(new MethodCall(parcel, "readList", 2, v, cl)); -} - - -// ================================================================ - -ParcelableType::ParcelableType(const string& package, const string& name, - bool builtIn, const string& declFile, int declLine) - :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, true, - declFile, declLine) -{ -} - -string -ParcelableType::CreatorName() const -{ - return QualifiedName() + ".CREATOR"; -} - -void -ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - // if (v != null) { - // parcel.writeInt(1); - // v.writeToParcel(parcel); - // } else { - // parcel.writeInt(0); - // } - IfStatement* elsepart = new IfStatement(); - elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1, - new LiteralExpression("0"))); - IfStatement* ifpart = new IfStatement; - ifpart->expression = new Comparison(v, "!=", NULL_VALUE); - ifpart->elseif = elsepart; - ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1, - new LiteralExpression("1"))); - ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, - parcel, BuildWriteToParcelFlags(flags))); - - addTo->Add(ifpart); -} - -void -ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - // if (0 != parcel.readInt()) { - // v = CLASS.CREATOR.createFromParcel(parcel) - // } else { - // v = null; - // } - IfStatement* elsepart = new IfStatement(); - elsepart->statements->Add(new Assignment(v, NULL_VALUE)); - - IfStatement* ifpart = new IfStatement(); - ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", - new MethodCall(parcel, "readInt")); - ifpart->elseif = elsepart; - ifpart->statements->Add(new Assignment(v, - new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel))); - - addTo->Add(ifpart); -} - -void -ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - // TODO: really, we don't need to have this extra check, but we - // don't have two separate marshalling code paths - // if (0 != parcel.readInt()) { - // v.readFromParcel(parcel) - // } - IfStatement* ifpart = new IfStatement(); - ifpart->expression = new Comparison(new LiteralExpression("0"), "!=", - new MethodCall(parcel, "readInt")); - ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel)); - addTo->Add(ifpart); -} - -bool -ParcelableType::CanBeArray() const -{ - return true; -} - -void -ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v, - BuildWriteToParcelFlags(flags))); -} - -void -ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - string creator = v->type->QualifiedName() + ".CREATOR"; - addTo->Add(new Assignment(v, new MethodCall(parcel, - "createTypedArray", 1, new LiteralExpression(creator)))); -} - -void -ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - string creator = v->type->QualifiedName() + ".CREATOR"; - addTo->Add(new MethodCall(parcel, "readTypedArray", 2, - v, new LiteralExpression(creator))); -} - - -// ================================================================ - -InterfaceType::InterfaceType(const string& package, const string& name, - bool builtIn, bool oneway, - const string& declFile, int declLine) - :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, - declFile, declLine) - ,m_oneway(oneway) -{ -} - -bool -InterfaceType::OneWay() const -{ - return m_oneway; -} - -void -InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - // parcel.writeStrongBinder(v != null ? v.asBinder() : null); - addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, - new Ternary( - new Comparison(v, "!=", NULL_VALUE), - new MethodCall(v, "asBinder"), - NULL_VALUE))); -} - -void -InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - // v = Interface.asInterface(parcel.readStrongBinder()); - string type = v->type->QualifiedName(); - type += ".Stub"; - addTo->Add(new Assignment(v, - new MethodCall( NAMES.Find(type), "asInterface", 1, - new MethodCall(parcel, "readStrongBinder")))); -} - - -// ================================================================ - -GenericType::GenericType(const string& package, const string& name, - const vector<Type*>& args) - :Type(package, name, BUILT_IN, true, true) -{ - m_args = args; - - m_importName = package + '.' + name; - - string gen = "<"; - int N = args.size(); - for (int i=0; i<N; i++) { - Type* t = args[i]; - gen += t->QualifiedName(); - if (i != N-1) { - gen += ','; - } - } - gen += '>'; - m_genericArguments = gen; - SetQualifiedName(m_importName + gen); -} - -string -GenericType::GenericArguments() const -{ - return m_genericArguments; -} - -string -GenericType::ImportType() const -{ - return m_importName; -} - -void -GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - fprintf(stderr, "implement GenericType::WriteToParcel\n"); -} - -void -GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - fprintf(stderr, "implement GenericType::CreateFromParcel\n"); -} - -void -GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - fprintf(stderr, "implement GenericType::ReadFromParcel\n"); -} - - -// ================================================================ - -GenericListType::GenericListType(const string& package, const string& name, - const vector<Type*>& args) - :GenericType(package, name, args), - m_creator(args[0]->CreatorName()) -{ -} - -string -GenericListType::CreatorName() const -{ - return "android.os.Parcel.arrayListCreator"; -} - -string -GenericListType::InstantiableName() const -{ - return "java.util.ArrayList" + GenericArguments(); -} - -void -GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags) -{ - if (m_creator == STRING_TYPE->CreatorName()) { - addTo->Add(new MethodCall(parcel, "writeStringList", 1, v)); - } else if (m_creator == IBINDER_TYPE->CreatorName()) { - addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v)); - } else { - // parcel.writeTypedListXX(arg); - addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v)); - } -} - -void -GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel) -{ - if (m_creator == STRING_TYPE->CreatorName()) { - addTo->Add(new Assignment(v, - new MethodCall(parcel, "createStringArrayList", 0))); - } else if (m_creator == IBINDER_TYPE->CreatorName()) { - addTo->Add(new Assignment(v, - new MethodCall(parcel, "createBinderArrayList", 0))); - } else { - // v = _data.readTypedArrayList(XXX.creator); - addTo->Add(new Assignment(v, - new MethodCall(parcel, "createTypedArrayList", 1, - new LiteralExpression(m_creator)))); - } -} - -void -GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - if (m_creator == STRING_TYPE->CreatorName()) { - addTo->Add(new MethodCall(parcel, "readStringList", 1, v)); - } else if (m_creator == IBINDER_TYPE->CreatorName()) { - addTo->Add(new MethodCall(parcel, "readBinderList", 1, v)); - } else { - // v = _data.readTypedList(v, XXX.creator); - addTo->Add(new MethodCall(parcel, "readTypedList", 2, - v, - new LiteralExpression(m_creator))); - } -} - -// ================================================================ - -ClassLoaderType::ClassLoaderType() - :Type("java.lang", "ClassLoader", BUILT_IN, false, false) -{ -} - - -// ================================================================ - -Namespace::Namespace() -{ -} - -Namespace::~Namespace() -{ - int N = m_types.size(); - for (int i=0; i<N; i++) { - delete m_types[i]; - } -} - -void -Namespace::Add(Type* type) -{ - Type* t = Find(type->QualifiedName()); - if (t == NULL) { - m_types.push_back(type); - } -} - -void -Namespace::AddGenericType(const string& package, const string& name, int args) -{ - Generic g; - g.package = package; - g.name = name; - g.qualified = package + '.' + name; - g.args = args; - m_generics.push_back(g); -} - -Type* -Namespace::Find(const string& name) const -{ - int N = m_types.size(); - for (int i=0; i<N; i++) { - if (m_types[i]->QualifiedName() == name) { - return m_types[i]; - } - } - return NULL; -} - -Type* -Namespace::Find(const char* package, const char* name) const -{ - string s; - if (package != NULL) { - s += package; - s += '.'; - } - s += name; - return Find(s); -} - -static string -normalize_generic(const string& s) -{ - string r; - int N = s.size(); - for (int i=0; i<N; i++) { - char c = s[i]; - if (!isspace(c)) { - r += c; - } - } - return r; -} - -Type* -Namespace::Search(const string& name) -{ - // an exact match wins - Type* result = Find(name); - if (result != NULL) { - return result; - } - - // try the class names - // our language doesn't allow you to not specify outer classes - // when referencing an inner class. that could be changed, and this - // would be the place to do it, but I don't think the complexity in - // scoping rules is worth it. - int N = m_types.size(); - for (int i=0; i<N; i++) { - if (m_types[i]->Name() == name) { - return m_types[i]; - } - } - - // we got to here and it's not a generic, give up - if (name.find('<') == name.npos) { - return NULL; - } - - // remove any whitespace - string normalized = normalize_generic(name); - - // find the part before the '<', find a generic for it - ssize_t baseIndex = normalized.find('<'); - string base(normalized.c_str(), baseIndex); - const Generic* g = search_generic(base); - if (g == NULL) { - return NULL; - } - - // For each of the args, do a recursive search on it. We don't allow - // generics within generics like Java does, because we're really limiting - // them to just built-in container classes, at least for now. Our syntax - // ensures this right now as well. - vector<Type*> args; - size_t start = baseIndex + 1; - size_t end = start; - while (normalized[start] != '\0') { - end = normalized.find(',', start); - if (end == normalized.npos) { - end = normalized.find('>', start); - } - string s(normalized.c_str()+start, end-start); - Type* t = this->Search(s); - if (t == NULL) { - // maybe we should print a warning here? - return NULL; - } - args.push_back(t); - start = end+1; - } - - // construct a GenericType, add it to our name set so they always get - // the same object, and return it. - result = make_generic_type(g->package, g->name, args); - if (result == NULL) { - return NULL; - } - - this->Add(result); - return this->Find(result->QualifiedName()); -} - -const Namespace::Generic* -Namespace::search_generic(const string& name) const -{ - int N = m_generics.size(); - - // first exact match - for (int i=0; i<N; i++) { - const Generic& g = m_generics[i]; - if (g.qualified == name) { - return &g; - } - } - - // then name match - for (int i=0; i<N; i++) { - const Generic& g = m_generics[i]; - if (g.name == name) { - return &g; - } - } - - return NULL; -} - -void -Namespace::Dump() const -{ - int n = m_types.size(); - for (int i=0; i<n; i++) { - Type* t = m_types[i]; - printf("type: package=%s name=%s qualifiedName=%s\n", - t->Package().c_str(), t->Name().c_str(), - t->QualifiedName().c_str()); - } -} diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h deleted file mode 100755 index 2ea3ac9..0000000 --- a/tools/aidl/Type.h +++ /dev/null @@ -1,466 +0,0 @@ -#ifndef AIDL_TYPE_H -#define AIDL_TYPE_H - -#include "AST.h" -#include <string> -#include <vector> - -using namespace std; - -class Type -{ -public: - // kinds - enum { - BUILT_IN, - PARCELABLE, - INTERFACE, - GENERATED - }; - - // WriteToParcel flags - enum { - PARCELABLE_WRITE_RETURN_VALUE = 0x0001 - }; - - Type(const string& name, int kind, bool canWriteToParcel, - bool canBeOut); - Type(const string& package, const string& name, - int kind, bool canWriteToParcel, bool canBeOut, - const string& declFile = "", int declLine = -1); - virtual ~Type(); - - inline string Package() const { return m_package; } - inline string Name() const { return m_name; } - inline string QualifiedName() const { return m_qualifiedName; } - inline int Kind() const { return m_kind; } - inline string DeclFile() const { return m_declFile; } - inline int DeclLine() const { return m_declLine; } - inline bool CanBeMarshalled() const { return m_canWriteToParcel; } - inline bool CanBeOutParameter() const { return m_canBeOut; } - - virtual string ImportType() const; - virtual string CreatorName() const; - virtual string InstantiableName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - -protected: - void SetQualifiedName(const string& qualified); - Expression* BuildWriteToParcelFlags(int flags); - -private: - Type(); - Type(const Type&); - - string m_package; - string m_name; - string m_qualifiedName; - string m_declFile; - int m_declLine; - int m_kind; - bool m_canWriteToParcel; - bool m_canBeOut; -}; - -class BasicType : public Type -{ -public: - BasicType(const string& name, const string& marshallMethod, - const string& unmarshallMethod, - const string& writeArray, - const string& createArray, - const string& readArray); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - -private: - string m_marshallMethod; - string m_unmarshallMethod; - string m_writeArrayMethod; - string m_createArrayMethod; - string m_readArrayMethod; -}; - -class BooleanType : public Type -{ -public: - BooleanType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class CharType : public Type -{ -public: - CharType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - - -class StringType : public Type -{ -public: - StringType(); - - virtual string CreatorName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class CharSequenceType : public Type -{ -public: - CharSequenceType(); - - virtual string CreatorName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class RemoteExceptionType : public Type -{ -public: - RemoteExceptionType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class RuntimeExceptionType : public Type -{ -public: - RuntimeExceptionType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class IBinderType : public Type -{ -public: - IBinderType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class IInterfaceType : public Type -{ -public: - IInterfaceType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class BinderType : public Type -{ -public: - BinderType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class BinderProxyType : public Type -{ -public: - BinderProxyType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class ParcelType : public Type -{ -public: - ParcelType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class ParcelableInterfaceType : public Type -{ -public: - ParcelableInterfaceType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class MapType : public Type -{ -public: - MapType(); - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class ListType : public Type -{ -public: - ListType(); - - virtual string InstantiableName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class ParcelableType : public Type -{ -public: - ParcelableType(const string& package, const string& name, - bool builtIn, const string& declFile, int declLine); - - virtual string CreatorName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - - virtual bool CanBeArray() const; - - virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); -}; - -class InterfaceType : public Type -{ -public: - InterfaceType(const string& package, const string& name, - bool builtIn, bool oneway, - const string& declFile, int declLine); - - bool OneWay() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - -private: - bool m_oneway; -}; - - -class GenericType : public Type -{ -public: - GenericType(const string& package, const string& name, - const vector<Type*>& args); - - string GenericArguments() const; - - virtual string ImportType() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - -private: - string m_genericArguments; - string m_importName; - vector<Type*> m_args; -}; - - -class GenericListType : public GenericType -{ -public: - GenericListType(const string& package, const string& name, - const vector<Type*>& args); - - virtual string CreatorName() const; - virtual string InstantiableName() const; - - virtual void WriteToParcel(StatementBlock* addTo, Variable* v, - Variable* parcel, int flags); - virtual void CreateFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - virtual void ReadFromParcel(StatementBlock* addTo, Variable* v, - Variable* parcel); - -private: - string m_creator; -}; - -class ClassLoaderType : public Type -{ -public: - ClassLoaderType(); -}; - -class Namespace -{ -public: - Namespace(); - ~Namespace(); - void Add(Type* type); - - // args is the number of template types (what is this called?) - void AddGenericType(const string& package, const string& name, int args); - - // lookup a specific class name - Type* Find(const string& name) const; - Type* Find(const char* package, const char* name) const; - - // try to search by either a full name or a partial name - Type* Search(const string& name); - - void Dump() const; - -private: - struct Generic { - string package; - string name; - string qualified; - int args; - }; - - const Generic* search_generic(const string& name) const; - - vector<Type*> m_types; - vector<Generic> m_generics; -}; - -extern Namespace NAMES; - -extern Type* VOID_TYPE; -extern Type* BOOLEAN_TYPE; -extern Type* CHAR_TYPE; -extern Type* INT_TYPE; -extern Type* LONG_TYPE; -extern Type* FLOAT_TYPE; -extern Type* DOUBLE_TYPE; -extern Type* STRING_TYPE; -extern Type* CHAR_SEQUENCE_TYPE; -extern Type* TEXT_UTILS_TYPE; -extern Type* REMOTE_EXCEPTION_TYPE; -extern Type* RUNTIME_EXCEPTION_TYPE; -extern Type* IBINDER_TYPE; -extern Type* IINTERFACE_TYPE; -extern Type* BINDER_NATIVE_TYPE; -extern Type* BINDER_PROXY_TYPE; -extern Type* PARCEL_TYPE; -extern Type* PARCELABLE_INTERFACE_TYPE; - -extern Expression* NULL_VALUE; -extern Expression* THIS_VALUE; -extern Expression* SUPER_VALUE; -extern Expression* TRUE_VALUE; -extern Expression* FALSE_VALUE; - -void register_base_types(); - -#endif // AIDL_TYPE_H diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp deleted file mode 100644 index dc61567..0000000 --- a/tools/aidl/aidl.cpp +++ /dev/null @@ -1,904 +0,0 @@ - -#include "aidl_language.h" -#include "options.h" -#include "search_path.h" -#include "Type.h" -#include "generate_java.h" -#include <unistd.h> -#include <fcntl.h> -#include <sys/param.h> -#include <sys/stat.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <map> - -#ifdef HAVE_MS_C_RUNTIME -#include <io.h> -#include <sys/stat.h> -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -using namespace std; - -static void -test_document(document_item_type* d) -{ - while (d) { - if (d->item_type == INTERFACE_TYPE) { - interface_type* c = (interface_type*)d; - printf("interface %s %s {\n", c->package, c->name.data); - interface_item_type *q = (interface_item_type*)c->interface_items; - while (q) { - if (q->item_type == METHOD_TYPE) { - method_type *m = (method_type*)q; - printf(" %s %s(", m->type.type.data, m->name.data); - arg_type *p = m->args; - while (p) { - printf("%s %s",p->type.type.data,p->name.data); - if (p->next) printf(", "); - p=p->next; - } - printf(")"); - printf(";\n"); - } - q=q->next; - } - printf("}\n"); - } - else if (d->item_type == PARCELABLE_TYPE) { - parcelable_type* b = (parcelable_type*)d; - printf("parcelable %s %s;\n", b->package, b->name.data); - } - else { - printf("UNKNOWN d=0x%08x d->item_type=%ld\n", (long)d, d->item_type); - } - d = d->next; - } -} - -// ========================================================== -int -convert_direction(const char* direction) -{ - if (direction == NULL) { - return IN_PARAMETER; - } - if (0 == strcmp(direction, "in")) { - return IN_PARAMETER; - } - if (0 == strcmp(direction, "out")) { - return OUT_PARAMETER; - } - return INOUT_PARAMETER; -} - -// ========================================================== -struct import_info { - const char* from; - const char* filename; - buffer_type statement; - const char* neededClass; - document_item_type* doc; - struct import_info* next; -}; - -document_item_type* g_document = NULL; -import_info* g_imports = NULL; - -static void -main_document_parsed(document_item_type* d) -{ - g_document = d; -} - -static void -main_import_parsed(buffer_type* statement) -{ - import_info* import = (import_info*)malloc(sizeof(import_info)); - memset(import, 0, sizeof(import_info)); - import->from = strdup(g_currentFilename); - import->statement.lineno = statement->lineno; - import->statement.data = strdup(statement->data); - import->statement.extra = NULL; - import->next = g_imports; - import->neededClass = parse_import_statement(statement->data); - g_imports = import; -} - -static ParserCallbacks g_mainCallbacks = { - &main_document_parsed, - &main_import_parsed -}; - -char* -parse_import_statement(const char* text) -{ - const char* end; - int len; - - while (isspace(*text)) { - text++; - } - while (!isspace(*text)) { - text++; - } - while (isspace(*text)) { - text++; - } - end = text; - while (!isspace(*end) && *end != ';') { - end++; - } - len = end-text; - - char* rv = (char*)malloc(len+1); - memcpy(rv, text, len); - rv[len] = '\0'; - - return rv; -} - -// ========================================================== -static void -import_import_parsed(buffer_type* statement) -{ -} - -static ParserCallbacks g_importCallbacks = { - &main_document_parsed, - &import_import_parsed -}; - -// ========================================================== -static int -check_filename(const char* filename, const char* package, buffer_type* name) -{ - const char* p; - string expected; - string fn; - size_t len; - char cwd[MAXPATHLEN]; - bool valid = false; - -#ifdef HAVE_WINDOWS_PATHS - if (isalpha(filename[0]) && filename[1] == ':' - && filename[2] == OS_PATH_SEPARATOR) { -#else - if (filename[0] == OS_PATH_SEPARATOR) { -#endif - fn = filename; - } else { - fn = getcwd(cwd, sizeof(cwd)); - len = fn.length(); - if (fn[len-1] != OS_PATH_SEPARATOR) { - fn += OS_PATH_SEPARATOR; - } - fn += filename; - } - - if (package) { - expected = package; - expected += '.'; - } - - len = expected.length(); - for (size_t i=0; i<len; i++) { - if (expected[i] == '.') { - expected[i] = OS_PATH_SEPARATOR; - } - } - - p = strchr(name->data, '.'); - len = p ? p-name->data : strlen(name->data); - expected.append(name->data, len); - - expected += ".aidl"; - - len = fn.length(); - valid = (len >= expected.length()); - - if (valid) { - p = fn.c_str() + (len - expected.length()); - -#ifdef HAVE_WINDOWS_PATHS - if (OS_PATH_SEPARATOR != '/') { - // Input filename under cygwin most likely has / separators - // whereas the expected string uses \\ separators. Adjust - // them accordingly. - for (char *c = const_cast<char *>(p); *c; ++c) { - if (*c == '/') *c = OS_PATH_SEPARATOR; - } - } -#endif - -#ifdef OS_CASE_SENSITIVE - valid = (expected == p); -#else - valid = !strcasecmp(expected.c_str(), p); -#endif - } - - if (!valid) { - fprintf(stderr, "%s:%d interface %s should be declared in a file" - " called %s.\n", - filename, name->lineno, name->data, expected.c_str()); - return 1; - } - - return 0; -} - -static int -check_filenames(const char* filename, document_item_type* items) -{ - int err = 0; - while (items) { - if (items->item_type == PARCELABLE_TYPE) { - parcelable_type* p = (parcelable_type*)items; - err |= check_filename(filename, p->package, &p->name); - } - else if (items->item_type == INTERFACE_TYPE) { - interface_type* c = (interface_type*)items; - err |= check_filename(filename, c->package, &c->name); - } - else { - fprintf(stderr, "aidl: internal error unkown document type %d.\n", - items->item_type); - return 1; - } - items = items->next; - } - return err; -} - -// ========================================================== -static const char* -kind_to_string(int kind) -{ - switch (kind) - { - case Type::INTERFACE: - return "an interface"; - case Type::PARCELABLE: - return "a parcelable"; - default: - return "ERROR"; - } -} - -static char* -rfind(char* str, char c) -{ - char* p = str + strlen(str) - 1; - while (p >= str) { - if (*p == c) { - return p; - } - p--; - } - return NULL; -} - -static int -gather_types(const char* filename, document_item_type* items) -{ - int err = 0; - while (items) { - Type* type; - if (items->item_type == PARCELABLE_TYPE) { - parcelable_type* p = (parcelable_type*)items; - type = new ParcelableType(p->package ? p->package : "", - p->name.data, false, filename, p->name.lineno); - } - else if (items->item_type == INTERFACE_TYPE) { - interface_type* c = (interface_type*)items; - type = new InterfaceType(c->package ? c->package : "", - c->name.data, false, c->oneway, - filename, c->name.lineno); - } - else { - fprintf(stderr, "aidl: internal error %s:%d\n", __FILE__, __LINE__); - return 1; - } - - Type* old = NAMES.Find(type->QualifiedName()); - if (old == NULL) { - NAMES.Add(type); - - if (items->item_type == INTERFACE_TYPE) { - // for interfaces, also add the stub and proxy types, we don't - // bother checking these for duplicates, because the parser - // won't let us do it. - interface_type* c = (interface_type*)items; - - string name = c->name.data; - name += ".Stub"; - Type* stub = new Type(c->package ? c->package : "", - name, Type::GENERATED, false, false, - filename, c->name.lineno); - NAMES.Add(stub); - - name = c->name.data; - name += ".Stub.Proxy"; - Type* proxy = new Type(c->package ? c->package : "", - name, Type::GENERATED, false, false, - filename, c->name.lineno); - NAMES.Add(proxy); - } - } else { - if (old->Kind() == Type::BUILT_IN) { - fprintf(stderr, "%s:%d attempt to redefine built in class %s\n", - filename, type->DeclLine(), - type->QualifiedName().c_str()); - err = 1; - } - else if (type->Kind() != old->Kind()) { - const char* oldKind = kind_to_string(old->Kind()); - const char* newKind = kind_to_string(type->Kind()); - - fprintf(stderr, "%s:%d attempt to redefine %s as %s,\n", - filename, type->DeclLine(), - type->QualifiedName().c_str(), newKind); - fprintf(stderr, "%s:%d previously defined here as %s.\n", - old->DeclFile().c_str(), old->DeclLine(), oldKind); - err = 1; - } - } - - items = items->next; - } - return err; -} - -// ========================================================== -static bool -matches_keyword(const char* str) -{ - static const char* KEYWORDS[] = { "abstract", "assert", "boolean", "break", - "byte", "case", "catch", "char", "class", "const", "continue", - "default", "do", "double", "else", "enum", "extends", "final", - "finally", "float", "for", "goto", "if", "implements", "import", - "instanceof", "int", "interface", "long", "native", "new", "package", - "private", "protected", "public", "return", "short", "static", - "strictfp", "super", "switch", "synchronized", "this", "throw", - "throws", "transient", "try", "void", "volatile", "while", - "true", "false", "null", - NULL - }; - const char** k = KEYWORDS; - while (*k) { - if (0 == strcmp(str, *k)) { - return true; - } - k++; - } - return false; -} - -static int -check_method(const char* filename, method_type* m) -{ - int err = 0; - - // return type - Type* returnType = NAMES.Search(m->type.type.data); - if (returnType == NULL) { - fprintf(stderr, "%s:%d unknown return type %s\n", filename, - m->type.type.lineno, m->type.type.data); - err = 1; - return err; - } - - if (!returnType->CanBeMarshalled()) { - fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename, - m->type.type.lineno, m->type.type.data); - err = 1; - } - - if (m->type.dimension > 0 && !returnType->CanBeArray()) { - fprintf(stderr, "%s:%d return type %s%s can't be an array.\n", filename, - m->type.array_token.lineno, m->type.type.data, - m->type.array_token.data); - err = 1; - } - - if (m->type.dimension > 1) { - fprintf(stderr, "%s:%d return type %s%s only one" - " dimensional arrays are supported\n", filename, - m->type.array_token.lineno, m->type.type.data, - m->type.array_token.data); - err = 1; - } - - int index = 1; - - arg_type* arg = m->args; - while (arg) { - Type* t = NAMES.Search(arg->type.type.data); - - // check the arg type - if (t == NULL) { - fprintf(stderr, "%s:%d parameter %s (%d) unknown type %s\n", - filename, m->type.type.lineno, arg->name.data, index, - arg->type.type.data); - err = 1; - goto next; - } - - if (!t->CanBeMarshalled()) { - fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n", - filename, m->type.type.lineno, index, - arg->type.type.data, arg->name.data); - err = 1; - } - - if (arg->direction.data == NULL - && (arg->type.dimension != 0 || t->CanBeOutParameter())) { - fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out" - " parameter, so you must declare it as in," - " out or inout.\n", - filename, m->type.type.lineno, index, - arg->type.type.data, arg->name.data); - err = 1; - } - - if (convert_direction(arg->direction.data) != IN_PARAMETER - && !t->CanBeOutParameter() - && arg->type.dimension == 0) { - fprintf(stderr, "%s:%d parameter %d: '%s %s %s' can only be an in" - " parameter.\n", - filename, m->type.type.lineno, index, - arg->direction.data, arg->type.type.data, - arg->name.data); - err = 1; - } - - if (arg->type.dimension > 0 && !t->CanBeArray()) { - fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' can't be an" - " array.\n", filename, - m->type.array_token.lineno, index, arg->direction.data, - arg->type.type.data, arg->type.array_token.data, - arg->name.data); - err = 1; - } - - if (arg->type.dimension > 1) { - fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' only one" - " dimensional arrays are supported\n", filename, - m->type.array_token.lineno, index, arg->direction.data, - arg->type.type.data, arg->type.array_token.data, - arg->name.data); - err = 1; - } - - // check that the name doesn't match a keyword - if (matches_keyword(arg->name.data)) { - fprintf(stderr, "%s:%d parameter %d %s is named the same as a" - " Java keyword\n", - filename, m->name.lineno, index, arg->name.data); - err = 1; - } - -next: - index++; - arg = arg->next; - } - - return err; -} - -static int -check_types(const char* filename, document_item_type* items) -{ - int err = 0; - while (items) { - // (nothing to check for PARCELABLE_TYPE) - if (items->item_type == INTERFACE_TYPE) { - map<string,method_type*> methodNames; - interface_type* c = (interface_type*)items; - - interface_item_type* member = c->interface_items; - while (member) { - if (member->item_type == METHOD_TYPE) { - method_type* m = (method_type*)member; - - err |= check_method(filename, m); - - // prevent duplicate methods - if (methodNames.find(m->name.data) == methodNames.end()) { - methodNames[m->name.data] = m; - } else { - fprintf(stderr,"%s:%d attempt to redefine method %s,\n", - filename, m->name.lineno, m->name.data); - method_type* old = methodNames[m->name.data]; - fprintf(stderr, "%s:%d previously defined here.\n", - filename, old->name.lineno); - err = 1; - } - } - member = member->next; - } - } - - items = items->next; - } - return err; -} - -// ========================================================== -static int -exactly_one_interface(const char* filename, const document_item_type* items, const Options& options, - bool* onlyParcelable) -{ - if (items == NULL) { - fprintf(stderr, "%s: file does not contain any interfaces\n", - filename); - return 1; - } - - const document_item_type* next = items->next; - if (items->next != NULL) { - int lineno = -1; - if (next->item_type == INTERFACE_TYPE) { - lineno = ((interface_type*)next)->interface_token.lineno; - } - else if (next->item_type == PARCELABLE_TYPE) { - lineno = ((parcelable_type*)next)->parcelable_token.lineno; - } - fprintf(stderr, "%s:%d aidl can only handle one interface per file\n", - filename, lineno); - return 1; - } - - if (items->item_type == PARCELABLE_TYPE) { - *onlyParcelable = true; - if (options.failOnParcelable) { - fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not" - " parcelables,\n", filename, - ((parcelable_type*)items)->parcelable_token.lineno); - fprintf(stderr, "%s:%d .aidl files that only declare parcelables " - "don't need to go in the Makefile.\n", filename, - ((parcelable_type*)items)->parcelable_token.lineno); - return 1; - } - } else { - *onlyParcelable = false; - } - - return 0; -} - -// ========================================================== -void -generate_dep_file(const Options& options) -{ - /* we open the file in binary mode to ensure that the same output is - * generated on all platforms !! - */ - FILE* to = fopen(options.depFileName.c_str(), "wb"); - if (to == NULL) { - return; - } - - const char* slash = "\\"; - import_info* import = g_imports; - if (import == NULL) { - slash = ""; - } - - fprintf(to, "%s: \\\n", options.outputFileName.c_str()); - fprintf(to, " %s %s\n", options.inputFileName.c_str(), slash); - - while (import) { - if (import->next == NULL) { - slash = ""; - } - if (import->filename) { - fprintf(to, " %s %s\n", import->filename, slash); - } - import = import->next; - } - - fprintf(to, "\n"); - - fclose(to); -} - -// ========================================================== -static int -parse_preprocessed_file(const string& filename) -{ - int err; - - FILE* f = fopen(filename.c_str(), "rb"); - if (f == NULL) { - fprintf(stderr, "aidl: can't open preprocessd file: %s\n", - filename.c_str()); - return 1; - } - - int lineno = 1; - char line[1024]; - char type[1024]; - char fullname[1024]; - while (fgets(line, sizeof(line), f)) { - // skip comments and empty lines - if (!line[0] || strncmp(line, "//", 2) == 0) { - continue; - } - - sscanf(line, "%s %[^; \r\n\t];", type, fullname); - - char* packagename; - char* classname = rfind(fullname, '.'); - if (classname != NULL) { - *classname = '\0'; - classname++; - packagename = fullname; - } else { - classname = fullname; - packagename = NULL; - } - - //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno, - // type, packagename, classname); - document_item_type* doc; - - if (0 == strcmp("parcelable", type)) { - parcelable_type* parcl = (parcelable_type*)malloc( - sizeof(parcelable_type)); - memset(parcl, 0, sizeof(parcelable_type)); - parcl->document_item.item_type = PARCELABLE_TYPE; - parcl->parcelable_token.lineno = lineno; - parcl->parcelable_token.data = strdup(type); - parcl->package = packagename ? strdup(packagename) : NULL; - parcl->name.lineno = lineno; - parcl->name.data = strdup(classname); - parcl->semicolon_token.lineno = lineno; - parcl->semicolon_token.data = strdup(";"); - doc = (document_item_type*)parcl; - } - else if (0 == strcmp("interface", type)) { - interface_type* iface = (interface_type*)malloc( - sizeof(interface_type)); - memset(iface, 0, sizeof(interface_type)); - iface->document_item.item_type = INTERFACE_TYPE; - iface->interface_token.lineno = lineno; - iface->interface_token.data = strdup(type); - iface->package = packagename ? strdup(packagename) : NULL; - iface->name.lineno = lineno; - iface->name.data = strdup(classname); - iface->open_brace_token.lineno = lineno; - iface->open_brace_token.data = strdup("{"); - iface->close_brace_token.lineno = lineno; - iface->close_brace_token.data = strdup("}"); - doc = (document_item_type*)iface; - } - else { - fprintf(stderr, "%s:%d: bad type in line: %s\n", - filename.c_str(), lineno, line); - return 1; - } - err = gather_types(filename.c_str(), doc); - lineno++; - } - - if (!feof(f)) { - fprintf(stderr, "%s:%d: error reading file, line to long.\n", - filename.c_str(), lineno); - return 1; - } - - fclose(f); - return 0; -} - -// ========================================================== -static int -compile_aidl(const Options& options) -{ - int err = 0, N; - - set_import_paths(options.importPaths); - - register_base_types(); - - // import the preprocessed file - N = options.preprocessedFiles.size(); - for (int i=0; i<N; i++) { - const string& s = options.preprocessedFiles[i]; - err |= parse_preprocessed_file(s); - } - if (err != 0) { - return err; - } - - // parse the main file - g_callbacks = &g_mainCallbacks; - err = parse_aidl(options.inputFileName.c_str()); - document_item_type* mainDoc = g_document; - g_document = NULL; - - // parse the imports - g_callbacks = &g_mainCallbacks; - import_info* import = g_imports; - while (import) { - if (NAMES.Find(import->neededClass) == NULL) { - import->filename = find_import_file(import->neededClass); - if (!import->filename) { - fprintf(stderr, "%s:%d: couldn't find import for class %s\n", - import->from, import->statement.lineno, - import->neededClass); - err |= 1; - } else { - err |= parse_aidl(import->filename); - import->doc = g_document; - if (import->doc == NULL) { - err |= 1; - } - } - } - import = import->next; - } - // bail out now if parsing wasn't successful - if (err != 0 || mainDoc == NULL) { - //fprintf(stderr, "aidl: parsing failed, stopping.\n"); - return 1; - } - - // complain about ones that aren't in the right files - err |= check_filenames(options.inputFileName.c_str(), mainDoc); - import = g_imports; - while (import) { - err |= check_filenames(import->filename, import->doc); - import = import->next; - } - - // gather the types that have been declared - err |= gather_types(options.inputFileName.c_str(), mainDoc); - import = g_imports; - while (import) { - err |= gather_types(import->filename, import->doc); - import = import->next; - } - -#if 0 - printf("---- main doc ----\n"); - test_document(mainDoc); - - import = g_imports; - while (import) { - printf("---- import doc ----\n"); - test_document(import->doc); - import = import->next; - } - NAMES.Dump(); -#endif - - // check the referenced types in mainDoc to make sure we've imported them - err |= check_types(options.inputFileName.c_str(), mainDoc); - - // finally, there really only needs to be one thing in mainDoc, and it - // needs to be an interface. - bool onlyParcelable = false; - err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable); - - // after this, there shouldn't be any more errors because of the - // input. - if (err != 0 || mainDoc == NULL) { - return 1; - } - - // they didn't ask to fail on parcelables, so just exit quietly. - if (onlyParcelable && !options.failOnParcelable) { - return 0; - } - - // if we were asked to, generate a make dependency file - if (options.depFileName != "") { - generate_dep_file(options); - } - - err = generate_java(options.outputFileName, options.inputFileName.c_str(), - (interface_type*)mainDoc); - - return err; -} - -static int -preprocess_aidl(const Options& options) -{ - vector<string> lines; - int err; - - // read files - int N = options.filesToPreprocess.size(); - for (int i=0; i<N; i++) { - g_callbacks = &g_mainCallbacks; - err = parse_aidl(options.filesToPreprocess[i].c_str()); - if (err != 0) { - return err; - } - document_item_type* doc = g_document; - string line; - if (doc->item_type == PARCELABLE_TYPE) { - line = "parcelable "; - parcelable_type* parcelable = (parcelable_type*)doc; - if (parcelable->package) { - line += parcelable->package; - line += '.'; - } - line += parcelable->name.data; - } else { - line = "interface "; - interface_type* iface = (interface_type*)doc; - if (iface->package) { - line += iface->package; - line += '.'; - } - line += iface->name.data; - } - line += ";\n"; - lines.push_back(line); - } - - // write preprocessed file - int fd = open( options.outputFileName.c_str(), - O_RDWR|O_CREAT|O_TRUNC|O_BINARY, -#ifdef HAVE_MS_C_RUNTIME - _S_IREAD|_S_IWRITE); -#else - S_IRUSR|S_IWUSR|S_IRGRP); -#endif - if (fd == -1) { - fprintf(stderr, "aidl: could not open file for write: %s\n", - options.outputFileName.c_str()); - return 1; - } - - N = lines.size(); - for (int i=0; i<N; i++) { - const string& s = lines[i]; - int len = s.length(); - if (len != write(fd, s.c_str(), len)) { - fprintf(stderr, "aidl: error writing to file %s\n", - options.outputFileName.c_str()); - close(fd); - unlink(options.outputFileName.c_str()); - return 1; - } - } - - close(fd); - return 0; -} - -// ========================================================== -int -main(int argc, const char **argv) -{ - int err = 0; - - Options options; - int result = parse_options(argc, argv, &options); - if (result) { - return result; - } - - switch (options.task) - { - case COMPILE_AIDL: - return compile_aidl(options); - case PREPROCESS_AIDL: - return preprocess_aidl(options); - } - fprintf(stderr, "aidl: internal error\n"); - return 1; -} - - diff --git a/tools/aidl/aidl_language.cpp b/tools/aidl/aidl_language.cpp deleted file mode 100644 index cd6a3bd..0000000 --- a/tools/aidl/aidl_language.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "aidl_language.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#ifdef HAVE_MS_C_RUNTIME -int isatty(int fd) -{ - return (fd == 0); -} -#endif - -#if 0 -ParserCallbacks k_parserCallbacks = { - NULL -}; -#endif - -ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks; - diff --git a/tools/aidl/aidl_language.h b/tools/aidl/aidl_language.h deleted file mode 100644 index 9ca5deb..0000000 --- a/tools/aidl/aidl_language.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H -#define DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H - - -typedef enum { - NO_EXTRA_TEXT = 0, - SHORT_COMMENT, - LONG_COMMENT, - COPY_TEXT, - WHITESPACE -} which_extra_text; - -typedef struct extra_text_type { - unsigned lineno; - which_extra_text which; - char* data; - unsigned len; - struct extra_text_type* next; -} extra_text_type; - -typedef struct buffer_type { - unsigned lineno; - unsigned token; - char *data; - extra_text_type* extra; -} buffer_type; - -typedef struct type_type { - buffer_type type; - buffer_type array_token; - int dimension; -} type_type; - -typedef struct arg_type { - buffer_type comma_token; // empty in the first one in the list - buffer_type direction; - type_type type; - buffer_type name; - struct arg_type *next; -} arg_type; - -enum { - METHOD_TYPE -}; - -typedef struct interface_item_type { - unsigned item_type; - struct interface_item_type* next; -} interface_item_type; - -typedef struct method_type { - interface_item_type interface_item; - type_type type; - bool oneway; - buffer_type oneway_token; - buffer_type name; - buffer_type open_paren_token; - arg_type* args; - buffer_type close_paren_token; - // XXX missing comments/copy text here - buffer_type semicolon_token; - buffer_type* comments_token; // points into this structure, DO NOT DELETE -} method_type; - -enum { - PARCELABLE_TYPE = 12, - INTERFACE_TYPE -}; - -typedef struct document_item_type { - unsigned item_type; - struct document_item_type* next; -} document_item_type; - -typedef struct parcelable_type { - document_item_type document_item; - buffer_type parcelable_token; - char* package; - buffer_type name; - buffer_type semicolon_token; -} parcelable_type; - -typedef struct interface_type { - document_item_type document_item; - buffer_type interface_token; - bool oneway; - buffer_type oneway_token; - char* package; - buffer_type name; - buffer_type open_brace_token; - interface_item_type* interface_items; - buffer_type close_brace_token; - buffer_type* comments_token; // points into this structure, DO NOT DELETE -} interface_type; - -typedef union lexer_type { - buffer_type buffer; - type_type type; - arg_type *arg; - method_type* method; - interface_item_type* interface_item; - interface_type* interface_obj; - parcelable_type* parcelable; - document_item_type* document_item; -} lexer_type; - - -#define YYSTYPE lexer_type - -#if __cplusplus -extern "C" { -#endif - -int parse_aidl(char const *); - -// strips off the leading whitespace, the "import" text -// also returns whether it's a local or system import -// we rely on the input matching the import regex from below -char* parse_import_statement(const char* text); - -// in, out or inout -enum { - IN_PARAMETER = 1, - OUT_PARAMETER = 2, - INOUT_PARAMETER = 3 -}; -int convert_direction(const char* direction); - -// callbacks from within the parser -// these functions all take ownership of the strings -typedef struct ParserCallbacks { - void (*document)(document_item_type* items); - void (*import)(buffer_type* statement); -} ParserCallbacks; - -extern ParserCallbacks* g_callbacks; - -// true if there was an error parsing, false otherwise -extern int g_error; - -// the name of the file we're currently parsing -extern char const* g_currentFilename; - -// the package name for our current file -extern char const* g_currentPackage; - -typedef enum { - STATEMENT_INSIDE_INTERFACE -} error_type; - -void init_buffer_type(buffer_type* buf, int lineno); - - -#if __cplusplus -} -#endif - - -#endif // DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H diff --git a/tools/aidl/aidl_language_l.l b/tools/aidl/aidl_language_l.l deleted file mode 100644 index 567b1cf..0000000 --- a/tools/aidl/aidl_language_l.l +++ /dev/null @@ -1,210 +0,0 @@ -%{ -#include "aidl_language.h" -#include "aidl_language_y.h" -#include "search_path.h" -#include <string.h> -#include <stdlib.h> - -extern YYSTYPE yylval; - -// comment and whitespace handling -// these functions save a copy of the buffer -static void begin_extra_text(unsigned lineno, which_extra_text which); -static void append_extra_text(char* text); -static extra_text_type* get_extra_text(void); // you now own the object - // this returns -static void drop_extra_text(void); - -// package handling -static void do_package_statement(const char* importText); - -#define SET_BUFFER(t) \ - do { \ - yylval.buffer.lineno = yylineno; \ - yylval.buffer.token = (t); \ - yylval.buffer.data = strdup(yytext); \ - yylval.buffer.extra = get_extra_text(); \ - } while(0) - -%} - -%option yylineno -%option noyywrap - -%x COPYING LONG_COMMENT - -identifier [_a-zA-Z][_a-zA-Z0-9\.]* -whitespace ([ \t\n\r]+) -brackets \[{whitespace}?\] - -%% - - -\%\%\{ { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); } -<COPYING>\}\%\% { BEGIN(INITIAL); } -<COPYING>.*\n { append_extra_text(yytext); } -<COPYING>.* { append_extra_text(yytext); } -<COPYING>\n+ { append_extra_text(yytext); } - - -\/\* { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT); - BEGIN(LONG_COMMENT); } -<LONG_COMMENT>[^*]* { append_extra_text(yytext); } -<LONG_COMMENT>\*+[^/] { append_extra_text(yytext); } -<LONG_COMMENT>\n { append_extra_text(yytext); } -<LONG_COMMENT>\**\/ { BEGIN(INITIAL); } - -^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?; { - SET_BUFFER(IMPORT); - return IMPORT; - } -^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?; { - do_package_statement(yytext); - SET_BUFFER(PACKAGE); - return PACKAGE; - } -<<EOF>> { yyterminate(); } - -\/\/.*\n { begin_extra_text(yylineno, SHORT_COMMENT); - append_extra_text(yytext); } - -{whitespace} { /* begin_extra_text(yylineno, WHITESPACE); - append_extra_text(yytext); */ } - -; { SET_BUFFER(';'); return ';'; } -\{ { SET_BUFFER('{'); return '{'; } -\} { SET_BUFFER('}'); return '}'; } -\( { SET_BUFFER('('); return '('; } -\) { SET_BUFFER(')'); return ')'; } -, { SET_BUFFER(','); return ','; } - - /* keywords */ -parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; } -interface { SET_BUFFER(INTERFACE); return INTERFACE; } -in { SET_BUFFER(IN); return IN; } -out { SET_BUFFER(OUT); return OUT; } -inout { SET_BUFFER(INOUT); return INOUT; } -oneway { SET_BUFFER(ONEWAY); return ONEWAY; } - -{brackets}+ { SET_BUFFER(ARRAY); return ARRAY; } - -{identifier} { SET_BUFFER(IDENTIFIER); return IDENTIFIER; } -{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> { - SET_BUFFER(GENERIC); return GENERIC; } - - /* syntax error! */ -. { printf("UNKNOWN(%s)", yytext); - yylval.buffer.lineno = yylineno; - yylval.buffer.token = IDENTIFIER; - yylval.buffer.data = strdup(yytext); - return IDENTIFIER; - } - -%% - -// comment and whitespace handling -// ================================================ -extra_text_type* g_extraText = NULL; -extra_text_type* g_nextExtraText = NULL; - -void begin_extra_text(unsigned lineno, which_extra_text which) -{ - extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type)); - text->lineno = lineno; - text->which = which; - text->data = NULL; - text->len = 0; - text->next = NULL; - if (g_nextExtraText == NULL) { - g_extraText = text; - } else { - g_nextExtraText->next = text; - } - g_nextExtraText = text; -} - -void append_extra_text(char* text) -{ - if (g_nextExtraText->data == NULL) { - g_nextExtraText->data = strdup(text); - g_nextExtraText->len = strlen(text); - } else { - char* orig = g_nextExtraText->data; - unsigned oldLen = g_nextExtraText->len; - unsigned len = strlen(text); - g_nextExtraText->len += len; - g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1); - memcpy(g_nextExtraText->data, orig, oldLen); - memcpy(g_nextExtraText->data+oldLen, text, len); - g_nextExtraText->data[g_nextExtraText->len] = '\0'; - free(orig); - } -} - -extra_text_type* -get_extra_text(void) -{ - extra_text_type* result = g_extraText; - g_extraText = NULL; - g_nextExtraText = NULL; - return result; -} - -void drop_extra_text(void) -{ - extra_text_type* p = g_extraText; - while (p) { - extra_text_type* next = p->next; - free(p->data); - free(p); - free(next); - } - g_extraText = NULL; - g_nextExtraText = NULL; -} - - -// package handling -// ================================================ -void do_package_statement(const char* importText) -{ - if (g_currentPackage) free((void*)g_currentPackage); - g_currentPackage = parse_import_statement(importText); -} - - -// main parse function -// ================================================ -char const* g_currentFilename = NULL; -char const* g_currentPackage = NULL; - -int yyparse(void); - -int parse_aidl(char const *filename) -{ - yyin = fopen(filename, "r"); - if (yyin) { - char const* oldFilename = g_currentFilename; - char const* oldPackage = g_currentPackage; - g_currentFilename = strdup(filename); - - g_error = 0; - yylineno = 1; - int rv = yyparse(); - if (g_error != 0) { - rv = g_error; - } - - free((void*)g_currentFilename); - g_currentFilename = oldFilename; - - if (g_currentPackage) free((void*)g_currentPackage); - g_currentPackage = oldPackage; - - return rv; - } else { - fprintf(stderr, "aidl: unable to open file for read: %s\n", filename); - return 1; - } -} - diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y deleted file mode 100644 index 3d65f17..0000000 --- a/tools/aidl/aidl_language_y.y +++ /dev/null @@ -1,288 +0,0 @@ -%{ -#include "aidl_language.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int yyerror(char* errstr); -int yylex(void); -extern int yylineno; - -static int count_brackets(const char*); - -%} - -%token IMPORT -%token PACKAGE -%token IDENTIFIER -%token GENERIC -%token ARRAY -%token PARCELABLE -%token INTERFACE -%token IN -%token OUT -%token INOUT -%token ONEWAY - -%% -document: - document_items { g_callbacks->document($1.document_item); } - | headers document_items { g_callbacks->document($2.document_item); } - ; - -headers: - package { } - | imports { } - | package imports { } - ; - -package: - PACKAGE { } - ; - -imports: - IMPORT { g_callbacks->import(&($1.buffer)); } - | IMPORT imports { g_callbacks->import(&($1.buffer)); } - ; - -document_items: - { $$.document_item = NULL; } - | document_items declaration { - if ($2.document_item == NULL) { - // error cases only - $$ = $1; - } else { - document_item_type* p = $1.document_item; - while (p && p->next) { - p=p->next; - } - if (p) { - p->next = (document_item_type*)$2.document_item; - $$ = $1; - } else { - $$.document_item = (document_item_type*)$2.document_item; - } - } - } - | document_items error { - fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename, - $2.buffer.lineno, $2.buffer.data); - $$ = $1; - } - ; - -declaration: - parcelable_decl { $$.document_item = (document_item_type*)$1.parcelable; } - | interface_decl { $$.document_item = (document_item_type*)$1.interface_item; } - ; - -parcelable_decl: - PARCELABLE IDENTIFIER ';' { - parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type)); - b->document_item.item_type = PARCELABLE_TYPE; - b->document_item.next = NULL; - b->parcelable_token = $1.buffer; - b->name = $2.buffer; - b->package = g_currentPackage ? strdup(g_currentPackage) : NULL; - b->semicolon_token = $3.buffer; - $$.parcelable = b; - } - | PARCELABLE ';' { - fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", - g_currentFilename, $1.buffer.lineno); - $$.parcelable = NULL; - } - | PARCELABLE error ';' { - fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n", - g_currentFilename, $2.buffer.lineno, $2.buffer.data); - $$.parcelable = NULL; - } - ; - -interface_header: - INTERFACE { - interface_type* c = (interface_type*)malloc(sizeof(interface_type)); - c->interface_token = $1.buffer; - c->oneway = false; - memset(&c->oneway_token, 0, sizeof(buffer_type)); - c->comments_token = &c->interface_token; - $$.interface_obj = c; - } - | ONEWAY INTERFACE { - interface_type* c = (interface_type*)malloc(sizeof(interface_type)); - c->interface_token = $2.buffer; - c->oneway = true; - c->oneway_token = $1.buffer; - c->comments_token = &c->oneway_token; - $$.interface_obj = c; - } - ; - -interface_decl: - interface_header IDENTIFIER '{' interface_items '}' { - interface_type* c = $1.interface_obj; - c->document_item.item_type = INTERFACE_TYPE; - c->document_item.next = NULL; - c->name = $2.buffer; - c->package = g_currentPackage ? strdup(g_currentPackage) : NULL; - c->open_brace_token = $3.buffer; - c->interface_items = $4.interface_item; - c->close_brace_token = $5.buffer; - $$.interface_obj = c; - } - | INTERFACE error '{' interface_items '}' { - fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n", - g_currentFilename, $2.buffer.lineno, $2.buffer.data); - $$.document_item = NULL; - } - | INTERFACE error '}' { - fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n", - g_currentFilename, $2.buffer.lineno, $2.buffer.data); - $$.document_item = NULL; - } - - ; - -interface_items: - { $$.interface_item = NULL; } - | interface_items method_decl { - interface_item_type* p=$1.interface_item; - while (p && p->next) { - p=p->next; - } - if (p) { - p->next = (interface_item_type*)$2.method; - $$ = $1; - } else { - $$.interface_item = (interface_item_type*)$2.method; - } - } - | interface_items error ';' { - fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n", - g_currentFilename, $3.buffer.lineno); - $$ = $1; - } - ; - -method_decl: - type IDENTIFIER '(' arg_list ')' ';' { - method_type *method = (method_type*)malloc(sizeof(method_type)); - method->interface_item.item_type = METHOD_TYPE; - method->interface_item.next = NULL; - method->type = $1.type; - method->oneway = false; - memset(&method->oneway_token, 0, sizeof(buffer_type)); - method->name = $2.buffer; - method->open_paren_token = $3.buffer; - method->args = $4.arg; - method->close_paren_token = $5.buffer; - method->semicolon_token = $6.buffer; - method->comments_token = &method->type.type; - $$.method = method; - } - | ONEWAY type IDENTIFIER '(' arg_list ')' ';' { - method_type *method = (method_type*)malloc(sizeof(method_type)); - method->interface_item.item_type = METHOD_TYPE; - method->interface_item.next = NULL; - method->oneway = true; - method->oneway_token = $1.buffer; - method->type = $2.type; - method->name = $3.buffer; - method->open_paren_token = $4.buffer; - method->args = $5.arg; - method->close_paren_token = $6.buffer; - method->semicolon_token = $7.buffer; - method->comments_token = &method->oneway_token; - $$.method = method; - } - ; - -arg_list: - { $$.arg = NULL; } - | arg { $$ = $1; } - | arg_list ',' arg { - if ($$.arg != NULL) { - // only NULL on error - $$ = $1; - arg_type *p = $1.arg; - while (p && p->next) { - p=p->next; - } - $3.arg->comma_token = $2.buffer; - p->next = $3.arg; - } - } - | error { - fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno); - $$.arg = NULL; - } - ; - -arg: - direction type IDENTIFIER { - arg_type* arg = (arg_type*)malloc(sizeof(arg_type)); - memset(&arg->comma_token, 0, sizeof(buffer_type)); - arg->direction = $1.buffer; - arg->type = $2.type; - arg->name = $3.buffer; - arg->next = NULL; - $$.arg = arg; - } - ; - -type: - IDENTIFIER { - $$.type.type = $1.buffer; - init_buffer_type(&$$.type.array_token, yylineno); - $$.type.dimension = 0; - } - | IDENTIFIER ARRAY { - $$.type.type = $1.buffer; - $$.type.array_token = $2.buffer; - $$.type.dimension = count_brackets($2.buffer.data); - } - | GENERIC { - $$.type.type = $1.buffer; - init_buffer_type(&$$.type.array_token, yylineno); - $$.type.dimension = 0; - } - ; - -direction: - { init_buffer_type(&$$.buffer, yylineno); } - | IN { $$.buffer = $1.buffer; } - | OUT { $$.buffer = $1.buffer; } - | INOUT { $$.buffer = $1.buffer; } - ; - -%% - -#include <ctype.h> -#include <stdio.h> - -int g_error = 0; - -int yyerror(char* errstr) -{ - fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr); - g_error = 1; - return 1; -} - -void init_buffer_type(buffer_type* buf, int lineno) -{ - buf->lineno = lineno; - buf->token = 0; - buf->data = NULL; - buf->extra = NULL; -} - -static int count_brackets(const char* s) -{ - int n=0; - while (*s) { - if (*s == '[') n++; - s++; - } - return n; -} diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp deleted file mode 100644 index e3c0af0..0000000 --- a/tools/aidl/generate_java.cpp +++ /dev/null @@ -1,652 +0,0 @@ -#include "generate_java.h" -#include "AST.h" -#include "Type.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -// ================================================= -class VariableFactory -{ -public: - VariableFactory(const string& base); // base must be short - Variable* Get(Type* type); - Variable* Get(int index); -private: - vector<Variable*> m_vars; - string m_base; - int m_index; -}; - -VariableFactory::VariableFactory(const string& base) - :m_base(base), - m_index(0) -{ -} - -Variable* -VariableFactory::Get(Type* type) -{ - char name[100]; - sprintf(name, "%s%d", m_base.c_str(), m_index); - m_index++; - Variable* v = new Variable(type, name); - m_vars.push_back(v); - return v; -} - -Variable* -VariableFactory::Get(int index) -{ - return m_vars[index]; -} - -// ================================================= -class StubClass : public Class -{ -public: - StubClass(Type* type, Type* interfaceType); - virtual ~StubClass(); - - Variable* transact_code; - Variable* transact_data; - Variable* transact_reply; - Variable* transact_flags; - SwitchStatement* transact_switch; -private: - void make_as_interface(Type* interfaceType); -}; - -StubClass::StubClass(Type* type, Type* interfaceType) - :Class() -{ - this->comment = "/** Local-side IPC implementation stub class. */"; - this->modifiers = PUBLIC | ABSTRACT | STATIC; - this->what = Class::CLASS; - this->type = type; - this->extends = BINDER_NATIVE_TYPE; - this->interfaces.push_back(interfaceType); - - // descriptor - Field* descriptor = new Field(STATIC | FINAL | PRIVATE, - new Variable(STRING_TYPE, "DESCRIPTOR")); - descriptor->value = "\"" + interfaceType->QualifiedName() + "\""; - this->elements.push_back(descriptor); - - // ctor - Method* ctor = new Method; - ctor->modifiers = PUBLIC; - ctor->comment = "/** Construct the stub at attach it to the " - "interface. */"; - ctor->name = "Stub"; - ctor->statements = new StatementBlock; - MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface", - 2, THIS_VALUE, new LiteralExpression("DESCRIPTOR")); - ctor->statements->Add(attach); - this->elements.push_back(ctor); - - // asInterface - make_as_interface(interfaceType); - - // asBinder - Method* asBinder = new Method; - asBinder->modifiers = PUBLIC; - asBinder->returnType = IBINDER_TYPE; - asBinder->name = "asBinder"; - asBinder->statements = new StatementBlock; - asBinder->statements->Add(new ReturnStatement(THIS_VALUE)); - this->elements.push_back(asBinder); - - // onTransact - this->transact_code = new Variable(INT_TYPE, "code"); - this->transact_data = new Variable(PARCEL_TYPE, "data"); - this->transact_reply = new Variable(PARCEL_TYPE, "reply"); - this->transact_flags = new Variable(INT_TYPE, "flags"); - Method* onTransact = new Method; - onTransact->modifiers = PUBLIC; - onTransact->returnType = BOOLEAN_TYPE; - onTransact->name = "onTransact"; - onTransact->parameters.push_back(this->transact_code); - onTransact->parameters.push_back(this->transact_data); - onTransact->parameters.push_back(this->transact_reply); - onTransact->parameters.push_back(this->transact_flags); - onTransact->statements = new StatementBlock; - onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE); - this->elements.push_back(onTransact); - this->transact_switch = new SwitchStatement(this->transact_code); - - onTransact->statements->Add(this->transact_switch); - MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4, - this->transact_code, this->transact_data, - this->transact_reply, this->transact_flags); - onTransact->statements->Add(new ReturnStatement(superCall)); -} - -StubClass::~StubClass() -{ -} - -void -StubClass::make_as_interface(Type *interfaceType) -{ - Variable* obj = new Variable(IBINDER_TYPE, "obj"); - - Method* m = new Method; - m->comment = "/**\n * Cast an IBinder object into an "; - m->comment += interfaceType->Name(); - m->comment += " interface,\n"; - m->comment += " * generating a proxy if needed.\n */"; - m->modifiers = PUBLIC | STATIC; - m->returnType = interfaceType; - m->name = "asInterface"; - m->parameters.push_back(obj); - m->statements = new StatementBlock; - - IfStatement* ifstatement = new IfStatement(); - ifstatement->expression = new Comparison(obj, "==", NULL_VALUE); - ifstatement->statements = new StatementBlock; - ifstatement->statements->Add(new ReturnStatement(NULL_VALUE)); - m->statements->Add(ifstatement); - - // IInterface iin = obj.queryLocalInterface(DESCRIPTOR) - MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface"); - queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR")); - IInterfaceType* iinType = new IInterfaceType(); - Variable *iin = new Variable(iinType, "iin"); - VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, iinType); - m->statements->Add(iinVd); - - // Ensure the instance type of the local object is as expected. - // One scenario where this is needed is if another package (with a - // different class loader) runs in the same process as the service. - - // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin; - Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE); - Comparison* instOfCheck = new Comparison(iin, " instanceof ", - new LiteralExpression(interfaceType->QualifiedName())); - IfStatement* instOfStatement = new IfStatement(); - instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck); - instOfStatement->statements = new StatementBlock; - instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin))); - m->statements->Add(instOfStatement); - - string proxyType = interfaceType->QualifiedName(); - proxyType += ".Stub.Proxy"; - NewExpression* ne = new NewExpression(NAMES.Find(proxyType)); - ne->arguments.push_back(obj); - m->statements->Add(new ReturnStatement(ne)); - - this->elements.push_back(m); -} - - - -// ================================================= -class ProxyClass : public Class -{ -public: - ProxyClass(Type* type, InterfaceType* interfaceType); - virtual ~ProxyClass(); - - Variable* mRemote; - bool mOneWay; -}; - -ProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType) - :Class() -{ - this->modifiers = PRIVATE | STATIC; - this->what = Class::CLASS; - this->type = type; - this->interfaces.push_back(interfaceType); - - mOneWay = interfaceType->OneWay(); - - // IBinder mRemote - mRemote = new Variable(IBINDER_TYPE, "mRemote"); - this->elements.push_back(new Field(PRIVATE, mRemote)); - - // Proxy() - Variable* remote = new Variable(IBINDER_TYPE, "remote"); - Method* ctor = new Method; - ctor->name = "Proxy"; - ctor->statements = new StatementBlock; - ctor->parameters.push_back(remote); - ctor->statements->Add(new Assignment(mRemote, remote)); - this->elements.push_back(ctor); - - // IBinder asBinder() - Method* asBinder = new Method; - asBinder->modifiers = PUBLIC; - asBinder->returnType = IBINDER_TYPE; - asBinder->name = "asBinder"; - asBinder->statements = new StatementBlock; - asBinder->statements->Add(new ReturnStatement(mRemote)); - this->elements.push_back(asBinder); -} - -ProxyClass::~ProxyClass() -{ -} - -// ================================================= -static string -gather_comments(extra_text_type* extra) -{ - string s; - while (extra) { - if (extra->which == SHORT_COMMENT) { - s += extra->data; - } - else if (extra->which == LONG_COMMENT) { - s += "/*"; - s += extra->data; - s += "*/"; - } - extra = extra->next; - } - return s; -} - -static string -append(const char* a, const char* b) -{ - string s = a; - s += b; - return s; -} - -static void -generate_new_array(Type* t, StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - Variable* len = new Variable(INT_TYPE, v->name + "_length"); - addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt"))); - IfStatement* lencheck = new IfStatement(); - lencheck->expression = new Comparison(len, "<", new LiteralExpression("0")); - lencheck->statements->Add(new Assignment(v, NULL_VALUE)); - lencheck->elseif = new IfStatement(); - lencheck->elseif->statements->Add(new Assignment(v, - new NewArrayExpression(t, len))); - addTo->Add(lencheck); -} - -static void -generate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v, - Variable* parcel, int flags) -{ - if (v->dimension == 0) { - t->WriteToParcel(addTo, v, parcel, flags); - } - if (v->dimension == 1) { - t->WriteArrayToParcel(addTo, v, parcel, flags); - } -} - -static void -generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - if (v->dimension == 0) { - t->CreateFromParcel(addTo, v, parcel); - } - if (v->dimension == 1) { - t->CreateArrayFromParcel(addTo, v, parcel); - } -} - -static void -generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v, - Variable* parcel) -{ - if (v->dimension == 0) { - t->ReadFromParcel(addTo, v, parcel); - } - if (v->dimension == 1) { - t->ReadArrayFromParcel(addTo, v, parcel); - } -} - - -static void -generate_method(const method_type* method, Class* interface, - StubClass* stubClass, ProxyClass* proxyClass, int index) -{ - arg_type* arg; - int i; - bool hasOutParams = false; - - const bool oneway = proxyClass->mOneWay || method->oneway; - - // == the TRANSACT_ constant ============================================= - string transactCodeName = "TRANSACTION_"; - transactCodeName += method->name.data; - - char transactCodeValue[50]; - sprintf(transactCodeValue, "(IBinder.FIRST_CALL_TRANSACTION + %d)", index); - - Field* transactCode = new Field(STATIC | FINAL, - new Variable(INT_TYPE, transactCodeName)); - transactCode->value = transactCodeValue; - stubClass->elements.push_back(transactCode); - - // == the declaration in the interface =================================== - Method* decl = new Method; - decl->comment = gather_comments(method->comments_token->extra); - decl->modifiers = PUBLIC; - decl->returnType = NAMES.Search(method->type.type.data); - decl->returnTypeDimension = method->type.dimension; - decl->name = method->name.data; - - arg = method->args; - while (arg != NULL) { - decl->parameters.push_back(new Variable( - NAMES.Search(arg->type.type.data), arg->name.data, - arg->type.dimension)); - arg = arg->next; - } - - decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE); - - interface->elements.push_back(decl); - - // == the stub method ==================================================== - - Case* c = new Case(transactCodeName); - - MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data); - - // interface token validation is the very first thing we do - c->statements->Add(new MethodCall(stubClass->transact_data, - "enforceInterface", 1, new LiteralExpression("DESCRIPTOR"))); - - // args - VariableFactory stubArgs("_arg"); - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = stubArgs.Get(t); - v->dimension = arg->type.dimension; - - c->statements->Add(new VariableDeclaration(v)); - - if (convert_direction(arg->direction.data) & IN_PARAMETER) { - generate_create_from_parcel(t, c->statements, v, - stubClass->transact_data); - } else { - if (arg->type.dimension == 0) { - c->statements->Add(new Assignment( - v, new NewExpression(v->type))); - } - else if (arg->type.dimension == 1) { - generate_new_array(v->type, c->statements, v, - stubClass->transact_data); - } - else { - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, - __LINE__); - } - } - - realCall->arguments.push_back(v); - - arg = arg->next; - } - - // the real call - Variable* _result = NULL; - if (0 == strcmp(method->type.type.data, "void")) { - c->statements->Add(realCall); - - if (!oneway) { - // report that there were no exceptions - MethodCall* ex = new MethodCall(stubClass->transact_reply, - "writeNoException", 0); - c->statements->Add(ex); - } - } else { - _result = new Variable(decl->returnType, "_result", - decl->returnTypeDimension); - c->statements->Add(new VariableDeclaration(_result, realCall)); - - if (!oneway) { - // report that there were no exceptions - MethodCall* ex = new MethodCall(stubClass->transact_reply, - "writeNoException", 0); - c->statements->Add(ex); - } - - // marshall the return value - generate_write_to_parcel(decl->returnType, c->statements, _result, - stubClass->transact_reply, - Type::PARCELABLE_WRITE_RETURN_VALUE); - } - - // out parameters - i = 0; - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = stubArgs.Get(i++); - - if (convert_direction(arg->direction.data) & OUT_PARAMETER) { - generate_write_to_parcel(t, c->statements, v, - stubClass->transact_reply, - Type::PARCELABLE_WRITE_RETURN_VALUE); - hasOutParams = true; - } - - arg = arg->next; - } - - // return true - c->statements->Add(new ReturnStatement(TRUE_VALUE)); - stubClass->transact_switch->cases.push_back(c); - - // == the proxy method =================================================== - Method* proxy = new Method; - proxy->comment = gather_comments(method->comments_token->extra); - proxy->modifiers = PUBLIC; - proxy->returnType = NAMES.Search(method->type.type.data); - proxy->returnTypeDimension = method->type.dimension; - proxy->name = method->name.data; - proxy->statements = new StatementBlock; - arg = method->args; - while (arg != NULL) { - proxy->parameters.push_back(new Variable( - NAMES.Search(arg->type.type.data), arg->name.data, - arg->type.dimension)); - arg = arg->next; - } - proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE); - proxyClass->elements.push_back(proxy); - - // the parcels - Variable* _data = new Variable(PARCEL_TYPE, "_data"); - proxy->statements->Add(new VariableDeclaration(_data, - new MethodCall(PARCEL_TYPE, "obtain"))); - Variable* _reply = NULL; - if (!oneway) { - _reply = new Variable(PARCEL_TYPE, "_reply"); - proxy->statements->Add(new VariableDeclaration(_reply, - new MethodCall(PARCEL_TYPE, "obtain"))); - } - - // the return value - _result = NULL; - if (0 != strcmp(method->type.type.data, "void")) { - _result = new Variable(proxy->returnType, "_result", - method->type.dimension); - proxy->statements->Add(new VariableDeclaration(_result)); - } - - // try and finally - TryStatement* tryStatement = new TryStatement(); - proxy->statements->Add(tryStatement); - FinallyStatement* finallyStatement = new FinallyStatement(); - proxy->statements->Add(finallyStatement); - - // the interface identifier token: the DESCRIPTOR constant, marshalled as a string - tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken", - 1, new LiteralExpression("DESCRIPTOR"))); - - // the parameters - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = new Variable(t, arg->name.data, arg->type.dimension); - int dir = convert_direction(arg->direction.data); - if (dir == OUT_PARAMETER && arg->type.dimension != 0) { - IfStatement* checklen = new IfStatement(); - checklen->expression = new Comparison(v, "==", NULL_VALUE); - checklen->statements->Add(new MethodCall(_data, "writeInt", 1, - new LiteralExpression("-1"))); - checklen->elseif = new IfStatement(); - checklen->elseif->statements->Add(new MethodCall(_data, "writeInt", - 1, new FieldVariable(v, "length"))); - tryStatement->statements->Add(checklen); - } - else if (dir & IN_PARAMETER) { - generate_write_to_parcel(t, tryStatement->statements, v, _data, 0); - } - arg = arg->next; - } - - // the transact call - MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4, - new LiteralExpression("Stub." + transactCodeName), - _data, _reply ? _reply : NULL_VALUE, - new LiteralExpression( - oneway ? "IBinder.FLAG_ONEWAY" : "0")); - tryStatement->statements->Add(call); - - // throw back exceptions. - if (_reply) { - MethodCall* ex = new MethodCall(_reply, "readException", 0); - tryStatement->statements->Add(ex); - } - - // returning and cleanup - if (_reply != NULL) { - if (_result != NULL) { - generate_create_from_parcel(proxy->returnType, - tryStatement->statements, _result, _reply); - } - - // the out/inout parameters - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = new Variable(t, arg->name.data, arg->type.dimension); - if (convert_direction(arg->direction.data) & OUT_PARAMETER) { - generate_read_from_parcel(t, tryStatement->statements, - v, _reply); - } - arg = arg->next; - } - - finallyStatement->statements->Add(new MethodCall(_reply, "recycle")); - } - finallyStatement->statements->Add(new MethodCall(_data, "recycle")); - - if (_result != NULL) { - proxy->statements->Add(new ReturnStatement(_result)); - } -} - -static void -generate_interface_descriptors(StubClass* stub, ProxyClass* proxy) -{ - // the interface descriptor transaction handler - Case* c = new Case("INTERFACE_TRANSACTION"); - c->statements->Add(new MethodCall(stub->transact_reply, "writeString", - 1, new LiteralExpression("DESCRIPTOR"))); - c->statements->Add(new ReturnStatement(TRUE_VALUE)); - stub->transact_switch->cases.push_back(c); - - // and the proxy-side method returning the descriptor directly - Method* getDesc = new Method; - getDesc->modifiers = PUBLIC; - getDesc->returnType = STRING_TYPE; - getDesc->returnTypeDimension = 0; - getDesc->name = "getInterfaceDescriptor"; - getDesc->statements = new StatementBlock; - getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR"))); - proxy->elements.push_back(getDesc); -} - -static Class* -generate_interface_class(const interface_type* iface) -{ - InterfaceType* interfaceType = static_cast<InterfaceType*>( - NAMES.Find(iface->package, iface->name.data)); - - // the interface class - Class* interface = new Class; - interface->comment = gather_comments(iface->comments_token->extra); - interface->modifiers = PUBLIC; - interface->what = Class::INTERFACE; - interface->type = interfaceType; - interface->interfaces.push_back(IINTERFACE_TYPE); - - // the stub inner class - StubClass* stub = new StubClass( - NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()), - interfaceType); - interface->elements.push_back(stub); - - // the proxy inner class - ProxyClass* proxy = new ProxyClass( - NAMES.Find(iface->package, - append(iface->name.data, ".Stub.Proxy").c_str()), - interfaceType); - stub->elements.push_back(proxy); - - // stub and proxy support for getInterfaceDescriptor() - generate_interface_descriptors(stub, proxy); - - // all the declared methods of the interface - int index = 0; - interface_item_type* item = iface->interface_items; - while (item != NULL) { - if (item->item_type == METHOD_TYPE) { - generate_method((method_type*)item, interface, stub, proxy, index); - } - item = item->next; - index++; - } - - return interface; -} - -int -generate_java(const string& filename, const string& originalSrc, - interface_type* iface) -{ - Document* document = new Document; - document->comment = ""; - if (iface->package) document->package = iface->package; - document->originalSrc = originalSrc; - document->classes.push_back(generate_interface_class(iface)); - -// printf("outputting... filename=%s\n", filename.c_str()); - FILE* to; - if (filename == "-") { - to = stdout; - } else { - /* open file in binary mode to ensure that the tool produces the - * same output on all platforms !! - */ - to = fopen(filename.c_str(), "wb"); - if (to == NULL) { - fprintf(stderr, "unable to open %s for write\n", filename.c_str()); - return 1; - } - } - - document->Write(to); - - fclose(to); - return 0; -} - diff --git a/tools/aidl/generate_java.h b/tools/aidl/generate_java.h deleted file mode 100644 index 203fe23..0000000 --- a/tools/aidl/generate_java.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef GENERATE_JAVA_H -#define GENERATE_JAVA_H - -#include "aidl_language.h" - -#include <string> - -using namespace std; - -int generate_java(const string& filename, const string& originalSrc, - interface_type* iface); - -#endif // GENERATE_JAVA_H - diff --git a/tools/aidl/options.cpp b/tools/aidl/options.cpp deleted file mode 100644 index 57b10ae..0000000 --- a/tools/aidl/options.cpp +++ /dev/null @@ -1,138 +0,0 @@ - -#include "options.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static int -usage() -{ - fprintf(stderr, - "usage: aidl OPTIONS INPUT [OUTPUT]\n" - " aidl --preprocess OUTPUT INPUT...\n" - "\n" - "OPTIONS:\n" - " -I<DIR> search path for import statements.\n" - " -d<FILE> generate dependency file.\n" - " -p<FILE> file created by --preprocess to import.\n" - " -b fail when trying to compile a parcelable.\n" - "\n" - "INPUT:\n" - " An aidl interface file.\n" - "\n" - "OUTPUT:\n" - " The generated interface files. If omitted, the input filename is used, with the .aidl extension changed to a .java extension.\n" - ); - return 1; -} - -int -parse_options(int argc, const char* const* argv, Options *options) -{ - int i = 1; - - if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) { - if (argc < 4) { - return usage(); - } - options->outputFileName = argv[2]; - for (int i=3; i<argc; i++) { - options->filesToPreprocess.push_back(argv[i]); - } - options->task = PREPROCESS_AIDL; - return 0; - } - - options->task = COMPILE_AIDL; - options->failOnParcelable = false; - - // OPTIONS - while (i < argc) { - const char* s = argv[i]; - int len = strlen(s); - if (s[0] == '-') { - if (len > 1) { - // -I<system-import-path> - if (s[1] == 'I') { - if (len > 2) { - options->importPaths.push_back(s+2); - } else { - fprintf(stderr, "-I option (%d) requires a path.\n", i); - return usage(); - } - } - else if (s[1] == 'd') { - if (len > 2) { - options->depFileName = s+2; - } else { - fprintf(stderr, "-d option (%d) requires a file.\n", i); - return usage(); - } - } - else if (s[1] == 'p') { - if (len > 2) { - options->preprocessedFiles.push_back(s+2); - } else { - fprintf(stderr, "-p option (%d) requires a file.\n", i); - return usage(); - } - } - else if (len == 2 && s[1] == 'b') { - options->failOnParcelable = true; - } - else { - // s[1] is not known - fprintf(stderr, "unknown option (%d): %s\n", i, s); - return usage(); - } - } else { - // len <= 1 - fprintf(stderr, "unknown option (%d): %s\n", i, s); - return usage(); - } - } else { - // s[0] != '-' - break; - } - i++; - } - - // INPUT - if (i < argc) { - options->inputFileName = argv[i]; - i++; - } else { - fprintf(stderr, "INPUT required\n"); - return usage(); - } - - // OUTPUT - if (i < argc) { - options->outputFileName = argv[i]; - i++; - } else { - // copy input into output and change the extension from .aidl to .java - options->outputFileName = options->inputFileName; - string::size_type pos = options->outputFileName.size()-5; - if (options->outputFileName.compare(pos, 5, ".aidl") == 0) { // 5 = strlen(".aidl") - options->outputFileName.replace(pos, 5, ".java"); // 5 = strlen(".aidl") - } else { - fprintf(stderr, "INPUT is not an .aidl file.\n"); - return usage(); - } - } - - // anything remaining? - if (i != argc) { - fprintf(stderr, "unknown option%s:", (i==argc-1?(const char*)"":(const char*)"s")); - for (; i<argc-1; i++) { - fprintf(stderr, " %s", argv[i]); - } - fprintf(stderr, "\n"); - return usage(); - } - - return 0; -} - diff --git a/tools/aidl/options.h b/tools/aidl/options.h deleted file mode 100644 index dc3c45a..0000000 --- a/tools/aidl/options.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef DEVICE_TOOLS_AIDL_H -#define DEVICE_TOOLS_AIDL_H - -#include <string> -#include <vector> - -using namespace std; - -enum { - COMPILE_AIDL, - PREPROCESS_AIDL -}; - -// This struct is the parsed version of the command line options -struct Options -{ - int task; - bool failOnParcelable; - vector<string> importPaths; - vector<string> preprocessedFiles; - string inputFileName; - string outputFileName; - string depFileName; - - vector<string> filesToPreprocess; -}; - -// takes the inputs from the command line and fills in the Options struct -// Returns 0 on success, and nonzero on failure. -// It also prints the usage statement on failure. -int parse_options(int argc, const char* const* argv, Options *options); - -#endif // DEVICE_TOOLS_AIDL_H diff --git a/tools/aidl/options_test.cpp b/tools/aidl/options_test.cpp deleted file mode 100644 index bd106ce..0000000 --- a/tools/aidl/options_test.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#include <iostream> -#include "options.h" - -const bool VERBOSE = false; - -using namespace std; - -struct Answer { - const char* argv[8]; - int result; - const char* systemSearchPath[8]; - const char* localSearchPath[8]; - const char* inputFileName; - language_t nativeLanguage; - const char* outputH; - const char* outputCPP; - const char* outputJava; -}; - -bool -match_arrays(const char* const*expected, const vector<string> &got) -{ - int count = 0; - while (expected[count] != NULL) { - count++; - } - if (got.size() != count) { - return false; - } - for (int i=0; i<count; i++) { - if (got[i] != expected[i]) { - return false; - } - } - return true; -} - -void -print_array(const char* prefix, const char* const*expected) -{ - while (*expected) { - cout << prefix << *expected << endl; - expected++; - } -} - -void -print_array(const char* prefix, const vector<string> &got) -{ - size_t count = got.size(); - for (size_t i=0; i<count; i++) { - cout << prefix << got[i] << endl; - } -} - -static int -test(const Answer& answer) -{ - int argc = 0; - while (answer.argv[argc]) { - argc++; - } - - int err = 0; - - Options options; - int result = parse_options(argc, answer.argv, &options); - - // result - if (((bool)result) != ((bool)answer.result)) { - cout << "mismatch: result: got " << result << " expected " << - answer.result << endl; - err = 1; - } - - if (result != 0) { - // if it failed, everything is invalid - return err; - } - - // systemSearchPath - if (!match_arrays(answer.systemSearchPath, options.systemSearchPath)) { - cout << "mismatch: systemSearchPath: got" << endl; - print_array(" ", options.systemSearchPath); - cout << " expected" << endl; - print_array(" ", answer.systemSearchPath); - err = 1; - } - - // localSearchPath - if (!match_arrays(answer.localSearchPath, options.localSearchPath)) { - cout << "mismatch: localSearchPath: got" << endl; - print_array(" ", options.localSearchPath); - cout << " expected" << endl; - print_array(" ", answer.localSearchPath); - err = 1; - } - - // inputFileName - if (answer.inputFileName != options.inputFileName) { - cout << "mismatch: inputFileName: got " << options.inputFileName - << " expected " << answer.inputFileName << endl; - err = 1; - } - - // nativeLanguage - if (answer.nativeLanguage != options.nativeLanguage) { - cout << "mismatch: nativeLanguage: got " << options.nativeLanguage - << " expected " << answer.nativeLanguage << endl; - err = 1; - } - - // outputH - if (answer.outputH != options.outputH) { - cout << "mismatch: outputH: got " << options.outputH - << " expected " << answer.outputH << endl; - err = 1; - } - - // outputCPP - if (answer.outputCPP != options.outputCPP) { - cout << "mismatch: outputCPP: got " << options.outputCPP - << " expected " << answer.outputCPP << endl; - err = 1; - } - - // outputJava - if (answer.outputJava != options.outputJava) { - cout << "mismatch: outputJava: got " << options.outputJava - << " expected " << answer.outputJava << endl; - err = 1; - } - - return err; -} - -const Answer g_tests[] = { - - { - /* argv */ { "test", "-i/moof", "-I/blah", "-Ibleh", "-imoo", "inputFileName.aidl_cpp", NULL, NULL }, - /* result */ 0, - /* systemSearchPath */ { "/blah", "bleh", NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { "/moof", "moo", NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "inputFileName.aidl_cpp", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "", - /* outputJava */ "" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", NULL, NULL, NULL, NULL }, - /* result */ 0, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "inputFileName.aidl_cpp", - /* nativeLanguage */ CPP, - /* outputH */ "outputH", - /* outputCPP */ "", - /* outputJava */ "" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", NULL, NULL, NULL, NULL }, - /* result */ 0, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "inputFileName.aidl_cpp", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "outputCPP", - /* outputJava */ "" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", NULL, NULL, NULL, NULL }, - /* result */ 0, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "inputFileName.aidl_cpp", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "", - /* outputJava */ "outputJava" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-ocpp", "outputCPP", "-ojava", "outputJava" }, - /* result */ 0, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "inputFileName.aidl_cpp", - /* nativeLanguage */ CPP, - /* outputH */ "outputH", - /* outputCPP */ "outputCPP", - /* outputJava */ "outputJava" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-oh", "outputH1", NULL, NULL }, - /* result */ 1, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "", - /* outputJava */ "" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", "-ocpp", "outputCPP1", NULL, NULL }, - /* result */ 1, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "", - /* outputJava */ "" - }, - - { - /* argv */ { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", "-ojava", "outputJava1", NULL, NULL }, - /* result */ 1, - /* systemSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* localSearchPath */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - /* inputFileName */ "", - /* nativeLanguage */ CPP, - /* outputH */ "", - /* outputCPP */ "", - /* outputJava */ "" - }, - -}; - -int -main(int argc, const char** argv) -{ - const int count = sizeof(g_tests)/sizeof(g_tests[0]); - int matches[count]; - - int result = 0; - for (int i=0; i<count; i++) { - if (VERBOSE) { - cout << endl; - cout << "---------------------------------------------" << endl; - const char* const* p = g_tests[i].argv; - while (*p) { - cout << " " << *p; - p++; - } - cout << endl; - cout << "---------------------------------------------" << endl; - } - matches[i] = test(g_tests[i]); - if (VERBOSE) { - if (0 == matches[i]) { - cout << "passed" << endl; - } else { - cout << "failed" << endl; - } - result |= matches[i]; - } - } - - cout << endl; - cout << "=============================================" << endl; - cout << "options_test summary" << endl; - cout << "=============================================" << endl; - - if (!result) { - cout << "passed" << endl; - } else { - cout << "failed the following tests:" << endl; - for (int i=0; i<count; i++) { - if (matches[i]) { - cout << " "; - const char* const* p = g_tests[i].argv; - while (*p) { - cout << " " << *p; - p++; - } - cout << endl; - } - } - } - - return result; -} - diff --git a/tools/aidl/search_path.cpp b/tools/aidl/search_path.cpp deleted file mode 100644 index ffb6cb2..0000000 --- a/tools/aidl/search_path.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include <unistd.h> -#include "search_path.h" -#include "options.h" -#include <string.h> - -#ifdef HAVE_MS_C_RUNTIME -#include <io.h> -#endif - -static vector<string> g_importPaths; - -void -set_import_paths(const vector<string>& importPaths) -{ - g_importPaths = importPaths; -} - -char* -find_import_file(const char* given) -{ - string expected = given; - - int N = expected.length(); - for (int i=0; i<N; i++) { - char c = expected[i]; - if (c == '.') { - expected[i] = OS_PATH_SEPARATOR; - } - } - expected += ".aidl"; - - vector<string>& paths = g_importPaths; - for (vector<string>::iterator it=paths.begin(); it!=paths.end(); it++) { - string f = *it; - if (f.size() == 0) { - f = "."; - f += OS_PATH_SEPARATOR; - } - else if (f[f.size()-1] != OS_PATH_SEPARATOR) { - f += OS_PATH_SEPARATOR; - } - f.append(expected); - -#ifdef HAVE_MS_C_RUNTIME - /* check that the file exists and is not write-only */ - if (0 == _access(f.c_str(), 0) && /* mode 0=exist */ - 0 == _access(f.c_str(), 4) ) { /* mode 4=readable */ -#else - if (0 == access(f.c_str(), R_OK)) { -#endif - return strdup(f.c_str()); - } - } - - return NULL; -} - diff --git a/tools/aidl/search_path.h b/tools/aidl/search_path.h deleted file mode 100644 index 2bf94b1..0000000 --- a/tools/aidl/search_path.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef DEVICE_TOOLS_AIDL_SEARCH_PATH_H -#define DEVICE_TOOLS_AIDL_SEARCH_PATH_H - -#include <stdio.h> - -#if __cplusplus -#include <vector> -#include <string> -using namespace std; -extern "C" { -#endif - -// returns a FILE* and the char* for the file that it found -// given is the class name we're looking for -char* find_import_file(const char* given); - -#if __cplusplus -}; // extern "C" -void set_import_paths(const vector<string>& importPaths); -#endif - -#endif // DEVICE_TOOLS_AIDL_SEARCH_PATH_H - diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk deleted file mode 100644 index 6d606a9..0000000 --- a/tools/layoutlib/Android.mk +++ /dev/null @@ -1,67 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(my-dir) -include $(CLEAR_VARS) - -# -# Define rules to build temp_layoutlib.jar, which contains a subset of -# the classes in framework.jar. The layoutlib_create tool is used to -# transform the framework jar into the temp_layoutlib jar. -# - -# We need to process the framework classes.jar file, but we can't -# depend directly on it (private vars won't be inherited correctly). -# So, we depend on framework's BUILT file. -built_framework_dep := \ - $(call intermediates-dir-for,JAVA_LIBRARIES,framework)/javalib.jar -built_framework_classes := \ - $(call intermediates-dir-for,JAVA_LIBRARIES,framework)/classes.jar - -built_core_dep := \ - $(call intermediates-dir-for,JAVA_LIBRARIES,core)/javalib.jar -built_core_classes := \ - $(call intermediates-dir-for,JAVA_LIBRARIES,core)/classes.jar - -built_layoutlib_create_jar := $(call intermediates-dir-for, \ - JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar - -# This is mostly a copy of config/host_java_library.mk -LOCAL_MODULE := temp_layoutlib -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) -LOCAL_IS_HOST_MODULE := true -LOCAL_BUILT_MODULE_STEM := javalib.jar - -####################################### -include $(BUILD_SYSTEM)/base_rules.mk -####################################### - -$(LOCAL_BUILT_MODULE): $(built_core_dep) \ - $(built_framework_dep) \ - $(built_layoutlib_create_jar) - @echo "host layoutlib_create: $@" - @mkdir -p $(dir $@) - @rm -f $@ - $(hide) java -jar $(built_layoutlib_create_jar) \ - $@ \ - $(built_core_classes) \ - $(built_framework_classes) - - -# -# Include the subdir makefiles. -# -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/layoutlib/api/.classpath b/tools/layoutlib/api/.classpath deleted file mode 100644 index a09ce5f..0000000 --- a/tools/layoutlib/api/.classpath +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" path="src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/tools/layoutlib/api/.project b/tools/layoutlib/api/.project deleted file mode 100644 index 4e4ca3b..0000000 --- a/tools/layoutlib/api/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>layoutlib_api</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/tools/layoutlib/api/Android.mk b/tools/layoutlib/api/Android.mk deleted file mode 100644 index d60987c..0000000 --- a/tools/layoutlib/api/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under,src) - -LOCAL_JAVA_LIBRARIES := \ - kxml2-2.3.0 - -LOCAL_MODULE := layoutlib_api - -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java deleted file mode 100644 index 0810d29..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -import java.util.Map; - -/** - * Entry point of the Layout Lib. Implementations of this interface provide a method to compute - * and render a layout. - * <p/> - * <p/>{@link #getApiLevel()} gives the ability to know which methods are available. - * <p/> - * Changes in API level 2: - * <ul> - * <li>{@link #getApiLevel()}</li> - * <li>{@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}, - * deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, String, Map, Map, IProjectCallback, ILayoutLog)}.</li> - * </ul> - */ -public interface ILayoutBridge { - - final int API_CURRENT = 2; - - /** - * Returns the API level of the layout library. - * While no methods will ever be removed, some may become deprecated, and some new ones - * will appear. - */ - int getApiLevel(); - - /** - * Initializes the Bridge object. - * @param fontOsLocation the location of the fonts. - * @param enumValueMap map attrName => { map enumFlagName => Integer value }. - * @return true if success. - * @since 1 - */ - boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap); - - /** - * Computes and renders a layout - * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the - * layout file. - * @param projectKey An Object identifying the project. This is used for the cache mechanism. - * @param screenWidth - * @param screenHeight - * @param themeName The name of the theme to use. - * @param isProjectTheme true if the theme is a project theme, false if it is a framework theme. - * @param projectResources the resources of the project. The map contains (String, map) pairs - * where the string is the type of the resource reference used in the layout file, and the - * map contains (String, {@link IResourceValue}) pairs where the key is the resource name, - * and the value is the resource value. - * @param frameworkResources the framework resources. The map contains (String, map) pairs - * where the string is the type of the resource reference used in the layout file, and the map - * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the - * value is the resource value. - * @param projectCallback The {@link IProjectCallback} object to get information from - * the project. - * @param logger the object responsible for displaying warning/errors to the user. - * @return an {@link ILayoutResult} object that contains the result of the layout. - * @since 2 - */ - ILayoutResult computeLayout(IXmlPullParser layoutDescription, - Object projectKey, - int screenWidth, int screenHeight, String themeName, boolean isProjectTheme, - Map<String, Map<String, IResourceValue>> projectResources, - Map<String, Map<String, IResourceValue>> frameworkResources, - IProjectCallback projectCallback, ILayoutLog logger); - - /** - * Computes and renders a layout - * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the - * layout file. - * @param projectKey An Object identifying the project. This is used for the cache mechanism. - * @param screenWidth - * @param screenHeight - * @param themeName The name of the theme to use. In order to differentiate project and platform - * themes sharing the same name, all project themes must be prepended with a '*' character. - * @param projectResources the resources of the project. The map contains (String, map) pairs - * where the string is the type of the resource reference used in the layout file, and the - * map contains (String, {@link IResourceValue}) pairs where the key is the resource name, - * and the value is the resource value. - * @param frameworkResources the framework resources. The map contains (String, map) pairs - * where the string is the type of the resource reference used in the layout file, and the map - * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the - * value is the resource value. - * @param projectCallback The {@link IProjectCallback} object to get information from - * the project. - * @param logger the object responsible for displaying warning/errors to the user. - * @return an {@link ILayoutResult} object that contains the result of the layout. - * @deprecated Use {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}. - * @since 1 - */ - @Deprecated - ILayoutResult computeLayout(IXmlPullParser layoutDescription, - Object projectKey, - int screenWidth, int screenHeight, String themeName, - Map<String, Map<String, IResourceValue>> projectResources, - Map<String, Map<String, IResourceValue>> frameworkResources, - IProjectCallback projectCallback, ILayoutLog logger); - - /** - * Clears the resource cache for a specific project. - * <p/>This cache contains bitmaps and nine patches that are loaded from the disk and reused - * until this method is called. - * <p/>The cache is not configuration dependent and should only be cleared when a - * resource changes (at this time only bitmaps and 9 patches go into the cache). - * @param objectKey the key for the project. - * @since 1 - */ - void clearCaches(Object projectKey); -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutLog.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutLog.java deleted file mode 100644 index cae15d3..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutLog.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -/** - * Callback interface to display warnings/errors that happened during the computation and - * rendering of the layout. - */ -public interface ILayoutLog { - - /** - * Displays a warning message. - * @param message the message to display. - */ - void warning(String message); - - /** - * Displays an error message. - * @param message the message to display. - */ - void error(String message); - - /** - * Displays an exception - * @param t the {@link Throwable} to display. - */ - void error(Throwable t); -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java deleted file mode 100644 index 5a06349..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutResult.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -import java.awt.image.BufferedImage; - -/** - * The result of a layout computation through - * {@link ILayoutLibBridge#computeLayout(IXmlPullParser, int, int, String, java.util.Map, java.util.Map, java.util.Map, IFontLoader, ILayoutLibLog, ICustomViewLoader)} - */ -public interface ILayoutResult { - /** Sucess return code */ - final static int SUCCESS = 0; - /** Error return code. - * <p/>See {@link #getErrorMessage()} - */ - final static int ERROR = 1; - - /** - * Returns the result code. - * @see #SUCCESS - * @see #ERROR - */ - int getSuccess(); - - /** - * Returns the {@link ILayoutViewInfo} object for the top level view. - */ - ILayoutViewInfo getRootView(); - - /** - * Returns the rendering of the full layout. - */ - BufferedImage getImage(); - - /** - * Returns the error message. - * <p/>Only valid when {@link #getSuccess()} returns {@link #ERROR} - */ - String getErrorMessage(); - - /** - * Layout information for a specific view. - */ - public interface ILayoutViewInfo { - - /** - * Returns the list of children views. - */ - ILayoutViewInfo[] getChildren(); - - /** - * Returns the key associated with the node. - * @see IXmlPullParser#getViewKey() - */ - Object getViewKey(); - - /** - * Returns the name of the view. - */ - String getName(); - - /** - * Returns the left of the view bounds. - */ - int getLeft(); - - /** - * Returns the top of the view bounds. - */ - int getTop(); - - /** - * Returns the right of the view bounds. - */ - int getRight(); - - /** - * Returns the bottom of the view bounds. - */ - int getBottom(); - } -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/IProjectCallback.java b/tools/layoutlib/api/src/com/android/layoutlib/api/IProjectCallback.java deleted file mode 100644 index 5ad5082..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/IProjectCallback.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -/** - * Callback for project information needed by the Layout Library. - * Classes implementing this interface provide methods giving access to some project data, like - * resource resolution, namespace information, and instantiation of custom view. - */ -public interface IProjectCallback { - - /** - * Loads a custom view with the given constructor signature and arguments. - * @param name The fully qualified name of the class. - * @param constructorSignature The signature of the class to use - * @param constructorArgs The arguments to use on the constructor - * @return A newly instantiated android.view.View object. - * @throws ClassNotFoundException. - * @throws Exception - */ - @SuppressWarnings("unchecked") - Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs) - throws ClassNotFoundException, Exception; - - /** - * Returns the namespace of the application. - * <p/>This lets the Layout Lib load custom attributes for custom views. - */ - String getNamespace(); - - /** - * Resolves the id of a resource Id. - * <p/>The resource id is the value of a <code>R.<type>.<name></code>, and - * this method will return both the type and name of the resource. - * @param id the Id to resolve. - * @return an array of 2 strings containing the resource name and type, or null if the id - * does not match any resource. - */ - String[] resolveResourceValue(int id); - - /** - * Resolves the id of a resource Id of type int[] - * <p/>The resource id is the value of a R.styleable.<name>, and this method will - * return the name of the resource. - * @param id the Id to resolve. - * @return the name of the resource or <code>null</code> if not found. - */ - String resolveResourceValue(int[] id); - - /** - * Returns the id of a resource. - * <p/>The provided type and name must match an existing constant defined as - * <code>R.<type>.<name></code>. - * @param type the type of the resource - * @param name the name of the resource - * @return an Integer containing the resource Id, or <code>null</code> if not found. - */ - Integer getResourceValue(String type, String name); - -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/IResourceValue.java b/tools/layoutlib/api/src/com/android/layoutlib/api/IResourceValue.java deleted file mode 100644 index 1da9508..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/IResourceValue.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -/** - * Represents an android resource with a name and a string value. - */ -public interface IResourceValue { - - /** - * Returns the type of the resource. For instance "drawable", "color", etc... - */ - String getType(); - - /** - * Returns the name of the resource, as defined in the XML. - */ - String getName(); - - /** - * Returns the value of the resource, as defined in the XML. This can be <code>null</code> - */ - String getValue(); - - /** - * Returns whether the resource is a framework resource (<code>true</code>) or a project - * resource (<code>false</false>). - */ - boolean isFramework(); -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/IStyleResourceValue.java b/tools/layoutlib/api/src/com/android/layoutlib/api/IStyleResourceValue.java deleted file mode 100644 index 2f17e69..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/IStyleResourceValue.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - - -/** - * Represents an android style resources with a name and a list of children {@link IResourceValue}. - */ -public interface IStyleResourceValue extends IResourceValue { - - /** - * Returns the parent style name or <code>null</code> if unknown. - */ - String getParentStyle(); - - /** - * Find an item in the list by name - * @param name - */ - IResourceValue findItem(String name); -} diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/IXmlPullParser.java b/tools/layoutlib/api/src/com/android/layoutlib/api/IXmlPullParser.java deleted file mode 100644 index cd43c56..0000000 --- a/tools/layoutlib/api/src/com/android/layoutlib/api/IXmlPullParser.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.api; - -import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo; - -import org.xmlpull.v1.XmlPullParser; - -/** - * Extended version of {@link XmlPullParser} to use with - * {@link ILayoutLibBridge#computeLayout(XmlPullParser, int, int, String, java.util.Map, java.util.Map, java.util.Map, com.android.layoutlib.api.ILayoutLibBridge.IFontInfo)} - */ -public interface IXmlPullParser extends XmlPullParser { - - /** - * Returns a key for the current XML node. - * <p/>This key will be passed back in the {@link ILayoutViewInfo} objects, allowing association - * of a particular XML node with its result from the layout computation. - */ - Object getViewKey(); -} - diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath deleted file mode 100644 index 175a98b..0000000 --- a/tools/layoutlib/bridge/.classpath +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry excluding="org/kxml2/io/" kind="src" path="src"/> - <classpathentry kind="src" path="tests"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> - <classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/> - <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/layoutlib.jar" sourcepath="/ANDROID_SRC/frameworks/base/core/java"/> - <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_SRC/development/tools/ninepatch/src"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/tools/layoutlib/bridge/.project b/tools/layoutlib/bridge/.project deleted file mode 100644 index e36e71b..0000000 --- a/tools/layoutlib/bridge/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>layoutlib_bridge</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk deleted file mode 100644 index b2010d5..0000000 --- a/tools/layoutlib/bridge/Android.mk +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under,src) - -LOCAL_JAVA_LIBRARIES := \ - kxml2-2.3.0 \ - layoutlib_api \ - ninepatch - -LOCAL_STATIC_JAVA_LIBRARIES := temp_layoutlib - -LOCAL_MODULE := layoutlib - -include $(BUILD_HOST_JAVA_LIBRARY) - diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap.java deleted file mode 100644 index 6bc01b1..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import com.android.layoutlib.bridge.BridgeCanvas; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; - -public final class Bitmap extends _Original_Bitmap { - - private BufferedImage mImage; - - public Bitmap(File input) throws IOException { - super(1, true, null); - - mImage = ImageIO.read(input); - } - - Bitmap(BufferedImage image) { - super(1, true, null); - mImage = image; - } - - public BufferedImage getImage() { - return mImage; - } - - // ----- overriden methods - - public enum Config { - // these native values must match up with the enum in SkBitmap.h - ALPHA_8 (2), - RGB_565 (4), - ARGB_4444 (5), - ARGB_8888 (6); - - Config(int ni) { - this.nativeInt = ni; - } - final int nativeInt; - - /* package */ static Config nativeToConfig(int ni) { - return sConfigs[ni]; - } - - private static Config sConfigs[] = { - null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888 - }; - } - - - @Override - public int getWidth() { - return mImage.getWidth(); - } - - @Override - public int getHeight() { - return mImage.getHeight(); - } - - /** - * Returns an immutable bitmap from the source bitmap. The new bitmap may - * be the same object as source, or a copy may have been made. - */ - public static Bitmap createBitmap(Bitmap src) { - return createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), null, false); - } - - /** - * Returns an immutable bitmap from the specified subset of the source - * bitmap. The new bitmap may be the same object as source, or a copy may - * have been made. - * - * @param source The bitmap we are subsetting - * @param x The x coordinate of the first pixel in source - * @param y The y coordinate of the first pixel in source - * @param width The number of pixels in each row - * @param height The number of rows - */ - public static Bitmap createBitmap(Bitmap source, int x, int y, - int width, int height) { - return new Bitmap(source.mImage.getSubimage(x, y, width, height)); - } - - /** - * Returns an immutable bitmap from subset of the source bitmap, - * transformed by the optional matrix. - * - * @param source The bitmap we are subsetting - * @param x The x coordinate of the first pixel in source - * @param y The y coordinate of the first pixel in source - * @param width The number of pixels in each row - * @param height The number of rows - * @param m Option matrix to be applied to the pixels - * @param filter true if the source should be filtered. - * Only applies if the matrix contains more than just - * translation. - * @return A bitmap that represents the specified subset of source - * @throws IllegalArgumentException if the x, y, width, height values are - * outside of the dimensions of the source bitmap. - */ - public static Bitmap createBitmap(Bitmap source, int x, int y, int width, - int height, Matrix m, boolean filter) { - checkXYSign(x, y); - checkWidthHeight(width, height); - if (x + width > source.getWidth()) { - throw new IllegalArgumentException( - "x + width must be <= bitmap.width()"); - } - if (y + height > source.getHeight()) { - throw new IllegalArgumentException( - "y + height must be <= bitmap.height()"); - } - - // check if we can just return our argument unchanged - if (!source.isMutable() && x == 0 && y == 0 - && width == source.getWidth() && height == source.getHeight() - && (m == null || m.isIdentity())) { - return source; - } - - if (m == null || m.isIdentity()) { - return new Bitmap(source.mImage.getSubimage(x, y, width, height)); - } - - int neww = width; - int newh = height; - Paint paint; - - Rect srcR = new Rect(x, y, x + width, y + height); - RectF dstR = new RectF(0, 0, width, height); - - /* the dst should have alpha if the src does, or if our matrix - doesn't preserve rectness - */ - boolean hasAlpha = source.hasAlpha() || !m.rectStaysRect(); - RectF deviceR = new RectF(); - m.mapRect(deviceR, dstR); - neww = Math.round(deviceR.width()); - newh = Math.round(deviceR.height()); - - BridgeCanvas canvas = new BridgeCanvas(neww, newh); - - canvas.translate(-deviceR.left, -deviceR.top); - canvas.concat(m); - paint = new Paint(); - paint.setFilterBitmap(filter); - if (!m.rectStaysRect()) { - paint.setAntiAlias(true); - } - - canvas.drawBitmap(source, srcR, dstR, paint); - - return new Bitmap(canvas.getImage()); - } - - /** - * Returns a mutable bitmap with the specified width and height. - * - * @param width The width of the bitmap - * @param height The height of the bitmap - * @param config The bitmap config to create. - * @throws IllegalArgumentException if the width or height are <= 0 - */ - public static Bitmap createBitmap(int width, int height, Config config) { - return new Bitmap(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)); - } - - /** - * Returns a immutable bitmap with the specified width and height, with each - * pixel value set to the corresponding value in the colors array. - * - * @param colors Array of {@link Color} used to initialize the pixels. - * @param offset Number of values to skip before the first color in the - * array of colors. - * @param stride Number of colors in the array between rows (must be >= - * width or <= -width). - * @param width The width of the bitmap - * @param height The height of the bitmap - * @param config The bitmap config to create. If the config does not - * support per-pixel alpha (e.g. RGB_565), then the alpha - * bytes in the colors[] will be ignored (assumed to be FF) - * @throws IllegalArgumentException if the width or height are <= 0, or if - * the color array's length is less than the number of pixels. - */ - public static Bitmap createBitmap(int colors[], int offset, int stride, - int width, int height, Config config) { - checkWidthHeight(width, height); - if (Math.abs(stride) < width) { - throw new IllegalArgumentException("abs(stride) must be >= width"); - } - int lastScanline = offset + (height - 1) * stride; - int length = colors.length; - if (offset < 0 || (offset + width > length) - || lastScanline < 0 - || (lastScanline + width > length)) { - throw new ArrayIndexOutOfBoundsException(); - } - - // TODO: create an immutable bitmap... - throw new UnsupportedOperationException(); - } - - /** - * Returns a immutable bitmap with the specified width and height, with each - * pixel value set to the corresponding value in the colors array. - * - * @param colors Array of {@link Color} used to initialize the pixels. - * This array must be at least as large as width * height. - * @param width The width of the bitmap - * @param height The height of the bitmap - * @param config The bitmap config to create. If the config does not - * support per-pixel alpha (e.g. RGB_565), then the alpha - * bytes in the colors[] will be ignored (assumed to be FF) - * @throws IllegalArgumentException if the width or height are <= 0, or if - * the color array's length is less than the number of pixels. - */ - public static Bitmap createBitmap(int colors[], int width, int height, - Config config) { - return createBitmap(colors, 0, width, width, height, config); - } - -} diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java deleted file mode 100644 index 8bf7fcc..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -public class BitmapShader extends Shader { - - // we hold on just for the GC, since our native counterpart is using it - private final Bitmap mBitmap; - - /** - * Call this to create a new shader that will draw with a bitmap. - * - * @param bitmap The bitmap to use inside the shader - * @param tileX The tiling mode for x to draw the bitmap in. - * @param tileY The tiling mode for y to draw the bitmap in. - */ - public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) { - mBitmap = bitmap; - } - - //---------- Custom methods - - public Bitmap getBitmap() { - return mBitmap; - } -} - diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java deleted file mode 100644 index 968a597..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -/** A subclass of shader that returns the composition of two other shaders, combined by - an {@link android.graphics.Xfermode} subclass. -*/ -public class ComposeShader extends Shader { - /** Create a new compose shader, given shaders A, B, and a combining mode. - When the mode is applied, it will be given the result from shader A as its - "dst", and the result of from shader B as its "src". - @param shaderA The colors from this shader are seen as the "dst" by the mode - @param shaderB The colors from this shader are seen as the "src" by the mode - @param mode The mode that combines the colors from the two shaders. If mode - is null, then SRC_OVER is assumed. - */ - public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) { - // FIXME Implement shader - } - - /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode. - When the mode is applied, it will be given the result from shader A as its - "dst", and the result of from shader B as its "src". - @param shaderA The colors from this shader are seen as the "dst" by the mode - @param shaderB The colors from this shader are seen as the "src" by the mode - @param mode The PorterDuff mode that combines the colors from the two shaders. - */ - public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) { - // FIXME Implement shader - } -} - diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java deleted file mode 100644 index 1a0dc05..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import java.awt.GradientPaint; -import java.awt.Color; -import java.awt.Paint; - -public class LinearGradient extends Shader { - - private GradientPaint mGradientPaint; - - /** Create a shader that draws a linear gradient along a line. - @param x0 The x-coordinate for the start of the gradient line - @param y0 The y-coordinate for the start of the gradient line - @param x1 The x-coordinate for the end of the gradient line - @param y1 The y-coordinate for the end of the gradient line - @param colors The colors to be distributed along the gradient line - @param positions May be null. The relative positions [0..1] of - each corresponding color in the colors array. If this is null, - the the colors are distributed evenly along the gradient line. - @param tile The Shader tiling mode - */ - public LinearGradient(float x0, float y0, float x1, float y1, - int colors[], float positions[], TileMode tile) { - if (colors.length < 2) { - throw new IllegalArgumentException("needs >= 2 number of colors"); - } - if (positions != null && colors.length != positions.length) { - throw new IllegalArgumentException("color and position arrays must be of equal length"); - } - - // FIXME implement multi color linear gradient - } - - /** Create a shader that draws a linear gradient along a line. - @param x0 The x-coordinate for the start of the gradient line - @param y0 The y-coordinate for the start of the gradient line - @param x1 The x-coordinate for the end of the gradient line - @param y1 The y-coordinate for the end of the gradient line - @param color0 The color at the start of the gradient line. - @param color1 The color at the end of the gradient line. - @param tile The Shader tiling mode - */ - public LinearGradient(float x0, float y0, float x1, float y1, - int color0, int color1, TileMode tile) { - mGradientPaint = new GradientPaint(x0, y0, new Color(color0, true /* hasalpha */), - x1,y1, new Color(color1, true /* hasalpha */), tile != TileMode.CLAMP); - } - - //---------- Custom Methods - - public Paint getPaint() { - return mGradientPaint; - } -} - diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix.java b/tools/layoutlib/bridge/src/android/graphics/Matrix.java deleted file mode 100644 index 3f9a993..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Matrix.java +++ /dev/null @@ -1,984 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import java.awt.geom.AffineTransform; - - -/** - * A matrix implementation overridden by the LayoutLib bridge. - */ -public class Matrix extends _Original_Matrix { - - float mValues[] = new float[9]; - - /** - * Create an identity matrix - */ - public Matrix() { - reset(); - } - - /** - * Create a matrix that is a (deep) copy of src - * @param src The matrix to copy into this matrix - */ - public Matrix(Matrix src) { - set(src); - } - - /** - * Creates a Matrix object from the float array. The array becomes the internal storage - * of the object. - * @param data - */ - private Matrix(float[] data) { - assert data.length != 9; - mValues = data; - } - - @Override - public void finalize() throws Throwable { - // pass - } - - //---------- Custom Methods - - /** - * Adds the given transformation to the current Matrix - * <p/>This in effect does this = this*matrix - * @param matrix - */ - private void addTransform(float[] matrix) { - float[] tmp = new float[9]; - - // first row - tmp[0] = matrix[0] * mValues[0] + matrix[1] * mValues[3] + matrix[2] * mValues[6]; - tmp[1] = matrix[0] * mValues[1] + matrix[1] * mValues[4] + matrix[2] * mValues[7]; - tmp[2] = matrix[0] * mValues[2] + matrix[1] * mValues[5] + matrix[2] * mValues[8]; - - // 2nd row - tmp[3] = matrix[3] * mValues[0] + matrix[4] * mValues[3] + matrix[5] * mValues[6]; - tmp[4] = matrix[3] * mValues[1] + matrix[4] * mValues[4] + matrix[5] * mValues[7]; - tmp[5] = matrix[3] * mValues[2] + matrix[4] * mValues[5] + matrix[5] * mValues[8]; - - // 3rd row - tmp[6] = matrix[6] * mValues[0] + matrix[7] * mValues[3] + matrix[8] * mValues[6]; - tmp[7] = matrix[6] * mValues[1] + matrix[7] * mValues[4] + matrix[8] * mValues[7]; - tmp[8] = matrix[6] * mValues[2] + matrix[7] * mValues[5] + matrix[8] * mValues[8]; - - // copy the result over to mValues - mValues = tmp; - } - - public AffineTransform getTransform() { - return new AffineTransform(mValues[0], mValues[1], mValues[2], - mValues[3], mValues[4], mValues[5]); - } - - public boolean hasPerspective() { - return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1); - } - - //---------- - - /** - * Returns true if the matrix is identity. - * This maybe faster than testing if (getType() == 0) - */ - @Override - public boolean isIdentity() { - for (int i = 0, k = 0; i < 3; i++) { - for (int j = 0; j < 3; j++, k++) { - if (mValues[k] != ((i==j) ? 1 : 0)) { - return false; - } - } - } - - return true; - } - - /** - * Returns true if will map a rectangle to another rectangle. This can be - * true if the matrix is identity, scale-only, or rotates a multiple of 90 - * degrees. - */ - @Override - public boolean rectStaysRect() { - return (computeTypeMask() & kRectStaysRect_Mask) != 0; - } - - /** - * (deep) copy the src matrix into this matrix. If src is null, reset this - * matrix to the identity matrix. - */ - public void set(Matrix src) { - if (src == null) { - reset(); - } else { - System.arraycopy(src.mValues, 0, mValues, 0, mValues.length); - } - } - - @Override - public void set(_Original_Matrix src) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** Returns true if obj is a Matrix and its values equal our values. - */ - @Override - public boolean equals(Object obj) { - if (obj != null && obj instanceof Matrix) { - Matrix matrix = (Matrix)obj; - for (int i = 0 ; i < 9 ; i++) { - if (mValues[i] != matrix.mValues[i]) { - return false; - } - } - - return true; - } - - return false; - } - - /** Set the matrix to identity */ - @Override - public void reset() { - for (int i = 0, k = 0; i < 3; i++) { - for (int j = 0; j < 3; j++, k++) { - mValues[k] = ((i==j) ? 1 : 0); - } - } - } - - /** Set the matrix to translate by (dx, dy). */ - @Override - public void setTranslate(float dx, float dy) { - mValues[0] = 1; - mValues[1] = 0; - mValues[2] = dx; - mValues[3] = 0; - mValues[4] = 1; - mValues[5] = dy; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - } - - /** - * Set the matrix to scale by sx and sy, with a pivot point at (px, py). - * The pivot point is the coordinate that should remain unchanged by the - * specified transformation. - */ - @Override - public void setScale(float sx, float sy, float px, float py) { - // TODO: do it in one pass - - // translate so that the pivot is in 0,0 - mValues[0] = 1; - mValues[1] = 0; - mValues[2] = -px; - mValues[3] = 0; - mValues[4] = 1; - mValues[5] = -py; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - - // scale - addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - } - - /** Set the matrix to scale by sx and sy. */ - @Override - public void setScale(float sx, float sy) { - mValues[0] = sx; - mValues[1] = 0; - mValues[2] = 0; - mValues[3] = 0; - mValues[4] = sy; - mValues[5] = 0; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - } - - /** - * Set the matrix to rotate by the specified number of degrees, with a pivot - * point at (px, py). The pivot point is the coordinate that should remain - * unchanged by the specified transformation. - */ - @Override - public void setRotate(float degrees, float px, float py) { - // TODO: do it in one pass - - // translate so that the pivot is in 0,0 - mValues[0] = 1; - mValues[1] = 0; - mValues[2] = -px; - mValues[3] = 0; - mValues[4] = 1; - mValues[5] = -py; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - - // scale - double rad = Math.toRadians(degrees); - float cos = (float)Math.cos(rad); - float sin = (float)Math.sin(rad); - addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - } - - /** - * Set the matrix to rotate about (0,0) by the specified number of degrees. - */ - @Override - public void setRotate(float degrees) { - double rad = Math.toRadians(degrees); - float cos = (float)Math.cos(rad); - float sin = (float)Math.sin(rad); - - mValues[0] = cos; - mValues[1] = -sin; - mValues[2] = 0; - mValues[3] = sin; - mValues[4] = cos; - mValues[5] = 0; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - } - - /** - * Set the matrix to rotate by the specified sine and cosine values, with a - * pivot point at (px, py). The pivot point is the coordinate that should - * remain unchanged by the specified transformation. - */ - @Override - public void setSinCos(float sinValue, float cosValue, float px, float py) { - // TODO: do it in one pass - - // translate so that the pivot is in 0,0 - mValues[0] = 1; - mValues[1] = 0; - mValues[2] = -px; - mValues[3] = 0; - mValues[4] = 1; - mValues[5] = -py; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - - // scale - addTransform(new float[] { cosValue, -sinValue, 0, sinValue, cosValue, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - } - - /** Set the matrix to rotate by the specified sine and cosine values. */ - @Override - public void setSinCos(float sinValue, float cosValue) { - mValues[0] = cosValue; - mValues[1] = -sinValue; - mValues[2] = 0; - mValues[3] = sinValue; - mValues[4] = cosValue; - mValues[5] = 0; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - } - - /** - * Set the matrix to skew by sx and sy, with a pivot point at (px, py). - * The pivot point is the coordinate that should remain unchanged by the - * specified transformation. - */ - @Override - public void setSkew(float kx, float ky, float px, float py) { - // TODO: do it in one pass - - // translate so that the pivot is in 0,0 - mValues[0] = 1; - mValues[1] = 0; - mValues[2] = -px; - mValues[3] = 0; - mValues[4] = 1; - mValues[5] = -py; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - - // scale - addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - } - - /** Set the matrix to skew by sx and sy. */ - @Override - public void setSkew(float kx, float ky) { - mValues[0] = 1; - mValues[1] = kx; - mValues[2] = -0; - mValues[3] = ky; - mValues[4] = 1; - mValues[5] = 0; - mValues[6] = 0; - mValues[7] = 0; - mValues[7] = 1; - } - - /** - * Set the matrix to the concatenation of the two specified matrices, - * returning true if the the result can be represented. Either of the two - * matrices may also be the target matrix. this = a * b - */ - public boolean setConcat(Matrix a, Matrix b) { - if (a == this) { - preConcat(b); - } else if (b == this) { - postConcat(b); - } else { - Matrix tmp = new Matrix(b); - tmp.addTransform(a.mValues); - set(tmp); - } - - return true; - } - - @Override - public boolean setConcat(_Original_Matrix a, _Original_Matrix b) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** - * Preconcats the matrix with the specified translation. - * M' = M * T(dx, dy) - */ - @Override - public boolean preTranslate(float dx, float dy) { - // create a matrix that will be multiply by this - Matrix m = new Matrix(new float[] { 1, 0, dx, 0, 1, dy, 0, 0, 1 }); - m.addTransform(this.mValues); - - System.arraycopy(m.mValues, 0, mValues, 0, 9); - return true; - } - - /** - * Preconcats the matrix with the specified scale. - * M' = M * S(sx, sy, px, py) - */ - @Override - public boolean preScale(float sx, float sy, float px, float py) { - Matrix m = new Matrix(); - m.setScale(sx, sy, px, py); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified scale. - * M' = M * S(sx, sy) - */ - @Override - public boolean preScale(float sx, float sy) { - Matrix m = new Matrix(); - m.setScale(sx, sy); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified rotation. - * M' = M * R(degrees, px, py) - */ - @Override - public boolean preRotate(float degrees, float px, float py) { - Matrix m = new Matrix(); - m.setRotate(degrees, px, py); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified rotation. - * M' = M * R(degrees) - */ - @Override - public boolean preRotate(float degrees) { - Matrix m = new Matrix(); - m.setRotate(degrees); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified skew. - * M' = M * K(kx, ky, px, py) - */ - @Override - public boolean preSkew(float kx, float ky, float px, float py) { - Matrix m = new Matrix(); - m.setSkew(kx, ky, px, py); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified skew. - * M' = M * K(kx, ky) - */ - @Override - public boolean preSkew(float kx, float ky) { - Matrix m = new Matrix(); - m.setSkew(kx, ky); - m.addTransform(mValues); - set(m); - - return true; - } - - /** - * Preconcats the matrix with the specified matrix. - * M' = M * other - */ - public boolean preConcat(Matrix other) { - Matrix m = new Matrix(other); - other.addTransform(mValues); - set(m); - - return true; - } - - @Override - public boolean preConcat(_Original_Matrix other) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** - * Postconcats the matrix with the specified translation. - * M' = T(dx, dy) * M - */ - @Override - public boolean postTranslate(float dx, float dy) { - addTransform(new float[] { 1, 0, dx, 0, 1, dy, 0, 0, 1 }); - return true; - } - - /** - * Postconcats the matrix with the specified scale. - * M' = S(sx, sy, px, py) * M - */ - @Override - public boolean postScale(float sx, float sy, float px, float py) { - // TODO: do it in one pass - // translate so that the pivot is in 0,0 - addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 }); - // scale - addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - - return true; - } - - /** - * Postconcats the matrix with the specified scale. - * M' = S(sx, sy) * M - */ - @Override - public boolean postScale(float sx, float sy) { - addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 }); - return true; - } - - /** - * Postconcats the matrix with the specified rotation. - * M' = R(degrees, px, py) * M - */ - @Override - public boolean postRotate(float degrees, float px, float py) { - // TODO: do it in one pass - // translate so that the pivot is in 0,0 - addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 }); - // scale - double rad = Math.toRadians(degrees); - float cos = (float)Math.cos(rad); - float sin = (float)Math.sin(rad); - addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - - return true; - } - - /** - * Postconcats the matrix with the specified rotation. - * M' = R(degrees) * M - */ - @Override - public boolean postRotate(float degrees) { - double rad = Math.toRadians(degrees); - float cos = (float)Math.cos(rad); - float sin = (float)Math.sin(rad); - addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 }); - - return true; - } - - /** - * Postconcats the matrix with the specified skew. - * M' = K(kx, ky, px, py) * M - */ - @Override - public boolean postSkew(float kx, float ky, float px, float py) { - // TODO: do it in one pass - // translate so that the pivot is in 0,0 - addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 }); - // scale - addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 }); - // translate back the pivot - addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 }); - - return true; - } - - /** - * Postconcats the matrix with the specified skew. - * M' = K(kx, ky) * M - */ - @Override - public boolean postSkew(float kx, float ky) { - addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 }); - - return true; - } - - /** - * Postconcats the matrix with the specified matrix. - * M' = other * M - */ - public boolean postConcat(Matrix other) { - addTransform(other.mValues); - - return true; - } - - @Override - public boolean postConcat(_Original_Matrix other) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** Controlls how the src rect should align into the dst rect for - setRectToRect(). - */ - public enum ScaleToFit { - /** - * Scale in X and Y independently, so that src matches dst exactly. - * This may change the aspect ratio of the src. - */ - FILL (0), - /** - * Compute a scale that will maintain the original src aspect ratio, - * but will also ensure that src fits entirely inside dst. At least one - * axis (X or Y) will fit exactly. START aligns the result to the - * left and top edges of dst. - */ - START (1), - /** - * Compute a scale that will maintain the original src aspect ratio, - * but will also ensure that src fits entirely inside dst. At least one - * axis (X or Y) will fit exactly. The result is centered inside dst. - */ - CENTER (2), - /** - * Compute a scale that will maintain the original src aspect ratio, - * but will also ensure that src fits entirely inside dst. At least one - * axis (X or Y) will fit exactly. END aligns the result to the - * right and bottom edges of dst. - */ - END (3); - - // the native values must match those in SkMatrix.h - ScaleToFit(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - /** - * Set the matrix to the scale and translate values that map the source - * rectangle to the destination rectangle, returning true if the result - * can be represented. - * - * @param src the source rectangle to map from. - * @param dst the destination rectangle to map to. - * @param stf the ScaleToFit option - * @return true if the matrix can be represented by the rectangle mapping. - */ - public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) { - if (dst == null || src == null) { - throw new NullPointerException(); - } - - if (src.isEmpty()) { - reset(); - return false; - } - - if (dst.isEmpty()) { - mValues[0] = mValues[1] = mValues[2] = mValues[3] = mValues[4] = mValues[5] - = mValues[6] = mValues[7] = 0; - mValues[8] = 1; - } else { - float tx, sx = dst.width() / src.width(); - float ty, sy = dst.height() / src.height(); - boolean xLarger = false; - - if (stf != ScaleToFit.FILL) { - if (sx > sy) { - xLarger = true; - sx = sy; - } else { - sy = sx; - } - } - - tx = dst.left - src.left * sx; - ty = dst.top - src.top * sy; - if (stf == ScaleToFit.CENTER || stf == ScaleToFit.END) { - float diff; - - if (xLarger) { - diff = dst.width() - src.width() * sy; - } else { - diff = dst.height() - src.height() * sy; - } - - if (stf == ScaleToFit.CENTER) { - diff = diff / 2; - } - - if (xLarger) { - tx += diff; - } else { - ty += diff; - } - } - - mValues[0] = sx; - mValues[4] = sy; - mValues[2] = tx; - mValues[5] = ty; - mValues[1] = mValues[3] = mValues[6] = mValues[7] = 0; - - } - // shared cleanup - mValues[8] = 1; - return true; - } - - @Override - public boolean setRectToRect(RectF src, RectF dst, _Original_Matrix.ScaleToFit stf) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** - * Set the matrix such that the specified src points would map to the - * specified dst points. The "points" are represented as an array of floats, - * order [x0, y0, x1, y1, ...], where each "point" is 2 float values. - * - * @param src The array of src [x,y] pairs (points) - * @param srcIndex Index of the first pair of src values - * @param dst The array of dst [x,y] pairs (points) - * @param dstIndex Index of the first pair of dst values - * @param pointCount The number of pairs/points to be used. Must be [0..4] - * @return true if the matrix was set to the specified transformation - */ - @Override - public boolean setPolyToPoly(float[] src, int srcIndex, - float[] dst, int dstIndex, - int pointCount) { - if (pointCount > 4) { - throw new IllegalArgumentException(); - } - checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); - throw new UnsupportedOperationException("STUB NEEDED"); - } - - /** - * If this matrix can be inverted, return true and if inverse is not null, - * set inverse to be the inverse of this matrix. If this matrix cannot be - * inverted, ignore inverse and return false. - */ - public boolean invert(Matrix inverse) { - throw new UnsupportedOperationException("STUB NEEDED"); - } - - @Override - public boolean invert(_Original_Matrix inverse) { - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - /** - * Apply this matrix to the array of 2D points specified by src, and write - * the transformed points into the array of points specified by dst. The - * two arrays represent their "points" as pairs of floats [x, y]. - * - * @param dst The array of dst points (x,y pairs) - * @param dstIndex The index of the first [x,y] pair of dst floats - * @param src The array of src points (x,y pairs) - * @param srcIndex The index of the first [x,y] pair of src floats - * @param pointCount The number of points (x,y pairs) to transform - */ - @Override - public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, - int pointCount) { - checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); - throw new UnsupportedOperationException("STUB NEEDED"); - } - - /** - * Apply this matrix to the array of 2D vectors specified by src, and write - * the transformed vectors into the array of vectors specified by dst. The - * two arrays represent their "vectors" as pairs of floats [x, y]. - * - * @param dst The array of dst vectors (x,y pairs) - * @param dstIndex The index of the first [x,y] pair of dst floats - * @param src The array of src vectors (x,y pairs) - * @param srcIndex The index of the first [x,y] pair of src floats - * @param vectorCount The number of vectors (x,y pairs) to transform - */ - @Override - public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, - int vectorCount) { - checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount); - throw new UnsupportedOperationException("STUB NEEDED"); - } - - /** - * Apply this matrix to the array of 2D points specified by src, and write - * the transformed points into the array of points specified by dst. The - * two arrays represent their "points" as pairs of floats [x, y]. - * - * @param dst The array of dst points (x,y pairs) - * @param src The array of src points (x,y pairs) - */ - @Override - public void mapPoints(float[] dst, float[] src) { - if (dst.length != src.length) { - throw new ArrayIndexOutOfBoundsException(); - } - mapPoints(dst, 0, src, 0, dst.length >> 1); - } - - /** - * Apply this matrix to the array of 2D vectors specified by src, and write - * the transformed vectors into the array of vectors specified by dst. The - * two arrays represent their "vectors" as pairs of floats [x, y]. - * - * @param dst The array of dst vectors (x,y pairs) - * @param src The array of src vectors (x,y pairs) - */ - @Override - public void mapVectors(float[] dst, float[] src) { - if (dst.length != src.length) { - throw new ArrayIndexOutOfBoundsException(); - } - mapVectors(dst, 0, src, 0, dst.length >> 1); - } - - /** - * Apply this matrix to the array of 2D points, and write the transformed - * points back into the array - * - * @param pts The array [x0, y0, x1, y1, ...] of points to transform. - */ - @Override - public void mapPoints(float[] pts) { - mapPoints(pts, 0, pts, 0, pts.length >> 1); - } - - /** - * Apply this matrix to the array of 2D vectors, and write the transformed - * vectors back into the array. - * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform. - */ - @Override - public void mapVectors(float[] vecs) { - mapVectors(vecs, 0, vecs, 0, vecs.length >> 1); - } - - /** - * Apply this matrix to the src rectangle, and write the transformed - * rectangle into dst. This is accomplished by transforming the 4 corners of - * src, and then setting dst to the bounds of those points. - * - * @param dst Where the transformed rectangle is written. - * @param src The original rectangle to be transformed. - * @return the result of calling rectStaysRect() - */ - @Override - public boolean mapRect(RectF dst, RectF src) { - if (dst == null || src == null) { - throw new NullPointerException(); - } - throw new UnsupportedOperationException("STUB NEEDED"); - } - - /** - * Apply this matrix to the rectangle, and write the transformed rectangle - * back into it. This is accomplished by transforming the 4 corners of rect, - * and then setting it to the bounds of those points - * - * @param rect The rectangle to transform. - * @return the result of calling rectStaysRect() - */ - @Override - public boolean mapRect(RectF rect) { - return mapRect(rect, rect); - } - - /** - * Return the mean radius of a circle after it has been mapped by - * this matrix. NOTE: in perspective this value assumes the circle - * has its center at the origin. - */ - @Override - public float mapRadius(float radius) { - throw new UnsupportedOperationException("STUB NEEDED"); - } - - /** Copy 9 values from the matrix into the array. - */ - @Override - public void getValues(float[] values) { - if (values.length < 9) { - throw new ArrayIndexOutOfBoundsException(); - } - System.arraycopy(mValues, 0, values, 0, mValues.length); - } - - /** Copy 9 values from the array into the matrix. - Depending on the implementation of Matrix, these may be - transformed into 16.16 integers in the Matrix, such that - a subsequent call to getValues() will not yield exactly - the same values. - */ - @Override - public void setValues(float[] values) { - if (values.length < 9) { - throw new ArrayIndexOutOfBoundsException(); - } - System.arraycopy(values, 0, mValues, 0, mValues.length); - } - - @SuppressWarnings("unused") - private final static int kIdentity_Mask = 0; - private final static int kTranslate_Mask = 0x01; //!< set if the matrix has translation - private final static int kScale_Mask = 0x02; //!< set if the matrix has X or Y scale - private final static int kAffine_Mask = 0x04; //!< set if the matrix skews or rotates - private final static int kPerspective_Mask = 0x08; //!< set if the matrix is in perspective - private final static int kRectStaysRect_Mask = 0x10; - @SuppressWarnings("unused") - private final static int kUnknown_Mask = 0x80; - - @SuppressWarnings("unused") - private final static int kAllMasks = kTranslate_Mask | - kScale_Mask | - kAffine_Mask | - kPerspective_Mask | - kRectStaysRect_Mask; - - // these guys align with the masks, so we can compute a mask from a variable 0/1 - @SuppressWarnings("unused") - private final static int kTranslate_Shift = 0; - @SuppressWarnings("unused") - private final static int kScale_Shift = 1; - @SuppressWarnings("unused") - private final static int kAffine_Shift = 2; - @SuppressWarnings("unused") - private final static int kPerspective_Shift = 3; - private final static int kRectStaysRect_Shift = 4; - - private int computeTypeMask() { - int mask = 0; - - if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) { - mask |= kPerspective_Mask; - } - - if (mValues[2] != 0. || mValues[5] != 0.) { - mask |= kTranslate_Mask; - } - - float m00 = mValues[0]; - float m01 = mValues[1]; - float m10 = mValues[3]; - float m11 = mValues[4]; - - if (m01 != 0. || m10 != 0.) { - mask |= kAffine_Mask; - } - - if (m00 != 1. || m11 != 1.) { - mask |= kScale_Mask; - } - - if ((mask & kPerspective_Mask) == 0) { - // map non-zero to 1 - int im00 = m00 != 0 ? 1 : 0; - int im01 = m01 != 0 ? 1 : 0; - int im10 = m10 != 0 ? 1 : 0; - int im11 = m11 != 0 ? 1 : 0; - - // record if the (p)rimary and (s)econdary diagonals are all 0 or - // all non-zero (answer is 0 or 1) - int dp0 = (im00 | im11) ^ 1; // true if both are 0 - int dp1 = im00 & im11; // true if both are 1 - int ds0 = (im01 | im10) ^ 1; // true if both are 0 - int ds1 = im01 & im10; // true if both are 1 - - // return 1 if primary is 1 and secondary is 0 or - // primary is 0 and secondary is 1 - mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift; - } - - return mask; - } -} diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint.java b/tools/layoutlib/bridge/src/android/graphics/Paint.java deleted file mode 100644 index ade07d6..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Paint.java +++ /dev/null @@ -1,864 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import android.text.SpannableString; -import android.text.SpannableStringBuilder; -import android.text.SpannedString; -import android.text.TextUtils; - -import java.awt.Font; -import java.awt.Toolkit; -import java.awt.font.FontRenderContext; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -/** - * A paint implementation overridden by the LayoutLib bridge. - */ -public class Paint extends _Original_Paint { - - private int mColor = 0xFFFFFFFF; - private float mTextSize = 20; - private float mScaleX = 1; - private float mSkewX = 0; - private Align mAlign = Align.LEFT; - private Style mStyle = Style.FILL; - private int mFlags = 0; - - private Font mFont; - private final FontRenderContext mFontContext = new FontRenderContext( - new AffineTransform(), true, true); - private java.awt.FontMetrics mMetrics; - - @SuppressWarnings("hiding") - public static final int ANTI_ALIAS_FLAG = _Original_Paint.ANTI_ALIAS_FLAG; - @SuppressWarnings("hiding") - public static final int FILTER_BITMAP_FLAG = _Original_Paint.FILTER_BITMAP_FLAG; - @SuppressWarnings("hiding") - public static final int DITHER_FLAG = _Original_Paint.DITHER_FLAG; - @SuppressWarnings("hiding") - public static final int UNDERLINE_TEXT_FLAG = _Original_Paint.UNDERLINE_TEXT_FLAG; - @SuppressWarnings("hiding") - public static final int STRIKE_THRU_TEXT_FLAG = _Original_Paint.STRIKE_THRU_TEXT_FLAG; - @SuppressWarnings("hiding") - public static final int FAKE_BOLD_TEXT_FLAG = _Original_Paint.FAKE_BOLD_TEXT_FLAG; - @SuppressWarnings("hiding") - public static final int LINEAR_TEXT_FLAG = _Original_Paint.LINEAR_TEXT_FLAG; - @SuppressWarnings("hiding") - public static final int SUBPIXEL_TEXT_FLAG = _Original_Paint.SUBPIXEL_TEXT_FLAG; - @SuppressWarnings("hiding") - public static final int DEV_KERN_TEXT_FLAG = _Original_Paint.DEV_KERN_TEXT_FLAG; - - public static class FontMetrics extends _Original_Paint.FontMetrics { - } - - public static class FontMetricsInt extends _Original_Paint.FontMetricsInt { - } - - /** - * The Style specifies if the primitive being drawn is filled, - * stroked, or both (in the same color). The default is FILL. - */ - public enum Style { - /** - * Geometry and text drawn with this style will be filled, ignoring all - * stroke-related settings in the paint. - */ - FILL (0), - /** - * Geometry and text drawn with this style will be stroked, respecting - * the stroke-related fields on the paint. - */ - STROKE (1), - /** - * Geometry and text drawn with this style will be both filled and - * stroked at the same time, respecting the stroke-related fields on - * the paint. - */ - FILL_AND_STROKE (2); - - Style(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - /** - * The Cap specifies the treatment for the beginning and ending of - * stroked lines and paths. The default is BUTT. - */ - public enum Cap { - /** - * The stroke ends with the path, and does not project beyond it. - */ - BUTT (0), - /** - * The stroke projects out as a square, with the center at the end - * of the path. - */ - ROUND (1), - /** - * The stroke projects out as a semicircle, with the center at the - * end of the path. - */ - SQUARE (2); - - private Cap(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - /** - * The Join specifies the treatment where lines and curve segments - * join on a stroked path. The default is MITER. - */ - public enum Join { - /** - * The outer edges of a join meet at a sharp angle - */ - MITER (0), - /** - * The outer edges of a join meet in a circular arc. - */ - ROUND (1), - /** - * The outer edges of a join meet with a straight line - */ - BEVEL (2); - - private Join(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - /** - * Align specifies how drawText aligns its text relative to the - * [x,y] coordinates. The default is LEFT. - */ - public enum Align { - /** - * The text is drawn to the right of the x,y origin - */ - LEFT (0), - /** - * The text is drawn centered horizontally on the x,y origin - */ - CENTER (1), - /** - * The text is drawn to the left of the x,y origin - */ - RIGHT (2); - - private Align(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - public Paint() { - this(0); - } - - public Paint(int flags) { - setFlags(flags | DEFAULT_PAINT_FLAGS); - initFont(); - } - - public Paint(Paint paint) { - set(paint); - initFont(); - } - - @Override - public void finalize() throws Throwable { - // pass - } - - /** - * Returns the {@link Font} object. - */ - public Font getFont() { - return mFont; - } - - private void initFont() { - mTypeface = Typeface.DEFAULT; - updateFontObject(); - } - - /** - * Update the {@link Font} object from the typeface, text size and scaling - */ - private void updateFontObject() { - if (mTypeface != null) { - // get the typeface font object, and get our font object from it, based on the current size - mFont = mTypeface.getFont().deriveFont(mTextSize); - if (mScaleX != 1.0 || mSkewX != 0) { - // TODO: support skew - mFont = mFont.deriveFont(new AffineTransform( - mScaleX, mSkewX, 0, 0, 1, 0)); - } - - mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(mFont); - } - } - - //---------------------------------------- - - public void set(Paint src) { - if (this != src) { - mColor = src.mColor; - mTextSize = src.mTextSize; - mScaleX = src.mScaleX; - mSkewX = src.mSkewX; - mAlign = src.mAlign; - mStyle = src.mStyle; - mFlags = src.mFlags; - - super.set(src); - } - } - - @Override - public int getFlags() { - return mFlags; - } - - @Override - public void setFlags(int flags) { - mFlags = flags; - } - - /** - * Return the font's recommended interline spacing, given the Paint's - * settings for typeface, textSize, etc. If metrics is not null, return the - * fontmetric values in it. - * - * @param metrics If this object is not null, its fields are filled with - * the appropriate values given the paint's text attributes. - * @return the font's recommended interline spacing. - */ - public float getFontMetrics(FontMetrics metrics) { - if (mMetrics != null) { - if (metrics != null) { - // ascent stuff should be negatif, but awt returns them as positive. - metrics.top = - mMetrics.getMaxAscent(); - metrics.ascent = - mMetrics.getAscent(); - metrics.descent = mMetrics.getDescent(); - metrics.bottom = mMetrics.getMaxDescent(); - metrics.leading = mMetrics.getLeading(); - } - - return mMetrics.getHeight(); - } - - return 0; - } - - public int getFontMetricsInt(FontMetricsInt metrics) { - if (mMetrics != null) { - if (metrics != null) { - // ascent stuff should be negatif, but awt returns them as positive. - metrics.top = - mMetrics.getMaxAscent(); - metrics.ascent = - mMetrics.getAscent(); - metrics.descent = mMetrics.getDescent(); - metrics.bottom = mMetrics.getMaxDescent(); - metrics.leading = mMetrics.getLeading(); - } - - return mMetrics.getHeight(); - } - - return 0; - } - - /** - * Reimplemented to return Paint.FontMetrics instead of _Original_Paint.FontMetrics - */ - public FontMetrics getFontMetrics() { - FontMetrics fm = new FontMetrics(); - getFontMetrics(fm); - return fm; - } - - /** - * Reimplemented to return Paint.FontMetricsInt instead of _Original_Paint.FontMetricsInt - */ - public FontMetricsInt getFontMetricsInt() { - FontMetricsInt fm = new FontMetricsInt(); - getFontMetricsInt(fm); - return fm; - } - - - - @Override - public float getFontMetrics(_Original_Paint.FontMetrics metrics) { - // TODO implement if needed - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - @Override - public int getFontMetricsInt(_Original_Paint.FontMetricsInt metrics) { - // TODO implement if needed - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - @Override - public Typeface setTypeface(Typeface typeface) { - if (typeface != null) { - mTypeface = typeface; - } else { - mTypeface = Typeface.DEFAULT; - } - - updateFontObject(); - - return typeface; - } - - @Override - public int getColor() { - return mColor; - } - - @Override - public void setColor(int color) { - mColor = color; - } - - - @Override - public void setAlpha(int alpha) { - mColor = (alpha << 24) | (mColor & 0x00FFFFFF); - } - - @Override - public int getAlpha() { - return mColor >>> 24; - } - - /** - * Set or clear the shader object. - * <p /> - * Pass null to clear any previous shader. - * As a convenience, the parameter passed is also returned. - * - * @param shader May be null. the new shader to be installed in the paint - * @return shader - */ - @Override - public Shader setShader(Shader shader) { - return mShader = shader; - } - - /** - * Set or clear the paint's colorfilter, returning the parameter. - * - * @param filter May be null. The new filter to be installed in the paint - * @return filter - */ - @Override - public ColorFilter setColorFilter(ColorFilter filter) { - int filterNative = 0; - if (filter != null) - filterNative = filter.native_instance; - mColorFilter = filter; - return filter; - } - - /** - * Set or clear the xfermode object. - * <p /> - * Pass null to clear any previous xfermode. - * As a convenience, the parameter passed is also returned. - * - * @param xfermode May be null. The xfermode to be installed in the paint - * @return xfermode - */ - @Override - public Xfermode setXfermode(Xfermode xfermode) { - return mXfermode = xfermode; - } - - public void setTextAlign(Align align) { - mAlign = align; - } - - @Override - public void setTextAlign(android.graphics._Original_Paint.Align align) { - // TODO implement if needed - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - public Align getTextAlign() { - return mAlign; - } - - public void setStyle(Style style) { - mStyle = style; - } - - @Override - public void setStyle(android.graphics._Original_Paint.Style style) { - // TODO implement if needed - throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); - } - - public Style getStyle() { - return mStyle; - } - - @Override - public void setDither(boolean dither) { - mFlags |= dither ? DITHER_FLAG : ~DITHER_FLAG; - } - - @Override - public void setAntiAlias(boolean aa) { - mFlags |= aa ? ANTI_ALIAS_FLAG : ~ANTI_ALIAS_FLAG; - } - - @Override - public void setFakeBoldText(boolean flag) { - mFlags |= flag ? FAKE_BOLD_TEXT_FLAG : ~FAKE_BOLD_TEXT_FLAG; - } - - /** - * Return the paint's text size. - * - * @return the paint's text size. - */ - @Override - public float getTextSize() { - return mTextSize; - } - - /** - * Set the paint's text size. This value must be > 0 - * - * @param textSize set the paint's text size. - */ - @Override - public void setTextSize(float textSize) { - mTextSize = textSize; - - updateFontObject(); - } - - /** - * Return the paint's horizontal scale factor for text. The default value - * is 1.0. - * - * @return the paint's scale factor in X for drawing/measuring text - */ - @Override - public float getTextScaleX() { - return mScaleX; - } - - /** - * Set the paint's horizontal scale factor for text. The default value - * is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will - * stretch the text narrower. - * - * @param scaleX set the paint's scale in X for drawing/measuring text. - */ - @Override - public void setTextScaleX(float scaleX) { - mScaleX = scaleX; - - updateFontObject(); - } - - /** - * Return the paint's horizontal skew factor for text. The default value - * is 0. - * - * @return the paint's skew factor in X for drawing text. - */ - @Override - public float getTextSkewX() { - return mSkewX; - } - - /** - * Set the paint's horizontal skew factor for text. The default value - * is 0. For approximating oblique text, use values around -0.25. - * - * @param skewX set the paint's skew factor in X for drawing text. - */ - @Override - public void setTextSkewX(float skewX) { - mSkewX = skewX; - - updateFontObject(); - } - - /** - * Return the distance above (negative) the baseline (ascent) based on the - * current typeface and text size. - * - * @return the distance above (negative) the baseline (ascent) based on the - * current typeface and text size. - */ - @Override - public float ascent() { - if (mMetrics != null) { - // ascent stuff should be negatif, but awt returns them as positive. - return - mMetrics.getAscent(); - } - - return 0; - } - - /** - * Return the distance below (positive) the baseline (descent) based on the - * current typeface and text size. - * - * @return the distance below (positive) the baseline (descent) based on - * the current typeface and text size. - */ - @Override - public float descent() { - if (mMetrics != null) { - return mMetrics.getDescent(); - } - - return 0; - } - - /** - * Return the width of the text. - * - * @param text The text to measure - * @param index The index of the first character to start measuring - * @param count THe number of characters to measure, beginning with start - * @return The width of the text - */ - @Override - public float measureText(char[] text, int index, int count) { - if (mFont != null && text != null && text.length > 0) { - Rectangle2D bounds = mFont.getStringBounds(text, index, index + count, mFontContext); - - return (float)bounds.getWidth(); - } - - return 0; - } - - /** - * Return the width of the text. - * - * @param text The text to measure - * @param start The index of the first character to start measuring - * @param end 1 beyond the index of the last character to measure - * @return The width of the text - */ - @Override - public float measureText(String text, int start, int end) { - return measureText(text.toCharArray(), start, end - start); - } - - /** - * Return the width of the text. - * - * @param text The text to measure - * @return The width of the text - */ - @Override - public float measureText(String text) { - return measureText(text.toCharArray(), 0, text.length()); - } - - /* - * re-implement to call SpannableStringBuilder.measureText with a Paint object - * instead of an _Original_Paint - */ - @Override - public float measureText(CharSequence text, int start, int end) { - if (text instanceof String) { - return measureText((String)text, start, end); - } - if (text instanceof SpannedString || - text instanceof SpannableString) { - return measureText(text.toString(), start, end); - } - if (text instanceof SpannableStringBuilder) { - return ((SpannableStringBuilder)text).measureText(start, end, this); - } - - char[] buf = TemporaryBuffer.obtain(end - start); - TextUtils.getChars(text, start, end, buf, 0); - float result = measureText(buf, 0, end - start); - TemporaryBuffer.recycle(buf); - return result; - } - - /** - * Measure the text, stopping early if the measured width exceeds maxWidth. - * Return the number of chars that were measured, and if measuredWidth is - * not null, return in it the actual width measured. - * - * @param text The text to measure - * @param index The offset into text to begin measuring at - * @param count The number of maximum number of entries to measure. If count - * is negative, then the characters before index are measured - * in reverse order. This allows for measuring the end of - * string. - * @param maxWidth The maximum width to accumulate. - * @param measuredWidth Optional. If not null, returns the actual width - * measured. - * @return The number of chars that were measured. Will always be <= - * abs(count). - */ - @Override - public int breakText(char[] text, int index, int count, - float maxWidth, float[] measuredWidth) { - int inc = count > 0 ? 1 : -1; - - int measureIndex = 0; - float measureAcc = 0; - for (int i = index ; i != index + count ; i += inc, measureIndex++) { - int start, end; - if (i < index) { - start = i; - end = index; - } else { - start = index; - end = i; - } - - // measure from start to end - float res = measureText(text, start, end - start + 1); - - if (measuredWidth != null) { - measuredWidth[measureIndex] = res; - } - - measureAcc += res; - if (res > maxWidth) { - // we should not return this char index, but since it's 0-based and we need - // to return a count, we simply return measureIndex; - return measureIndex; - } - - } - - return measureIndex; - } - - /** - * Measure the text, stopping early if the measured width exceeds maxWidth. - * Return the number of chars that were measured, and if measuredWidth is - * not null, return in it the actual width measured. - * - * @param text The text to measure - * @param measureForwards If true, measure forwards, starting at index. - * Otherwise, measure backwards, starting with the - * last character in the string. - * @param maxWidth The maximum width to accumulate. - * @param measuredWidth Optional. If not null, returns the actual width - * measured. - * @return The number of chars that were measured. Will always be <= - * abs(count). - */ - @Override - public int breakText(String text, boolean measureForwards, - float maxWidth, float[] measuredWidth) { - // NOTE: javadoc doesn't match. Just a guess. - return breakText(text, - 0 /* start */, text.length() /* end */, - measureForwards, maxWidth, measuredWidth); - } - - /** - * Return the advance widths for the characters in the string. - * - * @param text The text to measure - * @param index The index of the first char to to measure - * @param count The number of chars starting with index to measure - * @param widths array to receive the advance widths of the characters. - * Must be at least a large as count. - * @return the actual number of widths returned. - */ - @Override - public int getTextWidths(char[] text, int index, int count, - float[] widths) { - if (mMetrics != null) { - if ((index | count) < 0 || index + count > text.length - || count > widths.length) { - throw new ArrayIndexOutOfBoundsException(); - } - - for (int i = 0; i < count; i++) { - widths[i] = mMetrics.charWidth(text[i + index]); - } - - return count; - } - - return 0; - } - - /** - * Return the advance widths for the characters in the string. - * - * @param text The text to measure - * @param start The index of the first char to to measure - * @param end The end of the text slice to measure - * @param widths array to receive the advance widths of the characters. - * Must be at least a large as the text. - * @return the number of unichars in the specified text. - */ - @Override - public int getTextWidths(String text, int start, int end, float[] widths) { - if ((start | end | (end - start) | (text.length() - end)) < 0) { - throw new IndexOutOfBoundsException(); - } - if (end - start > widths.length) { - throw new ArrayIndexOutOfBoundsException(); - } - - return getTextWidths(text.toCharArray(), start, end - start, widths); - } - - /* - * re-implement to call SpannableStringBuilder.getTextWidths with a Paint object - * instead of an _Original_Paint - */ - @Override - public int getTextWidths(CharSequence text, int start, int end, float[] widths) { - if (text instanceof String) { - return getTextWidths((String)text, start, end, widths); - } - if (text instanceof SpannedString || text instanceof SpannableString) { - return getTextWidths(text.toString(), start, end, widths); - } - if (text instanceof SpannableStringBuilder) { - return ((SpannableStringBuilder)text).getTextWidths(start, end, widths, this); - } - - char[] buf = TemporaryBuffer.obtain(end - start); - TextUtils.getChars(text, start, end, buf, 0); - int result = getTextWidths(buf, 0, end - start, widths); - TemporaryBuffer.recycle(buf); - return result; - } - - - /** - * Return the path (outline) for the specified text. - * Note: just like Canvas.drawText, this will respect the Align setting in - * the paint. - * - * @param text The text to retrieve the path from - * @param index The index of the first character in text - * @param count The number of characterss starting with index - * @param x The x coordinate of the text's origin - * @param y The y coordinate of the text's origin - * @param path The path to receive the data describing the text. Must - * be allocated by the caller. - */ - @Override - public void getTextPath(char[] text, int index, int count, - float x, float y, Path path) { - - // TODO this is the ORIGINAL implementation. REPLACE AS NEEDED OR REMOVE - - if ((index | count) < 0 || index + count > text.length) { - throw new ArrayIndexOutOfBoundsException(); - } - - // TODO native_getTextPath(mNativePaint, text, index, count, x, y, path.ni()); - - throw new UnsupportedOperationException("IMPLEMENT AS NEEDED"); - } - - /** - * Return the path (outline) for the specified text. - * Note: just like Canvas.drawText, this will respect the Align setting - * in the paint. - * - * @param text The text to retrieve the path from - * @param start The first character in the text - * @param end 1 past the last charcter in the text - * @param x The x coordinate of the text's origin - * @param y The y coordinate of the text's origin - * @param path The path to receive the data describing the text. Must - * be allocated by the caller. - */ - @Override - public void getTextPath(String text, int start, int end, - float x, float y, Path path) { - if ((start | end | (end - start) | (text.length() - end)) < 0) { - throw new IndexOutOfBoundsException(); - } - - getTextPath(text.toCharArray(), start, end - start, x, y, path); - } - - /** - * Return in bounds (allocated by the caller) the smallest rectangle that - * encloses all of the characters, with an implied origin at (0,0). - * - * @param text String to measure and return its bounds - * @param start Index of the first char in the string to measure - * @param end 1 past the last char in the string measure - * @param bounds Returns the unioned bounds of all the text. Must be - * allocated by the caller. - */ - @Override - public void getTextBounds(String text, int start, int end, Rect bounds) { - if ((start | end | (end - start) | (text.length() - end)) < 0) { - throw new IndexOutOfBoundsException(); - } - if (bounds == null) { - throw new NullPointerException("need bounds Rect"); - } - - getTextBounds(text.toCharArray(), start, end - start, bounds); - } - - /** - * Return in bounds (allocated by the caller) the smallest rectangle that - * encloses all of the characters, with an implied origin at (0,0). - * - * @param text Array of chars to measure and return their unioned bounds - * @param index Index of the first char in the array to measure - * @param count The number of chars, beginning at index, to measure - * @param bounds Returns the unioned bounds of all the text. Must be - * allocated by the caller. - */ - @Override - public void getTextBounds(char[] text, int index, int count, Rect bounds) { - if (mFont != null) { - if ((index | count) < 0 || index + count > text.length) { - throw new ArrayIndexOutOfBoundsException(); - } - if (bounds == null) { - throw new NullPointerException("need bounds Rect"); - } - - Rectangle2D rect = mFont.getStringBounds(text, index, index + count, mFontContext); - bounds.set(0, 0, (int)rect.getWidth(), (int)rect.getHeight()); - } - } -} diff --git a/tools/layoutlib/bridge/src/android/graphics/Path.java b/tools/layoutlib/bridge/src/android/graphics/Path.java deleted file mode 100644 index 12d2cde..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Path.java +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.PathIterator; -import java.awt.geom.Rectangle2D; - -/** - * The Path class encapsulates compound (multiple contour) geometric paths - * consisting of straight line segments, quadratic curves, and cubic curves. - * It can be drawn with canvas.drawPath(path, paint), either filled or stroked - * (based on the paint's Style), or it can be used for clipping or to draw - * text on a path. - */ -public class Path { - - private FillType mFillType = FillType.WINDING; - private GeneralPath mPath = new GeneralPath(); - - private float mLastX = 0; - private float mLastY = 0; - - //---------- Custom methods ---------- - - public Shape getAwtShape() { - return mPath; - } - - //---------- - - /** - * Create an empty path - */ - public Path() { - } - - /** - * Create a new path, copying the contents from the src path. - * - * @param src The path to copy from when initializing the new path - */ - public Path(Path src) { - mPath.append(src.mPath, false /* connect */); - } - - /** - * Clear any lines and curves from the path, making it empty. - * This does NOT change the fill-type setting. - */ - public void reset() { - mPath = new GeneralPath(); - } - - /** - * Rewinds the path: clears any lines and curves from the path but - * keeps the internal data structure for faster reuse. - */ - public void rewind() { - // FIXME - throw new UnsupportedOperationException(); - } - - /** Replace the contents of this with the contents of src. - */ - public void set(Path src) { - mPath.append(src.mPath, false /* connect */); - } - - /** Enum for the ways a path may be filled - */ - public enum FillType { - // these must match the values in SkPath.h - WINDING (GeneralPath.WIND_NON_ZERO, false), - EVEN_ODD (GeneralPath.WIND_EVEN_ODD, false), - INVERSE_WINDING (GeneralPath.WIND_NON_ZERO, true), - INVERSE_EVEN_ODD(GeneralPath.WIND_EVEN_ODD, true); - - FillType(int rule, boolean inverse) { - this.rule = rule; - this.inverse = inverse; - } - - final int rule; - final boolean inverse; - } - - /** - * Return the path's fill type. This defines how "inside" is - * computed. The default value is WINDING. - * - * @return the path's fill type - */ - public FillType getFillType() { - return mFillType; - } - - /** - * Set the path's fill type. This defines how "inside" is computed. - * - * @param ft The new fill type for this path - */ - public void setFillType(FillType ft) { - mFillType = ft; - mPath.setWindingRule(ft.rule); - } - - /** - * Returns true if the filltype is one of the INVERSE variants - * - * @return true if the filltype is one of the INVERSE variants - */ - public boolean isInverseFillType() { - return mFillType.inverse; - } - - /** - * Toggles the INVERSE state of the filltype - */ - public void toggleInverseFillType() { - switch (mFillType) { - case WINDING: - mFillType = FillType.INVERSE_WINDING; - break; - case EVEN_ODD: - mFillType = FillType.INVERSE_EVEN_ODD; - break; - case INVERSE_WINDING: - mFillType = FillType.WINDING; - break; - case INVERSE_EVEN_ODD: - mFillType = FillType.EVEN_ODD; - break; - } - } - - /** - * Returns true if the path is empty (contains no lines or curves) - * - * @return true if the path is empty (contains no lines or curves) - */ - public boolean isEmpty() { - return mPath.getCurrentPoint() == null; - } - - /** - * Returns true if the path specifies a rectangle. If so, and if rect is - * not null, set rect to the bounds of the path. If the path does not - * specify a rectangle, return false and ignore rect. - * - * @param rect If not null, returns the bounds of the path if it specifies - * a rectangle - * @return true if the path specifies a rectangle - */ - public boolean isRect(RectF rect) { - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Compute the bounds of the path, and write the answer into bounds. If the - * path contains 0 or 1 points, the bounds is set to (0,0,0,0) - * - * @param bounds Returns the computed bounds of the path - * @param exact If true, return the exact (but slower) bounds, else return - * just the bounds of all control points - */ - public void computeBounds(RectF bounds, boolean exact) { - Rectangle2D rect = mPath.getBounds2D(); - bounds.left = (float)rect.getMinX(); - bounds.right = (float)rect.getMaxX(); - bounds.top = (float)rect.getMinY(); - bounds.bottom = (float)rect.getMaxY(); - } - - /** - * Hint to the path to prepare for adding more points. This can allow the - * path to more efficiently allocate its storage. - * - * @param extraPtCount The number of extra points that may be added to this - * path - */ - public void incReserve(int extraPtCount) { - // pass - } - - /** - * Set the beginning of the next contour to the point (x,y). - * - * @param x The x-coordinate of the start of a new contour - * @param y The y-coordinate of the start of a new contour - */ - public void moveTo(float x, float y) { - mPath.moveTo(mLastX = x, mLastY = y); - } - - /** - * Set the beginning of the next contour relative to the last point on the - * previous contour. If there is no previous contour, this is treated the - * same as moveTo(). - * - * @param dx The amount to add to the x-coordinate of the end of the - * previous contour, to specify the start of a new contour - * @param dy The amount to add to the y-coordinate of the end of the - * previous contour, to specify the start of a new contour - */ - public void rMoveTo(float dx, float dy) { - dx += mLastX; - dy += mLastY; - mPath.moveTo(mLastX = dx, mLastY = dy); - } - - /** - * Add a line from the last point to the specified point (x,y). - * If no moveTo() call has been made for this contour, the first point is - * automatically set to (0,0). - * - * @param x The x-coordinate of the end of a line - * @param y The y-coordinate of the end of a line - */ - public void lineTo(float x, float y) { - mPath.lineTo(mLastX = x, mLastY = y); - } - - /** - * Same as lineTo, but the coordinates are considered relative to the last - * point on this contour. If there is no previous point, then a moveTo(0,0) - * is inserted automatically. - * - * @param dx The amount to add to the x-coordinate of the previous point on - * this contour, to specify a line - * @param dy The amount to add to the y-coordinate of the previous point on - * this contour, to specify a line - */ - public void rLineTo(float dx, float dy) { - if (isEmpty()) { - mPath.moveTo(mLastX = 0, mLastY = 0); - } - dx += mLastX; - dy += mLastY; - mPath.lineTo(mLastX = dx, mLastY = dy); - } - - /** - * Add a quadratic bezier from the last point, approaching control point - * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for - * this contour, the first point is automatically set to (0,0). - * - * @param x1 The x-coordinate of the control point on a quadratic curve - * @param y1 The y-coordinate of the control point on a quadratic curve - * @param x2 The x-coordinate of the end point on a quadratic curve - * @param y2 The y-coordinate of the end point on a quadratic curve - */ - public void quadTo(float x1, float y1, float x2, float y2) { - mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2); - } - - /** - * Same as quadTo, but the coordinates are considered relative to the last - * point on this contour. If there is no previous point, then a moveTo(0,0) - * is inserted automatically. - * - * @param dx1 The amount to add to the x-coordinate of the last point on - * this contour, for the control point of a quadratic curve - * @param dy1 The amount to add to the y-coordinate of the last point on - * this contour, for the control point of a quadratic curve - * @param dx2 The amount to add to the x-coordinate of the last point on - * this contour, for the end point of a quadratic curve - * @param dy2 The amount to add to the y-coordinate of the last point on - * this contour, for the end point of a quadratic curve - */ - public void rQuadTo(float dx1, float dy1, float dx2, float dy2) { - if (isEmpty()) { - mPath.moveTo(mLastX = 0, mLastY = 0); - } - dx1 += mLastX; - dy1 += mLastY; - dx2 += mLastX; - dy2 += mLastY; - mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2); - } - - /** - * Add a cubic bezier from the last point, approaching control points - * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been - * made for this contour, the first point is automatically set to (0,0). - * - * @param x1 The x-coordinate of the 1st control point on a cubic curve - * @param y1 The y-coordinate of the 1st control point on a cubic curve - * @param x2 The x-coordinate of the 2nd control point on a cubic curve - * @param y2 The y-coordinate of the 2nd control point on a cubic curve - * @param x3 The x-coordinate of the end point on a cubic curve - * @param y3 The y-coordinate of the end point on a cubic curve - */ - public void cubicTo(float x1, float y1, float x2, float y2, - float x3, float y3) { - mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3); - } - - /** - * Same as cubicTo, but the coordinates are considered relative to the - * current point on this contour. If there is no previous point, then a - * moveTo(0,0) is inserted automatically. - */ - public void rCubicTo(float dx1, float dy1, float dx2, float dy2, - float dx3, float dy3) { - if (isEmpty()) { - mPath.moveTo(mLastX = 0, mLastY = 0); - } - dx1 += mLastX; - dy1 += mLastY; - dx2 += mLastX; - dy2 += mLastY; - dx3 += mLastX; - dy3 += mLastY; - mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3); - } - - /** - * Append the specified arc to the path as a new contour. If the start of - * the path is different from the path's current last point, then an - * automatic lineTo() is added to connect the current contour to the - * start of the arc. However, if the path is empty, then we call moveTo() - * with the first point of the arc. The sweep angle is tread mod 360. - * - * @param oval The bounds of oval defining shape and size of the arc - * @param startAngle Starting angle (in degrees) where the arc begins - * @param sweepAngle Sweep angle (in degrees) measured clockwise, treated - * mod 360. - * @param forceMoveTo If true, always begin a new contour with the arc - */ - public void arcTo(RectF oval, float startAngle, float sweepAngle, - boolean forceMoveTo) { - throw new UnsupportedOperationException(); - } - - /** - * Append the specified arc to the path as a new contour. If the start of - * the path is different from the path's current last point, then an - * automatic lineTo() is added to connect the current contour to the - * start of the arc. However, if the path is empty, then we call moveTo() - * with the first point of the arc. - * - * @param oval The bounds of oval defining shape and size of the arc - * @param startAngle Starting angle (in degrees) where the arc begins - * @param sweepAngle Sweep angle (in degrees) measured clockwise - */ - public void arcTo(RectF oval, float startAngle, float sweepAngle) { - throw new UnsupportedOperationException(); - } - - /** - * Close the current contour. If the current point is not equal to the - * first point of the contour, a line segment is automatically added. - */ - public void close() { - mPath.closePath(); - } - - /** - * Specifies how closed shapes (e.g. rects, ovals) are oriented when they - * are added to a path. - */ - public enum Direction { - /** clockwise */ - CW (0), // must match enum in SkPath.h - /** counter-clockwise */ - CCW (1); // must match enum in SkPath.h - - Direction(int ni) { - nativeInt = ni; - } - final int nativeInt; - } - - /** - * Add a closed rectangle contour to the path - * - * @param rect The rectangle to add as a closed contour to the path - * @param dir The direction to wind the rectangle's contour - */ - public void addRect(RectF rect, Direction dir) { - if (rect == null) { - throw new NullPointerException("need rect parameter"); - } - - addRect(rect.left, rect.top, rect.right, rect.bottom, dir); - } - - /** - * Add a closed rectangle contour to the path - * - * @param left The left side of a rectangle to add to the path - * @param top The top of a rectangle to add to the path - * @param right The right side of a rectangle to add to the path - * @param bottom The bottom of a rectangle to add to the path - * @param dir The direction to wind the rectangle's contour - */ - public void addRect(float left, float top, float right, float bottom, - Direction dir) { - moveTo(left, top); - - switch (dir) { - case CW: - lineTo(right, top); - lineTo(right, bottom); - lineTo(left, bottom); - break; - case CCW: - lineTo(left, bottom); - lineTo(right, bottom); - lineTo(right, top); - break; - } - - close(); - } - - /** - * Add a closed oval contour to the path - * - * @param oval The bounds of the oval to add as a closed contour to the path - * @param dir The direction to wind the oval's contour - */ - public void addOval(RectF oval, Direction dir) { - if (oval == null) { - throw new NullPointerException("need oval parameter"); - } - - // FIXME Need to support direction - Ellipse2D ovalShape = new Ellipse2D.Float(oval.left, oval.top, oval.width(), oval.height()); - - mPath.append(ovalShape, false /* connect */); - } - - /** - * Add a closed circle contour to the path - * - * @param x The x-coordinate of the center of a circle to add to the path - * @param y The y-coordinate of the center of a circle to add to the path - * @param radius The radius of a circle to add to the path - * @param dir The direction to wind the circle's contour - */ - public void addCircle(float x, float y, float radius, Direction dir) { - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Add the specified arc to the path as a new contour. - * - * @param oval The bounds of oval defining the shape and size of the arc - * @param startAngle Starting angle (in degrees) where the arc begins - * @param sweepAngle Sweep angle (in degrees) measured clockwise - */ - public void addArc(RectF oval, float startAngle, float sweepAngle) { - if (oval == null) { - throw new NullPointerException("need oval parameter"); - } - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Add a closed round-rectangle contour to the path - * - * @param rect The bounds of a round-rectangle to add to the path - * @param rx The x-radius of the rounded corners on the round-rectangle - * @param ry The y-radius of the rounded corners on the round-rectangle - * @param dir The direction to wind the round-rectangle's contour - */ - public void addRoundRect(RectF rect, float rx, float ry, Direction dir) { - if (rect == null) { - throw new NullPointerException("need rect parameter"); - } - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Add a closed round-rectangle contour to the path. Each corner receives - * two radius values [X, Y]. The corners are ordered top-left, top-right, - * bottom-right, bottom-left - * - * @param rect The bounds of a round-rectangle to add to the path - * @param radii Array of 8 values, 4 pairs of [X,Y] radii - * @param dir The direction to wind the round-rectangle's contour - */ - public void addRoundRect(RectF rect, float[] radii, Direction dir) { - if (rect == null) { - throw new NullPointerException("need rect parameter"); - } - if (radii.length < 8) { - throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values"); - } - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Add a copy of src to the path, offset by (dx,dy) - * - * @param src The path to add as a new contour - * @param dx The amount to translate the path in X as it is added - */ - public void addPath(Path src, float dx, float dy) { - PathIterator iterator = src.mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy)); - mPath.append(iterator, false /* connect */); - } - - /** - * Add a copy of src to the path - * - * @param src The path that is appended to the current path - */ - public void addPath(Path src) { - addPath(src, 0, 0); - } - - /** - * Add a copy of src to the path, transformed by matrix - * - * @param src The path to add as a new contour - */ - public void addPath(Path src, Matrix matrix) { - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Offset the path by (dx,dy), returning true on success - * - * @param dx The amount in the X direction to offset the entire path - * @param dy The amount in the Y direction to offset the entire path - * @param dst The translated path is written here. If this is null, then - * the original path is modified. - */ - public void offset(float dx, float dy, Path dst) { - GeneralPath newPath = new GeneralPath(); - - PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy)); - - newPath.append(iterator, false /* connect */); - - if (dst != null) { - dst.mPath = newPath; - } else { - mPath = newPath; - } - } - - /** - * Offset the path by (dx,dy), returning true on success - * - * @param dx The amount in the X direction to offset the entire path - * @param dy The amount in the Y direction to offset the entire path - */ - public void offset(float dx, float dy) { - offset(dx, dy, null /* dst */); - } - - /** - * Sets the last point of the path. - * - * @param dx The new X coordinate for the last point - * @param dy The new Y coordinate for the last point - */ - public void setLastPoint(float dx, float dy) { - mLastX = dx; - mLastY = dy; - } - - /** - * Transform the points in this path by matrix, and write the answer - * into dst. If dst is null, then the the original path is modified. - * - * @param matrix The matrix to apply to the path - * @param dst The transformed path is written here. If dst is null, - * then the the original path is modified - */ - public void transform(Matrix matrix, Path dst) { - // FIXME - throw new UnsupportedOperationException(); - } - - /** - * Transform the points in this path by matrix. - * - * @param matrix The matrix to apply to the path - */ - public void transform(Matrix matrix) { - transform(matrix, null /* dst */); - } -} diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java deleted file mode 100644 index 974ae49..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import android.graphics.PorterDuff.Mode; - -public class PorterDuffXfermode extends Xfermode { - private final Mode mMode; - - /** - * Create an xfermode that uses the specified porter-duff mode. - * - * @param mode The porter-duff mode that is applied - */ - public PorterDuffXfermode(PorterDuff.Mode mode) { - mMode = mode; - } - - //---------- Custom Methods - - public PorterDuff.Mode getMode() { - return mMode; - } - - //---------- -} diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java deleted file mode 100644 index 61b693a..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -public class RadialGradient extends Shader { - - /** Create a shader that draws a radial gradient given the center and radius. - @param x The x-coordinate of the center of the radius - @param y The y-coordinate of the center of the radius - @param radius Must be positive. The radius of the circle for this gradient - @param colors The colors to be distributed between the center and edge of the circle - @param positions May be NULL. The relative position of - each corresponding color in the colors array. If this is NULL, - the the colors are distributed evenly between the center and edge of the circle. - @param tile The Shader tiling mode - */ - public RadialGradient(float x, float y, float radius, - int colors[], float positions[], TileMode tile) { - if (radius <= 0) { - throw new IllegalArgumentException("radius must be > 0"); - } - if (colors.length < 2) { - throw new IllegalArgumentException("needs >= 2 number of colors"); - } - if (positions != null && colors.length != positions.length) { - throw new IllegalArgumentException("color and position arrays must be of equal length"); - } - - // FIXME Implement shader - } - - /** Create a shader that draws a radial gradient given the center and radius. - @param x The x-coordinate of the center of the radius - @param y The y-coordinate of the center of the radius - @param radius Must be positive. The radius of the circle for this gradient - @param color0 The color at the center of the circle. - @param color1 The color at the edge of the circle. - @param tile The Shader tiling mode - */ - public RadialGradient(float x, float y, float radius, - int color0, int color1, TileMode tile) { - if (radius <= 0) { - throw new IllegalArgumentException("radius must be > 0"); - } - // FIXME Implement shader - } -} - diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader.java b/tools/layoutlib/bridge/src/android/graphics/Shader.java deleted file mode 100644 index 3a9fda5..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Shader.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -/** - * Shader is the based class for objects that return horizontal spans of colors - * during drawing. A subclass of Shader is installed in a Paint calling - * paint.setShader(shader). After that any object (other than a bitmap) that is - * drawn with that paint will get its color(s) from the shader. - */ -public class Shader { - - private final Matrix mMatrix = new Matrix(); - - public enum TileMode { - /** - * replicate the edge color if the shader draws outside of its - * original bounds - */ - CLAMP (0), - /** - * repeat the shader's image horizontally and vertically - */ - REPEAT (1), - /** - * repeat the shader's image horizontally and vertically, alternating - * mirror images so that adjacent images always seam - */ - MIRROR (2); - - TileMode(int nativeInt) { - this.nativeInt = nativeInt; - } - final int nativeInt; - } - - /** - * Return true if the shader has a non-identity local matrix. - * @param localM If not null, it is set to the shader's local matrix. - * @return true if the shader has a non-identity local matrix - */ - public boolean getLocalMatrix(Matrix localM) { - if (localM != null) { - localM.set(mMatrix); - } - - return !mMatrix.isIdentity(); - } - - /** - * Set the shader's local matrix. Passing null will reset the shader's - * matrix to identity - * @param localM The shader's new local matrix, or null to specify identity - */ - public void setLocalMatrix(Matrix localM) { - if (localM != null) { - mMatrix.set(localM); - } else { - mMatrix.reset(); - } - } -} diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java deleted file mode 100644 index e79e970..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -public class SweepGradient extends Shader { - - /** - * A subclass of Shader that draws a sweep gradient around a center point. - * - * @param cx The x-coordinate of the center - * @param cy The y-coordinate of the center - * @param colors The colors to be distributed between around the center. - * There must be at least 2 colors in the array. - * @param positions May be NULL. The relative position of - * each corresponding color in the colors array, beginning - * with 0 and ending with 1.0. If the values are not - * monotonic, the drawing may produce unexpected results. - * If positions is NULL, then the colors are automatically - * spaced evenly. - */ - public SweepGradient(float cx, float cy, - int colors[], float positions[]) { - if (colors.length < 2) { - throw new IllegalArgumentException("needs >= 2 number of colors"); - } - if (positions != null && colors.length != positions.length) { - throw new IllegalArgumentException( - "color and position arrays must be of equal length"); - } - - // FIXME Implement shader - } - - /** - * A subclass of Shader that draws a sweep gradient around a center point. - * - * @param cx The x-coordinate of the center - * @param cy The y-coordinate of the center - * @param color0 The color to use at the start of the sweep - * @param color1 The color to use at the end of the sweep - */ - public SweepGradient(float cx, float cy, int color0, int color1) { - // FIXME Implement shader - } -} - diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface.java b/tools/layoutlib/bridge/src/android/graphics/Typeface.java deleted file mode 100644 index e878b04..0000000 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import com.android.layoutlib.bridge.FontLoader; - -import android.content.res.AssetManager; - -import java.awt.Font; - -/** - * Re-implementation of Typeface over java.awt - */ -public class Typeface { - private static final String DEFAULT_FAMILY = "sans-serif"; - private static final int[] styleBuffer = new int[1]; - - /** The default NORMAL typeface object */ - public static Typeface DEFAULT; - /** - * The default BOLD typeface object. Note: this may be not actually be - * bold, depending on what fonts are installed. Call getStyle() to know - * for sure. - */ - public static Typeface DEFAULT_BOLD; - /** The NORMAL style of the default sans serif typeface. */ - public static Typeface SANS_SERIF; - /** The NORMAL style of the default serif typeface. */ - public static Typeface SERIF; - /** The NORMAL style of the default monospace typeface. */ - public static Typeface MONOSPACE; - - private static Typeface[] sDefaults; - private static FontLoader mFontLoader; - - private final int mStyle; - private final Font mFont; - private final String mFamily; - - // Style - public static final int NORMAL = _Original_Typeface.NORMAL; - public static final int BOLD = _Original_Typeface.BOLD; - public static final int ITALIC = _Original_Typeface.ITALIC; - public static final int BOLD_ITALIC = _Original_Typeface.BOLD_ITALIC; - - /** - * Returns the underlying {@link Font} object. - */ - public Font getFont() { - return mFont; - } - - /** Returns the typeface's intrinsic style attributes */ - public int getStyle() { - return mStyle; - } - - /** Returns true if getStyle() has the BOLD bit set. */ - public final boolean isBold() { - return (getStyle() & BOLD) != 0; - } - - /** Returns true if getStyle() has the ITALIC bit set. */ - public final boolean isItalic() { - return (getStyle() & ITALIC) != 0; - } - - /** - * Create a typeface object given a family name, and option style information. - * If null is passed for the name, then the "default" font will be chosen. - * The resulting typeface object can be queried (getStyle()) to discover what - * its "real" style characteristics are. - * - * @param familyName May be null. The name of the font family. - * @param style The style (normal, bold, italic) of the typeface. - * e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC - * @return The best matching typeface. - */ - public static Typeface create(String familyName, int style) { - styleBuffer[0] = style; - Font font = mFontLoader.getFont(familyName, styleBuffer); - if (font != null) { - return new Typeface(familyName, styleBuffer[0], font); - } - - return null; - } - - /** - * Create a typeface object that best matches the specified existing - * typeface and the specified Style. Use this call if you want to pick a new - * style from the same family of an existing typeface object. If family is - * null, this selects from the default font's family. - * - * @param family May be null. The name of the existing type face. - * @param style The style (normal, bold, italic) of the typeface. - * e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC - * @return The best matching typeface. - */ - public static Typeface create(Typeface family, int style) { - styleBuffer[0] = style; - Font font = mFontLoader.getFont(family.mFamily, styleBuffer); - if (font != null) { - return new Typeface(family.mFamily, styleBuffer[0], font); - } - - return null; - } - - /** - * Returns one of the default typeface objects, based on the specified style - * - * @return the default typeface that corresponds to the style - */ - public static Typeface defaultFromStyle(int style) { - return sDefaults[style]; - } - - /** - * Create a new typeface from the specified font data. - * @param mgr The application's asset manager - * @param path The file name of the font data in the assets directory - * @return The new typeface. - */ - public static Typeface createFromAsset(AssetManager mgr, String path) { - return null; - //return new Typeface(nativeCreateFromAsset(mgr, path)); - } - - // don't allow clients to call this directly - private Typeface(String family, int style, Font f) { - mFamily = family; - mFont = f; - mStyle = style; - } - - public static void init(FontLoader fontLoader) { - mFontLoader = fontLoader; - - DEFAULT = create(DEFAULT_FAMILY, NORMAL); - DEFAULT_BOLD = create(DEFAULT_FAMILY, BOLD); - SANS_SERIF = create("sans-serif", NORMAL); - SERIF = create("serif", NORMAL); - MONOSPACE = create("monospace", NORMAL); - sDefaults = new Typeface[] { - DEFAULT, - DEFAULT_BOLD, - create(DEFAULT_FAMILY, ITALIC), - create(DEFAULT_FAMILY, BOLD_ITALIC), - }; - - /* - DEFAULT = create((String)null, 0); - DEFAULT_BOLD = create((String)null, Typeface.BOLD); - SANS_SERIF = create("sans-serif", 0); - SERIF = create("serif", 0); - MONOSPACE = create("monospace", 0); - - sDefaults = new Typeface[] { - DEFAULT, - DEFAULT_BOLD, - create((String)null, Typeface.ITALIC), - create((String)null, Typeface.BOLD_ITALIC), - };*/ - } -} diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath.java b/tools/layoutlib/bridge/src/android/util/FloatMath.java deleted file mode 100644 index aae44f2..0000000 --- a/tools/layoutlib/bridge/src/android/util/FloatMath.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.util; - -/** - * Reimplements _Original_FloatMath with the standard libraries. - * - * Math routines similar to those found in {@link java.lang.Math}. Performs - * computations on {@code float} values directly without incurring the overhead - * of conversions to and from {@code double}. - * - * <p>On one platform, {@code FloatMath.sqrt(100)} executes in one third of the - * time required by {@code java.lang.Math.sqrt(100)}.</p> - */ -public class FloatMath { - - /** Prevents instantiation. */ - private FloatMath() {} - - /** - * Returns the float conversion of the most positive (i.e. closest to - * positive infinity) integer value which is less than the argument. - * - * @param value to be converted - * @return the floor of value - */ - public static float floor(float value) { - return (float)Math.floor(value); - } - - /** - * Returns the float conversion of the most negative (i.e. closest to - * negative infinity) integer value which is greater than the argument. - * - * @param value to be converted - * @return the ceiling of value - */ - public static float ceil(float value) { - return (float)Math.ceil(value); - } - - /** - * Returns the closest float approximation of the sine of the argument. - * - * @param angle to compute the cosine of, in radians - * @return the sine of angle - */ - public static float sin(float angle) { - return (float)Math.sin(angle); - } - - /** - * Returns the closest float approximation of the cosine of the argument. - * - * @param angle to compute the cosine of, in radians - * @return the cosine of angle - */ - public static float cos(float angle) { - return (float)Math.cos(angle); - } - - /** - * Returns the closest float approximation of the square root of the - * argument. - * - * @param value to compute sqrt of - * @return the square root of value - */ - public static float sqrt(float value) { - return (float)Math.sqrt(value); - } -} diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java deleted file mode 100644 index 0910d79..0000000 --- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view; - -import com.android.layoutlib.api.IProjectCallback; -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.bridge.Bridge; -import com.android.layoutlib.bridge.BridgeConstants; -import com.android.layoutlib.bridge.BridgeContext; -import com.android.layoutlib.bridge.BridgeXmlBlockParser; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; - -import android.content.Context; -import android.util.AttributeSet; - -import java.io.File; -import java.io.FileReader; - -/** - * Custom implementation of {@link LayoutInflater} to handle custom views. - */ -public final class BridgeInflater extends LayoutInflater { - - private final IProjectCallback mProjectCallback; - - /** - * List of class prefixes which are tried first by default. - * <p/> - * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater. - */ - private static final String[] sClassPrefixList = { - "android.widget.", - "android.webkit." - }; - - protected BridgeInflater(LayoutInflater original, Context newContext) { - super(original, newContext); - mProjectCallback = null; - } - - /** - * Instantiate a new BridgeInflater with an {@link IProjectCallback} object. - * - * @param context The Android application context. - * @param projectCallback the {@link IProjectCallback} object. - */ - public BridgeInflater(Context context, IProjectCallback projectCallback) { - super(context); - mProjectCallback = projectCallback; - mConstructorArgs[0] = context; - } - - @Override - public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException { - View view = null; - - try { - // First try to find a class using the default Android prefixes - for (String prefix : sClassPrefixList) { - try { - view = createView(name, prefix, attrs); - if (view != null) { - break; - } - } catch (ClassNotFoundException e) { - // Ignore. We'll try again using the base class below. - } - } - - // Next try using the parent loader. This will most likely only work for - // fully-qualified class names. - try { - if (view == null) { - view = super.onCreateView(name, attrs); - } - } catch (ClassNotFoundException e) { - // Ignore. We'll try again using the custom view loader below. - } - - // Finally try again using the custom view loader - try { - if (view == null) { - view = loadCustomView(name, attrs); - } - } catch (ClassNotFoundException e) { - // If the class was not found, we throw the exception directly, because this - // method is already expected to throw it. - throw e; - } - } catch (Exception e) { - // Wrap the real exception in a ClassNotFoundException, so that the calling method - // can deal with it. - ClassNotFoundException exception = new ClassNotFoundException("onCreateView", e); - throw exception; - } - - setupViewInContext(view, attrs); - - return view; - } - - @Override - public View createViewFromTag(String name, AttributeSet attrs) { - View view = null; - try { - view = super.createViewFromTag(name, attrs); - } catch (InflateException e) { - // try to load the class from using the custom view loader - try { - view = loadCustomView(name, attrs); - } catch (Exception e2) { - // Wrap the real exception in an InflateException so that the calling - // method can deal with it. - InflateException exception = new InflateException(); - if (e2.getClass().equals(ClassNotFoundException.class) == false) { - exception.initCause(e2); - } else { - exception.initCause(e); - } - throw exception; - } - } - - setupViewInContext(view, attrs); - - return view; - } - - @Override - public View inflate(int resource, ViewGroup root) { - Context context = getContext(); - if (context instanceof BridgeContext) { - BridgeContext bridgeContext = (BridgeContext)context; - - IResourceValue value = null; - - String[] layoutInfo = Bridge.resolveResourceValue(resource); - if (layoutInfo != null) { - value = bridgeContext.getFrameworkResource(BridgeConstants.RES_LAYOUT, - layoutInfo[0]); - } else { - layoutInfo = mProjectCallback.resolveResourceValue(resource); - - if (layoutInfo != null) { - value = bridgeContext.getProjectResource(BridgeConstants.RES_LAYOUT, - layoutInfo[0]); - } - } - - if (value != null) { - File f = new File(value.getValue()); - if (f.isFile()) { - try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(f)); - - BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( - parser, bridgeContext, false); - - return inflate(bridgeParser, root); - } catch (Exception e) { - bridgeContext.getLogger().error(e); - // return null below. - } - } - } - } - return null; - } - - private View loadCustomView(String name, AttributeSet attrs) throws ClassNotFoundException, - Exception{ - if (mProjectCallback != null) { - // first get the classname in case it's not the node name - if (name.equals("view")) { - name = attrs.getAttributeValue(null, "class"); - } - - mConstructorArgs[1] = attrs; - - Object customView = mProjectCallback.loadView(name, mConstructorSignature, - mConstructorArgs); - - if (customView instanceof View) { - return (View)customView; - } - } - - return null; - } - - - - private void setupViewInContext(View view, AttributeSet attrs) { - if (getContext() instanceof BridgeContext) { - BridgeContext bc = (BridgeContext) getContext(); - if (attrs instanceof BridgeXmlBlockParser) { - Object viewKey = ((BridgeXmlBlockParser) attrs).getViewKey(); - if (viewKey != null) { - bc.addViewKey(view, viewKey); - } - } - } - } - - @Override - public LayoutInflater cloneInContext(Context newContext) { - return new BridgeInflater(this, newContext); - } -} diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java deleted file mode 100644 index ce32da9..0000000 --- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view; - -import com.android.layoutlib.bridge.MockView; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.util.AttributeSet; - -/** - * Mock version of the SurfaceView. - * Only non override public methods from the real SurfaceView have been added in there. - * Methods that take an unknown class as parameter or as return object, have been removed for now. - * - * TODO: generate automatically. - * - */ -public class SurfaceView extends MockView { - - public SurfaceView(Context context) { - this(context, null); - } - - public SurfaceView(Context context, AttributeSet attrs) { - this(context, attrs , 0); - } - - public SurfaceView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public SurfaceHolder getHolder() { - return mSurfaceHolder; - } - - private SurfaceHolder mSurfaceHolder = new SurfaceHolder() { - - public boolean isCreating() { - return false; - } - - public void addCallback(Callback callback) { - } - - public void removeCallback(Callback callback) { - } - - public void setFixedSize(int width, int height) { - } - - public void setSizeFromLayout() { - } - - public void setFormat(int format) { - } - - public void setType(int type) { - } - - public void setKeepScreenOn(boolean screenOn) { - } - - public Canvas lockCanvas() { - return null; - } - - public Canvas lockCanvas(Rect dirty) { - return null; - } - - public void unlockCanvasAndPost(Canvas canvas) { - } - - public Surface getSurface() { - return null; - } - - public Rect getSurfaceFrame() { - return null; - } - }; -} - diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java deleted file mode 100644 index 42e4dfa..0000000 --- a/tools/layoutlib/bridge/src/android/webkit/WebView.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.webkit; - -import com.android.layoutlib.bridge.MockView; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Picture; -import android.os.Bundle; -import android.os.Message; -import android.util.AttributeSet; -import android.view.View; - -/** - * Mock version of the WebView. - * Only non override public methods from the real WebView have been added in there. - * Methods that take an unknown class as parameter or as return object, have been removed for now. - * - * TODO: generate automatically. - * - */ -public class WebView extends MockView { - - /** - * Construct a new WebView with a Context object. - * @param context A Context object used to access application assets. - */ - public WebView(Context context) { - this(context, null); - } - - /** - * Construct a new WebView with layout parameters. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - */ - public WebView(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.webViewStyle); - } - - /** - * Construct a new WebView with layout parameters and a default style. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - * @param defStyle The default style resource ID. - */ - public WebView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - // START FAKE PUBLIC METHODS - - public void setHorizontalScrollbarOverlay(boolean overlay) { - } - - public void setVerticalScrollbarOverlay(boolean overlay) { - } - - public boolean overlayHorizontalScrollbar() { - return false; - } - - public boolean overlayVerticalScrollbar() { - return false; - } - - public void savePassword(String host, String username, String password) { - } - - public void setHttpAuthUsernamePassword(String host, String realm, - String username, String password) { - } - - public String[] getHttpAuthUsernamePassword(String host, String realm) { - return null; - } - - public void destroy() { - } - - public static void enablePlatformNotifications() { - } - - public static void disablePlatformNotifications() { - } - - public WebBackForwardList saveState(Bundle outState) { - return null; - } - - public WebBackForwardList restoreState(Bundle inState) { - return null; - } - - public void loadUrl(String url) { - } - - public void loadData(String data, String mimeType, String encoding) { - } - - public void loadDataWithBaseURL(String baseUrl, String data, - String mimeType, String encoding, String failUrl) { - } - - public void stopLoading() { - } - - public void reload() { - } - - public boolean canGoBack() { - return false; - } - - public void goBack() { - } - - public boolean canGoForward() { - return false; - } - - public void goForward() { - } - - public boolean canGoBackOrForward(int steps) { - return false; - } - - public void goBackOrForward(int steps) { - } - - public boolean pageUp(boolean top) { - return false; - } - - public boolean pageDown(boolean bottom) { - return false; - } - - public void clearView() { - } - - public Picture capturePicture() { - return null; - } - - public float getScale() { - return 0; - } - - public void setInitialScale(int scaleInPercent) { - } - - public void invokeZoomPicker() { - } - - public void requestFocusNodeHref(Message hrefMsg) { - } - - public void requestImageRef(Message msg) { - } - - public String getUrl() { - return null; - } - - public String getTitle() { - return null; - } - - public Bitmap getFavicon() { - return null; - } - - public int getProgress() { - return 0; - } - - public int getContentHeight() { - return 0; - } - - public void pauseTimers() { - } - - public void resumeTimers() { - } - - public void clearCache() { - } - - public void clearFormData() { - } - - public void clearHistory() { - } - - public void clearSslPreferences() { - } - - public WebBackForwardList copyBackForwardList() { - return null; - } - - public static String findAddress(String addr) { - return null; - } - - public void documentHasImages(Message response) { - } - - public void setWebViewClient(WebViewClient client) { - } - - public void setDownloadListener(DownloadListener listener) { - } - - public void setWebChromeClient(WebChromeClient client) { - } - - public void addJavascriptInterface(Object obj, String interfaceName) { - } - - public WebSettings getSettings() { - return null; - } - - public static synchronized PluginList getPluginList() { - return null; - } - - public void refreshPlugins(boolean reloadOpenPages) { - } - - public View getZoomControls() { - return null; - } - - public boolean zoomIn() { - return false; - } - - public boolean zoomOut() { - return false; - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java deleted file mode 100644 index 82fe365..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ /dev/null @@ -1,900 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.internal.util.XmlUtils; -import com.android.layoutlib.api.ILayoutBridge; -import com.android.layoutlib.api.ILayoutLog; -import com.android.layoutlib.api.ILayoutResult; -import com.android.layoutlib.api.IProjectCallback; -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; -import com.android.layoutlib.api.IXmlPullParser; -import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo; -import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo; -import com.android.ninepatch.NinePatch; -import com.android.tools.layoutlib.create.MethodAdapter; -import com.android.tools.layoutlib.create.OverrideMethod; - -import android.graphics.Bitmap; -import android.graphics.Rect; -import android.graphics.Region; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.util.TypedValue; -import android.view.BridgeInflater; -import android.view.IWindow; -import android.view.IWindowSession; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.Surface; -import android.view.SurfaceView; -import android.view.View; -import android.view.ViewGroup; -import android.view.View.AttachInfo; -import android.view.View.MeasureSpec; -import android.view.WindowManager.LayoutParams; -import android.widget.FrameLayout; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Main entry point of the LayoutLib Bridge. - * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call - * {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}. - */ -public final class Bridge implements ILayoutBridge { - - private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; - private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; - - public static class StaticMethodNotImplementedException extends RuntimeException { - public StaticMethodNotImplementedException(String msg) { - super(msg); - } - } - - /** - * Maps from id to resource name/type. - */ - private final static Map<Integer, String[]> sRMap = new HashMap<Integer, String[]>(); - /** - * Same as sRMap except for int[] instead of int resources. - */ - private final static Map<int[], String> sRArrayMap = new HashMap<int[], String>(); - /** - * Reverse map compared to sRMap, resource type -> (resource name -> id) - */ - private final static Map<String, Map<String, Integer>> sRFullMap = - new HashMap<String, Map<String,Integer>>(); - - private final static Map<Object, Map<String, Bitmap>> sProjectBitmapCache = - new HashMap<Object, Map<String, Bitmap>>(); - private final static Map<Object, Map<String, NinePatch>> sProject9PatchCache = - new HashMap<Object, Map<String, NinePatch>>(); - - private final static Map<String, Bitmap> sFrameworkBitmapCache = new HashMap<String, Bitmap>(); - private final static Map<String, NinePatch> sFramework9PatchCache = - new HashMap<String, NinePatch>(); - - private static Map<String, Map<String, Integer>> sEnumValueMap; - - /** - * A default logger than prints to stdout/stderr. - */ - private final static ILayoutLog sDefaultLogger = new ILayoutLog() { - public void error(String message) { - System.err.println(message); - } - - public void error(Throwable t) { - String message = t.getMessage(); - if (message == null) { - message = t.getClass().getName(); - } - - System.err.println(message); - } - - public void warning(String message) { - System.out.println(message); - } - }; - - /** - * Logger defined during a compute layout operation. - * <p/> - * This logger is generally set to {@link #sDefaultLogger} except during rendering - * operations when it might be set to a specific provided logger. - * <p/> - * To change this value, use a block synchronized on {@link #sDefaultLogger}. - */ - private static ILayoutLog sLogger = sDefaultLogger; - - /* - * (non-Javadoc) - * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel() - */ - public int getApiLevel() { - return API_CURRENT; - } - - /* - * (non-Javadoc) - * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map) - */ - public boolean init( - String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) { - - return sinit(fontOsLocation, enumValueMap); - } - - private static synchronized boolean sinit(String fontOsLocation, - Map<String, Map<String, Integer>> enumValueMap) { - - // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener - // on static (native) methods which prints the signature on the console and - // throws an exception. - // This is useful when testing the rendering in ADT to identify static native - // methods that are ignored -- layoutlib_create makes them returns 0/false/null - // which is generally OK yet might be a problem, so this is how you'd find out. - // - // Currently layoutlib_create only overrides static native method. - // Static non-natives are not overridden and thus do not get here. - final String debug = System.getenv("DEBUG_LAYOUT"); - if (debug != null && !debug.equals("0") && !debug.equals("false")) { - - OverrideMethod.setDefaultListener(new MethodAdapter() { - @Override - public void onInvokeV(String signature, boolean isNative, Object caller) { - if (sLogger != null) { - synchronized (sDefaultLogger) { - sLogger.error("Missing Stub: " + signature + - (isNative ? " (native)" : "")); - } - } - - if (debug.equalsIgnoreCase("throw")) { - // Throwing this exception doesn't seem that useful. It breaks - // the layout editor yet doesn't display anything meaningful to the - // user. Having the error in the console is just as useful. We'll - // throw it only if the environment variable is "throw" or "THROW". - throw new StaticMethodNotImplementedException(signature); - } - } - }); - } - - // Override View.isInEditMode to return true. - // - // This allows custom views that are drawn in the Graphical Layout Editor to adapt their - // rendering for preview. Most important this let custom views know that they can't expect - // the rest of their activities to be alive. - OverrideMethod.setMethodListener("android.view.View#isInEditMode()Z", - new MethodAdapter() { - @Override - public int onInvokeI(String signature, boolean isNative, Object caller) { - return 1; - } - } - ); - - // load the fonts. - FontLoader fontLoader = FontLoader.create(fontOsLocation); - if (fontLoader != null) { - Typeface.init(fontLoader); - } else { - return false; - } - - sEnumValueMap = enumValueMap; - - // now parse com.android.internal.R (and only this one as android.R is a subset of - // the internal version), and put the content in the maps. - try { - // WARNING: this only works because the class is already loaded, and therefore - // the objects returned by Field.get() are the same as the ones used by - // the code accessing the R class. - // int[] does not implement equals/hashCode, and if the parsing used a different class - // loader for the R class, this would NOT work. - Class<?> r = com.android.internal.R.class; - - for (Class<?> inner : r.getDeclaredClasses()) { - String resType = inner.getSimpleName(); - - Map<String, Integer> fullMap = new HashMap<String, Integer>(); - sRFullMap.put(resType, fullMap); - - for (Field f : inner.getDeclaredFields()) { - // only process static final fields. Since the final attribute may have - // been altered by layoutlib_create, we only check static - int modifiers = f.getModifiers(); - if (Modifier.isStatic(modifiers)) { - Class<?> type = f.getType(); - if (type.isArray() && type.getComponentType() == int.class) { - // if the object is an int[] we put it in sRArrayMap - sRArrayMap.put((int[]) f.get(null), f.getName()); - } else if (type == int.class) { - Integer value = (Integer) f.get(null); - sRMap.put(value, new String[] { f.getName(), resType }); - fullMap.put(f.getName(), value); - } else { - assert false; - } - } - } - } - } catch (IllegalArgumentException e) { - // FIXME: log/return the error (there's no logger object at this point!) - e.printStackTrace(); - return false; - } catch (IllegalAccessException e) { - e.printStackTrace(); - return false; - } - - return true; - } - - /* - * For compatilibty purposes, we implement the old deprecated version of computeLayout. - * (non-Javadoc) - * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog) - */ - @Deprecated - public ILayoutResult computeLayout(IXmlPullParser layoutDescription, - Object projectKey, - int screenWidth, int screenHeight, String themeName, - Map<String, Map<String, IResourceValue>> projectResources, - Map<String, Map<String, IResourceValue>> frameworkResources, - IProjectCallback customViewLoader, ILayoutLog logger) { - boolean isProjectTheme = false; - if (themeName.charAt(0) == '*') { - themeName = themeName.substring(1); - isProjectTheme = true; - } - - return computeLayout(layoutDescription, projectKey, screenWidth, screenHeight, themeName, isProjectTheme, - projectResources, frameworkResources, customViewLoader, logger); - } - - /* - * (non-Javadoc) - * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog) - */ - public ILayoutResult computeLayout(IXmlPullParser layoutDescription, - Object projectKey, - int screenWidth, int screenHeight, String themeName, boolean isProjectTheme, - Map<String, Map<String, IResourceValue>> projectResources, - Map<String, Map<String, IResourceValue>> frameworkResources, - IProjectCallback customViewLoader, ILayoutLog logger) { - if (logger == null) { - logger = sDefaultLogger; - } - - synchronized (sDefaultLogger) { - sLogger = logger; - } - - // find the current theme and compute the style inheritance map - Map<IStyleResourceValue, IStyleResourceValue> styleParentMap = - new HashMap<IStyleResourceValue, IStyleResourceValue>(); - - IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme, - projectResources.get(BridgeConstants.RES_STYLE), - frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap); - - BridgeContext context = null; - try { - context = new BridgeContext(projectKey, currentTheme, projectResources, - frameworkResources, styleParentMap, customViewLoader, logger); - BridgeInflater inflater = new BridgeInflater(context, customViewLoader); - context.setBridgeInflater(inflater); - - IResourceValue windowBackground = null; - int screenOffset = 0; - if (currentTheme != null) { - windowBackground = context.findItemInStyle(currentTheme, "windowBackground"); - windowBackground = context.resolveResValue(windowBackground); - - screenOffset = getScreenOffset(currentTheme, context); - } - - // we need to make sure the Looper has been initialized for this thread. - // this is required for View that creates Handler objects. - if (Looper.myLooper() == null) { - Looper.prepare(); - } - - BridgeXmlBlockParser parser = new BridgeXmlBlockParser(layoutDescription, - context, false /* platformResourceFlag */); - - ViewGroup root = new FrameLayout(context); - - View view = inflater.inflate(parser, root); - - // set the AttachInfo on the root view. - AttachInfo info = new AttachInfo(new WindowSession(), new Window(), - new Handler(), null); - info.mHasWindowFocus = true; - info.mWindowVisibility = View.VISIBLE; - info.mInTouchMode = false; // this is so that we can display selections. - root.dispatchAttachedToWindow(info, 0); - - // get the background drawable - if (windowBackground != null) { - Drawable d = ResourceHelper.getDrawable(windowBackground.getValue(), - context, true /* isFramework */); - root.setBackgroundDrawable(d); - } - - int w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY); - int h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset, - MeasureSpec.EXACTLY); - - // measure the views - view.measure(w_spec, h_spec); - view.layout(0, screenOffset, screenWidth, screenHeight); - - // draw them - BridgeCanvas canvas = new BridgeCanvas(screenWidth, screenHeight - screenOffset, - logger); - - root.draw(canvas); - canvas.dispose(); - - return new LayoutResult(visit(((ViewGroup)view).getChildAt(0), context), - canvas.getImage()); - } catch (Throwable e) { - // get the real cause of the exception. - Throwable t = e; - while (t.getCause() != null) { - t = t.getCause(); - } - - // log it - logger.error(t); - - // then return with an ERROR status and the message from the real exception - return new LayoutResult(ILayoutResult.ERROR, - t.getClass().getSimpleName() + ": " + t.getMessage()); - } finally { - // Make sure to remove static references, otherwise we could not unload the lib - BridgeResources.clearSystem(); - BridgeAssetManager.clearSystem(); - - // Remove the global logger - synchronized (sDefaultLogger) { - sLogger = sDefaultLogger; - } - } - } - - /* - * (non-Javadoc) - * @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object) - */ - public void clearCaches(Object projectKey) { - if (projectKey != null) { - sProjectBitmapCache.remove(projectKey); - sProject9PatchCache.remove(projectKey); - } - } - - /** - * Returns details of a framework resource from its integer value. - * @param value the integer value - * @return an array of 2 strings containing the resource name and type, or null if the id - * does not match any resource. - */ - public static String[] resolveResourceValue(int value) { - return sRMap.get(value); - - } - - /** - * Returns the name of a framework resource whose value is an int array. - * @param array - */ - public static String resolveResourceValue(int[] array) { - return sRArrayMap.get(array); - } - - /** - * Returns the integer id of a framework resource, from a given resource type and resource name. - * @param type the type of the resource - * @param name the name of the resource. - * @return an {@link Integer} containing the resource id, or null if no resource were found. - */ - public static Integer getResourceValue(String type, String name) { - Map<String, Integer> map = sRFullMap.get(type); - if (map != null) { - return map.get(name); - } - - return null; - } - - static Map<String, Integer> getEnumValues(String attributeName) { - if (sEnumValueMap != null) { - return sEnumValueMap.get(attributeName); - } - - return null; - } - - /** - * Visits a View and its children and generate a {@link ILayoutViewInfo} containing the - * bounds of all the views. - * @param view the root View - * @param context the context. - */ - private ILayoutViewInfo visit(View view, BridgeContext context) { - if (view == null) { - return null; - } - - LayoutViewInfo result = new LayoutViewInfo(view.getClass().getName(), - context.getViewKey(view), - view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); - - if (view instanceof ViewGroup) { - ViewGroup group = ((ViewGroup) view); - int n = group.getChildCount(); - ILayoutViewInfo[] children = new ILayoutViewInfo[n]; - for (int i = 0; i < group.getChildCount(); i++) { - children[i] = visit(group.getChildAt(i), context); - } - result.setChildren(children); - } - - return result; - } - - /** - * Compute style information from the given list of style for the project and framework. - * @param themeName the name of the current theme. In order to differentiate project and - * platform themes sharing the same name, all project themes must be prepended with - * a '*' character. - * @param isProjectTheme Is this a project theme - * @param inProjectStyleMap the project style map - * @param inFrameworkStyleMap the framework style map - * @param outInheritanceMap the map of style inheritance. This is filled by the method - * @return the {@link IStyleResourceValue} matching <var>themeName</var> - */ - private IStyleResourceValue computeStyleMaps( - String themeName, boolean isProjectTheme, Map<String, - IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap, - Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) { - - if (inProjectStyleMap != null && inFrameworkStyleMap != null) { - // first, get the theme - IResourceValue theme = null; - - // project theme names have been prepended with a * - if (isProjectTheme) { - theme = inProjectStyleMap.get(themeName); - } else { - theme = inFrameworkStyleMap.get(themeName); - } - - if (theme instanceof IStyleResourceValue) { - // compute the inheritance map for both the project and framework styles - computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap, - inFrameworkStyleMap, outInheritanceMap); - - // Compute the style inheritance for the framework styles/themes. - // Since, for those, the style parent values do not contain 'android:' - // we want to force looking in the framework style only to avoid using - // similarly named styles from the project. - // To do this, we pass null in lieu of the project style map. - computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */, - inFrameworkStyleMap, outInheritanceMap); - - return (IStyleResourceValue)theme; - } - } - - return null; - } - - /** - * Compute the parent style for all the styles in a given list. - * @param styles the styles for which we compute the parent. - * @param inProjectStyleMap the map of project styles. - * @param inFrameworkStyleMap the map of framework styles. - * @param outInheritanceMap the map of style inheritance. This is filled by the method. - */ - private void computeStyleInheritance(Collection<IResourceValue> styles, - Map<String, IResourceValue> inProjectStyleMap, - Map<String, IResourceValue> inFrameworkStyleMap, - Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) { - for (IResourceValue value : styles) { - if (value instanceof IStyleResourceValue) { - IStyleResourceValue style = (IStyleResourceValue)value; - IStyleResourceValue parentStyle = null; - - // first look for a specified parent. - String parentName = style.getParentStyle(); - - // no specified parent? try to infer it from the name of the style. - if (parentName == null) { - parentName = getParentName(value.getName()); - } - - if (parentName != null) { - parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap); - - if (parentStyle != null) { - outInheritanceMap.put(style, parentStyle); - } - } - } - } - } - - /** - * Searches for and returns the {@link IStyleResourceValue} from a given name. - * <p/>The format of the name can be: - * <ul> - * <li>[android:]<name></li> - * <li>[android:]style/<name></li> - * <li>@[android:]style/<name></li> - * </ul> - * @param parentName the name of the style. - * @param inProjectStyleMap the project style map. Can be <code>null</code> - * @param inFrameworkStyleMap the framework style map. - * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found. - */ - private IStyleResourceValue getStyle(String parentName, - Map<String, IResourceValue> inProjectStyleMap, - Map<String, IResourceValue> inFrameworkStyleMap) { - boolean frameworkOnly = false; - - String name = parentName; - - // remove the useless @ if it's there - if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) { - name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length()); - } - - // check for framework identifier. - if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) { - frameworkOnly = true; - name = name.substring(BridgeConstants.PREFIX_ANDROID.length()); - } - - // at this point we could have the format style/<name>. we want only the name - if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) { - name = name.substring(BridgeConstants.REFERENCE_STYLE.length()); - } - - IResourceValue parent = null; - - // if allowed, search in the project resources. - if (frameworkOnly == false && inProjectStyleMap != null) { - parent = inProjectStyleMap.get(name); - } - - // if not found, then look in the framework resources. - if (parent == null) { - parent = inFrameworkStyleMap.get(name); - } - - // make sure the result is the proper class type and return it. - if (parent instanceof IStyleResourceValue) { - return (IStyleResourceValue)parent; - } - - sLogger.error(String.format("Unable to resolve parent style name: ", parentName)); - - return null; - } - - /** - * Computes the name of the parent style, or <code>null</code> if the style is a root style. - */ - private String getParentName(String styleName) { - int index = styleName.lastIndexOf('.'); - if (index != -1) { - return styleName.substring(0, index); - } - - return null; - } - - /** - * Returns the top screen offset. This depends on whether the current theme defines the user - * of the title and status bars. - * @return the pixel height offset - */ - private int getScreenOffset(IStyleResourceValue currentTheme, BridgeContext context) { - int offset = 0; - - // get the title bar flag from the current theme. - IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle"); - - // because it may reference something else, we resolve it. - value = context.resolveResValue(value); - - // if there's a value and it's true (default is false) - if (value == null || value.getValue() == null || - XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) { - // get value from the theme. - value = context.findItemInStyle(currentTheme, "windowTitleSize"); - - // resolve it - value = context.resolveResValue(value); - - // default value - offset = DEFAULT_TITLE_BAR_HEIGHT; - - // get the real value; - if (value != null) { - TypedValue typedValue = ResourceHelper.getValue(value.getValue()); - if (typedValue != null) { - offset = (int)typedValue.getDimension(context.getResources().mMetrics); - } - } - } - - // get the fullscreen flag from the current theme. - value = context.findItemInStyle(currentTheme, "windowFullscreen"); - - // because it may reference something else, we resolve it. - value = context.resolveResValue(value); - - if (value == null || value.getValue() == null || - XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) { - // FIXME: Right now this is hard-coded in the platform, but once there's a constant, we'll need to use it. - offset += DEFAULT_STATUS_BAR_HEIGHT; - } - - return offset; - } - - /** - * Returns the bitmap for a specific path, from a specific project cache, or from the - * framework cache. - * @param value the path of the bitmap - * @param projectKey the key of the project, or null to query the framework cache. - * @return the cached Bitmap or null if not found. - */ - static Bitmap getCachedBitmap(String value, Object projectKey) { - if (projectKey != null) { - Map<String, Bitmap> map = sProjectBitmapCache.get(projectKey); - if (map != null) { - return map.get(value); - } - - return null; - } - - return sFrameworkBitmapCache.get(value); - } - - /** - * Sets a bitmap in a project cache or in the framework cache. - * @param value the path of the bitmap - * @param bmp the Bitmap object - * @param projectKey the key of the project, or null to put the bitmap in the framework cache. - */ - static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) { - if (projectKey != null) { - Map<String, Bitmap> map = sProjectBitmapCache.get(projectKey); - - if (map == null) { - map = new HashMap<String, Bitmap>(); - sProjectBitmapCache.put(projectKey, map); - } - - map.put(value, bmp); - } - - sFrameworkBitmapCache.put(value, bmp); - } - - /** - * Returns the 9 patch for a specific path, from a specific project cache, or from the - * framework cache. - * @param value the path of the 9 patch - * @param projectKey the key of the project, or null to query the framework cache. - * @return the cached 9 patch or null if not found. - */ - static NinePatch getCached9Patch(String value, Object projectKey) { - if (projectKey != null) { - Map<String, NinePatch> map = sProject9PatchCache.get(projectKey); - - if (map != null) { - return map.get(value); - } - - return null; - } - - return sFramework9PatchCache.get(value); - } - - /** - * Sets a 9 patch in a project cache or in the framework cache. - * @param value the path of the 9 patch - * @param ninePatch the 9 patch object - * @param projectKey the key of the project, or null to put the bitmap in the framework cache. - */ - static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) { - if (projectKey != null) { - Map<String, NinePatch> map = sProject9PatchCache.get(projectKey); - - if (map == null) { - map = new HashMap<String, NinePatch>(); - sProject9PatchCache.put(projectKey, map); - } - - map.put(value, ninePatch); - } - - sFramework9PatchCache.put(value, ninePatch); - } - - /** - * Implementation of {@link IWindowSession} so that mSession is not null in - * the {@link SurfaceView}. - */ - private static final class WindowSession implements IWindowSession { - - @SuppressWarnings("unused") - public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3) - throws RemoteException { - // pass for now. - return 0; - } - - @SuppressWarnings("unused") - public void finishDrawing(IWindow arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void finishKey(IWindow arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public boolean getInTouchMode() throws RemoteException { - // pass for now. - return false; - } - - @SuppressWarnings("unused") - public boolean performHapticFeedback(IWindow window, int effectId, boolean always) { - // pass for now. - return false; - } - - @SuppressWarnings("unused") - public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException { - // pass for now. - return null; - } - - @SuppressWarnings("unused") - public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException { - // pass for now. - return null; - } - - @SuppressWarnings("unused") - public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4, - boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Surface arg8) - throws RemoteException { - // pass for now. - return 0; - } - - public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { - // pass for now. - } - - @SuppressWarnings("unused") - public void remove(IWindow arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void setInTouchMode(boolean arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException { - // pass for now. - } - - public void setInsets(IWindow window, int touchable, Rect contentInsets, - Rect visibleInsets) { - // pass for now. - } - - public IBinder asBinder() { - // pass for now. - return null; - } - } - - /** - * Implementation of {@link IWindow} to pass to the {@link AttachInfo}. - */ - private static final class Window implements IWindow { - - @SuppressWarnings("unused") - public void dispatchAppVisibility(boolean arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void dispatchGetNewSurface() throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void dispatchKey(KeyEvent arg0) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void dispatchPointer(MotionEvent arg0, long arg1) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void dispatchTrackball(MotionEvent arg0, long arg1) throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2) - throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4) - throws RemoteException { - // pass for now. - } - - @SuppressWarnings("unused") - public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException { - // pass for now. - } - - public IBinder asBinder() { - // pass for now. - return null; - } - } - -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java deleted file mode 100644 index 1fa11af..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import android.content.res.AssetManager; -import android.content.res.Configuration; - -import java.util.Locale; - -public class BridgeAssetManager extends AssetManager { - - /** - * This initializes the static field {@link AssetManager#mSystem} which is used - * by methods who get a global asset manager using {@link AssetManager#getSystem()}. - * <p/> - * They will end up using our bridge asset manager. - * <p/> - * {@link Bridge} calls this method after setting up a new bridge. - */ - /*package*/ static AssetManager initSystem() { - if (!(AssetManager.mSystem instanceof BridgeAssetManager)) { - // Note that AssetManager() creates a system AssetManager and we override it - // with our BridgeAssetManager. - AssetManager.mSystem = new BridgeAssetManager(); - AssetManager.mSystem.makeStringBlocks(false); - } - return AssetManager.mSystem; - } - - /** - * Clears the static {@link AssetManager#mSystem} to make sure we don't leave objects - * around that would prevent us from unloading the library. - */ - /*package*/ static void clearSystem() { - AssetManager.mSystem = null; - } - - private BridgeAssetManager() { - } - - /** - * Change the configuration used when retrieving resources. Not for use by applications. - */ - @Override - public void setConfiguration(int mcc, int mnc, String locale, - int orientation, int touchscreen, int density, int keyboard, - int keyboardHidden, int navigation, int screenWidth, int screenHeight, - int version) { - - Configuration c = new Configuration(); - c.mcc = mcc; - c.mnc = mnc; - c.locale = new Locale(locale); - c.touchscreen = touchscreen; - c.keyboard = keyboard; - c.keyboardHidden = keyboardHidden; - c.navigation = navigation; - c.orientation = orientation; - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeCanvas.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeCanvas.java deleted file mode 100644 index 70c26a7..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeCanvas.java +++ /dev/null @@ -1,1099 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.ILayoutLog; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.DrawFilter; -import android.graphics.LinearGradient; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.Picture; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; -import android.graphics.Shader; -import android.graphics.Xfermode; -import android.graphics.Paint.Align; -import android.graphics.Paint.Style; -import android.graphics.Region.Op; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.util.Stack; - -import javax.microedition.khronos.opengles.GL; - -/** - * Re-implementation of the Canvas, 100% in java on top of a BufferedImage. - */ -public class BridgeCanvas extends Canvas { - - private BufferedImage mBufferedImage; - private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>(); - private final ILayoutLog mLogger; - - public BridgeCanvas(int width, int height, ILayoutLog logger) { - mLogger = logger; - mBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - mGraphicsStack.push(mBufferedImage.createGraphics()); - } - - public BridgeCanvas(int width, int height) { - this(width, height, null /* logger*/); - } - - public BufferedImage getImage() { - return mBufferedImage; - } - - Graphics2D getGraphics2d() { - return mGraphicsStack.peek(); - } - - void dispose() { - while (mGraphicsStack.size() > 0) { - mGraphicsStack.pop().dispose(); - } - } - - /** - * Creates a new {@link Graphics2D} based on the {@link Paint} parameters. - * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used. - */ - private Graphics2D getNewGraphics(Paint paint, Graphics2D g) { - // make new one - g = (Graphics2D)g.create(); - g.setColor(new Color(paint.getColor())); - int alpha = paint.getAlpha(); - float falpha = alpha / 255.f; - - Xfermode xfermode = paint.getXfermode(); - if (xfermode instanceof PorterDuffXfermode) { - PorterDuff.Mode mode = ((PorterDuffXfermode)xfermode).getMode(); - - setModeInGraphics(mode, g, falpha); - } else { - if (mLogger != null && xfermode != null) { - mLogger.warning(String.format( - "Xfermode '%1$s' is not supported in the Layout Editor.", - xfermode.getClass().getCanonicalName())); - } - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); - } - - Shader shader = paint.getShader(); - if (shader instanceof LinearGradient) { - g.setPaint(((LinearGradient)shader).getPaint()); - } else { - if (mLogger != null && shader != null) { - mLogger.warning(String.format( - "Shader '%1$s' is not supported in the Layout Editor.", - shader.getClass().getCanonicalName())); - } - } - - return g; - } - - private void setModeInGraphics(PorterDuff.Mode mode, Graphics2D g, float falpha) { - switch (mode) { - case CLEAR: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha)); - break; - case DARKEN: - break; - case DST: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, falpha)); - break; - case DST_ATOP: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha)); - break; - case DST_IN: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha)); - break; - case DST_OUT: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha)); - break; - case DST_OVER: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha)); - break; - case LIGHTEN: - break; - case MULTIPLY: - break; - case SCREEN: - break; - case SRC: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, falpha)); - break; - case SRC_ATOP: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha)); - break; - case SRC_IN: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha)); - break; - case SRC_OUT: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha)); - break; - case SRC_OVER: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); - break; - case XOR: - g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, falpha)); - break; - } - } - - // -------------------- - - @Override - public void finalize() throws Throwable { - // pass - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#translate(float, float) - */ - @Override - public void translate(float dx, float dy) { - getGraphics2d().translate(dx, dy); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#save() - */ - @Override - public int save() { - Graphics2D g = (Graphics2D)getGraphics2d().create(); - mGraphicsStack.push(g); - - return mGraphicsStack.size() - 1; - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#save(int) - */ - @Override - public int save(int saveFlags) { - // For now we ignore saveFlags - return save(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#restore() - */ - @Override - public void restore() { - mGraphicsStack.pop(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#restoreToCount(int) - */ - @Override - public void restoreToCount(int saveCount) { - while (mGraphicsStack.size() > saveCount) { - mGraphicsStack.pop(); - } - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getSaveCount() - */ - @Override - public int getSaveCount() { - return mGraphicsStack.size() - 1; - } - - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(float, float, float, float, android.graphics.Region.Op) - */ - @Override - public boolean clipRect(float left, float top, float right, float bottom, Op op) { - return clipRect(left, top, right, bottom); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(float, float, float, float) - */ - @Override - public boolean clipRect(float left, float top, float right, float bottom) { - getGraphics2d().clipRect((int)left, (int)top, (int)(right-left), (int)(bottom-top)); - return true; - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(int, int, int, int) - */ - @Override - public boolean clipRect(int left, int top, int right, int bottom) { - getGraphics2d().clipRect(left, top, right-left, bottom-top); - return true; - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(android.graphics.Rect, android.graphics.Region.Op) - */ - @Override - public boolean clipRect(Rect rect, Op op) { - return clipRect(rect.left, rect.top, rect.right, rect.bottom); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(android.graphics.Rect) - */ - @Override - public boolean clipRect(Rect rect) { - return clipRect(rect.left, rect.top, rect.right, rect.bottom); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(android.graphics.RectF, android.graphics.Region.Op) - */ - @Override - public boolean clipRect(RectF rect, Op op) { - return clipRect(rect.left, rect.top, rect.right, rect.bottom); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRect(android.graphics.RectF) - */ - @Override - public boolean clipRect(RectF rect) { - return clipRect(rect.left, rect.top, rect.right, rect.bottom); - } - - @Override - public boolean quickReject(RectF rect, EdgeType type) { - return false; - } - - @Override - public boolean quickReject(Path path, EdgeType type) { - return false; - } - - @Override - public boolean quickReject(float left, float top, float right, float bottom, - EdgeType type) { - return false; - } - - /** - * Retrieve the clip bounds, returning true if they are non-empty. - * - * @param bounds Return the clip bounds here. If it is null, ignore it but - * still return true if the current clip is non-empty. - * @return true if the current clip is non-empty. - */ - @Override - public boolean getClipBounds(Rect bounds) { - Rectangle rect = getGraphics2d().getClipBounds(); - if (rect != null) { - bounds.left = rect.x; - bounds.top = rect.y; - bounds.right = rect.x + rect.width; - bounds.bottom = rect.y + rect.height; - return true; - } - return false; - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawColor(int, android.graphics.PorterDuff.Mode) - */ - @Override - public void drawColor(int color, PorterDuff.Mode mode) { - Graphics2D g = getGraphics2d(); - - // save old color - Color c = g.getColor(); - - Composite composite = g.getComposite(); - - // get the alpha from the color - int alpha = color >>> 24; - float falpha = alpha / 255.f; - - setModeInGraphics(mode, g, falpha); - - g.setColor(new Color(color)); - - getGraphics2d().fillRect(0, 0, getWidth(), getHeight()); - - g.setComposite(composite); - - // restore color - g.setColor(c); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawColor(int) - */ - @Override - public void drawColor(int color) { - drawColor(color, PorterDuff.Mode.SRC_OVER); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawARGB(int, int, int, int) - */ - @Override - public void drawARGB(int a, int r, int g, int b) { - drawColor(a << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawRGB(int, int, int) - */ - @Override - public void drawRGB(int r, int g, int b) { - drawColor(0xFF << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER); - } - - - /* (non-Javadoc) - * @see android.graphics.Canvas#getWidth() - */ - @Override - public int getWidth() { - return mBufferedImage.getWidth(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getHeight() - */ - @Override - public int getHeight() { - return mBufferedImage.getHeight(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPaint(android.graphics.Paint) - */ - @Override - public void drawPaint(Paint paint) { - drawColor(paint.getColor()); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint) - */ - @Override - public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { - drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), - (int)left, (int)top, - (int)left+bitmap.getWidth(), (int)top+bitmap.getHeight(), paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint) - */ - @Override - public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) - */ - @Override - public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { - if (src == null) { - drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), - dst.left, dst.top, dst.right, dst.bottom, paint); - } else { - drawBitmap(bitmap, src.left, src.top, src.width(), src.height(), - dst.left, dst.top, dst.right, dst.bottom, paint); - } - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint) - */ - @Override - public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { - if (src == null) { - drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), - (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint); - } else { - drawBitmap(bitmap, src.left, src.top, src.width(), src.height(), - (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint); - } - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint) - */ - @Override - public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, - int height, boolean hasAlpha, Paint paint) { - throw new UnsupportedOperationException(); - } - - private void drawBitmap(Bitmap bitmap, int sleft, int stop, int sright, int sbottom, int dleft, - int dtop, int dright, int dbottom, Paint paint) { - BufferedImage image = bitmap.getImage(); - - Graphics2D g = getGraphics2d(); - - Composite c = null; - - if (paint.isFilterBitmap()) { - g = (Graphics2D)g.create(); - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR); - } - - if (paint.getAlpha() != 0xFF) { - c = g.getComposite(); - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, - paint.getAlpha()/255.f)); - } - - g.drawImage(image, dleft, dtop, dright, dbottom, - sleft, stop, sright, sbottom, null); - - if (paint.isFilterBitmap()) { - g.dispose(); - } - - if (c != null) { - g.setComposite(c); - } - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#rotate(float, float, float) - */ - @Override - public void rotate(float degrees, float px, float py) { - if (degrees != 0) { - Graphics2D g = getGraphics2d(); - g.translate(px, py); - g.rotate(Math.toRadians(degrees)); - g.translate(-px, -py); - } - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#rotate(float) - */ - @Override - public void rotate(float degrees) { - getGraphics2d().rotate(Math.toRadians(degrees)); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#scale(float, float, float, float) - */ - @Override - public void scale(float sx, float sy, float px, float py) { - Graphics2D g = getGraphics2d(); - g.translate(px, py); - g.scale(sx, sy); - g.translate(-px, -py); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#scale(float, float) - */ - @Override - public void scale(float sx, float sy) { - getGraphics2d().scale(sx, sy); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawText(char[], int, int, float, float, android.graphics.Paint) - */ - @Override - public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { - Graphics2D g = getGraphics2d(); - - g = (Graphics2D)g.create(); - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g.setFont(paint.getFont()); - - // set the color. because this only handles RGB we have to handle the alpha separately - g.setColor(new Color(paint.getColor())); - int alpha = paint.getAlpha(); - float falpha = alpha / 255.f; - g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); - - // Paint.TextAlign indicates how the text is positioned relative to X. - // LEFT is the default and there's nothing to do. - if (paint.getTextAlign() != Align.LEFT) { - float m = paint.measureText(text, index, count); - if (paint.getTextAlign() == Align.CENTER) { - x -= m / 2; - } else if (paint.getTextAlign() == Align.RIGHT) { - x -= m; - } - } - - g.drawChars(text, index, count, (int)x, (int)y); - - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint) - */ - @Override - public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { - drawText(text.toString().toCharArray(), start, end - start, x, y, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawText(java.lang.String, float, float, android.graphics.Paint) - */ - @Override - public void drawText(String text, float x, float y, Paint paint) { - drawText(text.toCharArray(), 0, text.length(), x, y, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawText(java.lang.String, int, int, float, float, android.graphics.Paint) - */ - @Override - public void drawText(String text, int start, int end, float x, float y, Paint paint) { - drawText(text.toCharArray(), start, end - start, x, y, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawRect(android.graphics.RectF, android.graphics.Paint) - */ - @Override - public void drawRect(RectF rect, Paint paint) { - doDrawRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(), paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawRect(float, float, float, float, android.graphics.Paint) - */ - @Override - public void drawRect(float left, float top, float right, float bottom, Paint paint) { - doDrawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top), paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawRect(android.graphics.Rect, android.graphics.Paint) - */ - @Override - public void drawRect(Rect r, Paint paint) { - doDrawRect(r.left, r.top, r.width(), r.height(), paint); - } - - private final void doDrawRect(int left, int top, int width, int height, Paint paint) { - // get current graphisc - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - Style style = paint.getStyle(); - - // draw - if (style == Style.FILL || style == Style.FILL_AND_STROKE) { - g.fillRect(left, top, width, height); - } - - if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { - g.drawRect(left, top, width, height); - } - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint) - */ - @Override - public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { - // get current graphisc - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - Style style = paint.getStyle(); - - // draw - - int arcWidth = (int)(rx * 2); - int arcHeight = (int)(ry * 2); - - if (style == Style.FILL || style == Style.FILL_AND_STROKE) { - g.fillRoundRect((int)rect.left, (int)rect.right, (int)rect.width(), (int)rect.height(), - arcWidth, arcHeight); - } - - if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { - g.drawRoundRect((int)rect.left, (int)rect.right, (int)rect.width(), (int)rect.height(), - arcWidth, arcHeight); - } - - // dispose Graphics2D object - g.dispose(); - } - - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawLine(float, float, float, float, android.graphics.Paint) - */ - @Override - public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { - // get current graphisc - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY); - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawLines(float[], int, int, android.graphics.Paint) - */ - @Override - public void drawLines(float[] pts, int offset, int count, Paint paint) { - // get current graphisc - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - for (int i = 0 ; i < count ; i += 4) { - g.drawLine((int)pts[i + offset], (int)pts[i + offset + 1], - (int)pts[i + offset + 2], (int)pts[i + offset + 3]); - } - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawLines(float[], android.graphics.Paint) - */ - @Override - public void drawLines(float[] pts, Paint paint) { - drawLines(pts, 0, pts.length, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawCircle(float, float, float, android.graphics.Paint) - */ - @Override - public void drawCircle(float cx, float cy, float radius, Paint paint) { - // get current graphisc - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - Style style = paint.getStyle(); - - int size = (int)(radius * 2); - - // draw - if (style == Style.FILL || style == Style.FILL_AND_STROKE) { - g.fillOval((int)(cx - radius), (int)(cy - radius), size, size); - } - - if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { - g.drawOval((int)(cx - radius), (int)(cy - radius), size, size); - } - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawOval(android.graphics.RectF, android.graphics.Paint) - */ - @Override - public void drawOval(RectF oval, Paint paint) { - // get current graphics - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - Style style = paint.getStyle(); - - // draw - if (style == Style.FILL || style == Style.FILL_AND_STROKE) { - g.fillOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height()); - } - - if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { - g.drawOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height()); - } - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPath(android.graphics.Path, android.graphics.Paint) - */ - @Override - public void drawPath(Path path, Paint paint) { - // get current graphics - Graphics2D g = getGraphics2d(); - - g = getNewGraphics(paint, g); - - Style style = paint.getStyle(); - - // draw - if (style == Style.FILL || style == Style.FILL_AND_STROKE) { - g.fill(path.getAwtShape()); - } - - if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { - g.draw(path.getAwtShape()); - } - - // dispose Graphics2D object - g.dispose(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#setMatrix(android.graphics.Matrix) - */ - @Override - public void setMatrix(Matrix matrix) { - // since SetMatrix *replaces* all the other transformation, we have to restore/save - restore(); - save(); - - // get the new current graphics - Graphics2D g = getGraphics2d(); - - // and apply the matrix - g.setTransform(matrix.getTransform()); - - if (mLogger != null && matrix.hasPerspective()) { - mLogger.warning("android.graphics.Canvas#setMatrix(android.graphics.Matrix) only supports affine transformations in the Layout Editor."); - } - } - - // -------------------- - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipPath(android.graphics.Path, android.graphics.Region.Op) - */ - @Override - public boolean clipPath(Path path, Op op) { - // TODO Auto-generated method stub - return super.clipPath(path, op); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipPath(android.graphics.Path) - */ - @Override - public boolean clipPath(Path path) { - // TODO Auto-generated method stub - return super.clipPath(path); - } - - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRegion(android.graphics.Region, android.graphics.Region.Op) - */ - @Override - public boolean clipRegion(Region region, Op op) { - // TODO Auto-generated method stub - return super.clipRegion(region, op); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#clipRegion(android.graphics.Region) - */ - @Override - public boolean clipRegion(Region region) { - // TODO Auto-generated method stub - return super.clipRegion(region); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#concat(android.graphics.Matrix) - */ - @Override - public void concat(Matrix matrix) { - // TODO Auto-generated method stub - super.concat(matrix); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint) - */ - @Override - public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, - Paint paint) { - // TODO Auto-generated method stub - super.drawArc(oval, startAngle, sweepAngle, useCenter, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint) - */ - @Override - public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, - int vertOffset, int[] colors, int colorOffset, Paint paint) { - // TODO Auto-generated method stub - super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.Rect) - */ - @Override - public void drawPicture(Picture picture, Rect dst) { - // TODO Auto-generated method stub - super.drawPicture(picture, dst); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.RectF) - */ - @Override - public void drawPicture(Picture picture, RectF dst) { - // TODO Auto-generated method stub - super.drawPicture(picture, dst); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPicture(android.graphics.Picture) - */ - @Override - public void drawPicture(Picture picture) { - // TODO Auto-generated method stub - super.drawPicture(picture); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPoint(float, float, android.graphics.Paint) - */ - @Override - public void drawPoint(float x, float y, Paint paint) { - // TODO Auto-generated method stub - super.drawPoint(x, y, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPoints(float[], int, int, android.graphics.Paint) - */ - @Override - public void drawPoints(float[] pts, int offset, int count, Paint paint) { - // TODO Auto-generated method stub - super.drawPoints(pts, offset, count, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPoints(float[], android.graphics.Paint) - */ - @Override - public void drawPoints(float[] pts, Paint paint) { - // TODO Auto-generated method stub - super.drawPoints(pts, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPosText(char[], int, int, float[], android.graphics.Paint) - */ - @Override - public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { - // TODO Auto-generated method stub - super.drawPosText(text, index, count, pos, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawPosText(java.lang.String, float[], android.graphics.Paint) - */ - @Override - public void drawPosText(String text, float[] pos, Paint paint) { - // TODO Auto-generated method stub - super.drawPosText(text, pos, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint) - */ - @Override - public void drawTextOnPath(char[] text, int index, int count, Path path, float offset, - float offset2, Paint paint) { - // TODO Auto-generated method stub - super.drawTextOnPath(text, index, count, path, offset, offset2, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint) - */ - @Override - public void drawTextOnPath(String text, Path path, float offset, float offset2, Paint paint) { - // TODO Auto-generated method stub - super.drawTextOnPath(text, path, offset, offset2, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint) - */ - @Override - public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, - float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, - int indexOffset, int indexCount, Paint paint) { - // TODO Auto-generated method stub - super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset, - indices, indexOffset, indexCount, paint); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getDrawFilter() - */ - @Override - public DrawFilter getDrawFilter() { - // TODO Auto-generated method stub - return super.getDrawFilter(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getGL() - */ - @Override - public GL getGL() { - // TODO Auto-generated method stub - return super.getGL(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getMatrix() - */ - @Override - public Matrix getMatrix() { - // TODO Auto-generated method stub - return super.getMatrix(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#getMatrix(android.graphics.Matrix) - */ - @Override - public void getMatrix(Matrix ctm) { - // TODO Auto-generated method stub - super.getMatrix(ctm); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#isOpaque() - */ - @Override - public boolean isOpaque() { - // TODO Auto-generated method stub - return super.isOpaque(); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#saveLayer(float, float, float, float, android.graphics.Paint, int) - */ - @Override - public int saveLayer(float left, float top, float right, float bottom, Paint paint, - int saveFlags) { - // TODO Auto-generated method stub - return super.saveLayer(left, top, right, bottom, paint, saveFlags); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#saveLayer(android.graphics.RectF, android.graphics.Paint, int) - */ - @Override - public int saveLayer(RectF bounds, Paint paint, int saveFlags) { - // TODO Auto-generated method stub - return super.saveLayer(bounds, paint, saveFlags); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#saveLayerAlpha(float, float, float, float, int, int) - */ - @Override - public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, - int saveFlags) { - // TODO Auto-generated method stub - return super.saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#saveLayerAlpha(android.graphics.RectF, int, int) - */ - @Override - public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { - // TODO Auto-generated method stub - return super.saveLayerAlpha(bounds, alpha, saveFlags); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#setBitmap(android.graphics.Bitmap) - */ - @Override - public void setBitmap(Bitmap bitmap) { - // TODO Auto-generated method stub - super.setBitmap(bitmap); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#setDrawFilter(android.graphics.DrawFilter) - */ - @Override - public void setDrawFilter(DrawFilter filter) { - // TODO Auto-generated method stub - super.setDrawFilter(filter); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#setViewport(int, int) - */ - @Override - public void setViewport(int width, int height) { - // TODO Auto-generated method stub - super.setViewport(width, height); - } - - /* (non-Javadoc) - * @see android.graphics.Canvas#skew(float, float) - */ - @Override - public void skew(float sx, float sy) { - // TODO Auto-generated method stub - super.skew(sx, sy); - } - - - -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java deleted file mode 100644 index b426247..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -/** - * Constant definition class.<br> - * <br> - * Most constants have a prefix defining the content. - * <ul> - * <li><code>WS_</code> Workspace path constant. Those are absolute paths, - * from the project root.</li> - * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li> - * <li><code>FN_</code> File name constant.</li> - * <li><code>FD_</code> Folder name constant.</li> - * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li> - * <li><code>DOT_</code> File extension constant. This start with a dot.</li> - * <li><code>RE_</code> Regexp constant.</li> - * <li><code>NS_</code> Namespace constant.</li> - * <li><code>CLASS_</code> Fully qualified class name.</li> - * </ul> - * - */ -public class BridgeConstants { - - /** Namespace for the resource XML */ - public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android"; - - public final static String R = "com.android.internal.R"; - - public final static String PREFIX_ANDROID_RESOURCE_REF = "@android:"; - public final static String PREFIX_RESOURCE_REF = "@"; - public final static String PREFIX_ANDROID_THEME_REF = "?android:"; - public final static String PREFIX_THEME_REF = "?"; - - public final static String PREFIX_ANDROID = "android:"; - - public final static String RES_STYLE = "style"; - public final static String RES_ATTR = "attr"; - public final static String RES_DRAWABLE = "drawable"; - public final static String RES_COLOR = "color"; - public final static String RES_LAYOUT = "layout"; - public final static String RES_STRING = "string"; - public final static String RES_ID = "id"; - - public final static String REFERENCE_STYLE = RES_STYLE + "/"; - public final static String REFERENCE_NULL = "@null"; - - public final static String FILL_PARENT = "fill_parent"; - public final static String WRAP_CONTENT = "wrap_content"; -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java deleted file mode 100644 index 727d6f2..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import android.content.ContentResolver; -import android.content.ContentServiceNative; -import android.content.Context; -import android.content.IContentProvider; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Bundle; - -/** - * A mock content resolver for the LayoutLib Bridge. - * <p/> - * It won't serve any actual data but it's good enough for all - * the widgets which expect to have a content resolver available via - * {@link BridgeContext#getContentResolver()}. - */ -public class BridgeContentResolver extends ContentResolver { - - public BridgeContentResolver(Context context) { - super(context); - } - - @Override - public IContentProvider acquireProvider(Context c, String name) { - // ignore - return null; - } - - @Override - public boolean releaseProvider(IContentProvider icp) { - // ignore - return false; - } - - /** - * Stub for the layoutlib bridge content resolver. - * <p/> - * The super implementation accesses the {@link ContentServiceNative#getDefault()} - * which returns null and would make the call crash. Instead we do nothing. - */ - @Override - public void registerContentObserver(Uri uri, boolean notifyForDescendents, - ContentObserver observer) { - // pass - } - - /** - * Stub for the layoutlib bridge content resolver. - * <p/> - * The super implementation accesses the {@link ContentServiceNative#getDefault()} - * which returns null and would make the call crash. Instead we do nothing. - */ - @Override - public void unregisterContentObserver(ContentObserver observer) { - // pass - } - - /** - * Stub for the layoutlib bridge content resolver. - * <p/> - * The super implementation accesses the {@link ContentServiceNative#getDefault()} - * which returns null and would make the call crash. Instead we do nothing. - */ - @Override - public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { - // pass - } - - /** - * Stub for the layoutlib bridge content resolver. - * <p/> - * The super implementation accesses the {@link ContentServiceNative#getDefault()} - * which returns null and would make the call crash. Instead we do nothing. - */ - @Override - public void startSync(Uri uri, Bundle extras) { - // pass - } - - /** - * Stub for the layoutlib bridge content resolver. - * <p/> - * The super implementation accesses the {@link ContentServiceNative#getDefault()} - * which returns null and would make the call crash. Instead we do nothing. - */ - @Override - public void cancelSync(Uri uri) { - // pass - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java deleted file mode 100644 index 0df20e4..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.ILayoutLog; -import com.android.layoutlib.api.IProjectCallback; -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; - -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.Resources.Theme; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteDatabase.CursorFactory; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.BridgeInflater; -import android.view.View; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; -import java.util.Map.Entry; - -/** - * Custom implementation of Context to handle non compiled resources. - */ -public final class BridgeContext extends Context { - - private Resources mResources; - private Theme mTheme; - private HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>(); - private IStyleResourceValue mThemeValues; - private final Object mProjectKey; - private Map<String, Map<String, IResourceValue>> mProjectResources; - private Map<String, Map<String, IResourceValue>> mFrameworkResources; - private Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap; - - // maps for dynamically generated id representing style objects (IStyleResourceValue) - private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap; - private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap; - private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style - - // cache for TypedArray generated from IStyleResourceValue object - private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache; - private BridgeInflater mInflater; - - private final IProjectCallback mProjectCallback; - private final ILayoutLog mLogger; - private BridgeContentResolver mContentResolver; - - /** - * @param projectKey - * @param currentTheme - * @param projectResources - * @param frameworkResources - * @param styleInheritanceMap - * @param customViewLoader - */ - public BridgeContext(Object projectKey, - IStyleResourceValue currentTheme, - Map<String, Map<String, IResourceValue>> projectResources, - Map<String, Map<String, IResourceValue>> frameworkResources, - Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap, - IProjectCallback customViewLoader, ILayoutLog logger) { - mProjectKey = projectKey; - mProjectCallback = customViewLoader; - mLogger = logger; - Configuration config = new Configuration(); - - DisplayMetrics metrics = new DisplayMetrics(); - metrics.setToDefaults(); - - - AssetManager assetManager = BridgeAssetManager.initSystem(); - mResources = BridgeResources.initSystem( - this, - assetManager, - metrics, - config, - customViewLoader); - - mTheme = mResources.newTheme(); - - mThemeValues = currentTheme; - mProjectResources = projectResources; - mFrameworkResources = frameworkResources; - mStyleInheritanceMap = styleInheritanceMap; - } - - public void setBridgeInflater(BridgeInflater inflater) { - mInflater = inflater; - } - - public void addViewKey(View view, Object viewKey) { - mViewKeyMap.put(view, viewKey); - } - - public Object getViewKey(View view) { - return mViewKeyMap.get(view); - } - - public Object getProjectKey() { - return mProjectKey; - } - - public IProjectCallback getProjectCallback() { - return mProjectCallback; - } - - public ILayoutLog getLogger() { - return mLogger; - } - - // ------------ Context methods - - @Override - public Resources getResources() { - return mResources; - } - - @Override - public Theme getTheme() { - return mTheme; - } - - @Override - public ClassLoader getClassLoader() { - return this.getClass().getClassLoader(); - } - - @Override - public Object getSystemService(String service) { - if (LAYOUT_INFLATER_SERVICE.equals(service)) { - return mInflater; - } - - // AutoCompleteTextView and MultiAutoCompleteTextView want a window - // service. We don't have any but it's not worth an exception. - if (WINDOW_SERVICE.equals(service)) { - return null; - } - - throw new UnsupportedOperationException("Unsupported Service: " + service); - } - - - @Override - public final TypedArray obtainStyledAttributes(int[] attrs) { - return createStyleBasedTypedArray(mThemeValues, attrs); - } - - @Override - public final TypedArray obtainStyledAttributes(int resid, int[] attrs) - throws Resources.NotFoundException { - // get the IStyleResourceValue based on the resId; - IStyleResourceValue style = getStyleByDynamicId(resid); - - if (style == null) { - throw new Resources.NotFoundException(); - } - - if (mTypedArrayCache == null) { - mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>(); - - Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>(); - mTypedArrayCache.put(attrs, map); - - BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs); - map.put(resid, ta); - - return ta; - } - - // get the 2nd map - Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs); - if (map == null) { - map = new HashMap<Integer, TypedArray>(); - mTypedArrayCache.put(attrs, map); - } - - // get the array from the 2nd map - TypedArray ta = map.get(resid); - - if (ta == null) { - ta = createStyleBasedTypedArray(style, attrs); - map.put(resid, ta); - } - - return ta; - } - - @Override - public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) { - return obtainStyledAttributes(set, attrs, 0, 0); - } - - @Override - public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, - int defStyleAttr, int defStyleRes) { - - // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java - BridgeXmlBlockParser parser = null; - if (set instanceof BridgeXmlBlockParser) { - parser = (BridgeXmlBlockParser)set; - } else { - // reall this should not be happening since its instantiated in Bridge - mLogger.error("Parser is not a BridgeXmlBlockParser!"); - return null; - } - - boolean[] frameworkAttributes = new boolean[1]; - TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes); - - BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length, - parser.isPlatformFile()); - - // resolve the defStyleAttr value into a IStyleResourceValue - IStyleResourceValue defStyleValues = null; - if (defStyleAttr != 0) { - // get the name from the int. - String defStyleName = searchAttr(defStyleAttr); - - // look for the style in the current theme, and its parent: - if (mThemeValues != null) { - IResourceValue item = findItemInStyle(mThemeValues, defStyleName); - - if (item != null) { - // item is a reference to a style entry. Search for it. - item = findResValue(item.getValue()); - - if (item instanceof IStyleResourceValue) { - defStyleValues = (IStyleResourceValue)item; - } - } else { - // TODO: log the error properly - System.out.println("Failed to find defStyle: " + defStyleName); - } - } - } - - if (defStyleRes != 0) { - // FIXME: See what we need to do with this. - throw new UnsupportedOperationException(); - } - - String namespace = BridgeConstants.NS_RESOURCES; - if (frameworkAttributes[0] == false) { - // need to use the application namespace - namespace = mProjectCallback.getNamespace(); - } - - if (styleNameMap != null) { - for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { - int index = styleAttribute.getKey().intValue(); - - String name = styleAttribute.getValue(); - String value = parser.getAttributeValue(namespace, name); - - // if there's no direct value for this attribute in the XML, we look for default - // values in the widget defStyle, and then in the theme. - if (value == null) { - IResourceValue resValue = null; - - // look for the value in the defStyle first (and its parent if needed) - if (defStyleValues != null) { - resValue = findItemInStyle(defStyleValues, name); - } - - // if the item is not present in the defStyle, we look in the main theme (and - // its parent themes) - if (resValue == null && mThemeValues != null) { - resValue = findItemInStyle(mThemeValues, name); - } - - // if we found a value, we make sure this doesn't reference another value. - // So we resolve it. - if (resValue != null) { - resValue = resolveResValue(resValue); - } - - ta.bridgeSetValue(index, name, resValue); - } else { - // there is a value in the XML, but we need to resolve it in case it's - // referencing another resource or a theme value. - ta.bridgeSetValue(index, name, resolveValue(null, name, value)); - } - } - } - - ta.sealArray(); - - return ta; - } - - - // ------------- private new methods - - /** - * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the - * values found in the given style. - * @see #obtainStyledAttributes(int, int[]) - */ - private BridgeTypedArray createStyleBasedTypedArray(IStyleResourceValue style, int[] attrs) - throws Resources.NotFoundException { - TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, null); - - BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length, - false /* platformResourceFlag */); - - // loop through all the values in the style map, and init the TypedArray with - // the style we got from the dynamic id - for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { - int index = styleAttribute.getKey().intValue(); - - String name = styleAttribute.getValue(); - - // get the value from the style, or its parent styles. - IResourceValue resValue = findItemInStyle(style, name); - - // resolve it to make sure there are no references left. - ta.bridgeSetValue(index, name, resolveResValue(resValue)); - } - - ta.sealArray(); - - return ta; - } - - - /** - * Resolves the value of a resource, if the value references a theme or resource value. - * <p/> - * This method ensures that it returns a {@link IResourceValue} object that does not - * reference another resource. - * If the resource cannot be resolved, it returns <code>null</code>. - * <p/> - * If a value that does not need to be resolved is given, the method will return a new - * instance of IResourceValue that contains the input value. - * - * @param type the type of the resource - * @param name the name of the attribute containing this value. - * @param value the resource value, or reference to resolve - * @return the resolved resource value or <code>null</code> if it failed to resolve it. - */ - private IResourceValue resolveValue(String type, String name, String value) { - if (value == null) { - return null; - } - - // get the IResourceValue referenced by this value - IResourceValue resValue = findResValue(value); - - // if resValue is null, but value is not null, this means it was not a reference. - // we return the name/value wrapper in a IResourceValue - if (resValue == null) { - return new ResourceValue(type, name, value); - } - - // we resolved a first reference, but we need to make sure this isn't a reference also. - return resolveResValue(resValue); - } - - /** - * Returns the {@link IResourceValue} referenced by the value of <var>value</var>. - * <p/> - * This method ensures that it returns a {@link IResourceValue} object that does not - * reference another resource. - * If the resource cannot be resolved, it returns <code>null</code>. - * <p/> - * If a value that does not need to be resolved is given, the method will return the input - * value. - * - * @param value the value containing the reference to resolve. - * @return a {@link IResourceValue} object or <code>null</code> - */ - IResourceValue resolveResValue(IResourceValue value) { - if (value == null) { - return null; - } - - // if the resource value is a style, we simply return it. - if (value instanceof IStyleResourceValue) { - return value; - } - - // else attempt to find another IResourceValue referenced by this one. - IResourceValue resolvedValue = findResValue(value.getValue()); - - // if the value did not reference anything, then we simply return the input value - if (resolvedValue == null) { - return value; - } - - // otherwise, we attempt to resolve this new value as well - return resolveResValue(resolvedValue); - } - - /** - * Searches for, and returns a {@link IResourceValue} by its reference. - * <p/> - * The reference format can be: - * <pre>@resType/resName</pre> - * <pre>@android:resType/resName</pre> - * <pre>@resType/android:resName</pre> - * <pre>?resType/resName</pre> - * <pre>?android:resType/resName</pre> - * <pre>?resType/android:resName</pre> - * Any other string format will return <code>null</code>. - * <p/> - * The actual format of a reference is <pre>@[namespace:]resType/resName</pre> but this method - * only support the android namespace. - * - * @param reference the resource reference to search for. - * @return a {@link IResourceValue} or <code>null</code>. - */ - IResourceValue findResValue(String reference) { - if (reference == null) { - return null; - } - if (reference.startsWith(BridgeConstants.PREFIX_THEME_REF)) { - // no theme? no need to go further! - if (mThemeValues == null) { - return null; - } - - boolean frameworkOnly = false; - - // eleminate the prefix from the string - if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_THEME_REF)) { - frameworkOnly = true; - reference = reference.substring(BridgeConstants.PREFIX_ANDROID_THEME_REF.length()); - } else { - reference = reference.substring(BridgeConstants.PREFIX_THEME_REF.length()); - } - - // at this point, value can contain type/name (drawable/foo for instance). - // split it to make sure. - String[] segments = reference.split("\\/"); - - // we look for the referenced item name. - String referenceName = null; - - if (segments.length == 2) { - // there was a resType in the reference. If it's attr, we ignore it - // else, we assert for now. - if (BridgeConstants.RES_ATTR.equals(segments[0])) { - referenceName = segments[1]; - } else { - // At this time, no support for ?type/name where type is not "attr" - return null; - } - } else { - // it's just an item name. - referenceName = segments[0]; - } - - // now we look for android: in the referenceName in order to support format - // such as: ?attr/android:name - if (referenceName.startsWith(BridgeConstants.PREFIX_ANDROID)) { - frameworkOnly = true; - referenceName = referenceName.substring(BridgeConstants.PREFIX_ANDROID.length()); - } - - // Now look for the item in the theme, starting with the current one. - if (frameworkOnly) { - // FIXME for now we do the same as if it didn't specify android: - return findItemInStyle(mThemeValues, referenceName); - } - - return findItemInStyle(mThemeValues, referenceName); - } else if (reference.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) { - boolean frameworkOnly = false; - - // check for the specific null reference value. - if (BridgeConstants.REFERENCE_NULL.equals(reference)) { - return null; - } - - // Eliminate the prefix from the string. - if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_RESOURCE_REF)) { - frameworkOnly = true; - reference = reference.substring( - BridgeConstants.PREFIX_ANDROID_RESOURCE_REF.length()); - } else { - reference = reference.substring(BridgeConstants.PREFIX_RESOURCE_REF.length()); - } - - // at this point, value contains type/[android:]name (drawable/foo for instance) - String[] segments = reference.split("\\/"); - - // now we look for android: in the resource name in order to support format - // such as: @drawable/android:name - if (segments[1].startsWith(BridgeConstants.PREFIX_ANDROID)) { - frameworkOnly = true; - segments[1] = segments[1].substring(BridgeConstants.PREFIX_ANDROID.length()); - } - - return findResValue(segments[0], segments[1], frameworkOnly); - } - - // Looks like the value didn't reference anything. Return null. - return null; - } - - /** - * Searches for, and returns a {@link IResourceValue} by its name, and type. - * @param resType the type of the resource - * @param resName the name of the resource - * @param frameworkOnly if <code>true</code>, the method does not search in the - * project resources - */ - private IResourceValue findResValue(String resType, String resName, boolean frameworkOnly) { - // map of IResouceValue for the given type - Map<String, IResourceValue> typeMap; - - // if allowed, search in the project resources first. - if (frameworkOnly == false) { - typeMap = mProjectResources.get(resType); - if (typeMap != null) { - IResourceValue item = typeMap.get(resName); - if (item != null) { - return item; - } - } - } - - // now search in the framework resources. - typeMap = mFrameworkResources.get(resType); - if (typeMap != null) { - IResourceValue item = typeMap.get(resName); - if (item != null) { - return item; - } - } - - // didn't find the resource anywhere. - return null; - } - - /** - * Returns a framework resource by type and name. The returned resource is resolved. - * @param resourceType the type of the resource - * @param resourceName the name of the resource - */ - public IResourceValue getFrameworkResource(String resourceType, String resourceName) { - return getResource(resourceType, resourceName, mFrameworkResources); - } - - /** - * Returns a project resource by type and name. The returned resource is resolved. - * @param resourceType the type of the resource - * @param resourceName the name of the resource - */ - public IResourceValue getProjectResource(String resourceType, String resourceName) { - return getResource(resourceType, resourceName, mProjectResources); - } - - IResourceValue getResource(String resourceType, String resourceName, - Map<String, Map<String, IResourceValue>> resourceRepository) { - Map<String, IResourceValue> typeMap = resourceRepository.get(resourceType); - if (typeMap != null) { - IResourceValue item = typeMap.get(resourceName); - if (item != null) { - item = resolveResValue(item); - return item; - } - } - - // didn't find the resource anywhere. - return null; - - } - - /** - * Returns the {@link IResourceValue} matching a given name in a given style. If the - * item is not directly available in the style, the method looks in its parent style. - * @param style the style to search in - * @param itemName the name of the item to search for. - * @return the {@link IResourceValue} object or <code>null</code> - */ - IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) { - IResourceValue item = style.findItem(itemName); - - // if we didn't find it, we look in the parent style (if applicable) - if (item == null && mStyleInheritanceMap != null) { - IStyleResourceValue parentStyle = mStyleInheritanceMap.get(style); - if (parentStyle != null) { - return findItemInStyle(parentStyle, itemName); - } - } - - return item; - } - - /** - * The input int[] attrs is one of com.android.internal.R.styleable fields where the name - * of the field is the style being referenced and the array contains one index per attribute. - * <p/> - * searchAttrs() finds all the names of the attributes referenced so for example if - * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where - * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index - * that is used to reference the attribute later in the TypedArray. - * - * @param attrs An attribute array reference given to obtainStyledAttributes. - * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the - * attribute array. Returns null if nothing is found. - */ - private TreeMap<Integer,String> searchAttrs(int[] attrs, boolean[] outFrameworkFlag) { - // get the name of the array from the framework resources - String arrayName = Bridge.resolveResourceValue(attrs); - if (arrayName != null) { - // if we found it, get the name of each of the int in the array. - TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); - for (int i = 0 ; i < attrs.length ; i++) { - String[] info = Bridge.resolveResourceValue(attrs[i]); - if (info != null) { - attributes.put(i, info[0]); - } else { - // FIXME Not sure what we should be doing here... - attributes.put(i, null); - } - } - - if (outFrameworkFlag != null) { - outFrameworkFlag[0] = true; - } - - return attributes; - } - - // if the name was not found in the framework resources, look in the project - // resources - arrayName = mProjectCallback.resolveResourceValue(attrs); - if (arrayName != null) { - TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); - for (int i = 0 ; i < attrs.length ; i++) { - String[] info = mProjectCallback.resolveResourceValue(attrs[i]); - if (info != null) { - attributes.put(i, info[0]); - } else { - // FIXME Not sure what we should be doing here... - attributes.put(i, null); - } - } - - if (outFrameworkFlag != null) { - outFrameworkFlag[0] = false; - } - - return attributes; - } - - return null; - } - - /** - * Searches for the attribute referenced by its internal id. - * - * @param attr An attribute reference given to obtainStyledAttributes such as defStyle. - * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null - * if nothing is found. - */ - public String searchAttr(int attr) { - String[] info = Bridge.resolveResourceValue(attr); - if (info != null) { - return info[0]; - } - - info = mProjectCallback.resolveResourceValue(attr); - if (info != null) { - return info[0]; - } - - return null; - } - - int getDynamicIdByStyle(IStyleResourceValue resValue) { - if (mDynamicIdToStyleMap == null) { - // create the maps. - mDynamicIdToStyleMap = new HashMap<Integer, IStyleResourceValue>(); - mStyleToDynamicIdMap = new HashMap<IStyleResourceValue, Integer>(); - } - - // look for an existing id - Integer id = mStyleToDynamicIdMap.get(resValue); - - if (id == null) { - // generate a new id - id = Integer.valueOf(++mDynamicIdGenerator); - - // and add it to the maps. - mDynamicIdToStyleMap.put(id, resValue); - mStyleToDynamicIdMap.put(resValue, id); - } - - return id; - } - - private IStyleResourceValue getStyleByDynamicId(int i) { - if (mDynamicIdToStyleMap != null) { - return mDynamicIdToStyleMap.get(i); - } - - return null; - } - - int getFrameworkIdValue(String idName, int defValue) { - Integer value = Bridge.getResourceValue(BridgeConstants.RES_ID, idName); - if (value != null) { - return value.intValue(); - } - - return defValue; - } - - int getProjectIdValue(String idName, int defValue) { - if (mProjectCallback != null) { - Integer value = mProjectCallback.getResourceValue(BridgeConstants.RES_ID, idName); - if (value != null) { - return value.intValue(); - } - } - - return defValue; - } - - //------------ NOT OVERRIDEN -------------------- - - @Override - public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int checkCallingOrSelfPermission(String arg0) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkCallingPermission(String arg0) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkCallingUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkPermission(String arg0, int arg1, int arg2) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, - int arg4, int arg5) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void clearWallpaper() { - // TODO Auto-generated method stub - - } - - @Override - public Context createPackageContext(String arg0, int arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String[] databaseList() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean deleteDatabase(String arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean deleteFile(String arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void enforceCallingOrSelfPermission(String arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1, - String arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void enforceCallingPermission(String arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void enforcePermission(String arg0, int arg1, int arg2, String arg3) { - // TODO Auto-generated method stub - - } - - @Override - public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3, - String arg4) { - // TODO Auto-generated method stub - - } - - @Override - public void enforceUriPermission(Uri arg0, String arg1, String arg2, - int arg3, int arg4, int arg5, String arg6) { - // TODO Auto-generated method stub - - } - - @Override - public String[] fileList() { - // TODO Auto-generated method stub - return null; - } - - @Override - public AssetManager getAssets() { - // TODO Auto-generated method stub - return null; - } - - @Override - public File getCacheDir() { - // TODO Auto-generated method stub - return null; - } - - @Override - public ContentResolver getContentResolver() { - if (mContentResolver == null) { - mContentResolver = new BridgeContentResolver(this); - } - return mContentResolver; - } - - @Override - public File getDatabasePath(String arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public File getDir(String arg0, int arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public File getFileStreamPath(String arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public File getFilesDir() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getPackageCodePath() { - // TODO Auto-generated method stub - return null; - } - - @Override - public PackageManager getPackageManager() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getPackageName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getPackageResourcePath() { - // TODO Auto-generated method stub - return null; - } - - @Override - public SharedPreferences getSharedPreferences(String arg0, int arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Drawable getWallpaper() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getWallpaperDesiredMinimumWidth() { - return -1; - } - - @Override - public int getWallpaperDesiredMinimumHeight() { - return -1; - } - - @Override - public void grantUriPermission(String arg0, Uri arg1, int arg2) { - // TODO Auto-generated method stub - - } - - @SuppressWarnings("unused") - @Override - public FileInputStream openFileInput(String arg0) - throws FileNotFoundException { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unused") - @Override - public FileOutputStream openFileOutput(String arg0, int arg1) - throws FileNotFoundException { - // TODO Auto-generated method stub - return null; - } - - @Override - public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, - CursorFactory arg2) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Drawable peekWallpaper() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, - String arg2, Handler arg3) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void removeStickyBroadcast(Intent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void revokeUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendBroadcast(Intent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void sendBroadcast(Intent arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendOrderedBroadcast(Intent arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void sendOrderedBroadcast(Intent arg0, String arg1, - BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, - Bundle arg6) { - // TODO Auto-generated method stub - - } - - @Override - public void sendStickyBroadcast(Intent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void setTheme(int arg0) { - // TODO Auto-generated method stub - - } - - @SuppressWarnings("unused") - @Override - public void setWallpaper(Bitmap arg0) throws IOException { - // TODO Auto-generated method stub - - } - - @SuppressWarnings("unused") - @Override - public void setWallpaper(InputStream arg0) throws IOException { - // TODO Auto-generated method stub - - } - - @Override - public void startActivity(Intent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public boolean startInstrumentation(ComponentName arg0, String arg1, - Bundle arg2) { - // TODO Auto-generated method stub - return false; - } - - @Override - public ComponentName startService(Intent arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean stopService(Intent arg0) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void unbindService(ServiceConnection arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void unregisterReceiver(BroadcastReceiver arg0) { - // TODO Auto-generated method stub - - } - - @Override - public Looper getMainLooper() { - throw new UnsupportedOperationException(); - } - - @Override - public Context getApplicationContext() { - throw new UnsupportedOperationException(); - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java deleted file mode 100644 index 0bcc7fd..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.IProjectCallback; -import com.android.layoutlib.api.IResourceValue; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.view.ViewGroup.LayoutParams; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.InputStream; - -/** - * - */ -public final class BridgeResources extends Resources { - - private BridgeContext mContext; - private IProjectCallback mProjectCallback; - private boolean[] mPlatformResourceFlag = new boolean[1]; - - /** - * This initializes the static field {@link Resources#mSystem} which is used - * by methods who get global resources using {@link Resources#getSystem()}. - * <p/> - * They will end up using our bridge resources. - * <p/> - * {@link Bridge} calls this method after setting up a new bridge. - */ - /*package*/ static Resources initSystem(BridgeContext context, - AssetManager assets, - DisplayMetrics metrics, - Configuration config, - IProjectCallback projectCallback) { - if (!(Resources.mSystem instanceof BridgeResources)) { - Resources.mSystem = new BridgeResources(context, - assets, - metrics, - config, - projectCallback); - } - return Resources.mSystem; - } - - /** - * Clears the static {@link Resources#mSystem} to make sure we don't leave objects - * around that would prevent us from unloading the library. - */ - /*package*/ static void clearSystem() { - if (Resources.mSystem instanceof BridgeResources) { - ((BridgeResources)(Resources.mSystem)).mContext = null; - ((BridgeResources)(Resources.mSystem)).mProjectCallback = null; - } - Resources.mSystem = null; - } - - private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics, - Configuration config, IProjectCallback projectCallback) { - super(assets, metrics, config); - mContext = context; - mProjectCallback = projectCallback; - } - - public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) { - return new BridgeTypedArray(this, mContext, numEntries, platformFile); - } - - private IResourceValue getResourceValue(int id, boolean[] platformResFlag_out) { - // first get the String related to this id in the framework - String[] resourceInfo = Bridge.resolveResourceValue(id); - - if (resourceInfo != null) { - platformResFlag_out[0] = true; - return mContext.getFrameworkResource(resourceInfo[1], resourceInfo[0]); - } - - // didn't find a match in the framework? look in the project. - if (mProjectCallback != null) { - resourceInfo = mProjectCallback.resolveResourceValue(id); - - if (resourceInfo != null) { - platformResFlag_out[0] = false; - return mContext.getProjectResource(resourceInfo[1], resourceInfo[0]); - } - } - - return null; - } - - @Override - public Drawable getDrawable(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - return ResourceHelper.getDrawable(value.getValue(), mContext, value.isFramework()); - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public int getColor(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - try { - return ResourceHelper.getColor(value.getValue()); - } catch (NumberFormatException e) { - return 0; - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return 0; - } - - @Override - public ColorStateList getColorStateList(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - try { - int color = ResourceHelper.getColor(value.getValue()); - return ColorStateList.valueOf(color); - } catch (NumberFormatException e) { - return null; - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public CharSequence getText(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - return value.getValue(); - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public XmlResourceParser getLayout(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - File xml = new File(value.getValue()); - if (xml.isFile()) { - // we need to create a pull parser around the layout XML file, and then - // give that to our XmlBlockParser - try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(xml)); - - return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]); - } catch (XmlPullParserException e) { - mContext.getLogger().error(e); - - // we'll return null below. - } catch (FileNotFoundException e) { - // this shouldn't happen since we check above. - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public TypedArray obtainAttributes(AttributeSet set, int[] attrs) { - return mContext.obtainStyledAttributes(set, attrs); - } - - @Override - public TypedArray obtainTypedArray(int id) throws NotFoundException { - throw new UnsupportedOperationException(); - } - - - @Override - public float getDimension(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - if (v.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; - } else if (v.equals(BridgeConstants.WRAP_CONTENT)) { - return LayoutParams.WRAP_CONTENT; - } - - if (ResourceHelper.stringToFloat(v, mTmpValue) && - mTmpValue.type == TypedValue.TYPE_DIMENSION) { - return mTmpValue.getDimension(mMetrics); - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return 0; - } - - @Override - public int getDimensionPixelOffset(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - if (ResourceHelper.stringToFloat(v, mTmpValue) && - mTmpValue.type == TypedValue.TYPE_DIMENSION) { - return TypedValue.complexToDimensionPixelOffset(mTmpValue.data, mMetrics); - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return 0; - } - - @Override - public int getDimensionPixelSize(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - if (ResourceHelper.stringToFloat(v, mTmpValue) && - mTmpValue.type == TypedValue.TYPE_DIMENSION) { - return TypedValue.complexToDimensionPixelSize(mTmpValue.data, mMetrics); - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return 0; - } - - @Override - public int getInteger(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null && value.getValue() != null) { - String v = value.getValue(); - int radix = 10; - if (v.startsWith("0x")) { - v = v.substring(2); - radix = 16; - } - try { - return Integer.parseInt(v, radix); - } catch (NumberFormatException e) { - // return exception below - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return 0; - } - - @Override - public String getResourceEntryName(int resid) throws NotFoundException { - throw new UnsupportedOperationException(); - } - - @Override - public String getResourceName(int resid) throws NotFoundException { - throw new UnsupportedOperationException(); - } - - @Override - public String getResourceTypeName(int resid) throws NotFoundException { - throw new UnsupportedOperationException(); - } - - @Override - public String getString(int id, Object... formatArgs) throws NotFoundException { - String s = getString(id); - if (s != null) { - return String.format(s, formatArgs); - - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public String getString(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null && value.getValue() != null) { - return value.getValue(); - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public void getValue(int id, TypedValue outValue, boolean resolveRefs) - throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - if (ResourceHelper.stringToFloat(v, outValue)) { - return; - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - } - - @Override - public void getValue(String name, TypedValue outValue, boolean resolveRefs) - throws NotFoundException { - throw new UnsupportedOperationException(); - } - - @Override - public XmlResourceParser getXml(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - // check this is a file - File f = new File(value.getValue()); - if (f.isFile()) { - try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(f)); - - return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]); - } catch (XmlPullParserException e) { - NotFoundException newE = new NotFoundException(); - newE.initCause(e); - throw newE; - } catch (FileNotFoundException e) { - NotFoundException newE = new NotFoundException(); - newE.initCause(e); - throw newE; - } - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public InputStream openRawResource(int id) throws NotFoundException { - IResourceValue value = getResourceValue(id, mPlatformResourceFlag); - - if (value != null) { - String v = value.getValue(); - - if (v != null) { - // check this is a file - File f = new File(value.getValue()); - if (f.isFile()) { - try { - return new FileInputStream(f); - } catch (FileNotFoundException e) { - NotFoundException newE = new NotFoundException(); - newE.initCause(e); - throw newE; - } - } - } - } - - // id was not found or not resolved. Throw a NotFoundException. - throwException(id); - - // this is not used since the method above always throws - return null; - } - - @Override - public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException { - throw new UnsupportedOperationException(); - } - - /** - * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource type. - * @param id the id of the resource - * @throws NotFoundException - */ - private void throwException(int id) throws NotFoundException { - // first get the String related to this id in the framework - String[] resourceInfo = Bridge.resolveResourceValue(id); - - // if the name is unknown in the framework, get it from the custom view loader. - if (resourceInfo == null && mProjectCallback != null) { - resourceInfo = mProjectCallback.resolveResourceValue(id); - } - - String message = null; - if (resourceInfo != null) { - message = String.format( - "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.", - resourceInfo[1], id, resourceInfo[0]); - } else { - message = String.format( - "Could not resolve resource value: 0x%1$X.", id); - } - - throw new NotFoundException(message); - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java deleted file mode 100644 index f5da91d..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.internal.util.XmlUtils; -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; - -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.view.ViewGroup.LayoutParams; - -import java.io.File; -import java.io.FileReader; -import java.util.Map; - -/** - * TODO: describe. - */ -public final class BridgeTypedArray extends TypedArray { - - @SuppressWarnings("hiding") - private BridgeResources mResources; - private BridgeContext mContext; - @SuppressWarnings("hiding") - private IResourceValue[] mData; - private String[] mNames; - private final boolean mPlatformFile; - - public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len, - boolean platformFile) { - super(null, null, null, 0); - mResources = resources; - mContext = context; - mPlatformFile = platformFile; - mData = new IResourceValue[len]; - mNames = new String[len]; - } - - /** A bridge-specific method that sets a value in the type array */ - public void bridgeSetValue(int index, String name, IResourceValue value) { - mData[index] = value; - mNames[index] = name; - } - - /** - * Seals the array after all calls to {@link #bridgeSetValue(int, String, IResourceValue)} have - * been done. - * <p/>This allows to compute the list of non default values, permitting - * {@link #getIndexCount()} to return the proper value. - */ - public void sealArray() { - // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt - // first count the array size - int count = 0; - for (IResourceValue data : mData) { - if (data != null) { - count++; - } - } - - // allocate the table with an extra to store the size - mIndices = new int[count+1]; - mIndices[0] = count; - - // fill the array with the indices. - int index = 1; - for (int i = 0 ; i < mData.length ; i++) { - if (mData[i] != null) { - mIndices[index++] = i; - } - } - } - - /** - * Return the number of values in this array. - */ - @Override - public int length() { - return mData.length; - } - - /** - * Return the Resources object this array was loaded from. - */ - @Override - public Resources getResources() { - return mResources; - } - - /** - * Retrieve the styled string value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * - * @return CharSequence holding string data. May be styled. Returns - * null if the attribute is not defined. - */ - @Override - public CharSequence getText(int index) { - if (mData[index] != null) { - // FIXME: handle styled strings! - return mData[index].getValue(); - } - - return null; - } - - /** - * Retrieve the string value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * - * @return String holding string data. Any styling information is - * removed. Returns null if the attribute is not defined. - */ - @Override - public String getString(int index) { - if (mData[index] != null) { - return mData[index].getValue(); - } - - return null; - } - - /** - * Retrieve the boolean value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined. - * - * @return Attribute boolean value, or defValue if not defined. - */ - @Override - public boolean getBoolean(int index, boolean defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - if (s != null) { - return XmlUtils.convertValueToBoolean(s, defValue); - } - - return defValue; - } - - /** - * Retrieve the integer value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined. - * - * @return Attribute int value, or defValue if not defined. - */ - @Override - public int getInt(int index, int defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - - try { - return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue); - } catch (NumberFormatException e) { - // pass - } - - // Field is not null and is not an integer. - // Check for possible constants and try to find them. - // Get the map of attribute-constant -> IntegerValue - Map<String, Integer> map = Bridge.getEnumValues(mNames[index]); - - if (map != null) { - // accumulator to store the value of the 1+ constants. - int result = 0; - - // split the value in case this is a mix of several flags. - String[] keywords = s.split("\\|"); - for (String keyword : keywords) { - Integer i = map.get(keyword.trim()); - if (i != null) { - result |= i.intValue(); - } else { - mContext.getLogger().warning(String.format( - "Unknown constant \"%s\" in attribute \"%2$s\"", - keyword, mNames[index])); - } - } - return result; - } - - return defValue; - } - - /** - * Retrieve the float value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * - * @return Attribute float value, or defValue if not defined.. - */ - @Override - public float getFloat(int index, float defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - - if (s != null) { - try { - return Float.parseFloat(s); - } catch (NumberFormatException e) { - mContext.getLogger().warning(String.format( - "Unable to convert \"%s\" into a float in attribute \"%2$s\"", - s, mNames[index])); - - // we'll return the default value below. - } - } - return defValue; - } - - /** - * Retrieve the color value for the attribute at <var>index</var>. If - * the attribute references a color resource holding a complex - * {@link android.content.res.ColorStateList}, then the default color from - * the set is returned. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute color value, or defValue if not defined. - */ - @Override - public int getColor(int index, int defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - try { - return ResourceHelper.getColor(s); - } catch (NumberFormatException e) { - mContext.getLogger().warning(String.format( - "Unable to convert \"%s\" into a color in attribute \"%2$s\"", - s, mNames[index])); - - // we'll return the default value below. - } - - return defValue; - } - - /** - * Retrieve the ColorStateList for the attribute at <var>index</var>. - * The value may be either a single solid color or a reference to - * a color or complex {@link android.content.res.ColorStateList} description. - * - * @param index Index of attribute to retrieve. - * - * @return ColorStateList for the attribute, or null if not defined. - */ - @Override - public ColorStateList getColorStateList(int index) { - if (mData[index] == null) { - return null; - } - - String value = mData[index].getValue(); - - if (value == null) { - return null; - } - - try { - int color = ResourceHelper.getColor(value); - return ColorStateList.valueOf(color); - } catch (NumberFormatException e) { - // if it's not a color value, we'll attempt to read the xml based color below. - } - - // let the framework inflate the ColorStateList from the XML file. - try { - File f = new File(value); - if (f.isFile()) { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(f)); - - ColorStateList colorStateList = ColorStateList.createFromXml( - mContext.getResources(), - // FIXME: we need to know if this resource is platform or not - new BridgeXmlBlockParser(parser, mContext, false)); - return colorStateList; - } - } catch (Exception e) { - // this is an error and not warning since the file existence is checked before - // attempting to parse it. - mContext.getLogger().error(e); - - // return null below. - } - - // looks like were unable to resolve the color value. - mContext.getLogger().warning(String.format( - "Unable to resolve color value \"%1$s\" in attribute \"%2$s\"", - value, mNames[index])); - - return null; - } - - /** - * Retrieve the integer value for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute integer value, or defValue if not defined. - */ - @Override - public int getInteger(int index, int defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - - if (s != null) { - try { - return Integer.parseInt(s); - } catch (NumberFormatException e) { - mContext.getLogger().warning(String.format( - "Unable to convert \"%s\" into a integer in attribute \"%2$s\"", - s, mNames[index])); - - // The default value is returned below. - } - } - - return defValue; - } - - /** - * Retrieve a dimensional unit attribute at <var>index</var>. Unit - * conversions are based on the current {@link DisplayMetrics} - * associated with the resources this {@link TypedArray} object - * came from. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute dimension value multiplied by the appropriate - * metric, or defValue if not defined. - * - * @see #getDimensionPixelOffset - * @see #getDimensionPixelSize - */ - @Override - public float getDimension(int index, float defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - - if (s == null) { - return defValue; - } else if (s.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; - } else if (s.equals(BridgeConstants.WRAP_CONTENT)) { - return LayoutParams.WRAP_CONTENT; - } - - if (ResourceHelper.stringToFloat(s, mValue)) { - return mValue.getDimension(mResources.mMetrics); - } - - // looks like we were unable to resolve the dimension value - mContext.getLogger().warning(String.format( - "Unable to resolve dimension value \"%1$s\" in attribute \"%2$s\"", - s, mNames[index])); - - return defValue; - } - - /** - * Retrieve a dimensional unit attribute at <var>index</var> for use - * as an offset in raw pixels. This is the same as - * {@link #getDimension}, except the returned value is converted to - * integer pixels for you. An offset conversion involves simply - * truncating the base value to an integer. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute dimension value multiplied by the appropriate - * metric and truncated to integer pixels, or defValue if not defined. - * - * @see #getDimension - * @see #getDimensionPixelSize - */ - @Override - public int getDimensionPixelOffset(int index, int defValue) { - return (int) getDimension(index, defValue); - } - - /** - * Retrieve a dimensional unit attribute at <var>index</var> for use - * as a size in raw pixels. This is the same as - * {@link #getDimension}, except the returned value is converted to - * integer pixels for use as a size. A size conversion involves - * rounding the base value, and ensuring that a non-zero base value - * is at least one pixel in size. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute dimension value multiplied by the appropriate - * metric and truncated to integer pixels, or defValue if not defined. - * - * @see #getDimension - * @see #getDimensionPixelOffset - */ - @Override - public int getDimensionPixelSize(int index, int defValue) { - if (mData[index] == null) { - return defValue; - } - - String s = mData[index].getValue(); - - if (s == null) { - return defValue; - } else if (s.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; - } else if (s.equals(BridgeConstants.WRAP_CONTENT)) { - return LayoutParams.WRAP_CONTENT; - } - - // FIXME huh? - - float f = getDimension(index, defValue); - final int res = (int)(f+0.5f); - if (res != 0) return res; - if (f == 0) return 0; - if (f > 0) return 1; - - throw new UnsupportedOperationException("Can't convert to dimension: " + - Integer.toString(index)); - } - - /** - * Special version of {@link #getDimensionPixelSize} for retrieving - * {@link android.view.ViewGroup}'s layout_width and layout_height - * attributes. This is only here for performance reasons; applications - * should use {@link #getDimensionPixelSize}. - * - * @param index Index of the attribute to retrieve. - * @param name Textual name of attribute for error reporting. - * - * @return Attribute dimension value multiplied by the appropriate - * metric and truncated to integer pixels. - */ - @Override - public int getLayoutDimension(int index, String name) { - return getDimensionPixelSize(index, 0); - } - - /** - * Retrieve a fractional unit attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * @param base The base value of this fraction. In other words, a - * standard fraction is multiplied by this value. - * @param pbase The parent base value of this fraction. In other - * words, a parent fraction (nn%p) is multiplied by this - * value. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute fractional value multiplied by the appropriate - * base value, or defValue if not defined. - */ - @Override - public float getFraction(int index, int base, int pbase, float defValue) { - if (mData[index] == null) { - return defValue; - } - - String value = mData[index].getValue(); - if (value == null) { - return defValue; - } - - if (ResourceHelper.stringToFloat(value, mValue)) { - return mValue.getFraction(base, pbase); - } - - // looks like we were unable to resolve the fraction value - mContext.getLogger().warning(String.format( - "Unable to resolve fraction value \"%1$s\" in attribute \"%2$s\"", - value, mNames[index])); - - return defValue; - } - - /** - * Retrieve the resource identifier for the attribute at - * <var>index</var>. Note that attribute resource as resolved when - * the overall {@link TypedArray} object is retrieved. As a - * result, this function will return the resource identifier of the - * final resource value that was found, <em>not</em> necessarily the - * original resource that was specified by the attribute. - * - * @param index Index of attribute to retrieve. - * @param defValue Value to return if the attribute is not defined or - * not a resource. - * - * @return Attribute resource identifier, or defValue if not defined. - */ - @Override - public int getResourceId(int index, int defValue) { - // get the IResource for this index - IResourceValue resValue = mData[index]; - - // no data, return the default value. - if (resValue == null) { - return defValue; - } - - // check if this is a style resource - if (resValue instanceof IStyleResourceValue) { - // get the id that will represent this style. - return mContext.getDynamicIdByStyle((IStyleResourceValue)resValue); - } - - // if the attribute was a reference to an id, and not a declaration of an id (@+id), then - // the xml attribute value was "resolved" which leads us to a IResourceValue with - // getType() returning "id" and getName() returning the id name - // (and getValue() returning null!). We need to handle this! - if (resValue.getType() != null && resValue.getType().equals(BridgeConstants.RES_ID)) { - // if this is a framework id - if (mPlatformFile || resValue.isFramework()) { - // look for idName in the android R classes - return mContext.getFrameworkIdValue(resValue.getName(), defValue); - } - - // look for idName in the project R class. - return mContext.getProjectIdValue(resValue.getName(), defValue); - } - - // else, try to get the value, and resolve it somehow. - String value = resValue.getValue(); - if (value == null) { - return defValue; - } - - // if the value is just an integer, return it. - try { - int i = Integer.parseInt(value); - if (Integer.toString(i).equals(value)) { - return i; - } - } catch (NumberFormatException e) { - // pass - } - - // Handle the @id/<name>, @+id/<name> and @android:id/<name> - // We need to return the exact value that was compiled (from the various R classes), - // as these values can be reused internally with calls to findViewById(). - // There's a trick with platform layouts that not use "android:" but their IDs are in - // fact in the android.R and com.android.internal.R classes. - // The field mPlatformFile will indicate that all IDs are to be looked up in the android R - // classes exclusively. - - // if this is a reference to an id, find it. - if (value.startsWith("@id/") || value.startsWith("@+") || - value.startsWith("@android:id/")) { - - int pos = value.indexOf('/'); - String idName = value.substring(pos + 1); - - // if this is a framework id - if (mPlatformFile || value.startsWith("@android") || value.startsWith("@+android")) { - // look for idName in the android R classes - return mContext.getFrameworkIdValue(idName, defValue); - } - - // look for idName in the project R class. - return mContext.getProjectIdValue(idName, defValue); - } - - // not a direct id valid reference? resolve it - Integer idValue = null; - - if (resValue.isFramework()) { - idValue = Bridge.getResourceValue(resValue.getType(), resValue.getName()); - } else { - idValue = mContext.getProjectCallback().getResourceValue( - resValue.getType(), resValue.getName()); - } - - if (idValue != null) { - return idValue.intValue(); - } - - mContext.getLogger().warning(String.format( - "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index])); - return defValue; - } - - /** - * Retrieve the Drawable for the attribute at <var>index</var>. This - * gets the resource ID of the selected attribute, and uses - * {@link Resources#getDrawable Resources.getDrawable} of the owning - * Resources object to retrieve its Drawable. - * - * @param index Index of attribute to retrieve. - * - * @return Drawable for the attribute, or null if not defined. - */ - @Override - public Drawable getDrawable(int index) { - if (mData[index] == null) { - return null; - } - - String value = mData[index].getValue(); - if (value == null || BridgeConstants.REFERENCE_NULL.equals(value)) { - return null; - } - - Drawable d = ResourceHelper.getDrawable(value, mContext, mData[index].isFramework()); - - if (d != null) { - return d; - } - - // looks like we were unable to resolve the drawable - mContext.getLogger().warning(String.format( - "Unable to resolve drawable \"%1$s\" in attribute \"%2$s\"", value, mNames[index])); - - return null; - } - - - /** - * Retrieve the CharSequence[] for the attribute at <var>index</var>. - * This gets the resource ID of the selected attribute, and uses - * {@link Resources#getTextArray Resources.getTextArray} of the owning - * Resources object to retrieve its String[]. - * - * @param index Index of attribute to retrieve. - * - * @return CharSequence[] for the attribute, or null if not defined. - */ - @Override - public CharSequence[] getTextArray(int index) { - if (mData[index] == null) { - return null; - } - - String value = mData[index].getValue(); - if (value == null) { - return null; - } - - throw new UnsupportedOperationException( - String.format("BridgeTypedArray: UNKNOWN VALUE FOR getTextArray(%d) => %s", //DEBUG - index, value)); - - } - - /** - * Retrieve the raw TypedValue for the attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * @param outValue TypedValue object in which to place the attribute's - * data. - * - * @return Returns true if the value was retrieved, else false. - */ - @Override - public boolean getValue(int index, TypedValue outValue) { - if (mData[index] == null) { - return false; - } - - String s = mData[index].getValue(); - - return ResourceHelper.stringToFloat(s, outValue); - } - - /** - * Determines whether there is an attribute at <var>index</var>. - * - * @param index Index of attribute to retrieve. - * - * @return True if the attribute has a value, false otherwise. - */ - @Override - public boolean hasValue(int index) { - return mData[index] != null; - } - - /** - * Retrieve the raw TypedValue for the attribute at <var>index</var> - * and return a temporary object holding its data. This object is only - * valid until the next call on to {@link TypedArray}. - * - * @param index Index of attribute to retrieve. - * - * @return Returns a TypedValue object if the attribute is defined, - * containing its data; otherwise returns null. (You will not - * receive a TypedValue whose type is TYPE_NULL.) - */ - @Override - public TypedValue peekValue(int index) { - if (getValue(index, mValue)) { - return mValue; - } - - return null; - } - - /** - * Returns a message about the parser state suitable for printing error messages. - */ - @Override - public String getPositionDescription() { - return "<internal -- stub if needed>"; - } - - /** - * Give back a previously retrieved StyledAttributes, for later re-use. - */ - @Override - public void recycle() { - // pass - } - - @Override - public boolean getValueAt(int index, TypedValue outValue) { - // pass - return false; - } - - @Override - public String toString() { - return mData.toString(); - } - } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java deleted file mode 100644 index d842a66..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.IXmlPullParser; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.content.res.XmlResourceParser; -import android.util.AttributeSet; -import android.util.XmlPullAttributes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -/** - * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser. - * It delegates to both an instance of {@link XmlPullParser} and an instance of - * {@link XmlPullAttributes} (for the {@link AttributeSet} part). - */ -public class BridgeXmlBlockParser implements XmlResourceParser { - - private XmlPullParser mParser; - private XmlPullAttributes mAttrib; - - private boolean mStarted = false; - private boolean mDecNextDepth = false; - private int mDepth = 0; - private int mEventType = START_DOCUMENT; - private final boolean mPlatformFile; - - /** - * Builds a {@link BridgeXmlBlockParser}. - * @param parser The XmlPullParser to get the content from. - * @param context the Context. - * @param platformFile Indicates whether the the file is a platform file or not. - */ - public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) { - mParser = parser; - mPlatformFile = platformFile; - mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile); - } - - public boolean isPlatformFile() { - return mPlatformFile; - } - - public Object getViewKey() { - if (mParser instanceof IXmlPullParser) { - return ((IXmlPullParser)mParser).getViewKey(); - } - - return null; - } - - - // ------- XmlResourceParser implementation - - public void setFeature(String name, boolean state) - throws XmlPullParserException { - if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) { - return; - } - if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) { - return; - } - throw new XmlPullParserException("Unsupported feature: " + name); - } - - public boolean getFeature(String name) { - if (FEATURE_PROCESS_NAMESPACES.equals(name)) { - return true; - } - if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) { - return true; - } - return false; - } - - public void setProperty(String name, Object value) throws XmlPullParserException { - throw new XmlPullParserException("setProperty() not supported"); - } - - public Object getProperty(String name) { - return null; - } - - public void setInput(Reader in) throws XmlPullParserException { - mParser.setInput(in); - } - - public void setInput(InputStream inputStream, String inputEncoding) - throws XmlPullParserException { - mParser.setInput(inputStream, inputEncoding); - } - - public void defineEntityReplacementText(String entityName, - String replacementText) throws XmlPullParserException { - throw new XmlPullParserException( - "defineEntityReplacementText() not supported"); - } - - public String getNamespacePrefix(int pos) throws XmlPullParserException { - throw new XmlPullParserException("getNamespacePrefix() not supported"); - } - - public String getInputEncoding() { - return null; - } - - public String getNamespace(String prefix) { - throw new RuntimeException("getNamespace() not supported"); - } - - public int getNamespaceCount(int depth) throws XmlPullParserException { - throw new XmlPullParserException("getNamespaceCount() not supported"); - } - - public String getPositionDescription() { - return "Binary XML file line #" + getLineNumber(); - } - - public String getNamespaceUri(int pos) throws XmlPullParserException { - throw new XmlPullParserException("getNamespaceUri() not supported"); - } - - public int getColumnNumber() { - return -1; - } - - public int getDepth() { - return mDepth; - } - - public String getText() { - return mParser.getText(); - } - - public int getLineNumber() { - return mParser.getLineNumber(); - } - - public int getEventType() { - return mEventType; - } - - public boolean isWhitespace() throws XmlPullParserException { - // Original comment: whitespace was stripped by aapt. - return mParser.isWhitespace(); - } - - public String getPrefix() { - throw new RuntimeException("getPrefix not supported"); - } - - public char[] getTextCharacters(int[] holderForStartAndLength) { - String txt = getText(); - char[] chars = null; - if (txt != null) { - holderForStartAndLength[0] = 0; - holderForStartAndLength[1] = txt.length(); - chars = new char[txt.length()]; - txt.getChars(0, txt.length(), chars, 0); - } - return chars; - } - - public String getNamespace() { - return mParser.getNamespace(); - } - - public String getName() { - return mParser.getName(); - } - - public String getAttributeNamespace(int index) { - return mParser.getAttributeNamespace(index); - } - - public String getAttributeName(int index) { - return mParser.getAttributeName(index); - } - - public String getAttributePrefix(int index) { - throw new RuntimeException("getAttributePrefix not supported"); - } - - public boolean isEmptyElementTag() { - // XXX Need to detect this. - return false; - } - - public int getAttributeCount() { - return mParser.getAttributeCount(); - } - - public String getAttributeValue(int index) { - return mParser.getAttributeValue(index); - } - - public String getAttributeType(int index) { - return "CDATA"; - } - - public boolean isAttributeDefault(int index) { - return false; - } - - public int nextToken() throws XmlPullParserException, IOException { - return next(); - } - - public String getAttributeValue(String namespace, String name) { - return mParser.getAttributeValue(namespace, name); - } - - public int next() throws XmlPullParserException, IOException { - if (!mStarted) { - mStarted = true; - return START_DOCUMENT; - } - int ev = mParser.next(); - if (mDecNextDepth) { - mDepth--; - mDecNextDepth = false; - } - switch (ev) { - case START_TAG: - mDepth++; - break; - case END_TAG: - mDecNextDepth = true; - break; - } - mEventType = ev; - return ev; - } - - public void require(int type, String namespace, String name) - throws XmlPullParserException { - if (type != getEventType() - || (namespace != null && !namespace.equals(getNamespace())) - || (name != null && !name.equals(getName()))) - throw new XmlPullParserException("expected " + TYPES[type] - + getPositionDescription()); - } - - public String nextText() throws XmlPullParserException, IOException { - if (getEventType() != START_TAG) { - throw new XmlPullParserException(getPositionDescription() - + ": parser must be on START_TAG to read next text", this, - null); - } - int eventType = next(); - if (eventType == TEXT) { - String result = getText(); - eventType = next(); - if (eventType != END_TAG) { - throw new XmlPullParserException( - getPositionDescription() - + ": event TEXT it must be immediately followed by END_TAG", - this, null); - } - return result; - } else if (eventType == END_TAG) { - return ""; - } else { - throw new XmlPullParserException(getPositionDescription() - + ": parser must be on START_TAG or TEXT to read text", - this, null); - } - } - - public int nextTag() throws XmlPullParserException, IOException { - int eventType = next(); - if (eventType == TEXT && isWhitespace()) { // skip whitespace - eventType = next(); - } - if (eventType != START_TAG && eventType != END_TAG) { - throw new XmlPullParserException(getPositionDescription() - + ": expected start or end tag", this, null); - } - return eventType; - } - - // AttributeSet implementation - - - public void close() { - // pass - } - - public boolean getAttributeBooleanValue(int index, boolean defaultValue) { - return mAttrib.getAttributeBooleanValue(index, defaultValue); - } - - public boolean getAttributeBooleanValue(String namespace, String attribute, - boolean defaultValue) { - return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue); - } - - public float getAttributeFloatValue(int index, float defaultValue) { - return mAttrib.getAttributeFloatValue(index, defaultValue); - } - - public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) { - return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue); - } - - public int getAttributeIntValue(int index, int defaultValue) { - return mAttrib.getAttributeIntValue(index, defaultValue); - } - - public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { - return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue); - } - - public int getAttributeListValue(int index, String[] options, int defaultValue) { - return mAttrib.getAttributeListValue(index, options, defaultValue); - } - - public int getAttributeListValue(String namespace, String attribute, - String[] options, int defaultValue) { - return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue); - } - - public int getAttributeNameResource(int index) { - return mAttrib.getAttributeNameResource(index); - } - - public int getAttributeResourceValue(int index, int defaultValue) { - return mAttrib.getAttributeResourceValue(index, defaultValue); - } - - public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { - return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue); - } - - public int getAttributeUnsignedIntValue(int index, int defaultValue) { - return mAttrib.getAttributeUnsignedIntValue(index, defaultValue); - } - - public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) { - return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue); - } - - public String getClassAttribute() { - return mAttrib.getClassAttribute(); - } - - public String getIdAttribute() { - return mAttrib.getIdAttribute(); - } - - public int getIdAttributeResourceValue(int defaultValue) { - return mAttrib.getIdAttributeResourceValue(defaultValue); - } - - public int getStyleAttribute() { - return mAttrib.getStyleAttribute(); - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java deleted file mode 100644 index 4be6eab..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.IResourceValue; - -import org.xmlpull.v1.XmlPullParser; - -import android.util.AttributeSet; -import android.util.XmlPullAttributes; - -/** - * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser - */ -public class BridgeXmlPullAttributes extends XmlPullAttributes { - - private final BridgeContext mContext; - private final boolean mPlatformFile; - - public BridgeXmlPullAttributes(XmlPullParser parser, BridgeContext context, - boolean platformFile) { - super(parser); - mContext = context; - mPlatformFile = platformFile; - } - - /* - * (non-Javadoc) - * @see android.util.XmlPullAttributes#getAttributeNameResource(int) - * - * This methods must return com.android.internal.R.attr.<name> matching - * the name of the attribute. - * It returns 0 if it doesn't find anything. - */ - @Override - public int getAttributeNameResource(int index) { - // get the attribute name. - String name = getAttributeName(index); - - // get the attribute namespace - String ns = mParser.getAttributeNamespace(index); - - if (BridgeConstants.NS_RESOURCES.equals(ns)) { - Integer v = Bridge.getResourceValue(BridgeConstants.RES_ATTR, name); - if (v != null) { - return v.intValue(); - } - - return 0; - } - - // this is not an attribute in the android namespace, we query the customviewloader, if - // the namespaces match. - if (mContext.getProjectCallback().getNamespace().equals(ns)) { - Integer v = mContext.getProjectCallback().getResourceValue(BridgeConstants.RES_ATTR, - name); - if (v != null) { - return v.intValue(); - } - } - - return 0; - } - - /* - * (non-Javadoc) - * @see android.util.XmlPullAttributes#getAttributeResourceValue(int, int) - */ - @Override - public int getAttributeResourceValue(int index, int defaultValue) { - String value = getAttributeValue(index); - - return resolveResourceValue(value, defaultValue); - } - - /* - * (non-Javadoc) - * @see android.util.XmlPullAttributes#getAttributeResourceValue(java.lang.String, java.lang.String, int) - */ - @Override - public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { - String value = getAttributeValue(namespace, attribute); - - return resolveResourceValue(value, defaultValue); - } - - private int resolveResourceValue(String value, int defaultValue) { - // now look for this particular value - IResourceValue resource = mContext.resolveResValue(mContext.findResValue(value)); - - if (resource != null) { - Integer id = null; - if (mPlatformFile || resource.isFramework()) { - id = Bridge.getResourceValue(resource.getType(), resource.getName()); - } else { - id = mContext.getProjectCallback().getResourceValue( - resource.getType(), resource.getName()); - } - - if (id != null) { - return id; - } - } - - return defaultValue; - } - -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java deleted file mode 100644 index 1bdd1cc..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import android.graphics.Typeface; - -import java.awt.Font; -import java.awt.FontFormatException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -/** - * Provides {@link Font} object to the layout lib. - * <p/> - * The fonts are loaded from the SDK directory. Family/style mapping is done by parsing the - * fonts.xml file located alongside the ttf files. - */ -public final class FontLoader { - private static final String FONTS_DEFINITIONS = "fonts.xml"; - - private static final String NODE_FONTS = "fonts"; - private static final String NODE_FONT = "font"; - private static final String NODE_NAME = "name"; - - private static final String ATTR_TTF = "ttf"; - - private static final String[] NODE_LEVEL = { NODE_FONTS, NODE_FONT, NODE_NAME }; - - private static final String FONT_EXT = ".ttf"; - - private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" }; - private static final String[] FONT_STYLE_BOLD = { "-Bold" }; - private static final String[] FONT_STYLE_ITALIC = { "-Italic" }; - private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" }; - - // list of font style, in the order matching the Typeface Font style - private static final String[][] FONT_STYLES = { - FONT_STYLE_DEFAULT, - FONT_STYLE_BOLD, - FONT_STYLE_ITALIC, - FONT_STYLE_BOLDITALIC - }; - - private final Map<String, String> mFamilyToTtf = new HashMap<String, String>(); - private final Map<String, Map<Integer, Font>> mTtfToFontMap = - new HashMap<String, Map<Integer, Font>>(); - - public static FontLoader create(String fontOsLocation) { - try { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - - SAXParser parser = parserFactory.newSAXParser(); - File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS); - - FontDefinitionParser definitionParser = new FontDefinitionParser( - fontOsLocation + File.separator); - parser.parse(new FileInputStream(f), definitionParser); - - return definitionParser.getFontLoader(); - } catch (ParserConfigurationException e) { - // return null below - } catch (SAXException e) { - // return null below - } catch (FileNotFoundException e) { - // return null below - } catch (IOException e) { - // return null below - } - - return null; - } - - private FontLoader(List<FontInfo> fontList) { - for (FontInfo info : fontList) { - for (String family : info.families) { - mFamilyToTtf.put(family, info.ttf); - } - } - } - - public synchronized Font getFont(String family, int[] style) { - if (family == null) { - return null; - } - - // get the ttf name from the family - String ttf = mFamilyToTtf.get(family); - - if (ttf == null) { - return null; - } - - // get the font from the ttf - Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf); - - if (styleMap == null) { - styleMap = new HashMap<Integer, Font>(); - mTtfToFontMap.put(ttf, styleMap); - } - - Font f = styleMap.get(style); - - if (f != null) { - return f; - } - - // if it doesn't exist, we create it, and we can't, we try with a simpler style - switch (style[0]) { - case Typeface.NORMAL: - f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); - break; - case Typeface.BOLD: - case Typeface.ITALIC: - f = getFont(ttf, FONT_STYLES[style[0]]); - if (f == null) { - f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); - style[0] = Typeface.NORMAL; - } - break; - case Typeface.BOLD_ITALIC: - f = getFont(ttf, FONT_STYLES[style[0]]); - if (f == null) { - f = getFont(ttf, FONT_STYLES[Typeface.BOLD]); - if (f != null) { - style[0] = Typeface.BOLD; - } else { - f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]); - if (f != null) { - style[0] = Typeface.ITALIC; - } else { - f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); - style[0] = Typeface.NORMAL; - } - } - } - break; - } - - if (f != null) { - styleMap.put(style[0], f); - return f; - } - - return null; - } - - private Font getFont(String ttf, String[] fontFileSuffix) { - for (String suffix : fontFileSuffix) { - String name = ttf + suffix + FONT_EXT; - - File f = new File(name); - if (f.isFile()) { - try { - Font font = Font.createFont(Font.TRUETYPE_FONT, f); - if (font != null) { - return font; - } - } catch (FontFormatException e) { - // skip this font name - } catch (IOException e) { - // skip this font name - } - } - } - - return null; - } - - private final static class FontInfo { - String ttf; - final Set<String> families; - - FontInfo() { - families = new HashSet<String>(); - } - } - - private final static class FontDefinitionParser extends DefaultHandler { - private final String mOsFontsLocation; - - private int mDepth = 0; - private FontInfo mFontInfo = null; - private final StringBuilder mBuilder = new StringBuilder(); - private final List<FontInfo> mFontList = new ArrayList<FontInfo>(); - - private FontDefinitionParser(String osFontsLocation) { - super(); - mOsFontsLocation = osFontsLocation; - } - - FontLoader getFontLoader() { - return new FontLoader(mFontList); - } - - /* (non-Javadoc) - * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) - */ - @Override - public void startElement(String uri, String localName, String name, Attributes attributes) - throws SAXException { - if (localName.equals(NODE_LEVEL[mDepth])) { - mDepth++; - - if (mDepth == 2) { // font level. - String ttf = attributes.getValue(ATTR_TTF); - if (ttf != null) { - mFontInfo = new FontInfo(); - mFontInfo.ttf = mOsFontsLocation + ttf; - mFontList.add(mFontInfo); - } - } - } - - super.startElement(uri, localName, name, attributes); - } - - /* (non-Javadoc) - * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) - */ - @SuppressWarnings("unused") - @Override - public void characters(char[] ch, int start, int length) throws SAXException { - if (mFontInfo != null) { - mBuilder.append(ch, start, length); - } - } - - /* (non-Javadoc) - * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) - */ - @SuppressWarnings("unused") - @Override - public void endElement(String uri, String localName, String name) throws SAXException { - if (localName.equals(NODE_LEVEL[mDepth-1])) { - mDepth--; - if (mDepth == 2) { // end of a <name> node - if (mFontInfo != null) { - String family = trimXmlWhitespaces(mBuilder.toString()); - mFontInfo.families.add(family); - mBuilder.setLength(0); - } - } else if (mDepth == 1) { // end of a <font> node - mFontInfo = null; - } - } - } - - private String trimXmlWhitespaces(String value) { - if (value == null) { - return null; - } - - // look for carriage return and replace all whitespace around it by just 1 space. - int index; - - while ((index = value.indexOf('\n')) != -1) { - // look for whitespace on each side - int left = index - 1; - while (left >= 0) { - if (Character.isWhitespace(value.charAt(left))) { - left--; - } else { - break; - } - } - - int right = index + 1; - int count = value.length(); - while (right < count) { - if (Character.isWhitespace(value.charAt(right))) { - right++; - } else { - break; - } - } - - // remove all between left and right (non inclusive) and replace by a single space. - String leftString = null; - if (left >= 0) { - leftString = value.substring(0, left + 1); - } - String rightString = null; - if (right < count) { - rightString = value.substring(right); - } - - if (leftString != null) { - value = leftString; - if (rightString != null) { - value += " " + rightString; - } - } else { - value = rightString != null ? rightString : ""; - } - } - - // now we un-escape the string - int length = value.length(); - char[] buffer = value.toCharArray(); - - for (int i = 0 ; i < length ; i++) { - if (buffer[i] == '\\') { - if (buffer[i+1] == 'n') { - // replace the char with \n - buffer[i+1] = '\n'; - } - - // offset the rest of the buffer since we go from 2 to 1 char - System.arraycopy(buffer, i+1, buffer, i, length - i - 1); - length--; - } - } - - return new String(buffer, 0, length); - } - - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java deleted file mode 100644 index c4c5225..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.ILayoutResult; - -import java.awt.image.BufferedImage; - -/** - * Implementation of {@link ILayoutResult} - */ -public final class LayoutResult implements ILayoutResult { - - private final ILayoutViewInfo mRootView; - private final BufferedImage mImage; - private final int mSuccess; - private final String mErrorMessage; - - /** - * Creates a {@link #SUCCESS} {@link ILayoutResult} with the specified params - * @param rootView - * @param image - */ - public LayoutResult(ILayoutViewInfo rootView, BufferedImage image) { - mSuccess = SUCCESS; - mErrorMessage = null; - mRootView = rootView; - mImage = image; - } - - /** - * Creates a LayoutResult with a specific success code and associated message - * @param code - * @param message - */ - public LayoutResult(int code, String message) { - mSuccess = code; - mErrorMessage = message; - mRootView = null; - mImage = null; - } - - public int getSuccess() { - return mSuccess; - } - - public String getErrorMessage() { - return mErrorMessage; - } - - public BufferedImage getImage() { - return mImage; - } - - public ILayoutViewInfo getRootView() { - return mRootView; - } - - /** - * Implementation of {@link ILayoutResult.ILayoutViewInfo} - */ - public static final class LayoutViewInfo implements ILayoutViewInfo { - private final Object mKey; - private final String mName; - private final int mLeft; - private final int mRight; - private final int mTop; - private final int mBottom; - private ILayoutViewInfo[] mChildren; - - public LayoutViewInfo(String name, Object key, int left, int top, int right, int bottom) { - mName = name; - mKey = key; - mLeft = left; - mRight = right; - mTop = top; - mBottom = bottom; - } - - public void setChildren(ILayoutViewInfo[] children) { - mChildren = children; - } - - public ILayoutViewInfo[] getChildren() { - return mChildren; - } - - public Object getViewKey() { - return mKey; - } - - public String getName() { - return mName; - } - - public int getLeft() { - return mLeft; - } - - public int getTop() { - return mTop; - } - - public int getRight() { - return mRight; - } - - public int getBottom() { - return mBottom; - } - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java deleted file mode 100644 index 1ca3182..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.widget.TextView; - -/** - * Base class for mocked views. - * - * TODO: implement onDraw and draw a rectangle in a random color with the name of the class - * (or better the id of the view). - */ -public class MockView extends TextView { - - public MockView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - setText(this.getClass().getSimpleName()); - setTextColor(0xFF000000); - } - - @Override - public void onDraw(Canvas canvas) { - canvas.drawARGB(0xFF, 0x7F, 0x7F, 0x7F); - - super.onDraw(canvas); - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java deleted file mode 100644 index 5f0852e..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.ninepatch.NinePatch; - -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; - -public class NinePatchDrawable extends Drawable { - - private NinePatch m9Patch; - - NinePatchDrawable(NinePatch ninePatch) { - m9Patch = ninePatch; - } - - @Override - public int getMinimumWidth() { - return m9Patch.getWidth(); - } - - @Override - public int getMinimumHeight() { - return m9Patch.getHeight(); - } - - /** - * Return the intrinsic width of the underlying drawable object. Returns - * -1 if it has no intrinsic width, such as with a solid color. - */ - @Override - public int getIntrinsicWidth() { - return m9Patch.getWidth(); - } - - /** - * Return the intrinsic height of the underlying drawable object. Returns - * -1 if it has no intrinsic height, such as with a solid color. - */ - @Override - public int getIntrinsicHeight() { - return m9Patch.getHeight(); - } - - /** - * Return in padding the insets suggested by this Drawable for placing - * content inside the drawable's bounds. Positive values move toward the - * center of the Drawable (set Rect.inset). Returns true if this drawable - * actually has a padding, else false. When false is returned, the padding - * is always set to 0. - */ - @Override - public boolean getPadding(Rect padding) { - int[] padd = new int[4]; - m9Patch.getPadding(padd); - padding.left = padd[0]; - padding.top = padd[1]; - padding.right = padd[2]; - padding.bottom = padd[3]; - return true; - } - - @Override - public void draw(Canvas canvas) { - if (canvas instanceof BridgeCanvas) { - BridgeCanvas bridgeCanvas = (BridgeCanvas)canvas; - - Rect r = getBounds(); - m9Patch.draw(bridgeCanvas.getGraphics2d(), r.left, r.top, r.width(), r.height()); - - return; - } - - throw new UnsupportedOperationException(); - } - - - // ----------- Not implemented methods --------------- - - - @Override - public int getOpacity() { - // FIXME - return 0xFF; - } - - @Override - public void setAlpha(int arg0) { - // FIXME ! - } - - @Override - public void setColorFilter(ColorFilter arg0) { - // FIXME - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java deleted file mode 100644 index fbdf8dc..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.ninepatch.NinePatch; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.util.TypedValue; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Helper class to provide various convertion method used in handling android resources. - */ -public final class ResourceHelper { - - private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)"); - private final static float[] sFloatOut = new float[1]; - - private final static TypedValue mValue = new TypedValue(); - - /** - * Returns the color value represented by the given string value - * @param value the color value - * @return the color as an int - * @throw NumberFormatException if the conversion failed. - */ - static int getColor(String value) { - if (value != null) { - if (value.startsWith("#") == false) { - throw new NumberFormatException(); - } - - value = value.substring(1); - - // make sure it's not longer than 32bit - if (value.length() > 8) { - throw new NumberFormatException(); - } - - if (value.length() == 3) { // RGB format - char[] color = new char[8]; - color[0] = color[1] = 'F'; - color[2] = color[3] = value.charAt(0); - color[4] = color[5] = value.charAt(1); - color[6] = color[7] = value.charAt(2); - value = new String(color); - } else if (value.length() == 4) { // ARGB format - char[] color = new char[8]; - color[0] = color[1] = value.charAt(0); - color[2] = color[3] = value.charAt(1); - color[4] = color[5] = value.charAt(2); - color[6] = color[7] = value.charAt(3); - value = new String(color); - } else if (value.length() == 6) { - value = "FF" + value; - } - - // this is a RRGGBB or AARRGGBB value - - // Integer.parseInt will fail to parse strings like "ff191919", so we use - // a Long, but cast the result back into an int, since we know that we're only - // dealing with 32 bit values. - return (int)Long.parseLong(value, 16); - } - - throw new NumberFormatException(); - } - - /** - * Returns a drawable from the given value. - * @param value The value. A path to a 9 patch, a bitmap or a xml based drawable, - * or an hexadecimal color - * @param context - * @param isFramework indicates whether the resource is a framework resources. - * Framework resources are cached, and loaded only once. - */ - public static Drawable getDrawable(String value, BridgeContext context, boolean isFramework) { - Drawable d = null; - - String lowerCaseValue = value.toLowerCase(); - - if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) { - File f = new File(value); - if (f.isFile()) { - NinePatch ninePatch = Bridge.getCached9Patch(value, - isFramework ? null : context.getProjectKey()); - - if (ninePatch == null) { - try { - ninePatch = NinePatch.load(new File(value).toURL(), false /* convert */); - - Bridge.setCached9Patch(value, ninePatch, - isFramework ? null : context.getProjectKey()); - } catch (MalformedURLException e) { - // URL is wrong, we'll return null below - } catch (IOException e) { - // failed to read the file, we'll return null below. - } - } - - if (ninePatch != null) { - return new NinePatchDrawable(ninePatch); - } - } - - return null; - } else if (lowerCaseValue.endsWith(".xml")) { - // create a blockparser for the file - File f = new File(value); - if (f.isFile()) { - try { - // let the framework inflate the Drawable from the XML file. - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(f)); - - d = Drawable.createFromXml(context.getResources(), - // FIXME: we need to know if this resource is platform or not - new BridgeXmlBlockParser(parser, context, false)); - return d; - } catch (XmlPullParserException e) { - context.getLogger().error(e); - } catch (FileNotFoundException e) { - // will not happen, since we pre-check - } catch (IOException e) { - context.getLogger().error(e); - } - } - - return null; - } else { - File bmpFile = new File(value); - if (bmpFile.isFile()) { - try { - Bitmap bitmap = Bridge.getCachedBitmap(value, - isFramework ? null : context.getProjectKey()); - - if (bitmap == null) { - bitmap = new Bitmap(bmpFile); - Bridge.setCachedBitmap(value, bitmap, - isFramework ? null : context.getProjectKey()); - } - - return new BitmapDrawable(bitmap); - } catch (IOException e) { - // we'll return null below - // TODO: log the error. - } - } else { - // attempt to get a color from the value - try { - int color = getColor(value); - return new ColorDrawable(color); - } catch (NumberFormatException e) { - // we'll return null below. - // TODO: log the error - } - } - } - - return null; - } - - - // ------- TypedValue stuff - // This is taken from //device/libs/utils/ResourceTypes.cpp - - private static final class UnitEntry { - String name; - int type; - int unit; - float scale; - - UnitEntry(String name, int type, int unit, float scale) { - this.name = name; - this.type = type; - this.unit = unit; - this.scale = scale; - } - } - - private final static UnitEntry[] sUnitNames = new UnitEntry[] { - new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f), - new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f), - new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f), - new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f), - new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f), - new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f), - new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f), - new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100), - new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100), - }; - - /** - * Returns the raw value from the given string. - * This object is only valid until the next call on to {@link ResourceHelper}. - */ - public static TypedValue getValue(String s) { - if (stringToFloat(s, mValue)) { - return mValue; - } - - return null; - } - - /** - * Convert the string into a {@link TypedValue}. - * @param s - * @param outValue - * @return true if success. - */ - public static boolean stringToFloat(String s, TypedValue outValue) { - // remove the space before and after - s.trim(); - int len = s.length(); - - if (len <= 0) { - return false; - } - - // check that there's no non ascii characters. - char[] buf = s.toCharArray(); - for (int i = 0 ; i < len ; i++) { - if (buf[i] > 255) { - return false; - } - } - - // check the first character - if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') { - return false; - } - - // now look for the string that is after the float... - Matcher m = sFloatPattern.matcher(s); - if (m.matches()) { - String f_str = m.group(1); - String end = m.group(2); - - float f; - try { - f = Float.parseFloat(f_str); - } catch (NumberFormatException e) { - // this shouldn't happen with the regexp above. - return false; - } - - if (end.length() > 0 && end.charAt(0) != ' ') { - // Might be a unit... - if (parseUnit(end, outValue, sFloatOut)) { - - f *= sFloatOut[0]; - boolean neg = f < 0; - if (neg) { - f = -f; - } - long bits = (long)(f*(1<<23)+.5f); - int radix; - int shift; - if ((bits&0x7fffff) == 0) { - // Always use 23p0 if there is no fraction, just to make - // things easier to read. - radix = TypedValue.COMPLEX_RADIX_23p0; - shift = 23; - } else if ((bits&0xffffffffff800000L) == 0) { - // Magnitude is zero -- can fit in 0 bits of precision. - radix = TypedValue.COMPLEX_RADIX_0p23; - shift = 0; - } else if ((bits&0xffffffff80000000L) == 0) { - // Magnitude can fit in 8 bits of precision. - radix = TypedValue.COMPLEX_RADIX_8p15; - shift = 8; - } else if ((bits&0xffffff8000000000L) == 0) { - // Magnitude can fit in 16 bits of precision. - radix = TypedValue.COMPLEX_RADIX_16p7; - shift = 16; - } else { - // Magnitude needs entire range, so no fractional part. - radix = TypedValue.COMPLEX_RADIX_23p0; - shift = 23; - } - int mantissa = (int)( - (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK); - if (neg) { - mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK; - } - outValue.data |= - (radix<<TypedValue.COMPLEX_RADIX_SHIFT) - | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT); - return true; - } - return false; - } - - // make sure it's only spaces at the end. - end = end.trim(); - - if (end.length() == 0) { - if (outValue != null) { - outValue.type = TypedValue.TYPE_FLOAT; - outValue.data = Float.floatToIntBits(f); - return true; - } - } - } - - return false; - } - - private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) { - str = str.trim(); - - for (UnitEntry unit : sUnitNames) { - if (unit.name.equals(str)) { - outValue.type = unit.type; - outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT; - outScale[0] = unit.scale; - - return true; - } - } - - return false; - } -} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java deleted file mode 100644 index 01a4871..0000000 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.IResourceValue; - -/** - * Basic implementation of IResourceValue. - */ -class ResourceValue implements IResourceValue { - private final String mType; - private final String mName; - private String mValue = null; - - ResourceValue(String name) { - mType = null; - mName = name; - } - - public ResourceValue(String type, String name, String value) { - mType = type; - mName = name; - mValue = value; - } - - public String getType() { - return mType; - } - - public final String getName() { - return mName; - } - - public final String getValue() { - return mValue; - } - - public final void setValue(String value) { - mValue = value; - } - - public void replaceWith(ResourceValue value) { - mValue = value.mValue; - } - - public boolean isFramework() { - // ResourceValue object created directly in the framework are used to describe - // non resolvable coming from the XML. Since they will never be cached (as they can't - // be a value pointing to a bitmap, or they'd be resolvable.), the return value deoes - // not matter. - return false; - } -} diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java deleted file mode 100644 index 6d013bb..0000000 --- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.maps; - -import com.android.layoutlib.bridge.MockView; - -import android.content.Context; -import android.os.Bundle; -import android.util.AttributeSet; -import android.view.View; - -/** - * Mock version of the MapView. - * Only non override public methods from the real MapView have been added in there. - * Methods that take an unknown class as parameter or as return object, have been removed for now. - * - * TODO: generate automatically. - * - */ -public class MapView extends MockView { - - /** - * Construct a new WebView with a Context object. - * @param context A Context object used to access application assets. - */ - public MapView(Context context) { - this(context, null); - } - - /** - * Construct a new WebView with layout parameters. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - */ - public MapView(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.mapViewStyle); - } - - /** - * Construct a new WebView with layout parameters and a default style. - * @param context A Context object used to access application assets. - * @param attrs An AttributeSet passed to our parent. - * @param defStyle The default style resource ID. - */ - public MapView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - // START FAKE PUBLIC METHODS - - public void displayZoomControls(boolean takeFocus) { - } - - public boolean canCoverCenter() { - return false; - } - - public void preLoad() { - } - - public int getZoomLevel() { - return 0; - } - - public void setSatellite(boolean on) { - } - - public boolean isSatellite() { - return false; - } - - public void setTraffic(boolean on) { - } - - public boolean isTraffic() { - return false; - } - - public void setStreetView(boolean on) { - } - - public boolean isStreetView() { - return false; - } - - public int getLatitudeSpan() { - return 0; - } - - public int getLongitudeSpan() { - return 0; - } - - public int getMaxZoomLevel() { - return 0; - } - - public void onSaveInstanceState(Bundle state) { - } - - public void onRestoreInstanceState(Bundle state) { - } - - public View getZoomControls() { - return null; - } -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java deleted file mode 100644 index ac144e7..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics._Original_Paint; -import android.text.TextPaint; - -import junit.framework.TestCase; - -/** - * - */ -public class AndroidGraphicsTests extends TestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testMatrix() { - Matrix m1 = new Matrix(); - - assertFalse(m1.isIdentity()); - - m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 }); - assertTrue(m1.isIdentity()); - - Matrix m2 = new Matrix(m1); - - float[] v1 = new float[9]; - float[] v2 = new float[9]; - m1.getValues(v1); - m2.getValues(v2); - - for (int i = 0 ; i < 9; i++) { - assertEquals(v1[i], v2[i]); - } - } - - public void testPaint() { - _Original_Paint o = new _Original_Paint(); - assertNotNull(o); - - Paint p = new Paint(); - assertNotNull(p); - } - - public void textTextPaint() { - TextPaint p = new TextPaint(); - assertNotNull(p); - } -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeTest.java deleted file mode 100644 index e424f1d..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.ILayoutResult; -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; -import com.android.layoutlib.api.IXmlPullParser; -import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; - -import java.io.File; -import java.io.FileReader; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestCase; - -public class BridgeTest extends TestCase { - - /** the class being tested */ - private Bridge mBridge; - /** the path to the sample layout.xml file */ - private String mLayoutXml1Path; - private String mTextOnlyXmlPath; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mBridge = new Bridge(); - - // FIXME: need some fonts somewhere. - mBridge.init(null /* fontOsLocation */, getAttributeValues()); - - URL url = this.getClass().getClassLoader().getResource("data/layout1.xml"); - mLayoutXml1Path = url.getFile(); - - url = this.getClass().getClassLoader().getResource("data/textonly.xml"); - mTextOnlyXmlPath = url.getFile(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - // --------------- - - /** - * Test parser that implements {@link IXmlPullParser}. - */ - private static class TestParser extends KXmlParser implements IXmlPullParser { - public Object getViewKey() { - return null; - } - } - - public void testComputeLayout() throws Exception { - - TestParser parser = new TestParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(new File(mLayoutXml1Path))); - - Map<String, Map<String, IResourceValue>> projectResources = getProjectResources(); - - Map<String, Map<String, IResourceValue>> frameworkResources = getFrameworkResources(); - - int screenWidth = 320; - int screenHeight = 480; - - // FIXME need a dummy font for the tests! - ILayoutResult result = mBridge.computeLayout(parser, new Integer(1) /* projectKey */, - screenWidth, screenHeight, - "Theme", projectResources, frameworkResources, null, null); - - display(result.getRootView(), ""); - } - - private Map<String, Map<String, Integer>> getAttributeValues() { - Map<String, Map<String, Integer>> attributeValues = - new HashMap<String, Map<String,Integer>>(); - - // lets create a map for the orientation attribute - Map<String, Integer> attributeMap = new HashMap<String, Integer>(); - - attributeMap.put("horizontal", Integer.valueOf(0)); - attributeMap.put("vertical", Integer.valueOf(1)); - - attributeValues.put("orientation", attributeMap); - - return attributeValues; - } - - private Map<String, Map<String, IResourceValue>> getFrameworkResources() { - Map<String, Map<String, IResourceValue>> frameworkResources = - new HashMap<String, Map<String, IResourceValue>>(); - - // create the style map - Map<String, IResourceValue> styleMap = new HashMap<String, IResourceValue>(); - frameworkResources.put("style", styleMap); - - // create a button style. - IStyleResourceValue style = createStyle("Widget.Button", - "background", "@android:drawable/something", - "focusable", "true", - "clickable", "true", - "textAppearance", "?android:attr/textAppearanceSmallInverse", - "textColor", "?android:attr/textColorBrightInverseNoDisable", - "gravity", "center_vertical|center_horizontal" - ); - styleMap.put(style.getName(), style); - - // create the parent style of button style - style = createStyle("Widget", - "textAppearance", "?textAppearance"); - styleMap.put(style.getName(), style); - - // link the buttonStyle info in the default theme. - style = createStyle("Theme", - BridgeConstants.RES_STYLE, "buttonStyle", "@android:style/Widget.Button", - BridgeConstants.RES_STYLE, "textAppearance", "@android:style/TextAppearance", - BridgeConstants.RES_STYLE, "textAppearanceSmallInverse", "@android:style/TextAppearance.Small.Inverse", - BridgeConstants.RES_COLOR, "textColorBrightInverseNoDisable", "@android:color/bright_text_light_nodisable" - ); - styleMap.put(style.getName(), style); - - // create a dummy drawable to go with it - Map<String, IResourceValue> drawableMap = new HashMap<String, IResourceValue>(); - frameworkResources.put("drawable", drawableMap); - - // get the 9 patch test location - URL url = this.getClass().getClassLoader().getResource("data/button.9.png"); - - IResourceValue drawable = new ResourceValue(BridgeConstants.RES_DRAWABLE, "something", - url.getPath()); - drawableMap.put(drawable.getName(), drawable); - return frameworkResources; - } - - private Map<String, Map<String, IResourceValue>> getProjectResources() { - Map<String, Map<String, IResourceValue>> projectResources = - new HashMap<String, Map<String, IResourceValue>>(); - - // create the style map (even empty there should be one) - Map<String, IResourceValue> styleMap = new HashMap<String, IResourceValue>(); - projectResources.put("style", styleMap); - - return projectResources; - } - - - private void display(ILayoutViewInfo result, String offset) { - - String msg = String.format("%s%s L:%d T:%d R:%d B:%d", - offset, - result.getName(), - result.getLeft(), result.getTop(), result.getRight(), result.getBottom()); - - System.out.println(msg); - ILayoutViewInfo[] children = result.getChildren(); - if (children != null) { - offset += "+-"; - for (ILayoutViewInfo child : children) { - display(child, offset); - } - } - } - - /** - * Creates a {@link IStyleResourceValue} based on the given values. - * @param styleName the name of the style. - * @param items An array of Strings. Even indices contain a style item name, and odd indices - * a style item value. If the number of string in the array is not even, an exception is thrown. - */ - private IStyleResourceValue createStyle(String styleName, String... items) { - StyleResourceValue value = new StyleResourceValue(styleName); - - if (items.length % 3 == 0) { - for (int i = 0 ; i < items.length;) { - value.addItem(new ResourceValue(items[i++], items[i++], items[i++])); - } - } else { - throw new IllegalArgumentException("Need a multiple of 3 for the number of strings"); - } - - return value; - } - - // --------------- - - public void testTextLayout() throws Exception { - - TestParser parser = new TestParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileReader(new File(mTextOnlyXmlPath))); - - Map<String, Map<String, IResourceValue>> projectResources = getProjectResources(); - Map<String, Map<String, IResourceValue>> frameworkResources = getFrameworkResources(); - - int screenWidth = 320; - int screenHeight = 480; - - // FIXME need a dummy font for the tests! - ILayoutResult result = mBridge.computeLayout(parser, new Integer(1) /* projectKey */, - screenWidth, screenHeight, - "Theme", projectResources, frameworkResources, null, null); - - display(result.getRootView(), ""); - } - -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java deleted file mode 100644 index cac1f95..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import org.kxml2.io.KXmlParser; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; -import org.xmlpull.v1.XmlPullParser; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.net.URL; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import junit.framework.TestCase; - -public class BridgeXmlBlockParserTest extends TestCase { - - private String mXmlPath; - private Document mDoc; - - @Override - protected void setUp() throws Exception { - super.setUp(); - URL url = this.getClass().getClassLoader().getResource("data/layout1.xml"); - mXmlPath = url.getFile(); - mDoc = getXmlDocument(mXmlPath); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testXmlBlockParser() throws Exception { - XmlPullParser parser = new KXmlParser(); - parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */); - parser.setInput(new FileReader(new File(mXmlPath))); - - assertEquals(XmlPullParser.START_DOCUMENT, parser.next()); - - assertEquals(XmlPullParser.START_TAG, parser.next()); - assertEquals("LinearLayout", parser.getName()); - - assertEquals(XmlPullParser.TEXT, parser.next()); - - assertEquals(XmlPullParser.START_TAG, parser.next()); - assertEquals("Button", parser.getName()); - assertEquals(XmlPullParser.TEXT, parser.next()); - assertEquals(XmlPullParser.END_TAG, parser.next()); - - assertEquals(XmlPullParser.TEXT, parser.next()); - - assertEquals(XmlPullParser.START_TAG, parser.next()); - assertEquals("View", parser.getName()); - assertEquals(XmlPullParser.END_TAG, parser.next()); - - assertEquals(XmlPullParser.TEXT, parser.next()); - - assertEquals(XmlPullParser.START_TAG, parser.next()); - assertEquals("TextView", parser.getName()); - assertEquals(XmlPullParser.END_TAG, parser.next()); - - assertEquals(XmlPullParser.TEXT, parser.next()); - - assertEquals(XmlPullParser.END_TAG, parser.next()); - assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); - } - - //------------ - - private Document getXmlDocument(String xmlFilePath) - throws ParserConfigurationException, SAXException, IOException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - // keep comments - factory.setIgnoringComments(false); - // don't validate our bogus DTD - factory.setValidating(false); - // we want namespaces - factory.setNamespaceAware(true); - - DocumentBuilder builder = factory.newDocumentBuilder(); - return builder.parse(new File(xmlFilePath)); - } - - - /** - * Quick'n'dirty debug helper that dumps an XML structure to stdout. - */ - @SuppressWarnings("unused") - private void dump(Node node, String prefix) { - Node n; - - String[] types = { - "unknown", - "ELEMENT_NODE", - "ATTRIBUTE_NODE", - "TEXT_NODE", - "CDATA_SECTION_NODE", - "ENTITY_REFERENCE_NODE", - "ENTITY_NODE", - "PROCESSING_INSTRUCTION_NODE", - "COMMENT_NODE", - "DOCUMENT_NODE", - "DOCUMENT_TYPE_NODE", - "DOCUMENT_FRAGMENT_NODE", - "NOTATION_NODE" - }; - - String s = String.format("%s<%s> %s %s", - prefix, - types[node.getNodeType()], - node.getNodeName(), - node.getNodeValue() == null ? "" : node.getNodeValue().trim()); - - System.out.println(s); - - n = node.getFirstChild(); - if (n != null) { - dump(n, prefix + "- "); - } - - n = node.getNextSibling(); - if (n != null) { - dump(n, prefix); - } - - } - -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java deleted file mode 100644 index 67ec5e1..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.android.layoutlib.bridge; - -import com.android.ninepatch.NinePatch; - -import java.net.URL; - -import junit.framework.TestCase; - -public class NinePatchTest extends TestCase { - - private NinePatch mPatch; - - @Override - protected void setUp() throws Exception { - URL url = this.getClass().getClassLoader().getResource("data/button.9.png"); - - mPatch = NinePatch.load(url, false /* convert */); - } - - public void test9PatchLoad() throws Exception { - assertNotNull(mPatch); - } - - public void test9PatchMinSize() { - int[] padding = new int[4]; - mPatch.getPadding(padding); - assertEquals(13, padding[0]); - assertEquals(3, padding[1]); - assertEquals(13, padding[2]); - assertEquals(4, padding[3]); - assertEquals(38, mPatch.getWidth()); - assertEquals(27, mPatch.getHeight()); - } - -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/StyleResourceValue.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/StyleResourceValue.java deleted file mode 100644 index 84bdc2f..0000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/StyleResourceValue.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.layoutlib.bridge; - -import com.android.layoutlib.api.IResourceValue; -import com.android.layoutlib.api.IStyleResourceValue; - -import java.util.HashMap; - -class StyleResourceValue extends ResourceValue implements IStyleResourceValue { - - private String mParentStyle = null; - private HashMap<String, IResourceValue> mItems = new HashMap<String, IResourceValue>(); - - StyleResourceValue(String name) { - super(name); - } - - StyleResourceValue(String name, String parentStyle) { - super(name); - mParentStyle = parentStyle; - } - - public String getParentStyle() { - return mParentStyle; - } - - public IResourceValue findItem(String name) { - return mItems.get(name); - } - - public void addItem(IResourceValue value) { - mItems.put(value.getName(), value); - } - - @Override - public void replaceWith(ResourceValue value) { - super.replaceWith(value); - - if (value instanceof StyleResourceValue) { - mItems.clear(); - mItems.putAll(((StyleResourceValue)value).mItems); - } - } - -} diff --git a/tools/layoutlib/bridge/tests/data/button.9.png b/tools/layoutlib/bridge/tests/data/button.9.png Binary files differdeleted file mode 100644 index 9d52f40..0000000 --- a/tools/layoutlib/bridge/tests/data/button.9.png +++ /dev/null diff --git a/tools/layoutlib/bridge/tests/data/layout1.xml b/tools/layoutlib/bridge/tests/data/layout1.xml deleted file mode 100644 index 554f541..0000000 --- a/tools/layoutlib/bridge/tests/data/layout1.xml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" -> - <Button - android:id="@+id/bouton" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:text="My Button Text" - > - </Button> - <View - android:id="@+id/surface" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:layout_weight="2" - /> - <TextView - android:id="@+id/status" - android:paddingLeft="2dip" - android:layout_weight="0" - android:background="@drawable/black" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:lines="1" - android:gravity="center_vertical|center_horizontal" - android:text="My TextView Text" - /> -</LinearLayout> diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath deleted file mode 100644 index 0c60f6a..0000000 --- a/tools/layoutlib/create/.classpath +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" path="src"/> - <classpathentry excluding="mock_android/" kind="src" path="tests"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/tools/layoutlib/create/.project b/tools/layoutlib/create/.project deleted file mode 100644 index e100d17..0000000 --- a/tools/layoutlib/create/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>layoutlib_create</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk deleted file mode 100644 index 310fae5..0000000 --- a/tools/layoutlib/create/Android.mk +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under,src) - -LOCAL_JAR_MANIFEST := manifest.txt -LOCAL_STATIC_JAVA_LIBRARIES := \ - asm-3.1 - -LOCAL_MODULE := layoutlib_create - -include $(BUILD_HOST_JAVA_LIBRARY) - diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt deleted file mode 100644 index 09b392b..0000000 --- a/tools/layoutlib/create/README.txt +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (C) 2008 The Android Open Source Project - - -- Description - ---------------- - -makeLayoutLib generates a library used by the Eclipse graphical layout editor -to perform layout. - - - -- Usage - ---------- - - ./makeLayoutLib path/to/android.jar destination.jar - - - -- Implementation Notes - ------------------------- - -The goal of makeLayoutLib is to list all the classes from the input jar and create a new -jar that only keeps certain classes and create stubs for all their dependencies. - -First the input jar is parsed to find all the classes defined. - -In the Main(), the following list of classes are hardcoded (TODO config file later): -- keep all classes that derive from android.view.View. -- keep all classes in the android.view and android.widget packages (sub-packages excluded). -- keep specific classes such as android.policy.PhoneLayoutInflater. - -For each class to keep, their dependencies are examined using BCEL. -A dependency is defined as a class needed to instantiate the given class that should be kept, -directly or indirectly. So a dependency is a class that is used by the input class, that is -defined in the input jar and that is not part of the current JRE. - -Dependencies are computed recursively. - -Once all dependencies are found, the final jar can be created. -There are three kind of classes to write: -- classes that are to be kept as-is. They are just dumped in the new jar unchanged. -- classes that are to be kept yet contain native methods or fields. -- classes that are just dependencies. We don't want to expose their implementation in the final - jar. - -The implementation of native methods and all methods of mock classes is replaced by a stub -that throws UnsupportedOperationException. - -Incidentally, the access level of native and mock classes needs to be changed in order for -native methods to be later overridden. Methods that are "final private native" must become -non-final, non-native and at most protected. Package-default access is changed to public. -Classes that are final are made non-final. Abstract methods are left untouched. - - - ----- -20080617 Replace Class - -Some classes are basically wrappers over native objects. -Subclassing doesn't work as most methods are either static or we don't -control object creation. In this scenario the idea is to be able to -replace classes in the final jar. - -Example: android.graphics.Paint would get renamed to OriginalPaint -in the generated jar. Then in the bridge we'll introduce a replacement -Paint class that derives from OriginalPaint. - -This won't rename/replace the inner static methods of a given class. - - - diff --git a/tools/layoutlib/create/manifest.txt b/tools/layoutlib/create/manifest.txt deleted file mode 100644 index 238e7f9..0000000 --- a/tools/layoutlib/create/manifest.txt +++ /dev/null @@ -1 +0,0 @@ -Main-Class: com.android.tools.layoutlib.create.Main diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java deleted file mode 100644 index b197ea7..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Attribute; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.Map.Entry; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * Analyzes the input JAR using the ASM java bytecode manipulation library - * to list the desired classes and their dependencies. - */ -public class AsmAnalyzer { - - // Note: a bunch of stuff has package-level access for unit tests. Consider it private. - - /** Output logger. */ - private final Log mLog; - /** The input source JAR to parse. */ - private final List<String> mOsSourceJar; - /** The generator to fill with the class list and dependency list. */ - private final AsmGenerator mGen; - /** Keep all classes that derive from these one (these included). */ - private final String[] mDeriveFrom; - /** Glob patterns of classes to keep, e.g. "com.foo.*" */ - private final String[] mIncludeGlobs; - - /** - * Creates a new analyzer. - * - * @param log The log output. - * @param osJarPath The input source JARs to parse. - * @param gen The generator to fill with the class list and dependency list. - * @param deriveFrom Keep all classes that derive from these one (these included). - * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*" - * ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is) - */ - public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen, - String[] deriveFrom, String[] includeGlobs) { - mLog = log; - mGen = gen; - mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>(); - mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0]; - mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0]; - } - - /** - * Starts the analysis using parameters from the constructor. - * Fills the generator with classes & dependencies found. - */ - public void analyze() throws IOException, LogAbortException { - - AsmAnalyzer visitor = this; - - Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar); - mLog.info("Found %d classes in input JAR%s.", zipClasses.size(), - mOsSourceJar.size() > 1 ? "s" : ""); - - Map<String, ClassReader> found = findIncludes(zipClasses); - Map<String, ClassReader> deps = findDeps(zipClasses, found); - - if (mGen != null) { - mGen.setKeep(found); - mGen.setDeps(deps); - } - } - - /** - * Parses a JAR file and returns a list of all classes founds using a map - * class name => ASM ClassReader. Class names are in the form "android.view.View". - */ - Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException { - TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); - - for (String jarPath : jarPathList) { - ZipFile zip = new ZipFile(jarPath); - Enumeration<? extends ZipEntry> entries = zip.entries(); - ZipEntry entry; - while (entries.hasMoreElements()) { - entry = entries.nextElement(); - if (entry.getName().endsWith(".class")) { - ClassReader cr = new ClassReader(zip.getInputStream(entry)); - String className = classReaderToClassName(cr); - classes.put(className, cr); - } - } - } - - return classes; - } - - /** - * Utility that returns the fully qualified binary class name for a ClassReader. - * E.g. it returns something like android.view.View. - */ - static String classReaderToClassName(ClassReader classReader) { - if (classReader == null) { - return null; - } else { - return classReader.getClassName().replace('/', '.'); - } - } - - /** - * Utility that returns the fully qualified binary class name from a path-like FQCN. - * E.g. it returns android.view.View from android/view/View. - */ - static String internalToBinaryClassName(String className) { - if (className == null) { - return null; - } else { - return className.replace('/', '.'); - } - } - - /** - * Process the "includes" arrays. - * <p/> - * This updates the in_out_found map. - */ - Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses) - throws LogAbortException { - TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); - - mLog.debug("Find classes to include."); - - for (String s : mIncludeGlobs) { - findGlobs(s, zipClasses, found); - } - for (String s : mDeriveFrom) { - findClassesDerivingFrom(s, zipClasses, found); - } - - return found; - } - - - /** - * Uses ASM to find the class reader for the given FQCN class name. - * If found, insert it in the in_out_found map. - * Returns the class reader object. - */ - ClassReader findClass(String className, Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inOutFound) throws LogAbortException { - ClassReader classReader = zipClasses.get(className); - if (classReader == null) { - throw new LogAbortException("Class %s not found by ASM in %s", - className, mOsSourceJar); - } - - inOutFound.put(className, classReader); - return classReader; - } - - /** - * Insert in the inOutFound map all classes found in zipClasses that match the - * given glob pattern. - * <p/> - * The glob pattern is not a regexp. It only accepts the "*" keyword to mean - * "anything but a period". The "." and "$" characters match themselves. - * The "**" keyword means everything including ".". - * <p/> - * Examples: - * <ul> - * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages. - * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class. - * </ul> - */ - void findGlobs(String globPattern, Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inOutFound) throws LogAbortException { - // transforms the glob pattern in a regexp: - // - escape "." with "\." - // - replace "*" by "[^.]*" - // - escape "$" with "\$" - // - add end-of-line match $ - globPattern = globPattern.replaceAll("\\$", "\\\\\\$"); - globPattern = globPattern.replaceAll("\\.", "\\\\."); - // prevent ** from being altered by the next rule, then process the * rule and finally - // the real ** rule (which is now @) - globPattern = globPattern.replaceAll("\\*\\*", "@"); - globPattern = globPattern.replaceAll("\\*", "[^.]*"); - globPattern = globPattern.replaceAll("@", ".*"); - globPattern += "$"; - - Pattern regexp = Pattern.compile(globPattern); - - for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { - String class_name = entry.getKey(); - if (regexp.matcher(class_name).matches()) { - findClass(class_name, zipClasses, inOutFound); - } - } - } - - /** - * Checks all the classes defined in the JarClassName instance and uses BCEL to - * determine if they are derived from the given FQCN super class name. - * Inserts the super class and all the class objects found in the map. - */ - void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inOutFound) throws LogAbortException { - ClassReader super_clazz = findClass(super_name, zipClasses, inOutFound); - - for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { - String className = entry.getKey(); - if (super_name.equals(className)) { - continue; - } - ClassReader classReader = entry.getValue(); - ClassReader parent_cr = classReader; - while (parent_cr != null) { - String parent_name = internalToBinaryClassName(parent_cr.getSuperName()); - if (parent_name == null) { - // not found - break; - } else if (super_name.equals(parent_name)) { - inOutFound.put(className, classReader); - break; - } - parent_cr = zipClasses.get(parent_name); - } - } - } - - /** - * Instantiates a new DependencyVisitor. Useful for unit tests. - */ - DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inKeep, - Map<String, ClassReader> outKeep, - Map<String, ClassReader> inDeps, - Map<String, ClassReader> outDeps) { - return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps); - } - - /** - * Finds all dependencies for all classes in keepClasses which are also - * listed in zipClasses. Returns a map of all the dependencies found. - */ - Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inOutKeepClasses) { - - TreeMap<String, ClassReader> deps = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> new_deps = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> temp = new TreeMap<String, ClassReader>(); - - DependencyVisitor visitor = getVisitor(zipClasses, - inOutKeepClasses, new_keep, - deps, new_deps); - - for (ClassReader cr : inOutKeepClasses.values()) { - cr.accept(visitor, 0 /* flags */); - } - - while (new_deps.size() > 0 || new_keep.size() > 0) { - deps.putAll(new_deps); - inOutKeepClasses.putAll(new_keep); - - temp.clear(); - temp.putAll(new_deps); - temp.putAll(new_keep); - new_deps.clear(); - new_keep.clear(); - mLog.debug("Found %1$d to keep, %2$d dependencies.", - inOutKeepClasses.size(), deps.size()); - - for (ClassReader cr : temp.values()) { - cr.accept(visitor, 0 /* flags */); - } - } - - mLog.info("Found %1$d classes to keep, %2$d class dependencies.", - inOutKeepClasses.size(), deps.size()); - - return deps; - } - - - - // ---------------------------------- - - /** - * Visitor to collect all the type dependencies from a class. - */ - public class DependencyVisitor - implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor { - - /** All classes found in the source JAR. */ - private final Map<String, ClassReader> mZipClasses; - /** Classes from which dependencies are to be found. */ - private final Map<String, ClassReader> mInKeep; - /** Dependencies already known. */ - private final Map<String, ClassReader> mInDeps; - /** New dependencies found by this visitor. */ - private final Map<String, ClassReader> mOutDeps; - /** New classes to keep as-is found by this visitor. */ - private final Map<String, ClassReader> mOutKeep; - - /** - * Creates a new visitor that will find all the dependencies for the visited class. - * Types which are already in the zipClasses, keepClasses or inDeps are not marked. - * New dependencies are marked in outDeps. - * - * @param zipClasses All classes found in the source JAR. - * @param inKeep Classes from which dependencies are to be found. - * @param inDeps Dependencies already known. - * @param outDeps New dependencies found by this visitor. - */ - public DependencyVisitor(Map<String, ClassReader> zipClasses, - Map<String, ClassReader> inKeep, - Map<String, ClassReader> outKeep, - Map<String,ClassReader> inDeps, - Map<String,ClassReader> outDeps) { - mZipClasses = zipClasses; - mInKeep = inKeep; - mOutKeep = outKeep; - mInDeps = inDeps; - mOutDeps = outDeps; - } - - /** - * Considers the given class name as a dependency. - * If it does, add to the mOutDeps map. - */ - public void considerName(String className) { - if (className == null) { - return; - } - - className = internalToBinaryClassName(className); - - // exclude classes that have already been found - if (mInKeep.containsKey(className) || - mOutKeep.containsKey(className) || - mInDeps.containsKey(className) || - mOutDeps.containsKey(className)) { - return; - } - - // exclude classes that are not part of the JAR file being examined - ClassReader cr = mZipClasses.get(className); - if (cr == null) { - return; - } - - try { - // exclude classes that are part of the default JRE (the one executing this program) - if (getClass().getClassLoader().loadClass(className) != null) { - return; - } - } catch (ClassNotFoundException e) { - // ignore - } - - // accept this class: - // - android classes are added to dependencies - // - non-android classes are added to the list of classes to keep as-is (they don't need - // to be stubbed). - if (className.indexOf("android") >= 0) { // TODO make configurable - mOutDeps.put(className, cr); - } else { - mOutKeep.put(className, cr); - } - } - - /** - * Considers this array of names using considerName(). - */ - public void considerNames(String[] classNames) { - if (classNames != null) { - for (String className : classNames) { - considerName(className); - } - } - } - - /** - * Considers this signature or type signature by invoking the {@link SignatureVisitor} - * on it. - */ - public void considerSignature(String signature) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - // SignatureReader.accept will call accessType so we don't really have - // to differentiate where the signature comes from. - sr.accept(this); - } - } - - /** - * Considers this {@link Type}. For arrays, the element type is considered. - * If the type is an object, it's internal name is considered. - */ - public void considerType(Type t) { - if (t != null) { - if (t.getSort() == Type.ARRAY) { - t = t.getElementType(); - } - if (t.getSort() == Type.OBJECT) { - considerName(t.getInternalName()); - } - } - } - - /** - * Considers a descriptor string. The descriptor is converted to a {@link Type} - * and then considerType() is invoked. - */ - public void considerDesc(String desc) { - if (desc != null) { - try { - Type t = Type.getType(desc); - considerType(t); - } catch (ArrayIndexOutOfBoundsException e) { - // ignore, not a valid type. - } - } - } - - - // --------------------------------------------------- - // --- ClassVisitor, FieldVisitor - // --------------------------------------------------- - - // Visits a class header - public void visit(int version, int access, String name, - String signature, String superName, String[] interfaces) { - // signature is the signature of this class. May be null if the class is not a generic - // one, and does not extend or implement generic classes or interfaces. - - if (signature != null) { - considerSignature(signature); - } - - // superName is the internal of name of the super class (see getInternalName). - // For interfaces, the super class is Object. May be null but only for the Object class. - considerName(superName); - - // interfaces is the internal names of the class's interfaces (see getInternalName). - // May be null. - considerNames(interfaces); - } - - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - // desc is the class descriptor of the annotation class. - considerDesc(desc); - return this; // return this to visit annotion values - } - - public void visitAttribute(Attribute attr) { - // pass - } - - // Visits the end of a class - public void visitEnd() { - // pass - } - - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - // desc is the field's descriptor (see Type). - considerDesc(desc); - - // signature is the field's signature. May be null if the field's type does not use - // generic types. - considerSignature(signature); - - return this; // a visitor to visit field annotations and attributes - } - - public void visitInnerClass(String name, String outerName, String innerName, int access) { - // name is the internal name of an inner class (see getInternalName). - considerName(name); - } - - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - // desc is the method's descriptor (see Type). - considerDesc(desc); - // signature is the method's signature. May be null if the method parameters, return - // type and exceptions do not use generic types. - considerSignature(signature); - - return this; // returns this to visit the method - } - - public void visitOuterClass(String owner, String name, String desc) { - // pass - } - - public void visitSource(String source, String debug) { - // pass - } - - - // --------------------------------------------------- - // --- MethodVisitor - // --------------------------------------------------- - - public AnnotationVisitor visitAnnotationDefault() { - return this; // returns this to visit the default value - } - - - public void visitCode() { - // pass - } - - // field instruction - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - // name is the field's name. - considerName(name); - // desc is the field's descriptor (see Type). - considerDesc(desc); - } - - public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { - // pass - } - - public void visitIincInsn(int var, int increment) { - // pass -- an IINC instruction - } - - public void visitInsn(int opcode) { - // pass -- a zero operand instruction - } - - public void visitIntInsn(int opcode, int operand) { - // pass -- a single int operand instruction - } - - public void visitJumpInsn(int opcode, Label label) { - // pass -- a jump instruction - } - - public void visitLabel(Label label) { - // pass -- a label target - } - - // instruction to load a constant from the stack - public void visitLdcInsn(Object cst) { - if (cst instanceof Type) { - considerType((Type) cst); - } - } - - public void visitLineNumber(int line, Label start) { - // pass - } - - public void visitLocalVariable(String name, String desc, - String signature, Label start, Label end, int index) { - // desc is the type descriptor of this local variable. - considerDesc(desc); - // signature is the type signature of this local variable. May be null if the local - // variable type does not use generic types. - considerSignature(signature); - } - - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - // pass -- a lookup switch instruction - } - - public void visitMaxs(int maxStack, int maxLocals) { - // pass - } - - // instruction that invokes a method - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - - // owner is the internal name of the method's owner class - considerName(owner); - // desc is the method's descriptor (see Type). - considerDesc(desc); - } - - // instruction multianewarray, whatever that is - public void visitMultiANewArrayInsn(String desc, int dims) { - - // desc an array type descriptor. - considerDesc(desc); - } - - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, - boolean visible) { - // desc is the class descriptor of the annotation class. - considerDesc(desc); - return this; // return this to visit annotation values - } - - public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { - // pass -- table switch instruction - - } - - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - // type is the internal name of the type of exceptions handled by the handler, - // or null to catch any exceptions (for "finally" blocks). - considerName(type); - } - - // type instruction - public void visitTypeInsn(int opcode, String type) { - // type is the operand of the instruction to be visited. This operand must be the - // internal name of an object or array class. - considerName(type); - } - - public void visitVarInsn(int opcode, int var) { - // pass -- local variable instruction - } - - - // --------------------------------------------------- - // --- SignatureVisitor - // --------------------------------------------------- - - private String mCurrentSignatureClass = null; - - // Starts the visit of a signature corresponding to a class or interface type - public void visitClassType(String name) { - mCurrentSignatureClass = name; - considerName(name); - } - - // Visits an inner class - public void visitInnerClassType(String name) { - if (mCurrentSignatureClass != null) { - mCurrentSignatureClass += "$" + name; - considerName(mCurrentSignatureClass); - } - } - - public SignatureVisitor visitArrayType() { - return this; // returns this to visit the signature of the array element type - } - - public void visitBaseType(char descriptor) { - // pass -- a primitive type, ignored - } - - public SignatureVisitor visitClassBound() { - return this; // returns this to visit the signature of the class bound - } - - public SignatureVisitor visitExceptionType() { - return this; // return this to visit the signature of the exception type. - } - - public void visitFormalTypeParameter(String name) { - // pass - } - - public SignatureVisitor visitInterface() { - return this; // returns this to visit the signature of the interface type - } - - public SignatureVisitor visitInterfaceBound() { - return this; // returns this to visit the signature of the interface bound - } - - public SignatureVisitor visitParameterType() { - return this; // returns this to visit the signature of the parameter type - } - - public SignatureVisitor visitReturnType() { - return this; // returns this to visit the signature of the return type - } - - public SignatureVisitor visitSuperclass() { - return this; // returns this to visit the signature of the super class type - } - - public SignatureVisitor visitTypeArgument(char wildcard) { - return this; // returns this to visit the signature of the type argument - } - - public void visitTypeVariable(String name) { - // pass - } - - public void visitTypeArgument() { - // pass - } - - - // --------------------------------------------------- - // --- AnnotationVisitor - // --------------------------------------------------- - - - // Visits a primitive value of an annotation - public void visit(String name, Object value) { - // value is the actual value, whose type must be Byte, Boolean, Character, Short, - // Integer, Long, Float, Double, String or Type - if (value instanceof Type) { - considerType((Type) value); - } - } - - public AnnotationVisitor visitAnnotation(String name, String desc) { - // desc is the class descriptor of the nested annotation class. - considerDesc(desc); - return this; // returns this to visit the actual nested annotation value - } - - public AnnotationVisitor visitArray(String name) { - return this; // returns this to visit the actual array value elements - } - - public void visitEnum(String name, String desc, String value) { - // desc is the class descriptor of the enumeration class. - considerDesc(desc); - } - - } -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java deleted file mode 100644 index 1adcc17..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.Map.Entry; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; - -/** - * Class that generates a new JAR from a list of classes, some of which are to be kept as-is - * and some of which are to be stubbed partially or totally. - */ -public class AsmGenerator { - - /** Output logger. */ - private final Log mLog; - /** The path of the destination JAR to create. */ - private final String mOsDestJar; - /** List of classes to inject in the final JAR from _this_ archive. */ - private final Class<?>[] mInjectClasses; - /** The set of methods to stub out. */ - private final Set<String> mStubMethods; - /** All classes to output as-is, except if they have native methods. */ - private Map<String, ClassReader> mKeep; - /** All dependencies that must be completely stubbed. */ - private Map<String, ClassReader> mDeps; - /** Counter of number of classes renamed during transform. */ - private int mRenameCount; - /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */ - private final HashMap<String, String> mRenameClasses; - /** FQCN Names of "old" classes that were NOT renamed. This starts with the full list of - * old-FQCN to rename and they get erased as they get renamed. At the end, classes still - * left here are not in the code base anymore and thus were not renamed. */ - private HashSet<String> mClassesNotRenamed; - /** A map { FQCN => map { list of return types to delete from the FQCN } }. */ - private HashMap<String, Set<String>> mDeleteReturns; - - /** - * Creates a new generator that can generate the output JAR with the stubbed classes. - * - * @param log Output logger. - * @param osDestJar The path of the destination JAR to create. - * @param stubMethods The list of methods to stub out. Each entry must be in the form - * "package.package.OuterClass$InnerClass#MethodName". - * @param renameClasses The list of classes to rename, must be an even list: the binary FQCN - * of class to replace followed by the new FQCN. - * @param deleteReturns List of classes for which the methods returning them should be deleted. - * The array contains a list of null terminated section starting with the name of the class - * to rename in which the methods are deleted, followed by a list of return types identifying - * the methods to delete. - */ - public AsmGenerator(Log log, String osDestJar, - Class<?>[] injectClasses, - String[] stubMethods, - String[] renameClasses, String[] deleteReturns) { - mLog = log; - mOsDestJar = osDestJar; - mInjectClasses = injectClasses != null ? injectClasses : new Class<?>[0]; - mStubMethods = stubMethods != null ? new HashSet<String>(Arrays.asList(stubMethods)) : - new HashSet<String>(); - - // Create the map of classes to rename. - mRenameClasses = new HashMap<String, String>(); - mClassesNotRenamed = new HashSet<String>(); - int n = renameClasses == null ? 0 : renameClasses.length; - for (int i = 0; i < n; i += 2) { - assert i + 1 < n; - // The ASM class names uses "/" separators, whereas regular FQCN use "." - String oldFqcn = binaryToInternalClassName(renameClasses[i]); - String newFqcn = binaryToInternalClassName(renameClasses[i + 1]); - mRenameClasses.put(oldFqcn, newFqcn); - mClassesNotRenamed.add(oldFqcn); - } - - // create the map of renamed class -> return type of method to delete. - mDeleteReturns = new HashMap<String, Set<String>>(); - if (deleteReturns != null) { - Set<String> returnTypes = null; - String renamedClass = null; - for (String className : deleteReturns) { - // if we reach the end of a section, add it to the main map - if (className == null) { - if (returnTypes != null) { - mDeleteReturns.put(renamedClass, returnTypes); - } - - renamedClass = null; - continue; - } - - // if the renamed class is null, this is the beginning of a section - if (renamedClass == null) { - renamedClass = binaryToInternalClassName(className); - continue; - } - - // just a standard return type, we add it to the list. - if (returnTypes == null) { - returnTypes = new HashSet<String>(); - } - returnTypes.add(binaryToInternalClassName(className)); - } - } - } - - /** - * Returns the list of classes that have not been renamed yet. - * <p/> - * The names are "internal class names" rather than FQCN, i.e. they use "/" instead "." - * as package separators. - */ - public Set<String> getClassesNotRenamed() { - return mClassesNotRenamed; - } - - /** - * Utility that returns the internal ASM class name from a fully qualified binary class - * name. E.g. it returns android/view/View from android.view.View. - */ - String binaryToInternalClassName(String className) { - if (className == null) { - return null; - } else { - return className.replace('.', '/'); - } - } - - /** Sets the map of classes to output as-is, except if they have native methods */ - public void setKeep(Map<String, ClassReader> keep) { - mKeep = keep; - } - - /** Sets the map of dependencies that must be completely stubbed */ - public void setDeps(Map<String, ClassReader> deps) { - mDeps = deps; - } - - /** Gets the map of classes to output as-is, except if they have native methods */ - public Map<String, ClassReader> getKeep() { - return mKeep; - } - - /** Gets the map of dependencies that must be completely stubbed */ - public Map<String, ClassReader> getDeps() { - return mDeps; - } - - /** Generates the final JAR */ - public void generate() throws FileNotFoundException, IOException { - TreeMap<String, byte[]> all = new TreeMap<String, byte[]>(); - - for (Class<?> clazz : mInjectClasses) { - String name = classToEntryPath(clazz); - InputStream is = ClassLoader.getSystemResourceAsStream(name); - ClassReader cr = new ClassReader(is); - byte[] b = transform(cr, true /* stubNativesOnly */); - name = classNameToEntryPath(transformName(cr.getClassName())); - all.put(name, b); - } - - for (Entry<String, ClassReader> entry : mDeps.entrySet()) { - ClassReader cr = entry.getValue(); - byte[] b = transform(cr, true /* stubNativesOnly */); - String name = classNameToEntryPath(transformName(cr.getClassName())); - all.put(name, b); - } - - for (Entry<String, ClassReader> entry : mKeep.entrySet()) { - ClassReader cr = entry.getValue(); - byte[] b = transform(cr, true /* stubNativesOnly */); - String name = classNameToEntryPath(transformName(cr.getClassName())); - all.put(name, b); - } - - mLog.info("# deps classes: %d", mDeps.size()); - mLog.info("# keep classes: %d", mKeep.size()); - mLog.info("# renamed : %d", mRenameCount); - - createJar(new FileOutputStream(mOsDestJar), all); - mLog.info("Created JAR file %s", mOsDestJar); - } - - /** - * Writes the JAR file. - * - * @param outStream The file output stream were to write the JAR. - * @param all The map of all classes to output. - * @throws IOException if an I/O error has occurred - */ - void createJar(FileOutputStream outStream, Map<String,byte[]> all) throws IOException { - JarOutputStream jar = new JarOutputStream(outStream); - for (Entry<String, byte[]> entry : all.entrySet()) { - String name = entry.getKey(); - JarEntry jar_entry = new JarEntry(name); - jar.putNextEntry(jar_entry); - jar.write(entry.getValue()); - jar.closeEntry(); - } - jar.flush(); - jar.close(); - } - - /** - * Utility method that converts a fully qualified java name into a JAR entry path - * e.g. for the input "android.view.View" it returns "android/view/View.class" - */ - String classNameToEntryPath(String className) { - return className.replaceAll("\\.", "/").concat(".class"); - } - - /** - * Utility method to get the JAR entry path from a Class name. - * e.g. it returns someting like "com/foo/OuterClass$InnerClass1$InnerClass2.class" - */ - private String classToEntryPath(Class<?> clazz) { - String name = ""; - Class<?> parent; - while ((parent = clazz.getEnclosingClass()) != null) { - name = "$" + clazz.getSimpleName() + name; - clazz = parent; - } - return classNameToEntryPath(clazz.getCanonicalName() + name); - } - - /** - * Transforms a class. - * <p/> - * There are 3 kind of transformations: - * - * 1- For "mock" dependencies classes, we want to remove all code from methods and replace - * by a stub. Native methods must be implemented with this stub too. Abstract methods are - * left intact. Modified classes must be overridable (non-private, non-final). - * Native methods must be made non-final, non-private. - * - * 2- For "keep" classes, we want to rewrite all native methods as indicated above. - * If a class has native methods, it must also be made non-private, non-final. - * - * Note that unfortunately static methods cannot be changed to non-static (since static and - * non-static are invoked differently.) - */ - byte[] transform(ClassReader cr, boolean stubNativesOnly) { - - boolean hasNativeMethods = hasNativeMethods(cr); - String className = cr.getClassName(); - - String newName = transformName(className); - // transformName returns its input argument if there's no need to rename the class - if (newName != className) { - mRenameCount++; - // This class is being renamed, so remove it from the list of classes not renamed. - mClassesNotRenamed.remove(className); - } - - mLog.debug("Transform %s%s%s%s", className, - newName == className ? "" : " (renamed to " + newName + ")", - hasNativeMethods ? " -- has natives" : "", - stubNativesOnly ? " -- stub natives only" : ""); - - // Rewrite the new class from scratch, without reusing the constant pool from the - // original class reader. - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - - ClassVisitor rv = cw; - if (newName != className) { - rv = new RenameClassAdapter(cw, className, newName); - } - - TransformClassAdapter cv = new TransformClassAdapter(mLog, mStubMethods, - mDeleteReturns.get(className), - newName, rv, - stubNativesOnly, stubNativesOnly || hasNativeMethods); - cr.accept(cv, 0 /* flags */); - return cw.toByteArray(); - } - - /** - * Should this class be renamed, this returns the new name. Otherwise it returns the - * original name. - * - * @param className The internal ASM name of the class that may have to be renamed - * @return A new transformed name or the original input argument. - */ - String transformName(String className) { - String newName = mRenameClasses.get(className); - if (newName != null) { - return newName; - } - int pos = className.indexOf('$'); - if (pos > 0) { - // Is this an inner class of a renamed class? - String base = className.substring(0, pos); - newName = mRenameClasses.get(base); - if (newName != null) { - return newName + className.substring(pos); - } - } - - return className; - } - - /** - * Returns true if a class has any native methods. - */ - boolean hasNativeMethods(ClassReader cr) { - ClassHasNativeVisitor cv = new ClassHasNativeVisitor(); - cr.accept(cv, 0 /* flags */); - return cv.hasNativeMethods(); - } - -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java deleted file mode 100644 index 5424efa..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Attribute; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Indicates if a class contains any native methods. - */ -public class ClassHasNativeVisitor implements ClassVisitor { - - private boolean mHasNativeMethods = false; - - public boolean hasNativeMethods() { - return mHasNativeMethods; - } - - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - // pass - } - - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - // pass - return null; - } - - public void visitAttribute(Attribute attr) { - // pass - } - - public void visitEnd() { - // pass - } - - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - // pass - return null; - } - - public void visitInnerClass(String name, String outerName, - String innerName, int access) { - // pass - } - - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - mHasNativeMethods |= ((access & Opcodes.ACC_NATIVE) != 0); - return null; - } - - public void visitOuterClass(String owner, String name, String desc) { - // pass - } - - public void visitSource(String source, String debug) { - // pass - } - -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java deleted file mode 100644 index 8efd871..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import java.io.PrintWriter; -import java.io.StringWriter; - -public class Log { - - private boolean mVerbose = false; - - public void setVerbose(boolean verbose) { - mVerbose = verbose; - } - - public void debug(String format, Object... args) { - if (mVerbose) { - info(format, args); - } - } - - public void info(String format, Object... args) { - String s = String.format(format, args); - outPrintln(s); - } - - public void error(String format, Object... args) { - String s = String.format(format, args); - errPrintln(s); - } - - public void exception(Throwable t, String format, Object... args) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - pw.flush(); - error(format + "\n" + sw.toString(), args); - } - - /** for unit testing */ - protected void errPrintln(String msg) { - System.err.println(msg); - } - - /** for unit testing */ - protected void outPrintln(String msg) { - System.out.println(msg); - } - -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java deleted file mode 100644 index dc4b4a7..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -public class LogAbortException extends Exception { - - private final String mFormat; - private final Object[] mArgs; - - public LogAbortException(String format, Object... args) { - mFormat = format; - mArgs = args; - } - - public void error(Log log) { - log.error(mFormat, mArgs); - } -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java deleted file mode 100644 index 76bd8d4..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Set; - - - -public class Main { - - public static void main(String[] args) { - - Log log = new Log(); - - ArrayList<String> osJarPath = new ArrayList<String>(); - String[] osDestJar = { null }; - - if (!processArgs(log, args, osJarPath, osDestJar)) { - log.error("Usage: layoutlib_create [-v] output.jar input.jar ..."); - System.exit(1); - } - - log.info("Output: %1$s", osDestJar[0]); - for (String path : osJarPath) { - log.info("Input : %1$s", path); - } - - try { - AsmGenerator agen = new AsmGenerator(log, osDestJar[0], - new Class<?>[] { // classes to inject in the final JAR - OverrideMethod.class, - MethodListener.class, - MethodAdapter.class - }, - new String[] { // methods to force override - "android.view.View#isInEditMode", - "android.content.res.Resources$Theme#obtainStyledAttributes", - }, - new String[] { // classes to rename (so that we can replace them in layoutlib) - // original-platform-class-name ======> renamed-class-name - "android.graphics.Matrix", "android.graphics._Original_Matrix", - "android.graphics.Paint", "android.graphics._Original_Paint", - "android.graphics.Typeface", "android.graphics._Original_Typeface", - "android.graphics.Bitmap", "android.graphics._Original_Bitmap", - "android.graphics.Path", "android.graphics._Original_Path", - "android.graphics.PorterDuffXfermode", "android.graphics._Original_PorterDuffXfermode", - "android.graphics.Shader", "android.graphics._Original_Shader", - "android.graphics.LinearGradient", "android.graphics._Original_LinearGradient", - "android.graphics.BitmapShader", "android.graphics._Original_BitmapShader", - "android.graphics.ComposeShader", "android.graphics._Original_ComposeShader", - "android.graphics.RadialGradient", "android.graphics._Original_RadialGradient", - "android.graphics.SweepGradient", "android.graphics._Original_SweepGradient", - "android.util.FloatMath", "android.util._Original_FloatMath", - "android.view.SurfaceView", "android.view._Original_SurfaceView", - }, - new String[] { // methods deleted from their return type. - "android.graphics.Paint", // class to delete method from - "android.graphics.Paint$Align", // list of type identifying methods to delete - "android.graphics.Paint$Style", - "android.graphics.Paint$Join", - "android.graphics.Paint$Cap", - "android.graphics.Paint$FontMetrics", - "android.graphics.Paint$FontMetricsInt", - null } - ); - - AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen, - new String[] { "android.view.View" }, // derived from - new String[] { // include classes - "android.*", // for android.R - "android.util.*", - "com.android.internal.util.*", - "android.view.*", - "android.widget.*", - "com.android.internal.widget.*", - "android.text.**", - "android.graphics.*", - "android.graphics.drawable.*", - "android.content.*", - "android.content.res.*", - "org.apache.harmony.xml.*", - "com.android.internal.R**", - "android.pim.*", // for datepicker - "android.os.*", // for android.os.Handler - }); - aa.analyze(); - agen.generate(); - - // Throw an error if any class failed to get renamed by the generator - // - // IMPORTANT: if you're building the platform and you get this error message, - // it means the renameClasses[] array in AsmGenerator needs to be updated: some - // class should have been renamed but it was not found in the input JAR files. - Set<String> notRenamed = agen.getClassesNotRenamed(); - if (notRenamed.size() > 0) { - // (80-column guide below for error formatting) - // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 - log.error( - "ERROR when running layoutlib_create: the following classes are referenced\n" + - "by tools/layoutlib/create but were not actually found in the input JAR files.\n" + - "This may be due to some platform classes having been renamed."); - for (String fqcn : notRenamed) { - log.error("- Class not found: %s", fqcn.replace('/', '.')); - } - for (String path : osJarPath) { - log.info("- Input JAR : %1$s", path); - } - System.exit(1); - } - - System.exit(0); - } catch (IOException e) { - log.exception(e, "Failed to load jar"); - } catch (LogAbortException e) { - e.error(log); - } - - System.exit(1); - } - - /** - * Returns true if args where properly parsed. - * Returns false if program should exit with command-line usage. - * <p/> - * Note: the String[0] is an output parameter wrapped in an array, since there is no - * "out" parameter support. - */ - private static boolean processArgs(Log log, String[] args, - ArrayList<String> osJarPath, String[] osDestJar) { - for (int i = 0; i < args.length; i++) { - String s = args[i]; - if (s.equals("-v")) { - log.setVerbose(true); - } else if (!s.startsWith("-")) { - if (osDestJar[0] == null) { - osDestJar[0] = s; - } else { - osJarPath.add(s); - } - } else { - log.error("Unknow argument: %s", s); - return false; - } - } - - if (osJarPath.isEmpty()) { - log.error("Missing parameter: path to input jar"); - return false; - } - if (osDestJar[0] == null) { - log.error("Missing parameter: path to output jar"); - return false; - } - - return true; - } - -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java deleted file mode 100644 index 627ea17..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - - -/** - * An adapter to make it easier to use {@link MethodListener}. - * <p/> - * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener - * for all types (I, L, F, D and A), returning 0 or null as appropriate. - */ -public class MethodAdapter implements MethodListener { - /** - * A stub method is being invoked. - * <p/> - * Known limitation: caller arguments are not available. - * - * @param signature The signature of the method being invoked, composed of the - * binary class name followed by the method descriptor (aka argument - * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V". - * @param isNative True if the method was a native method. - * @param caller The calling object. Null for static methods, "this" for instance methods. - */ - public void onInvokeV(String signature, boolean isNative, Object caller) { - } - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar. - * @see #onInvokeV(String, boolean, Object) - * @return an integer, or a boolean, or a short or a byte. - */ - public int onInvokeI(String signature, boolean isNative, Object caller) { - onInvokeV(signature, isNative, caller); - return 0; - } - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long. - * @see #onInvokeV(String, boolean, Object) - * @return a long. - */ - public long onInvokeL(String signature, boolean isNative, Object caller) { - onInvokeV(signature, isNative, caller); - return 0; - } - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float. - * @see #onInvokeV(String, boolean, Object) - * @return a float. - */ - public float onInvokeF(String signature, boolean isNative, Object caller) { - onInvokeV(signature, isNative, caller); - return 0; - } - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double. - * @see #onInvokeV(String, boolean, Object) - * @return a double. - */ - public double onInvokeD(String signature, boolean isNative, Object caller) { - onInvokeV(signature, isNative, caller); - return 0; - } - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object. - * @see #onInvokeV(String, boolean, Object) - * @return an object. - */ - public Object onInvokeA(String signature, boolean isNative, Object caller) { - onInvokeV(signature, isNative, caller); - return null; - } -} - diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java deleted file mode 100644 index 6fc2b24..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - - -/** - * Interface to allow a method invocation to be listened upon. - * <p/> - * This is used by {@link OverrideMethod} to register a listener for methods that - * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a - * default global listener or a specific listener based on the method signature. - */ -public interface MethodListener { - /** - * A stub method is being invoked. - * <p/> - * Known limitation: caller arguments are not available. - * - * @param signature The signature of the method being invoked, composed of the - * binary class name followed by the method descriptor (aka argument - * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V". - * @param isNative True if the method was a native method. - * @param caller The calling object. Null for static methods, "this" for instance methods. - */ - public void onInvokeV(String signature, boolean isNative, Object caller); - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar. - * @see #onInvokeV(String, boolean, Object) - * @return an integer, or a boolean, or a short or a byte. - */ - public int onInvokeI(String signature, boolean isNative, Object caller); - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long. - * @see #onInvokeV(String, boolean, Object) - * @return a long. - */ - public long onInvokeL(String signature, boolean isNative, Object caller); - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float. - * @see #onInvokeV(String, boolean, Object) - * @return a float. - */ - public float onInvokeF(String signature, boolean isNative, Object caller); - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double. - * @see #onInvokeV(String, boolean, Object) - * @return a double. - */ - public double onInvokeD(String signature, boolean isNative, Object caller); - - /** - * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object. - * @see #onInvokeV(String, boolean, Object) - * @return an object. - */ - public Object onInvokeA(String signature, boolean isNative, Object caller); -} - diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java deleted file mode 100644 index a6aff99..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import java.util.HashMap; - -/** - * Allows stub methods from LayoutLib to be overriden at runtime. - * <p/> - * Implementation note: all types required by this class(inner/outer classes & interfaces) - * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java; - * Otherwise they won't be accessible in layoutlib.jar at runtime. - */ -public final class OverrideMethod { - - /** Map of method overridden. */ - private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>(); - /** Default listener for all method not listed in sMethods. Nothing if null. */ - private static MethodListener sDefaultListener = null; - - /** - * Sets the default listener for all methods not specifically handled. - * Null means to do nothing. - */ - public static void setDefaultListener(MethodListener listener) { - sDefaultListener = listener; - } - - /** - * Defines or reset a listener for the given method signature. - * - * @param signature The signature of the method being invoked, composed of the - * binary class name followed by the method descriptor (aka argument - * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V" - * @param listener The new listener. Removes it if null. - */ - public static void setMethodListener(String signature, MethodListener listener) { - if (listener == null) { - sMethods.remove(signature); - } else { - sMethods.put(signature, listener); - } - } - - /** - * Invokes the specific listener for the given signature or the default one if defined. - * <p/> - * This version invokes the method listener for the void return type. - * <p/> - * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called - * by the stubbed methods generated by the LayoutLib_create tool. - * - * @param signature The signature of the method being invoked, composed of the - * binary class name followed by the method descriptor (aka argument - * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V". - * @param isNative True if the method was a native method. - * @param caller The calling object. Null for static methods, "this" for instance methods. - */ - public static void invokeV(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - i.onInvokeV(signature, isNative, caller); - } else if (sDefaultListener != null) { - sDefaultListener.onInvokeV(signature, isNative, caller); - } - } - - /** - * Invokes the specific listener for the int return type. - * @see #invokeV(String, boolean, Object) - */ - public static int invokeI(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - return i.onInvokeI(signature, isNative, caller); - } else if (sDefaultListener != null) { - return sDefaultListener.onInvokeI(signature, isNative, caller); - } - return 0; - } - - /** - * Invokes the specific listener for the long return type. - * @see #invokeV(String, boolean, Object) - */ - public static long invokeL(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - return i.onInvokeL(signature, isNative, caller); - } else if (sDefaultListener != null) { - return sDefaultListener.onInvokeL(signature, isNative, caller); - } - return 0; - } - - /** - * Invokes the specific listener for the float return type. - * @see #invokeV(String, boolean, Object) - */ - public static float invokeF(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - return i.onInvokeF(signature, isNative, caller); - } else if (sDefaultListener != null) { - return sDefaultListener.onInvokeF(signature, isNative, caller); - } - return 0; - } - - /** - * Invokes the specific listener for the double return type. - * @see #invokeV(String, boolean, Object) - */ - public static double invokeD(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - return i.onInvokeD(signature, isNative, caller); - } else if (sDefaultListener != null) { - return sDefaultListener.onInvokeD(signature, isNative, caller); - } - return 0; - } - - /** - * Invokes the specific listener for the object return type. - * @see #invokeV(String, boolean, Object) - */ - public static Object invokeA(String signature, boolean isNative, Object caller) { - MethodListener i = sMethods.get(signature); - if (i != null) { - return i.onInvokeA(signature, isNative, caller); - } else if (sDefaultListener != null) { - return sDefaultListener.onInvokeA(signature, isNative, caller); - } - return null; - } -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java deleted file mode 100644 index 0956b92..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodAdapter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.objectweb.asm.signature.SignatureWriter; - -/** - * This class visitor renames a class from a given old name to a given new name. - * The class visitor will also rename all inner classes and references in the methods. - * <p/> - * - * For inner classes, this handles only the case where the outer class name changes. - * The inner class name should remain the same. - */ -public class RenameClassAdapter extends ClassAdapter { - - - private final String mOldName; - private final String mNewName; - private String mOldBase; - private String mNewBase; - - /** - * Creates a class visitor that renames a class from a given old name to a given new name. - * The class visitor will also rename all inner classes and references in the methods. - * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). - */ - public RenameClassAdapter(ClassWriter cv, String oldName, String newName) { - super(cv); - mOldBase = mOldName = oldName; - mNewBase = mNewName = newName; - - int pos = mOldName.indexOf('$'); - if (pos > 0) { - mOldBase = mOldName.substring(0, pos); - } - pos = mNewName.indexOf('$'); - if (pos > 0) { - mNewBase = mNewName.substring(0, pos); - } - - assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null); - } - - - /** - * Renames a type descriptor, e.g. "Lcom.package.MyClass;" - * If the type doesn't need to be renamed, returns the input string as-is. - */ - String renameTypeDesc(String desc) { - if (desc == null) { - return null; - } - - return renameType(Type.getType(desc)); - } - - /** - * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an - * object element, e.g. "[Lcom.package.MyClass;" - * If the type doesn't need to be renamed, returns the internal name of the input type. - */ - String renameType(Type type) { - if (type == null) { - return null; - } - - if (type.getSort() == Type.OBJECT) { - String in = type.getInternalName(); - return "L" + renameInternalType(in) + ";"; - } else if (type.getSort() == Type.ARRAY) { - StringBuilder sb = new StringBuilder(); - for (int n = type.getDimensions(); n > 0; n--) { - sb.append('['); - } - sb.append(renameType(type.getElementType())); - return sb.toString(); - } - return type.getDescriptor(); - } - - /** - * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an - * object element, e.g. "[Lcom.package.MyClass;". - * This is like renameType() except that it returns a Type object. - * If the type doesn't need to be renamed, returns the input type object. - */ - Type renameTypeAsType(Type type) { - if (type == null) { - return null; - } - - if (type.getSort() == Type.OBJECT) { - String in = type.getInternalName(); - String newIn = renameInternalType(in); - if (newIn != in) { - return Type.getType("L" + newIn + ";"); - } - } else if (type.getSort() == Type.ARRAY) { - StringBuilder sb = new StringBuilder(); - for (int n = type.getDimensions(); n > 0; n--) { - sb.append('['); - } - sb.append(renameType(type.getElementType())); - return Type.getType(sb.toString()); - } - return type; - } - - /** - * Renames an internal type name, e.g. "com.package.MyClass". - * If the type doesn't need to be renamed, returns the input string as-is. - * <p/> - * The internal type of some of the MethodVisitor turns out to be a type - descriptor sometimes so descriptors are renamed too. - */ - String renameInternalType(String type) { - if (type == null) { - return null; - } - - if (type.equals(mOldName)) { - return mNewName; - } - - if (mOldBase != mOldName && type.equals(mOldBase)) { - return mNewBase; - } - - int pos = type.indexOf('$'); - if (pos == mOldBase.length() && type.startsWith(mOldBase)) { - return mNewBase + type.substring(pos); - } - - // The internal type of some of the MethodVisitor turns out to be a type - // descriptor sometimes. This is the case with visitTypeInsn(type) and - // visitMethodInsn(owner). We try to detect it and adjust it here. - if (type.indexOf(';') > 0) { - type = renameTypeDesc(type); - } - - return type; - } - - /** - * Renames a method descriptor, i.e. applies renameType to all arguments and to the - * return value. - */ - String renameMethodDesc(String desc) { - if (desc == null) { - return null; - } - - Type[] args = Type.getArgumentTypes(desc); - - StringBuilder sb = new StringBuilder("("); - for (Type arg : args) { - String name = renameType(arg); - sb.append(name); - } - sb.append(')'); - - Type ret = Type.getReturnType(desc); - String name = renameType(ret); - sb.append(name); - - return sb.toString(); - } - - - /** - * Renames the ClassSignature handled by ClassVisitor.visit - * or the MethodTypeSignature handled by ClassVisitor.visitMethod. - */ - String renameTypeSignature(String sig) { - if (sig == null) { - return null; - } - SignatureReader reader = new SignatureReader(sig); - SignatureWriter writer = new SignatureWriter(); - reader.accept(new RenameSignatureAdapter(writer)); - sig = writer.toString(); - return sig; - } - - - /** - * Renames the FieldTypeSignature handled by ClassVisitor.visitField - * or MethodVisitor.visitLocalVariable. - */ - String renameFieldSignature(String sig) { - if (sig == null) { - return null; - } - SignatureReader reader = new SignatureReader(sig); - SignatureWriter writer = new SignatureWriter(); - reader.acceptType(new RenameSignatureAdapter(writer)); - sig = writer.toString(); - return sig; - } - - - //---------------------------------- - // Methods from the ClassAdapter - - @Override - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - name = renameInternalType(name); - superName = renameInternalType(superName); - signature = renameTypeSignature(signature); - - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - assert outerName.equals(mOldName); - outerName = renameInternalType(outerName); - name = outerName + "$" + innerName; - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - desc = renameMethodDesc(desc); - signature = renameTypeSignature(signature); - MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions); - return new RenameMethodAdapter(mw); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - desc = renameTypeDesc(desc); - return super.visitAnnotation(desc, visible); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - desc = renameTypeDesc(desc); - signature = renameFieldSignature(signature); - return super.visitField(access, name, desc, signature, value); - } - - - //---------------------------------- - - /** - * A method visitor that renames all references from an old class name to a new class name. - */ - public class RenameMethodAdapter extends MethodAdapter { - - /** - * Creates a method visitor that renames all references from a given old name to a given new - * name. The method visitor will also rename all inner classes. - * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). - */ - public RenameMethodAdapter(MethodVisitor mv) { - super(mv); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - desc = renameTypeDesc(desc); - - return super.visitAnnotation(desc, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - desc = renameTypeDesc(desc); - - return super.visitParameterAnnotation(parameter, desc, visible); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - type = renameInternalType(type); - - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - owner = renameInternalType(owner); - desc = renameTypeDesc(desc); - - super.visitFieldInsn(opcode, owner, name, desc); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - owner = renameInternalType(owner); - desc = renameMethodDesc(desc); - - super.visitMethodInsn(opcode, owner, name, desc); - } - - @Override - public void visitLdcInsn(Object cst) { - // If cst is a Type, this means the code is trying to pull the .class constant - // for this class, so it needs to be renamed too. - if (cst instanceof Type) { - cst = renameTypeAsType((Type) cst); - } - super.visitLdcInsn(cst); - } - - @Override - public void visitMultiANewArrayInsn(String desc, int dims) { - desc = renameTypeDesc(desc); - - super.visitMultiANewArrayInsn(desc, dims); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - type = renameInternalType(type); - - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public void visitLocalVariable(String name, String desc, String signature, - Label start, Label end, int index) { - desc = renameTypeDesc(desc); - signature = renameFieldSignature(signature); - - super.visitLocalVariable(name, desc, signature, start, end, index); - } - - } - - //---------------------------------- - - public class RenameSignatureAdapter implements SignatureVisitor { - - private final SignatureVisitor mSv; - - public RenameSignatureAdapter(SignatureVisitor sv) { - mSv = sv; - } - - public void visitClassType(String name) { - name = renameInternalType(name); - mSv.visitClassType(name); - } - - public void visitInnerClassType(String name) { - name = renameInternalType(name); - mSv.visitInnerClassType(name); - } - - public SignatureVisitor visitArrayType() { - SignatureVisitor sv = mSv.visitArrayType(); - return new RenameSignatureAdapter(sv); - } - - public void visitBaseType(char descriptor) { - mSv.visitBaseType(descriptor); - } - - public SignatureVisitor visitClassBound() { - SignatureVisitor sv = mSv.visitClassBound(); - return new RenameSignatureAdapter(sv); - } - - public void visitEnd() { - mSv.visitEnd(); - } - - public SignatureVisitor visitExceptionType() { - SignatureVisitor sv = mSv.visitExceptionType(); - return new RenameSignatureAdapter(sv); - } - - public void visitFormalTypeParameter(String name) { - mSv.visitFormalTypeParameter(name); - } - - public SignatureVisitor visitInterface() { - SignatureVisitor sv = mSv.visitInterface(); - return new RenameSignatureAdapter(sv); - } - - public SignatureVisitor visitInterfaceBound() { - SignatureVisitor sv = mSv.visitInterfaceBound(); - return new RenameSignatureAdapter(sv); - } - - public SignatureVisitor visitParameterType() { - SignatureVisitor sv = mSv.visitParameterType(); - return new RenameSignatureAdapter(sv); - } - - public SignatureVisitor visitReturnType() { - SignatureVisitor sv = mSv.visitReturnType(); - return new RenameSignatureAdapter(sv); - } - - public SignatureVisitor visitSuperclass() { - SignatureVisitor sv = mSv.visitSuperclass(); - return new RenameSignatureAdapter(sv); - } - - public void visitTypeArgument() { - mSv.visitTypeArgument(); - } - - public SignatureVisitor visitTypeArgument(char wildcard) { - SignatureVisitor sv = mSv.visitTypeArgument(wildcard); - return new RenameSignatureAdapter(sv); - } - - public void visitTypeVariable(String name) { - mSv.visitTypeVariable(name); - } - - } -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java deleted file mode 100644 index 9a57a4a..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Attribute; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -/** - * This method adapter rewrites a method by discarding the original code and generating - * a stub depending on the return type. Original annotations are passed along unchanged. - */ -class StubMethodAdapter implements MethodVisitor { - - private static String CONSTRUCTOR = "<init>"; - private static String CLASS_INIT = "<clinit>"; - - /** The parent method writer */ - private MethodVisitor mParentVisitor; - /** The method return type. Can be null. */ - private Type mReturnType; - /** Message to be printed by stub methods. */ - private String mInvokeSignature; - /** Flag to output the first line number. */ - private boolean mOutputFirstLineNumber = true; - /** Flag that is true when implementing a constructor, to accept all original - * code calling the original super constructor. */ - private boolean mIsInitMethod = false; - - private boolean mMessageGenerated; - private final boolean mIsStatic; - private final boolean mIsNative; - - public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType, - String invokeSignature, boolean isStatic, boolean isNative) { - mParentVisitor = mv; - mReturnType = returnType; - mInvokeSignature = invokeSignature; - mIsStatic = isStatic; - mIsNative = isNative; - - if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) { - mIsInitMethod = true; - } - } - - private void generateInvoke() { - /* Generates the code: - * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this); - */ - mParentVisitor.visitLdcInsn(mInvokeSignature); - // push true or false - mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0); - // push null or this - if (mIsStatic) { - mParentVisitor.visitInsn(Opcodes.ACONST_NULL); - } else { - mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); - } - - int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID; - switch(sort) { - case Type.VOID: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeV", - "(Ljava/lang/String;ZLjava/lang/Object;)V"); - mParentVisitor.visitInsn(Opcodes.RETURN); - break; - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeI", - "(Ljava/lang/String;ZLjava/lang/Object;)I"); - switch(sort) { - case Type.BOOLEAN: - Label l1 = new Label(); - mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1); - mParentVisitor.visitInsn(Opcodes.ICONST_1); - mParentVisitor.visitInsn(Opcodes.IRETURN); - mParentVisitor.visitLabel(l1); - mParentVisitor.visitInsn(Opcodes.ICONST_0); - break; - case Type.CHAR: - mParentVisitor.visitInsn(Opcodes.I2C); - break; - case Type.BYTE: - mParentVisitor.visitInsn(Opcodes.I2B); - break; - case Type.SHORT: - mParentVisitor.visitInsn(Opcodes.I2S); - break; - } - mParentVisitor.visitInsn(Opcodes.IRETURN); - break; - case Type.LONG: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeL", - "(Ljava/lang/String;ZLjava/lang/Object;)J"); - mParentVisitor.visitInsn(Opcodes.LRETURN); - break; - case Type.FLOAT: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeF", - "(Ljava/lang/String;ZLjava/lang/Object;)F"); - mParentVisitor.visitInsn(Opcodes.FRETURN); - break; - case Type.DOUBLE: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeD", - "(Ljava/lang/String;ZLjava/lang/Object;)D"); - mParentVisitor.visitInsn(Opcodes.DRETURN); - break; - case Type.ARRAY: - case Type.OBJECT: - mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, - "com/android/tools/layoutlib/create/OverrideMethod", - "invokeA", - "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;"); - mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); - mParentVisitor.visitInsn(Opcodes.ARETURN); - break; - } - - } - - private void generatePop() { - /* Pops the stack, depending on the return type. - */ - switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) { - case Type.VOID: - break; - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - case Type.FLOAT: - case Type.ARRAY: - case Type.OBJECT: - mParentVisitor.visitInsn(Opcodes.POP); - break; - case Type.LONG: - case Type.DOUBLE: - mParentVisitor.visitInsn(Opcodes.POP2); - break; - } - } - - /* Pass down to visitor writer. In this implementation, either do nothing. */ - public void visitCode() { - mParentVisitor.visitCode(); - } - - /* - * visitMaxs is called just before visitEnd if there was any code to rewrite. - * For non-constructor, generate the messaging code and the return statement - * if it hasn't been done before. - */ - public void visitMaxs(int maxStack, int maxLocals) { - if (!mIsInitMethod && !mMessageGenerated) { - generateInvoke(); - mMessageGenerated = true; - } - mParentVisitor.visitMaxs(maxStack, maxLocals); - } - - /** - * End of visiting. - * For non-constructor, generate the messaging code and the return statement - * if it hasn't been done before. - */ - public void visitEnd() { - if (!mIsInitMethod && !mMessageGenerated) { - generateInvoke(); - mMessageGenerated = true; - mParentVisitor.visitMaxs(1, 1); - } - mParentVisitor.visitEnd(); - } - - /* Writes all annotation from the original method. */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - return mParentVisitor.visitAnnotation(desc, visible); - } - - /* Writes all annotation default values from the original method. */ - public AnnotationVisitor visitAnnotationDefault() { - return mParentVisitor.visitAnnotationDefault(); - } - - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, - boolean visible) { - return mParentVisitor.visitParameterAnnotation(parameter, desc, visible); - } - - /* Writes all attributes from the original method. */ - public void visitAttribute(Attribute attr) { - mParentVisitor.visitAttribute(attr); - } - - /* - * Only writes the first line number present in the original code so that source - * viewers can direct to the correct method, even if the content doesn't match. - */ - public void visitLineNumber(int line, Label start) { - if (mIsInitMethod || mOutputFirstLineNumber) { - mParentVisitor.visitLineNumber(line, start); - mOutputFirstLineNumber = false; - } - } - - /** - * For non-constructor, rewrite existing "return" instructions to write the message. - */ - public void visitInsn(int opcode) { - if (mIsInitMethod) { - switch (opcode) { - case Opcodes.RETURN: - case Opcodes.ARETURN: - case Opcodes.DRETURN: - case Opcodes.FRETURN: - case Opcodes.IRETURN: - case Opcodes.LRETURN: - // Pop the last word from the stack since invoke will generate its own return. - generatePop(); - generateInvoke(); - mMessageGenerated = true; - default: - mParentVisitor.visitInsn(opcode); - } - } - } - - public void visitLabel(Label label) { - if (mIsInitMethod) { - mParentVisitor.visitLabel(label); - } - } - - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - if (mIsInitMethod) { - mParentVisitor.visitTryCatchBlock(start, end, handler, type); - } - } - - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - if (mIsInitMethod) { - mParentVisitor.visitMethodInsn(opcode, owner, name, desc); - } - } - - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - if (mIsInitMethod) { - mParentVisitor.visitFieldInsn(opcode, owner, name, desc); - } - } - - public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { - if (mIsInitMethod) { - mParentVisitor.visitFrame(type, nLocal, local, nStack, stack); - } - } - - public void visitIincInsn(int var, int increment) { - if (mIsInitMethod) { - mParentVisitor.visitIincInsn(var, increment); - } - } - - public void visitIntInsn(int opcode, int operand) { - if (mIsInitMethod) { - mParentVisitor.visitIntInsn(opcode, operand); - } - } - - public void visitJumpInsn(int opcode, Label label) { - if (mIsInitMethod) { - mParentVisitor.visitJumpInsn(opcode, label); - } - } - - public void visitLdcInsn(Object cst) { - if (mIsInitMethod) { - mParentVisitor.visitLdcInsn(cst); - } - } - - public void visitLocalVariable(String name, String desc, String signature, - Label start, Label end, int index) { - if (mIsInitMethod) { - mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index); - } - } - - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - if (mIsInitMethod) { - mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels); - } - } - - public void visitMultiANewArrayInsn(String desc, int dims) { - if (mIsInitMethod) { - mParentVisitor.visitMultiANewArrayInsn(desc, dims); - } - } - - public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { - if (mIsInitMethod) { - mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels); - } - } - - public void visitTypeInsn(int opcode, String type) { - if (mIsInitMethod) { - mParentVisitor.visitTypeInsn(opcode, type); - } - } - - public void visitVarInsn(int opcode, int var) { - if (mIsInitMethod) { - mParentVisitor.visitVarInsn(opcode, var); - } - } - -} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java deleted file mode 100644 index e294d56..0000000 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -import java.util.Set; - -/** - * Class adapter that can stub some or all of the methods of the class. - */ -class TransformClassAdapter extends ClassAdapter { - - /** True if all methods should be stubbed, false if only native ones must be stubbed. */ - private final boolean mStubAll; - /** True if the class is an interface. */ - private boolean mIsInterface; - private final String mClassName; - private final Log mLog; - private final Set<String> mStubMethods; - private Set<String> mDeleteReturns; - - /** - * Creates a new class adapter that will stub some or all methods. - * @param logger - * @param stubMethods - * @param deleteReturns list of types that trigger the deletion of methods returning them. - * @param className The name of the class being modified - * @param cv The parent class writer visitor - * @param stubNativesOnly True if only native methods should be stubbed. False if all - * methods should be stubbed. - * @param hasNative True if the method has natives, in which case its access should be - * changed. - */ - public TransformClassAdapter(Log logger, Set<String> stubMethods, - Set<String> deleteReturns, String className, ClassVisitor cv, - boolean stubNativesOnly, boolean hasNative) { - super(cv); - mLog = logger; - mStubMethods = stubMethods; - mClassName = className; - mStubAll = !stubNativesOnly; - mIsInterface = false; - mDeleteReturns = deleteReturns; - } - - /* Visits the class header. */ - @Override - public void visit(int version, int access, String name, - String signature, String superName, String[] interfaces) { - - // This class might be being renamed. - name = mClassName; - - // remove protected or private and set as public - access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED); - access |= Opcodes.ACC_PUBLIC; - // remove final - access = access & ~Opcodes.ACC_FINAL; - // note: leave abstract classes as such - // don't try to implement stub for interfaces - - mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0); - super.visit(version, access, name, signature, superName, interfaces); - } - - /* Visits the header of an inner class. */ - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - // remove protected or private and set as public - access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED); - access |= Opcodes.ACC_PUBLIC; - // remove final - access = access & ~Opcodes.ACC_FINAL; - // note: leave abstract classes as such - // don't try to implement stub for interfaces - - super.visitInnerClass(name, outerName, innerName, access); - } - - /* Visits a method. */ - @Override - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - - if (mDeleteReturns != null) { - Type t = Type.getReturnType(desc); - if (t.getSort() == Type.OBJECT) { - String returnType = t.getInternalName(); - if (returnType != null) { - if (mDeleteReturns.contains(returnType)) { - return null; - } - } - } - } - - String methodSignature = mClassName.replace('/', '.') + "#" + name; - - // change access to public - access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); - access |= Opcodes.ACC_PUBLIC; - - // remove final - access = access & ~Opcodes.ACC_FINAL; - - // stub this method if they are all to be stubbed or if it is a native method - // and don't try to stub interfaces nor abstract non-native methods. - if (!mIsInterface && - ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) && - (mStubAll || - (access & Opcodes.ACC_NATIVE) != 0) || - mStubMethods.contains(methodSignature)) { - - boolean isStatic = (access & Opcodes.ACC_STATIC) != 0; - boolean isNative = (access & Opcodes.ACC_NATIVE) != 0; - - // remove abstract, final and native - access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE); - - String invokeSignature = methodSignature + desc; - mLog.debug(" Stub: %s (%s)", invokeSignature, isNative ? "native" : ""); - - MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions); - return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature, - isStatic, isNative); - - } else { - mLog.debug(" Keep: %s %s", name, desc); - return super.visitMethod(access, name, desc, signature, exceptions); - } - } - - /* Visits a field. Makes it public. */ - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, - Object value) { - // change access to public - access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); - access |= Opcodes.ACC_PUBLIC; - - return super.visitField(access, name, desc, signature, value); - } - - /** - * Extracts the return {@link Type} of this descriptor. - */ - Type returnType(String desc) { - if (desc != null) { - try { - return Type.getReturnType(desc); - } catch (ArrayIndexOutOfBoundsException e) { - // ignore, not a valid type. - } - } - return null; - } -} diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java deleted file mode 100644 index 603284e..0000000 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.tools.layoutlib.create; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor; -import com.android.tools.layoutlib.create.LogTest.MockLog; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.objectweb.asm.ClassReader; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Map; -import java.util.TreeMap; - -/** - * Unit tests for some methods of {@link AsmAnalyzer}. - */ -public class AsmAnalyzerTest { - - private MockLog mLog; - private ArrayList<String> mOsJarPath; - private AsmAnalyzer mAa; - - @Before - public void setUp() throws Exception { - mLog = new LogTest.MockLog(); - URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); - - mOsJarPath = new ArrayList<String>(); - mOsJarPath.add(url.getFile()); - - mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, - null /* deriveFrom */, null /* includeGlobs */ ); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testParseZip() throws IOException { - Map<String, ClassReader> map = mAa.parseZip(mOsJarPath); - - assertArrayEquals(new String[] { - "mock_android.dummy.InnerTest", - "mock_android.dummy.InnerTest$DerivingClass", - "mock_android.dummy.InnerTest$MyGenerics1", - "mock_android.dummy.InnerTest$MyIntEnum", - "mock_android.dummy.InnerTest$MyStaticInnerClass", - "mock_android.dummy.InnerTest$NotStaticInner1", - "mock_android.dummy.InnerTest$NotStaticInner2", - "mock_android.view.View", - "mock_android.view.ViewGroup", - "mock_android.view.ViewGroup$LayoutParams", - "mock_android.view.ViewGroup$MarginLayoutParams", - "mock_android.widget.LinearLayout", - "mock_android.widget.LinearLayout$LayoutParams", - "mock_android.widget.TableLayout", - "mock_android.widget.TableLayout$LayoutParams" - }, - map.keySet().toArray()); - } - - @Test - public void testFindClass() throws IOException, LogAbortException { - Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath); - TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); - - ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams", - zipClasses, found); - - assertNotNull(cr); - assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName()); - assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" }, - found.keySet().toArray()); - assertArrayEquals(new ClassReader[] { cr }, found.values().toArray()); - } - - @Test - public void testFindGlobs() throws IOException, LogAbortException { - Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath); - TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); - - // this matches classes, a package match returns nothing - found.clear(); - mAa.findGlobs("mock_android.view", zipClasses, found); - - assertArrayEquals(new String[] { }, - found.keySet().toArray()); - - // a complex glob search. * is a search pattern that matches names, not dots - mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found); - - assertArrayEquals(new String[] { - "mock_android.view.ViewGroup$LayoutParams", - "mock_android.view.ViewGroup$MarginLayoutParams" - }, - found.keySet().toArray()); - - // a complex glob search. ** is a search pattern that matches names including dots - mAa.findGlobs("mock_android.**Group*", zipClasses, found); - - assertArrayEquals(new String[] { - "mock_android.view.ViewGroup", - "mock_android.view.ViewGroup$LayoutParams", - "mock_android.view.ViewGroup$MarginLayoutParams" - }, - found.keySet().toArray()); - - // matches a single class - found.clear(); - mAa.findGlobs("mock_android.view.View", zipClasses, found); - - assertArrayEquals(new String[] { - "mock_android.view.View" - }, - found.keySet().toArray()); - - // matches everyting inside the given package but not sub-packages - found.clear(); - mAa.findGlobs("mock_android.view.*", zipClasses, found); - - assertArrayEquals(new String[] { - "mock_android.view.View", - "mock_android.view.ViewGroup", - "mock_android.view.ViewGroup$LayoutParams", - "mock_android.view.ViewGroup$MarginLayoutParams" - }, - found.keySet().toArray()); - - for (String key : found.keySet()) { - ClassReader value = found.get(key); - assertNotNull("No value for " + key, value); - assertEquals(key, AsmAnalyzer.classReaderToClassName(value)); - } - } - - @Test - public void testFindClassesDerivingFrom() throws LogAbortException, IOException { - Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath); - TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); - - mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found); - - assertArrayEquals(new String[] { - "mock_android.view.View", - "mock_android.view.ViewGroup", - "mock_android.widget.LinearLayout", - "mock_android.widget.TableLayout", - }, - found.keySet().toArray()); - - for (String key : found.keySet()) { - ClassReader value = found.get(key); - assertNotNull("No value for " + key, value); - assertEquals(key, AsmAnalyzer.classReaderToClassName(value)); - } - } - - @Test - public void testDependencyVisitor() throws IOException, LogAbortException { - Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath); - TreeMap<String, ClassReader> keep = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> in_deps = new TreeMap<String, ClassReader>(); - TreeMap<String, ClassReader> out_deps = new TreeMap<String, ClassReader>(); - - ClassReader cr = mAa.findClass("mock_android.widget.TableLayout", zipClasses, keep); - DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps); - - // get first level dependencies - cr.accept(visitor, 0 /* flags */); - - assertArrayEquals(new String[] { - "mock_android.view.ViewGroup", - "mock_android.widget.TableLayout$LayoutParams", - }, - out_deps.keySet().toArray()); - - in_deps.putAll(out_deps); - out_deps.clear(); - - // get second level dependencies - for (ClassReader cr2 : in_deps.values()) { - cr2.accept(visitor, 0 /* flags */); - } - - assertArrayEquals(new String[] { - "mock_android.view.View", - "mock_android.view.ViewGroup$LayoutParams", - "mock_android.view.ViewGroup$MarginLayoutParams", - }, - out_deps.keySet().toArray()); - - in_deps.putAll(out_deps); - out_deps.clear(); - - // get third level dependencies (there are none) - for (ClassReader cr2 : in_deps.values()) { - cr2.accept(visitor, 0 /* flags */); - } - - assertArrayEquals(new String[] { }, out_deps.keySet().toArray()); - } -} diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java deleted file mode 100644 index 7cdf79a..0000000 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.tools.layoutlib.create; - - -import static org.junit.Assert.assertArrayEquals; - -import com.android.tools.layoutlib.create.LogTest.MockLog; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Set; - -/** - * Unit tests for some methods of {@link AsmGenerator}. - */ -public class AsmGeneratorTest { - - private MockLog mLog; - private ArrayList<String> mOsJarPath; - private String mOsDestJar; - private File mTempFile; - - @Before - public void setUp() throws Exception { - mLog = new LogTest.MockLog(); - URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); - - mOsJarPath = new ArrayList<String>(); - mOsJarPath.add(url.getFile()); - - mTempFile = File.createTempFile("mock", "jar"); - mOsDestJar = mTempFile.getAbsolutePath(); - mTempFile.deleteOnExit(); - } - - @After - public void tearDown() throws Exception { - if (mTempFile != null) { - mTempFile.delete(); - mTempFile = null; - } - } - - @Test - public void testClassRenaming() throws IOException, LogAbortException { - - AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, - null, // classes to inject in the final JAR - null, // methods to force override - new String[] { // classes to rename (so that we can replace them) - "mock_android.view.View", "mock_android.view._Original_View", - "not.an.actual.ClassName", "anoter.fake.NewClassName", - }, - null // methods deleted from their return type. - ); - - AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen, - null, // derived from - new String[] { // include classes - "**" - }); - aa.analyze(); - agen.generate(); - - Set<String> notRenamed = agen.getClassesNotRenamed(); - assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray()); - } -} diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java deleted file mode 100644 index 3f13158..0000000 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.tools.layoutlib.create; - -import static org.junit.Assert.*; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class LogTest { - - public static class MockLog extends Log { - StringBuilder mOut = new StringBuilder(); - StringBuilder mErr = new StringBuilder(); - - public String getOut() { - return mOut.toString(); - } - - public String getErr() { - return mErr.toString(); - } - - @Override - protected void outPrintln(String msg) { - mOut.append(msg); - mOut.append('\n'); - } - - @Override - protected void errPrintln(String msg) { - mErr.append(msg); - mErr.append('\n'); - } - } - - private MockLog mLog; - - @Before - public void setUp() throws Exception { - mLog = new MockLog(); - } - - @After - public void tearDown() throws Exception { - // pass - } - - @Test - public void testDebug() { - assertEquals("", mLog.getOut()); - assertEquals("", mLog.getErr()); - - mLog.setVerbose(false); - mLog.debug("Test %d", 42); - assertEquals("", mLog.getOut()); - - mLog.setVerbose(true); - mLog.debug("Test %d", 42); - - assertEquals("Test 42\n", mLog.getOut()); - assertEquals("", mLog.getErr()); - } - - @Test - public void testInfo() { - assertEquals("", mLog.getOut()); - assertEquals("", mLog.getErr()); - - mLog.info("Test %d", 43); - - assertEquals("Test 43\n", mLog.getOut()); - assertEquals("", mLog.getErr()); - } - - @Test - public void testError() { - assertEquals("", mLog.getOut()); - assertEquals("", mLog.getErr()); - - mLog.error("Test %d", 44); - - assertEquals("", mLog.getOut()); - assertEquals("Test 44\n", mLog.getErr()); - } - - @Test - public void testException() { - assertEquals("", mLog.getOut()); - assertEquals("", mLog.getErr()); - - Exception e = new Exception("My Exception"); - mLog.exception(e, "Test %d", 44); - - assertEquals("", mLog.getOut()); - assertTrue(mLog.getErr().startsWith("Test 44\njava.lang.Exception: My Exception")); - } -} diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java deleted file mode 100644 index 90c6a9c..0000000 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.tools.layoutlib.create; - -import static org.junit.Assert.*; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * - */ -public class RenameClassAdapterTest { - - private RenameClassAdapter mOuter; - private RenameClassAdapter mInner; - - @Before - public void setUp() throws Exception { - mOuter = new RenameClassAdapter(null, // cv - "com.pack.Old", - "org.blah.New"); - - mInner = new RenameClassAdapter(null, // cv - "com.pack.Old$Inner", - "org.blah.New$Inner"); - } - - @After - public void tearDown() throws Exception { - } - - /** - * Renames a type, e.g. "Lcom.package.My;" - * If the type doesn't need to be renamed, returns the input string as-is. - */ - @Test - public void testRenameTypeDesc() { - - // primitive types are left untouched - assertEquals("I", mOuter.renameTypeDesc("I")); - assertEquals("D", mOuter.renameTypeDesc("D")); - assertEquals("V", mOuter.renameTypeDesc("V")); - - // object types that need no renaming are left untouched - assertEquals("Lcom.package.MyClass;", mOuter.renameTypeDesc("Lcom.package.MyClass;")); - assertEquals("Lcom.package.MyClass;", mInner.renameTypeDesc("Lcom.package.MyClass;")); - - // object types that match the requirements - assertEquals("Lorg.blah.New;", mOuter.renameTypeDesc("Lcom.pack.Old;")); - assertEquals("Lorg.blah.New$Inner;", mInner.renameTypeDesc("Lcom.pack.Old$Inner;")); - // inner classes match the base type which is being renamed - assertEquals("Lorg.blah.New$Other;", mOuter.renameTypeDesc("Lcom.pack.Old$Other;")); - assertEquals("Lorg.blah.New$Other;", mInner.renameTypeDesc("Lcom.pack.Old$Other;")); - - // arrays - assertEquals("[Lorg.blah.New;", mOuter.renameTypeDesc("[Lcom.pack.Old;")); - assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;")); - - assertEquals("[Lorg.blah.New;", mInner.renameTypeDesc("[Lcom.pack.Old;")); - assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;")); - } - - /** - * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an - * object element, e.g. "[Lcom.package.MyClass;" - * If the type doesn't need to be renamed, returns the internal name of the input type. - */ - @Test - public void testRenameType() { - // Skip. This is actually tested by testRenameTypeDesc above. - } - - /** - * Renames an internal type name, e.g. "com.package.MyClass". - * If the type doesn't need to be renamed, returns the input string as-is. - */ - @Test - public void testRenameInternalType() { - // a descriptor is not left untouched - assertEquals("Lorg.blah.New;", mOuter.renameInternalType("Lcom.pack.Old;")); - assertEquals("Lorg.blah.New$Inner;", mOuter.renameInternalType("Lcom.pack.Old$Inner;")); - - // an actual FQCN - assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old")); - assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner")); - - assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other")); - assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other")); - } - - /** - * Renames a method descriptor, i.e. applies renameType to all arguments and to the - * return value. - */ - @Test - public void testRenameMethodDesc() { - assertEquals("(IDLorg.blah.New;[Lorg.blah.New$Inner;)Lorg.blah.New$Other;", - mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;")); - } - - - -} diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar Binary files differdeleted file mode 100644 index a7ea74f..0000000 --- a/tools/layoutlib/create/tests/data/mock_android.jar +++ /dev/null diff --git a/tools/layoutlib/create/tests/data/mock_android.jardesc b/tools/layoutlib/create/tests/data/mock_android.jardesc deleted file mode 100644 index 95f7591..0000000 --- a/tools/layoutlib/create/tests/data/mock_android.jardesc +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?> -<jardesc> - <jar path="C:/ralf/google/src/raphael-lapdroid/device/tools/layoutlib/create/tests/data/mock_android.jar"/> - <options buildIfNeeded="true" compress="true" descriptionLocation="/layoutlib_create/tests/data/mock_android.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/> - <storedRefactorings deprecationInfo="true" structuralOnly="false"/> - <selectedProjects/> - <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true"> - <sealing sealJar="false"> - <packagesToSeal/> - <packagesToUnSeal/> - </sealing> - </manifest> - <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false"> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.widget"/> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.view"/> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.dummy"/> - </selectedElements> -</jardesc> diff --git a/tools/layoutlib/create/tests/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_android/dummy/InnerTest.java deleted file mode 100644 index e355ead..0000000 --- a/tools/layoutlib/create/tests/mock_android/dummy/InnerTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mock_android.dummy; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; - -public class InnerTest { - - private int mSomeField; - private MyStaticInnerClass mInnerInstance; - private MyIntEnum mTheIntEnum; - private MyGenerics1<int[][], InnerTest, MyIntEnum, float[]> mGeneric1; - - public class NotStaticInner2 extends NotStaticInner1 { - - } - - public class NotStaticInner1 { - - public void someThing() { - mSomeField = 2; - mInnerInstance = null; - } - - } - - private static class MyStaticInnerClass { - - } - - private static class DerivingClass extends InnerTest { - - } - - // enums are a kind of inner static class - public enum MyIntEnum { - VALUE0(0), - VALUE1(1), - VALUE2(2); - - MyIntEnum(int myInt) { - this.myInt = myInt; - } - final int myInt; - } - - public static class MyGenerics1<T, U, V, W> { - public MyGenerics1() { - int a = 1; - } - } - - public <X> void genericMethod1(X a, X[] a) { - } - - public <X, Y> void genericMethod2(X a, List<Y> b) { - } - - public <X, Y> void genericMethod3(X a, List<Y extends InnerTest> b) { - } - - public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) { - Iterator<T> i = b.iterator(); - } - - public void someMethod(InnerTest self) { - mSomeField = self.mSomeField; - MyStaticInnerClass m = new MyStaticInnerClass(); - mInnerInstance = m; - mTheIntEnum = null; - mGeneric1 = new MyGenerics1(); - genericMethod(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>()); - } -} diff --git a/tools/layoutlib/create/tests/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_android/view/View.java deleted file mode 100644 index a80a98d..0000000 --- a/tools/layoutlib/create/tests/mock_android/view/View.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mock_android.view; - -public class View { - -} diff --git a/tools/layoutlib/create/tests/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_android/view/ViewGroup.java deleted file mode 100644 index 466470f..0000000 --- a/tools/layoutlib/create/tests/mock_android/view/ViewGroup.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mock_android.view; - -public class ViewGroup extends View { - - public class MarginLayoutParams extends LayoutParams { - - } - - public class LayoutParams { - - } - -} diff --git a/tools/layoutlib/create/tests/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_android/widget/LinearLayout.java deleted file mode 100644 index 3870a63..0000000 --- a/tools/layoutlib/create/tests/mock_android/widget/LinearLayout.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mock_android.widget; - -import mock_android.view.ViewGroup; - -public class LinearLayout extends ViewGroup { - - public class LayoutParams extends mock_android.view.ViewGroup.LayoutParams { - - } - -} diff --git a/tools/layoutlib/create/tests/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_android/widget/TableLayout.java deleted file mode 100644 index e455e7d..0000000 --- a/tools/layoutlib/create/tests/mock_android/widget/TableLayout.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mock_android.widget; - -import mock_android.view.ViewGroup; - -public class TableLayout extends ViewGroup { - - public class LayoutParams extends MarginLayoutParams { - - } - -} diff --git a/tools/localize/Android.mk b/tools/localize/Android.mk deleted file mode 100644 index 186177f..0000000 --- a/tools/localize/Android.mk +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2006 The Android Open Source Project -# -# Android Asset Packaging Tool -# - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - file_utils.cpp \ - localize.cpp \ - merge_res_and_xliff.cpp \ - res_check.cpp \ - xmb.cpp \ - Configuration.cpp \ - Perforce.cpp \ - SourcePos.cpp \ - Values.cpp \ - ValuesFile.cpp \ - XLIFFFile.cpp \ - XMLHandler.cpp - -LOCAL_C_INCLUDES := \ - external/expat/lib \ - build/libs/host/include - -LOCAL_CFLAGS += -g -O0 - -LOCAL_STATIC_LIBRARIES := \ - libexpat \ - libhost \ - libutils \ - libcutils - -ifeq ($(HOST_OS),linux) -LOCAL_LDLIBS += -lrt -endif - - -LOCAL_MODULE := localize - -ifeq (a,a) - LOCAL_CFLAGS += -DLOCALIZE_WITH_TESTS - LOCAL_SRC_FILES += \ - test.cpp \ - localize_test.cpp \ - merge_res_and_xliff_test.cpp \ - Perforce_test.cpp \ - ValuesFile_test.cpp \ - XLIFFFile_test.cpp \ - XMLHandler_test.cpp -endif - -include $(BUILD_HOST_EXECUTABLE) - diff --git a/tools/localize/Configuration.cpp b/tools/localize/Configuration.cpp deleted file mode 100644 index 56addbd..0000000 --- a/tools/localize/Configuration.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "Configuration.h" -#include <string.h> - -int -Configuration::Compare(const Configuration& that) const -{ - int n; - - n = locale.compare(that.locale); - if (n != 0) return n; - - n = vendor.compare(that.vendor); - if (n != 0) return n; - - n = orientation.compare(that.orientation); - if (n != 0) return n; - - n = density.compare(that.density); - if (n != 0) return n; - - n = touchscreen.compare(that.touchscreen); - if (n != 0) return n; - - n = keyboard.compare(that.keyboard); - if (n != 0) return n; - - n = navigation.compare(that.navigation); - if (n != 0) return n; - - n = screenSize.compare(that.screenSize); - if (n != 0) return n; - - return 0; -} - -string -Configuration::ToString() const -{ - string s; - if (locale.length() > 0) { - if (s.length() > 0) { - s += "-"; - } - s += locale; - } - return s; -} - -bool -split_locale(const string& in, string* language, string* region) -{ - const int len = in.length(); - if (len == 2) { - if (isalpha(in[0]) && isalpha(in[1])) { - *language = in; - region->clear(); - return true; - } else { - return false; - } - } - else if (len == 5) { - if (isalpha(in[0]) && isalpha(in[1]) && (in[2] == '_' || in[2] == '-') - && isalpha(in[3]) && isalpha(in[4])) { - language->assign(in.c_str(), 2); - region->assign(in.c_str()+3, 2); - return true; - } else { - return false; - } - } - else { - return false; - } -} - diff --git a/tools/localize/Configuration.h b/tools/localize/Configuration.h deleted file mode 100644 index f91bf04..0000000 --- a/tools/localize/Configuration.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CONFIGURATION_H -#define CONFIGURATION_H - -#include <string> - -using namespace std; - -struct Configuration -{ - string locale; - string vendor; - string orientation; - string density; - string touchscreen; - string keyboard; - string navigation; - string screenSize; - - // Compare two configurations - int Compare(const Configuration& that) const; - - inline bool operator<(const Configuration& that) const { return Compare(that) < 0; } - inline bool operator<=(const Configuration& that) const { return Compare(that) <= 0; } - inline bool operator==(const Configuration& that) const { return Compare(that) == 0; } - inline bool operator!=(const Configuration& that) const { return Compare(that) != 0; } - inline bool operator>=(const Configuration& that) const { return Compare(that) >= 0; } - inline bool operator>(const Configuration& that) const { return Compare(that) > 0; } - - // Parse a directory name, like "values-en-rUS". Return the first segment in resType. - bool ParseDiectoryName(const string& dir, string* resType); - - string ToString() const; -}; - -bool split_locale(const string& in, string* language, string* region); - - -#endif // CONFIGURATION_H diff --git a/tools/localize/Perforce.cpp b/tools/localize/Perforce.cpp deleted file mode 100644 index 3425668..0000000 --- a/tools/localize/Perforce.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#include "Perforce.h" -#include "log.h" -#include <string.h> -#include <stdlib.h> -#include <sstream> -#include <sys/types.h> -#include <unistd.h> -#include <sys/wait.h> - -using namespace std; - -extern char** environ; - -int -Perforce::RunCommand(const string& cmd, string* result, bool printOnFailure) -{ - int err; - int outPipe[2]; - int errPipe[2]; - pid_t pid; - - log_printf("Perforce::RunCommand: %s\n", cmd.c_str()); - - err = pipe(outPipe); - err |= pipe(errPipe); - if (err == -1) { - printf("couldn't create pipe. exiting.\n"); - exit(1); - return -1; - } - - pid = fork(); - if (pid == -1) { - printf("couldn't fork. eixiting\n"); - exit(1); - return -1; - } - else if (pid == 0) { - char const* args[] = { - "/bin/sh", - "-c", - cmd.c_str(), - NULL - }; - close(outPipe[0]); - close(errPipe[0]); - dup2(outPipe[1], 1); - dup2(errPipe[1], 2); - execve(args[0], (char* const*)args, environ); - // done - } - - close(outPipe[1]); - close(errPipe[1]); - - result->clear(); - - char buf[1024]; - - // stdout - while (true) { - size_t amt = read(outPipe[0], buf, sizeof(buf)); - result->append(buf, amt); - if (amt <= 0) { - break; - } - } - - // stderr -- the messages are short so it ought to just fit in the buffer - string error; - while (true) { - size_t amt = read(errPipe[0], buf, sizeof(buf)); - error.append(buf, amt); - if (amt <= 0) { - break; - } - } - - close(outPipe[0]); - close(errPipe[0]); - - waitpid(pid, &err, 0); - if (WIFEXITED(err)) { - err = WEXITSTATUS(err); - } else { - err = -1; - } - if (err != 0 && printOnFailure) { - write(2, error.c_str(), error.length()); - } - return err; -} - -int -Perforce::GetResourceFileNames(const string& version, const string& base, - const vector<string>& apps, vector<string>* results, - bool printOnFailure) -{ - int err; - string text; - stringstream cmd; - - cmd << "p4 files"; - - const size_t I = apps.size(); - for (size_t i=0; i<I; i++) { - cmd << " \"" << base << '/' << apps[i] << "/res/values/strings.xml@" << version << '"'; - } - - err = RunCommand(cmd.str(), &text, printOnFailure); - - const char* str = text.c_str(); - while (*str) { - const char* lineend = strchr(str, '\n'); - if (lineend == str) { - str++; - continue; - } - if (lineend-str > 1023) { - fprintf(stderr, "line too long!\n"); - return 1; - } - - string s(str, lineend-str); - - char filename[1024]; - char edit[1024]; - int count = sscanf(str, "%[^#]#%*d - %s change %*d %*[^\n]\n", filename, edit); - - if (count == 2 && 0 != strcmp("delete", edit)) { - results->push_back(string(filename)); - } - - str = lineend + 1; - } - - return err; -} - -int -Perforce::GetFile(const string& file, const string& version, string* result, - bool printOnFailure) -{ - stringstream cmd; - cmd << "p4 print -q \"" << file << '@' << version << '"'; - return RunCommand(cmd.str(), result, printOnFailure); -} - -string -Perforce::GetCurrentChange(bool printOnFailure) -{ - int err; - string text; - - err = RunCommand("p4 changes -m 1 \\#have", &text, printOnFailure); - if (err != 0) { - return ""; - } - - long long n; - int count = sscanf(text.c_str(), "Change %lld on", &n); - if (count != 1) { - return ""; - } - - char result[100]; - sprintf(result, "%lld", n); - - return string(result); -} - -static int -do_files(const string& op, const vector<string>& files, bool printOnFailure) -{ - string text; - stringstream cmd; - - cmd << "p4 " << op; - - const size_t I = files.size(); - for (size_t i=0; i<I; i++) { - cmd << " \"" << files[i] << "\""; - } - - return Perforce::RunCommand(cmd.str(), &text, printOnFailure); -} - -int -Perforce::EditFiles(const vector<string>& files, bool printOnFailure) -{ - return do_files("edit", files, printOnFailure); -} - -int -Perforce::AddFiles(const vector<string>& files, bool printOnFailure) -{ - return do_files("add", files, printOnFailure); -} - -int -Perforce::DeleteFiles(const vector<string>& files, bool printOnFailure) -{ - return do_files("delete", files, printOnFailure); -} - -string -Perforce::Where(const string& depotPath, bool printOnFailure) -{ - int err; - string text; - string cmd = "p4 where "; - cmd += depotPath; - - err = RunCommand(cmd, &text, printOnFailure); - if (err != 0) { - return ""; - } - - size_t index = text.find(' '); - if (index == text.npos) { - return ""; - } - index = text.find(' ', index+1)+1; - if (index == text.npos) { - return ""; - } - - return text.substr(index, text.length()-index-1); -} - diff --git a/tools/localize/Perforce.h b/tools/localize/Perforce.h deleted file mode 100644 index 522797d..0000000 --- a/tools/localize/Perforce.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PERFORCE_H -#define PERFORCE_H - -#include <string> -#include <vector> - -using namespace std; - -class Perforce -{ -public: - static int RunCommand(const string& cmd, string* result, bool printOnFailure); - static int GetResourceFileNames(const string& version, const string& base, - const vector<string>& apps, vector<string>* result, - bool printOnFailure); - static int GetFile(const string& file, const string& version, string* result, - bool printOnFailure); - static string GetCurrentChange(bool printOnFailure); - static int EditFiles(const vector<string>& filename, bool printOnFailure); - static int AddFiles(const vector<string>& files, bool printOnFailure); - static int DeleteFiles(const vector<string>& files, bool printOnFailure); - static string Where(const string& depotPath, bool printOnFailure); -}; - -#endif // PERFORCE_H diff --git a/tools/localize/Perforce_test.cpp b/tools/localize/Perforce_test.cpp deleted file mode 100644 index 142b20e..0000000 --- a/tools/localize/Perforce_test.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "Perforce.h" -#include <stdio.h> - -static int -RunCommand_test() -{ - string result; - int err = Perforce::RunCommand("p4 help csommands", &result, true); - printf("err=%d result=[[%s]]\n", err, result.c_str()); - return 0; -} - -static int -GetResourceFileNames_test() -{ - vector<string> results; - vector<string> apps; - apps.push_back("apps/common"); - apps.push_back("apps/Contacts"); - int err = Perforce::GetResourceFileNames("43019", "//device", apps, &results, true); - if (err != 0) { - return err; - } - if (results.size() != 2) { - return 1; - } - if (results[0] != "//device/apps/common/res/values/strings.xml") { - return 1; - } - if (results[1] != "//device/apps/Contacts/res/values/strings.xml") { - return 1; - } - if (false) { - for (size_t i=0; i<results.size(); i++) { - printf("[%zd] '%s'\n", i, results[i].c_str()); - } - } - return 0; -} - -static int -GetFile_test() -{ - string result; - int err = Perforce::GetFile("//device/Makefile", "296", &result, true); - printf("err=%d result=[[%s]]\n", err, result.c_str()); - return 0; -} - -int -Perforce_test() -{ - bool all = false; - int err = 0; - - if (all) err |= RunCommand_test(); - if (all) err |= GetResourceFileNames_test(); - if (all) err |= GetFile_test(); - - return err; -} - diff --git a/tools/localize/SourcePos.cpp b/tools/localize/SourcePos.cpp deleted file mode 100644 index 9d7c5c6..0000000 --- a/tools/localize/SourcePos.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "SourcePos.h" - -#include <stdarg.h> -#include <set> - -using namespace std; - -const SourcePos GENERATED_POS("<generated>", -1); - -// ErrorPos -// ============================================================================= -struct ErrorPos -{ - string file; - int line; - string error; - - ErrorPos(); - ErrorPos(const ErrorPos& that); - ErrorPos(const string& file, int line, const string& error); - ~ErrorPos(); - bool operator<(const ErrorPos& rhs) const; - bool operator==(const ErrorPos& rhs) const; - ErrorPos& operator=(const ErrorPos& rhs); - - void Print(FILE* to) const; -}; - -static set<ErrorPos> g_errors; - -ErrorPos::ErrorPos() -{ -} - -ErrorPos::ErrorPos(const ErrorPos& that) - :file(that.file), - line(that.line), - error(that.error) -{ -} - -ErrorPos::ErrorPos(const string& f, int l, const string& e) - :file(f), - line(l), - error(e) -{ -} - -ErrorPos::~ErrorPos() -{ -} - -bool -ErrorPos::operator<(const ErrorPos& rhs) const -{ - if (this->file < rhs.file) return true; - if (this->file == rhs.file) { - if (this->line < rhs.line) return true; - if (this->line == rhs.line) { - if (this->error < rhs.error) return true; - } - } - return false; -} - -bool -ErrorPos::operator==(const ErrorPos& rhs) const -{ - return this->file == rhs.file - && this->line == rhs.line - && this->error == rhs.error; -} - -ErrorPos& -ErrorPos::operator=(const ErrorPos& rhs) -{ - this->file = rhs.file; - this->line = rhs.line; - this->error = rhs.error; - return *this; -} - -void -ErrorPos::Print(FILE* to) const -{ - if (this->line >= 0) { - fprintf(to, "%s:%d: %s\n", this->file.c_str(), this->line, this->error.c_str()); - } else { - fprintf(to, "%s: %s\n", this->file.c_str(), this->error.c_str()); - } -} - -// SourcePos -// ============================================================================= -SourcePos::SourcePos(const string& f, int l) - : file(f), line(l) -{ -} - -SourcePos::SourcePos(const SourcePos& that) - : file(that.file), line(that.line) -{ -} - -SourcePos::SourcePos() - : file("???", 0) -{ -} - -SourcePos::~SourcePos() -{ -} - -string -SourcePos::ToString() const -{ - char buf[1024]; - if (this->line >= 0) { - snprintf(buf, sizeof(buf)-1, "%s:%d", this->file.c_str(), this->line); - } else { - snprintf(buf, sizeof(buf)-1, "%s:", this->file.c_str()); - } - buf[sizeof(buf)-1] = '\0'; - return string(buf); -} - -int -SourcePos::Error(const char* fmt, ...) const -{ - int retval=0; - char buf[1024]; - va_list ap; - va_start(ap, fmt); - retval = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - char* p = buf + retval - 1; - while (p > buf && *p == '\n') { - *p = '\0'; - p--; - } - ErrorPos err(this->file, this->line, string(buf)); - if (g_errors.find(err) == g_errors.end()) { - err.Print(stderr); - g_errors.insert(err); - } - return retval; -} - -bool -SourcePos::HasErrors() -{ - return g_errors.size() > 0; -} - -void -SourcePos::PrintErrors(FILE* to) -{ - set<ErrorPos>::const_iterator it; - for (it=g_errors.begin(); it!=g_errors.end(); it++) { - it->Print(to); - } -} - - - - diff --git a/tools/localize/SourcePos.h b/tools/localize/SourcePos.h deleted file mode 100644 index 5027129..0000000 --- a/tools/localize/SourcePos.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SOURCEPOS_H -#define SOURCEPOS_H - -#include <string> - -using namespace std; - -class SourcePos -{ -public: - string file; - int line; - - SourcePos(const string& f, int l); - SourcePos(const SourcePos& that); - SourcePos(); - ~SourcePos(); - - string ToString() const; - int Error(const char* fmt, ...) const; - - static bool HasErrors(); - static void PrintErrors(FILE* to); -}; - -extern const SourcePos GENERATED_POS; - -#endif // SOURCEPOS_H diff --git a/tools/localize/Values.cpp b/tools/localize/Values.cpp deleted file mode 100644 index e396f8b..0000000 --- a/tools/localize/Values.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "Values.h" -#include <stdlib.h> - - -// ===================================================================================== -StringResource::StringResource(const SourcePos& p, const string& f, const Configuration& c, - const string& i, int ix, XMLNode* v, const int ve, const string& vs, - const string& cmnt) - :pos(p), - file(f), - config(c), - id(i), - index(ix), - value(v), - version(ve), - versionString(vs), - comment(cmnt) -{ -} - -StringResource::StringResource() - :pos(), - file(), - config(), - id(), - index(-1), - value(NULL), - version(), - versionString(), - comment() -{ -} - -StringResource::StringResource(const StringResource& that) - :pos(that.pos), - file(that.file), - config(that.config), - id(that.id), - index(that.index), - value(that.value), - version(that.version), - versionString(that.versionString), - comment(that.comment) -{ -} - -int -StringResource::Compare(const StringResource& that) const -{ - if (file != that.file) { - return file < that.file ? -1 : 1; - } - if (id != that.id) { - return id < that.id ? -1 : 1; - } - if (index != that.index) { - return index - that.index; - } - if (config != that.config) { - return config < that.config ? -1 : 1; - } - if (version != that.version) { - return version < that.version ? -1 : 1; - } - return 0; -} - -string -StringResource::TypedID() const -{ - string result; - if (index < 0) { - result = "string:"; - } else { - char n[20]; - sprintf(n, "%d:", index); - result = "array:"; - result += n; - } - result += id; - return result; -} - -static void -split(const string& raw, vector<string>*parts) -{ - size_t index = 0; - while (true) { - size_t next = raw.find(':', index); - if (next != raw.npos) { - parts->push_back(string(raw, index, next-index)); - index = next + 1; - } else { - parts->push_back(string(raw, index)); - break; - } - } -} - -bool -StringResource::ParseTypedID(const string& raw, string* id, int* index) -{ - vector<string> parts; - split(raw, &parts); - - const size_t N = parts.size(); - - for (size_t i=0; i<N; i++) { - if (parts[i].length() == 0) { - return false; - } - } - - if (N == 2 && parts[0] == "string") { - *id = parts[1]; - *index = -1; - return true; - } - else if (N == 3 && parts[0] == "array") { - char* p; - int n = (int)strtol(parts[1].c_str(), &p, 0); - if (*p == '\0') { - *id = parts[2]; - *index = n; - return true; - } else { - return false; - } - } - else { - return false; - } -} - diff --git a/tools/localize/Values.h b/tools/localize/Values.h deleted file mode 100644 index 0a60b6d..0000000 --- a/tools/localize/Values.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef VALUES_H -#define VALUES_H - -#include "Configuration.h" -#include "XMLHandler.h" - -#include <string> - -using namespace std; - -enum { - CURRENT_VERSION, - OLD_VERSION -}; - -struct StringResource -{ - StringResource(); - StringResource(const SourcePos& pos, const string& file, const Configuration& config, - const string& id, int index, XMLNode* value, - int version, const string& versionString, const string& comment = ""); - StringResource(const StringResource& that); - - // Compare two configurations - int Compare(const StringResource& that) const; - - inline bool operator<(const StringResource& that) const { return Compare(that) < 0; } - inline bool operator<=(const StringResource& that) const { return Compare(that) <= 0; } - inline bool operator==(const StringResource& that) const { return Compare(that) == 0; } - inline bool operator!=(const StringResource& that) const { return Compare(that) != 0; } - inline bool operator>=(const StringResource& that) const { return Compare(that) >= 0; } - inline bool operator>(const StringResource& that) const { return Compare(that) > 0; } - - string TypedID() const; - static bool ParseTypedID(const string& typed, string* id, int* index); - - SourcePos pos; - string file; - Configuration config; - string id; - int index; - XMLNode* value; - int version; - string versionString; - string comment; -}; - -#endif // VALUES_H diff --git a/tools/localize/ValuesFile.cpp b/tools/localize/ValuesFile.cpp deleted file mode 100644 index bd6f494..0000000 --- a/tools/localize/ValuesFile.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "ValuesFile.h" - -#include "XMLHandler.h" - -#include <algorithm> -#include <fcntl.h> -#include <expat.h> -#include <unistd.h> -#include <errno.h> - -using namespace std; - -const char* const ANDROID_XMLNS = "http://schemas.android.com/apk/res/android"; -const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2"; - -const char *const NS_MAP[] = { - "android", ANDROID_XMLNS, - "xliff", XLIFF_XMLNS, - NULL, NULL -}; - -const XMLNamespaceMap ANDROID_NAMESPACES(NS_MAP); - - -// ===================================================================================== -class ArrayHandler : public XMLHandler -{ -public: - ArrayHandler(ValuesFile* vf, int version, const string& versionString, const string& id); - - virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next); - virtual int OnText(const SourcePos& pos, const string& text); - virtual int OnComment(const SourcePos& pos, const string& text); - -private: - ValuesFile* m_vf; - int m_version; - int m_index; - string m_versionString; - string m_id; - string m_comment; -}; - -ArrayHandler::ArrayHandler(ValuesFile* vf, int version, const string& versionString, - const string& id) - :m_vf(vf), - m_version(version), - m_index(0), - m_versionString(versionString), - m_id(id) -{ -} - -int -ArrayHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next) -{ - if (ns == "" && name == "item") { - XMLNode* node = XMLNode::NewElement(pos, ns, name, attrs, XMLNode::EXACT); - m_vf->AddString(StringResource(pos, pos.file, m_vf->GetConfiguration(), - m_id, m_index, node, m_version, m_versionString, - trim_string(m_comment))); - *next = new NodeHandler(node, XMLNode::EXACT); - m_index++; - m_comment = ""; - return 0; - } else { - pos.Error("invalid <%s> element inside <array>\n", name.c_str()); - return 1; - } -} - -int -ArrayHandler::OnText(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -ArrayHandler::OnComment(const SourcePos& pos, const string& text) -{ - m_comment += text; - return 0; -} - -// ===================================================================================== -class ValuesHandler : public XMLHandler -{ -public: - ValuesHandler(ValuesFile* vf, int version, const string& versionString); - - virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next); - virtual int OnText(const SourcePos& pos, const string& text); - virtual int OnComment(const SourcePos& pos, const string& text); - -private: - ValuesFile* m_vf; - int m_version; - string m_versionString; - string m_comment; -}; - -ValuesHandler::ValuesHandler(ValuesFile* vf, int version, const string& versionString) - :m_vf(vf), - m_version(version), - m_versionString(versionString) -{ -} - -int -ValuesHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next) -{ - if (ns == "" && name == "string") { - string id = XMLAttribute::Find(attrs, "", "name", ""); - XMLNode* node = XMLNode::NewElement(pos, ns, name, attrs, XMLNode::EXACT); - m_vf->AddString(StringResource(pos, pos.file, m_vf->GetConfiguration(), - id, -1, node, m_version, m_versionString, - trim_string(m_comment))); - *next = new NodeHandler(node, XMLNode::EXACT); - } - else if (ns == "" && name == "array") { - string id = XMLAttribute::Find(attrs, "", "name", ""); - *next = new ArrayHandler(m_vf, m_version, m_versionString, id); - } - m_comment = ""; - return 0; -} - -int -ValuesHandler::OnText(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -ValuesHandler::OnComment(const SourcePos& pos, const string& text) -{ - m_comment += text; - return 0; -} - -// ===================================================================================== -ValuesFile::ValuesFile(const Configuration& config) - :m_config(config), - m_strings(), - m_arrays() -{ -} - -ValuesFile::~ValuesFile() -{ -} - -ValuesFile* -ValuesFile::ParseFile(const string& filename, const Configuration& config, - int version, const string& versionString) -{ - ValuesFile* result = new ValuesFile(config); - - TopElementHandler top("", "resources", new ValuesHandler(result, version, versionString)); - XMLHandler::ParseFile(filename, &top); - - return result; -} - -ValuesFile* -ValuesFile::ParseString(const string& filename, const string& text, const Configuration& config, - int version, const string& versionString) -{ - ValuesFile* result = new ValuesFile(config); - - TopElementHandler top("", "resources", new ValuesHandler(result, version, versionString)); - XMLHandler::ParseString(filename, text, &top); - - return result; -} - -const Configuration& -ValuesFile::GetConfiguration() const -{ - return m_config; -} - -void -ValuesFile::AddString(const StringResource& str) -{ - if (str.index < 0) { - m_strings.insert(str); - } else { - m_arrays[str.id].insert(str); - } -} - -set<StringResource> -ValuesFile::GetStrings() const -{ - set<StringResource> result = m_strings; - - for (map<string,set<StringResource> >::const_iterator it = m_arrays.begin(); - it != m_arrays.end(); it++) { - result.insert(it->second.begin(), it->second.end()); - } - - return result; -} - -XMLNode* -ValuesFile::ToXMLNode() const -{ - XMLNode* root; - - // <resources> - { - vector<XMLAttribute> attrs; - ANDROID_NAMESPACES.AddToAttributes(&attrs); - root = XMLNode::NewElement(GENERATED_POS, "", "resources", attrs, XMLNode::PRETTY); - } - - // <array> - for (map<string,set<StringResource> >::const_iterator it = m_arrays.begin(); - it != m_arrays.end(); it++) { - vector<XMLAttribute> arrayAttrs; - arrayAttrs.push_back(XMLAttribute("", "name", it->first)); - const set<StringResource>& items = it->second; - XMLNode* arrayNode = XMLNode::NewElement(items.begin()->pos, "", "array", arrayAttrs, - XMLNode::PRETTY); - root->EditChildren().push_back(arrayNode); - - // <item> - for (set<StringResource>::const_iterator item = items.begin(); - item != items.end(); item++) { - XMLNode* itemNode = item->value->Clone(); - itemNode->SetName("", "item"); - itemNode->EditAttributes().clear(); - arrayNode->EditChildren().push_back(itemNode); - } - } - - // <string> - for (set<StringResource>::const_iterator it=m_strings.begin(); it!=m_strings.end(); it++) { - const StringResource& str = *it; - vector<XMLAttribute> attrs; - XMLNode* strNode = str.value->Clone(); - strNode->SetName("", "string"); - strNode->EditAttributes().clear(); - strNode->EditAttributes().push_back(XMLAttribute("", "name", str.id)); - root->EditChildren().push_back(strNode); - } - - return root; -} - -string -ValuesFile::ToString() const -{ - XMLNode* xml = ToXMLNode(); - string s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; - s += xml->ToString(ANDROID_NAMESPACES); - delete xml; - s += '\n'; - return s; -} - diff --git a/tools/localize/ValuesFile.h b/tools/localize/ValuesFile.h deleted file mode 100644 index 752fd78..0000000 --- a/tools/localize/ValuesFile.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef VALUES_FILE_H -#define VALUES_FILE_H - -#include "SourcePos.h" -#include "Configuration.h" -#include "XMLHandler.h" -#include "Values.h" - -#include <string> -#include <set> - -using namespace std; - -extern const XMLNamespaceMap ANDROID_NAMESPACES; - -class ValuesFile -{ -public: - ValuesFile(const Configuration& config); - - static ValuesFile* ParseFile(const string& filename, const Configuration& config, - int version, const string& versionString); - static ValuesFile* ParseString(const string& filename, const string& text, - const Configuration& config, - int version, const string& versionString); - ~ValuesFile(); - - const Configuration& GetConfiguration() const; - - void AddString(const StringResource& str); - set<StringResource> GetStrings() const; - - // exports this file as a n XMLNode, you own this object - XMLNode* ToXMLNode() const; - - // writes the ValuesFile out to a string in the canonical format (i.e. writes the contents of - // ToXMLNode()). - string ToString() const; - -private: - class ParseState; - friend class ValuesFile::ParseState; - friend class StringHandler; - - ValuesFile(); - - Configuration m_config; - set<StringResource> m_strings; - map<string,set<StringResource> > m_arrays; -}; - -#endif // VALUES_FILE_H diff --git a/tools/localize/ValuesFile_test.cpp b/tools/localize/ValuesFile_test.cpp deleted file mode 100644 index 56d2ec2..0000000 --- a/tools/localize/ValuesFile_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "ValuesFile.h" -#include <stdio.h> - -int -ValuesFile_test() -{ - int err = 0; - Configuration config; - config.locale = "zz_ZZ"; - ValuesFile* vf = ValuesFile::ParseFile("testdata/values/strings.xml", config, - OLD_VERSION, "1"); - - const set<StringResource>& strings = vf->GetStrings(); - string canonical = vf->ToString(); - - if (false) { - printf("Strings (%zd)\n", strings.size()); - for (set<StringResource>::const_iterator it=strings.begin(); - it!=strings.end(); it++) { - const StringResource& str = *it; - printf("%s: '%s'[%d]='%s' (%s) <!-- %s -->\n", str.pos.ToString().c_str(), - str.id.c_str(), str.index, - str.value->ContentsToString(ANDROID_NAMESPACES).c_str(), - str.config.ToString().c_str(), str.comment.c_str()); - } - - printf("XML:[[%s]]\n", canonical.c_str()); - } - - const char * const EXPECTED = - "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<resources xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" - " xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n" - " <array name=\"emailAddressTypes\">\n" - " <item>Email</item>\n" - " <item>Home</item>\n" - " <item>Work</item>\n" - " <item>Other\\u2026</item>\n" - " </array>\n" - " <string name=\"test1\">Discard</string>\n" - " <string name=\"test2\">a<b>b<i>c</i></b>d</string>\n" - " <string name=\"test3\">a<xliff:g a=\"b\" xliff:a=\"asdf\">bBb</xliff:g>C</string>\n" - "</resources>\n"; - - if (canonical != EXPECTED) { - fprintf(stderr, "ValuesFile_test failed\n"); - fprintf(stderr, "canonical=[[%s]]\n", canonical.c_str()); - fprintf(stderr, "EXPECTED=[[%s]]\n", EXPECTED); - err = 1; - } - - delete vf; - return err; -} diff --git a/tools/localize/XLIFFFile.cpp b/tools/localize/XLIFFFile.cpp deleted file mode 100644 index 51f81de..0000000 --- a/tools/localize/XLIFFFile.cpp +++ /dev/null @@ -1,609 +0,0 @@ -#include "XLIFFFile.h" - -#include <algorithm> -#include <sys/time.h> -#include <time.h> - -const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2"; - -const char *const NS_MAP[] = { - "", XLIFF_XMLNS, - "xml", XMLNS_XMLNS, - NULL, NULL -}; - -const XMLNamespaceMap XLIFF_NAMESPACES(NS_MAP); - -int -XLIFFFile::File::Compare(const XLIFFFile::File& that) const -{ - if (filename != that.filename) { - return filename < that.filename ? -1 : 1; - } - return 0; -} - -// ===================================================================================== -XLIFFFile::XLIFFFile() -{ -} - -XLIFFFile::~XLIFFFile() -{ -} - -static XMLNode* -get_unique_node(const XMLNode* parent, const string& ns, const string& name, bool required) -{ - size_t count = parent->CountElementsByName(ns, name); - if (count == 1) { - return parent->GetElementByNameAt(ns, name, 0); - } else { - if (required) { - SourcePos pos = count == 0 - ? parent->Position() - : parent->GetElementByNameAt(XLIFF_XMLNS, name, 1)->Position(); - pos.Error("<%s> elements must contain exactly one <%s> element", - parent->Name().c_str(), name.c_str()); - } - return NULL; - } -} - -XLIFFFile* -XLIFFFile::Parse(const string& filename) -{ - XLIFFFile* result = new XLIFFFile(); - - XMLNode* root = NodeHandler::ParseFile(filename, XMLNode::PRETTY); - if (root == NULL) { - return NULL; - } - - // <file> - vector<XMLNode*> files = root->GetElementsByName(XLIFF_XMLNS, "file"); - for (size_t i=0; i<files.size(); i++) { - XMLNode* file = files[i]; - - string datatype = file->GetAttribute("", "datatype", ""); - string originalFile = file->GetAttribute("", "original", ""); - - Configuration sourceConfig; - sourceConfig.locale = file->GetAttribute("", "source-language", ""); - result->m_sourceConfig = sourceConfig; - - Configuration targetConfig; - targetConfig.locale = file->GetAttribute("", "target-language", ""); - result->m_targetConfig = targetConfig; - - result->m_currentVersion = file->GetAttribute("", "build-num", ""); - result->m_oldVersion = "old"; - - // <body> - XMLNode* body = get_unique_node(file, XLIFF_XMLNS, "body", true); - if (body == NULL) continue; - - // <trans-unit> - vector<XMLNode*> transUnits = body->GetElementsByName(XLIFF_XMLNS, "trans-unit"); - for (size_t j=0; j<transUnits.size(); j++) { - XMLNode* transUnit = transUnits[j]; - - string rawID = transUnit->GetAttribute("", "id", ""); - if (rawID == "") { - transUnit->Position().Error("<trans-unit> tag requires an id"); - continue; - } - string id; - int index; - - if (!StringResource::ParseTypedID(rawID, &id, &index)) { - transUnit->Position().Error("<trans-unit> has invalid id '%s'\n", rawID.c_str()); - continue; - } - - // <source> - XMLNode* source = get_unique_node(transUnit, XLIFF_XMLNS, "source", false); - if (source != NULL) { - XMLNode* node = source->Clone(); - node->SetPrettyRecursive(XMLNode::EXACT); - result->AddStringResource(StringResource(source->Position(), originalFile, - sourceConfig, id, index, node, CURRENT_VERSION, - result->m_currentVersion)); - } - - // <target> - XMLNode* target = get_unique_node(transUnit, XLIFF_XMLNS, "target", false); - if (target != NULL) { - XMLNode* node = target->Clone(); - node->SetPrettyRecursive(XMLNode::EXACT); - result->AddStringResource(StringResource(target->Position(), originalFile, - targetConfig, id, index, node, CURRENT_VERSION, - result->m_currentVersion)); - } - - // <alt-trans> - XMLNode* altTrans = get_unique_node(transUnit, XLIFF_XMLNS, "alt-trans", false); - if (altTrans != NULL) { - // <source> - XMLNode* altSource = get_unique_node(altTrans, XLIFF_XMLNS, "source", false); - if (altSource != NULL) { - XMLNode* node = altSource->Clone(); - node->SetPrettyRecursive(XMLNode::EXACT); - result->AddStringResource(StringResource(altSource->Position(), - originalFile, sourceConfig, id, index, node, OLD_VERSION, - result->m_oldVersion)); - } - - // <target> - XMLNode* altTarget = get_unique_node(altTrans, XLIFF_XMLNS, "target", false); - if (altTarget != NULL) { - XMLNode* node = altTarget->Clone(); - node->SetPrettyRecursive(XMLNode::EXACT); - result->AddStringResource(StringResource(altTarget->Position(), - originalFile, targetConfig, id, index, node, OLD_VERSION, - result->m_oldVersion)); - } - } - } - } - delete root; - return result; -} - -XLIFFFile* -XLIFFFile::Create(const Configuration& sourceConfig, const Configuration& targetConfig, - const string& currentVersion) -{ - XLIFFFile* result = new XLIFFFile(); - result->m_sourceConfig = sourceConfig; - result->m_targetConfig = targetConfig; - result->m_currentVersion = currentVersion; - return result; -} - -set<string> -XLIFFFile::Files() const -{ - set<string> result; - for (vector<File>::const_iterator f = m_files.begin(); f != m_files.end(); f++) { - result.insert(f->filename); - } - return result; -} - -void -XLIFFFile::AddStringResource(const StringResource& str) -{ - string id = str.TypedID(); - - File* f = NULL; - const size_t I = m_files.size(); - for (size_t i=0; i<I; i++) { - if (m_files[i].filename == str.file) { - f = &m_files[i]; - break; - } - } - if (f == NULL) { - File file; - file.filename = str.file; - m_files.push_back(file); - f = &m_files[I]; - } - - const size_t J = f->transUnits.size(); - TransUnit* g = NULL; - for (size_t j=0; j<J; j++) { - if (f->transUnits[j].id == id) { - g = &f->transUnits[j]; - } - } - if (g == NULL) { - TransUnit group; - group.id = id; - f->transUnits.push_back(group); - g = &f->transUnits[J]; - } - - StringResource* res = find_string_res(*g, str); - if (res == NULL) { - return ; - } - if (res->id != "") { - str.pos.Error("Duplicate string resource: %s", res->id.c_str()); - res->pos.Error("Previous definition here"); - return ; - } - *res = str; - - m_strings.insert(str); -} - -void -XLIFFFile::Filter(bool (*func)(const string&,const TransUnit&,void*), void* cookie) -{ - const size_t I = m_files.size(); - for (size_t ix=0, i=I-1; ix<I; ix++, i--) { - File& file = m_files[i]; - - const size_t J = file.transUnits.size(); - for (size_t jx=0, j=J-1; jx<J; jx++, j--) { - TransUnit& tu = file.transUnits[j]; - - bool keep = func(file.filename, tu, cookie); - if (!keep) { - if (tu.source.id != "") { - m_strings.erase(tu.source); - } - if (tu.target.id != "") { - m_strings.erase(tu.target); - } - if (tu.altSource.id != "") { - m_strings.erase(tu.altSource); - } - if (tu.altTarget.id != "") { - m_strings.erase(tu.altTarget); - } - file.transUnits.erase(file.transUnits.begin()+j); - } - } - if (file.transUnits.size() == 0) { - m_files.erase(m_files.begin()+i); - } - } -} - -void -XLIFFFile::Map(void (*func)(const string&,TransUnit*,void*), void* cookie) -{ - const size_t I = m_files.size(); - for (size_t i=0; i<I; i++) { - File& file = m_files[i]; - - const size_t J = file.transUnits.size(); - for (size_t j=0; j<J; j++) { - func(file.filename, &(file.transUnits[j]), cookie); - } - } -} - -TransUnit* -XLIFFFile::EditTransUnit(const string& filename, const string& id) -{ - const size_t I = m_files.size(); - for (size_t ix=0, i=I-1; ix<I; ix++, i--) { - File& file = m_files[i]; - if (file.filename == filename) { - const size_t J = file.transUnits.size(); - for (size_t jx=0, j=J-1; jx<J; jx++, j--) { - TransUnit& tu = file.transUnits[j]; - if (tu.id == id) { - return &tu; - } - } - } - } - return NULL; -} - -StringResource* -XLIFFFile::find_string_res(TransUnit& g, const StringResource& str) -{ - int index; - if (str.version == CURRENT_VERSION) { - index = 0; - } - else if (str.version == OLD_VERSION) { - index = 2; - } - else { - str.pos.Error("Internal Error %s:%d\n", __FILE__, __LINE__); - return NULL; - } - if (str.config == m_sourceConfig) { - // index += 0; - } - else if (str.config == m_targetConfig) { - index += 1; - } - else { - str.pos.Error("unknown config for string %s: %s", str.id.c_str(), - str.config.ToString().c_str()); - return NULL; - } - switch (index) { - case 0: - return &g.source; - case 1: - return &g.target; - case 2: - return &g.altSource; - case 3: - return &g.altTarget; - } - str.pos.Error("Internal Error %s:%d\n", __FILE__, __LINE__); - return NULL; -} - -int -convert_html_to_xliff(const XMLNode* original, const string& name, XMLNode* addTo, int* phID) -{ - int err = 0; - if (original->Type() == XMLNode::TEXT) { - addTo->EditChildren().push_back(original->Clone()); - return 0; - } else { - string ctype; - if (original->Namespace() == "") { - if (original->Name() == "b") { - ctype = "bold"; - } - else if (original->Name() == "i") { - ctype = "italic"; - } - else if (original->Name() == "u") { - ctype = "underline"; - } - } - if (ctype != "") { - vector<XMLAttribute> attrs; - attrs.push_back(XMLAttribute(XLIFF_XMLNS, "ctype", ctype)); - XMLNode* copy = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, "g", - attrs, XMLNode::EXACT); - - const vector<XMLNode*>& children = original->Children(); - size_t I = children.size(); - for (size_t i=0; i<I; i++) { - err |= convert_html_to_xliff(children[i], name, copy, phID); - } - return err; - } - else { - if (original->Namespace() == XLIFF_XMLNS) { - addTo->EditChildren().push_back(original->Clone()); - return 0; - } else { - if (original->Namespace() == "") { - // flatten out the tag into ph tags -- but only if there is no namespace - // that's still unsupported because propagating the xmlns attribute is hard. - vector<XMLAttribute> attrs; - char idStr[30]; - (*phID)++; - sprintf(idStr, "id-%d", *phID); - attrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", idStr)); - - if (original->Children().size() == 0) { - XMLNode* ph = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, - "ph", attrs, XMLNode::EXACT); - ph->EditChildren().push_back( - XMLNode::NewText(original->Position(), - original->ToString(XLIFF_NAMESPACES), - XMLNode::EXACT)); - addTo->EditChildren().push_back(ph); - } else { - XMLNode* begin = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, - "bpt", attrs, XMLNode::EXACT); - begin->EditChildren().push_back( - XMLNode::NewText(original->Position(), - original->OpenTagToString(XLIFF_NAMESPACES, XMLNode::EXACT), - XMLNode::EXACT)); - XMLNode* end = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, - "ept", attrs, XMLNode::EXACT); - string endText = "</"; - endText += original->Name(); - endText += ">"; - end->EditChildren().push_back(XMLNode::NewText(original->Position(), - endText, XMLNode::EXACT)); - - addTo->EditChildren().push_back(begin); - - const vector<XMLNode*>& children = original->Children(); - size_t I = children.size(); - for (size_t i=0; i<I; i++) { - err |= convert_html_to_xliff(children[i], name, addTo, phID); - } - - addTo->EditChildren().push_back(end); - } - return err; - } else { - original->Position().Error("invalid <%s> element in <%s> tag\n", - original->Name().c_str(), name.c_str()); - return 1; - } - } - } - } -} - -XMLNode* -create_string_node(const StringResource& str, const string& name) -{ - vector<XMLAttribute> attrs; - attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve")); - XMLNode* node = XMLNode::NewElement(str.pos, XLIFF_XMLNS, name, attrs, XMLNode::EXACT); - - const vector<XMLNode*>& children = str.value->Children(); - size_t I = children.size(); - int err = 0; - for (size_t i=0; i<I; i++) { - int phID = 0; - err |= convert_html_to_xliff(children[i], name, node, &phID); - } - - if (err != 0) { - delete node; - } - return node; -} - -static bool -compare_id(const TransUnit& lhs, const TransUnit& rhs) -{ - string lid, rid; - int lindex, rindex; - StringResource::ParseTypedID(lhs.id, &lid, &lindex); - StringResource::ParseTypedID(rhs.id, &rid, &rindex); - if (lid < rid) return true; - if (lid == rid && lindex < rindex) return true; - return false; -} - -XMLNode* -XLIFFFile::ToXMLNode() const -{ - XMLNode* root; - size_t N; - - // <xliff> - { - vector<XMLAttribute> attrs; - XLIFF_NAMESPACES.AddToAttributes(&attrs); - attrs.push_back(XMLAttribute(XLIFF_XMLNS, "version", "1.2")); - root = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "xliff", attrs, XMLNode::PRETTY); - } - - vector<TransUnit> groups; - - // <file> - vector<File> files = m_files; - sort(files.begin(), files.end()); - const size_t I = files.size(); - for (size_t i=0; i<I; i++) { - const File& file = files[i]; - - vector<XMLAttribute> fileAttrs; - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "datatype", "x-android-res")); - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "original", file.filename)); - - struct timeval tv; - struct timezone tz; - gettimeofday(&tv, &tz); - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "date", trim_string(ctime(&tv.tv_sec)))); - - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "source-language", m_sourceConfig.locale)); - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "target-language", m_targetConfig.locale)); - fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "build-num", m_currentVersion)); - - XMLNode* fileNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "file", fileAttrs, - XMLNode::PRETTY); - root->EditChildren().push_back(fileNode); - - // <body> - XMLNode* bodyNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "body", - vector<XMLAttribute>(), XMLNode::PRETTY); - fileNode->EditChildren().push_back(bodyNode); - - // <trans-unit> - vector<TransUnit> transUnits = file.transUnits; - sort(transUnits.begin(), transUnits.end(), compare_id); - const size_t J = transUnits.size(); - for (size_t j=0; j<J; j++) { - const TransUnit& transUnit = transUnits[j]; - - vector<XMLAttribute> tuAttrs; - - // strings start with string: - tuAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", transUnit.id)); - XMLNode* transUnitNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "trans-unit", - tuAttrs, XMLNode::PRETTY); - bodyNode->EditChildren().push_back(transUnitNode); - - // <extradata> - if (transUnit.source.comment != "") { - vector<XMLAttribute> extradataAttrs; - XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "extradata", - extradataAttrs, XMLNode::EXACT); - transUnitNode->EditChildren().push_back(extraNode); - extraNode->EditChildren().push_back( - XMLNode::NewText(GENERATED_POS, transUnit.source.comment, - XMLNode::PRETTY)); - } - - // <source> - if (transUnit.source.id != "") { - transUnitNode->EditChildren().push_back( - create_string_node(transUnit.source, "source")); - } - - // <target> - if (transUnit.target.id != "") { - transUnitNode->EditChildren().push_back( - create_string_node(transUnit.target, "target")); - } - - // <alt-trans> - if (transUnit.altSource.id != "" || transUnit.altTarget.id != "" - || transUnit.rejectComment != "") { - vector<XMLAttribute> altTransAttrs; - XMLNode* altTransNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "alt-trans", - altTransAttrs, XMLNode::PRETTY); - transUnitNode->EditChildren().push_back(altTransNode); - - // <extradata> - if (transUnit.rejectComment != "") { - vector<XMLAttribute> extradataAttrs; - XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, - "extradata", extradataAttrs, - XMLNode::EXACT); - altTransNode->EditChildren().push_back(extraNode); - extraNode->EditChildren().push_back( - XMLNode::NewText(GENERATED_POS, transUnit.rejectComment, - XMLNode::PRETTY)); - } - - // <source> - if (transUnit.altSource.id != "") { - altTransNode->EditChildren().push_back( - create_string_node(transUnit.altSource, "source")); - } - - // <target> - if (transUnit.altTarget.id != "") { - altTransNode->EditChildren().push_back( - create_string_node(transUnit.altTarget, "target")); - } - } - - } - } - - return root; -} - - -string -XLIFFFile::ToString() const -{ - XMLNode* xml = ToXMLNode(); - string s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; - s += xml->ToString(XLIFF_NAMESPACES); - delete xml; - s += '\n'; - return s; -} - -Stats -XLIFFFile::GetStats(const string& config) const -{ - Stats stat; - stat.config = config; - stat.files = m_files.size(); - stat.toBeTranslated = 0; - stat.noComments = 0; - - for (vector<File>::const_iterator file=m_files.begin(); file!=m_files.end(); file++) { - stat.toBeTranslated += file->transUnits.size(); - - for (vector<TransUnit>::const_iterator tu=file->transUnits.begin(); - tu!=file->transUnits.end(); tu++) { - if (tu->source.comment == "") { - stat.noComments++; - } - } - } - - stat.totalStrings = stat.toBeTranslated; - - return stat; -} diff --git a/tools/localize/XLIFFFile.h b/tools/localize/XLIFFFile.h deleted file mode 100644 index a93d479..0000000 --- a/tools/localize/XLIFFFile.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef XLIFF_FILE_H -#define XLIFF_FILE_H - -#include "Values.h" - -#include "Configuration.h" - -#include <set> - -using namespace std; - -extern const XMLNamespaceMap XLIFF_NAMESPACES; - -extern const char*const XLIFF_XMLNS; - -struct Stats -{ - string config; - size_t files; - size_t toBeTranslated; - size_t noComments; - size_t totalStrings; -}; - -struct TransUnit { - string id; - StringResource source; - StringResource target; - StringResource altSource; - StringResource altTarget; - string rejectComment; -}; - -class XLIFFFile -{ -public: - static XLIFFFile* Parse(const string& filename); - static XLIFFFile* Create(const Configuration& sourceConfig, const Configuration& targetConfig, - const string& currentVersion); - ~XLIFFFile(); - - inline const Configuration& SourceConfig() const { return m_sourceConfig; } - inline const Configuration& TargetConfig() const { return m_targetConfig; } - - inline const string& CurrentVersion() const { return m_currentVersion; } - inline const string& OldVersion() const { return m_oldVersion; } - - set<string> Files() const; - - void AddStringResource(const StringResource& res); - inline set<StringResource> const& GetStringResources() const { return m_strings; } - bool FindStringResource(const string& filename, int version, bool source); - - void Filter(bool (*func)(const string&,const TransUnit&,void*), void* cookie); - void Map(void (*func)(const string&,TransUnit*,void*), void* cookie); - - TransUnit* EditTransUnit(const string& file, const string& id); - - // exports this file as a n XMLNode, you own this object - XMLNode* ToXMLNode() const; - - // writes the ValuesFile out to a string in the canonical format (i.e. writes the contents of - // ToXMLNode()). - string ToString() const; - - Stats GetStats(const string& config) const; - -private: - struct File { - int Compare(const File& that) const; - - inline bool operator<(const File& that) const { return Compare(that) < 0; } - inline bool operator<=(const File& that) const { return Compare(that) <= 0; } - inline bool operator==(const File& that) const { return Compare(that) == 0; } - inline bool operator!=(const File& that) const { return Compare(that) != 0; } - inline bool operator>=(const File& that) const { return Compare(that) >= 0; } - inline bool operator>(const File& that) const { return Compare(that) > 0; } - - string filename; - vector<TransUnit> transUnits; - }; - - XLIFFFile(); - StringResource* find_string_res(TransUnit& g, const StringResource& str); - - Configuration m_sourceConfig; - Configuration m_targetConfig; - - string m_currentVersion; - string m_oldVersion; - - set<StringResource> m_strings; - vector<File> m_files; -}; - -int convert_html_to_xliff(const XMLNode* original, const string& name, XMLNode* addTo, int* phID); - -#endif // XLIFF_FILE_H diff --git a/tools/localize/XLIFFFile_test.cpp b/tools/localize/XLIFFFile_test.cpp deleted file mode 100644 index 52ed4c3..0000000 --- a/tools/localize/XLIFFFile_test.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "XLIFFFile.h" -#include <stdio.h> -#include "ValuesFile.h" - -XMLNode* create_string_node(const StringResource& str, const string& name); - -static int -Parse_test() -{ - XLIFFFile* xf = XLIFFFile::Parse("testdata/xliff1.xliff"); - if (xf == NULL) { - return 1; - } - - set<StringResource> const& strings = xf->GetStringResources(); - - if (false) { - for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { - const StringResource& str = *it; - printf("STRING!!! id=%s index=%d value='%s' pos=%s file=%s version=%d(%s)\n", - str.id.c_str(), str.index, - str.value->ContentsToString(ANDROID_NAMESPACES).c_str(), - str.pos.ToString().c_str(), str.file.c_str(), str.version, - str.versionString.c_str()); - } - printf("XML:[[%s]]\n", xf->ToString().c_str()); - } - - delete xf; - return 0; -} - -static XMLNode* -add_html_tag(XMLNode* addTo, const string& tag) -{ - vector<XMLAttribute> attrs; - XMLNode* node = XMLNode::NewElement(GENERATED_POS, "", tag, attrs, XMLNode::EXACT); - addTo->EditChildren().push_back(node); - return node; -} - -static int -create_string_node_test() -{ - int err = 0; - StringResource res; - vector<XMLAttribute> attrs; - res.value = XMLNode::NewElement(GENERATED_POS, "", "something", attrs, XMLNode::EXACT); - res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " begin ", XMLNode::EXACT)); - - XMLNode* child; - - child = add_html_tag(res.value, "b"); - child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT)); - - child = add_html_tag(res.value, "i"); - child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "i", XMLNode::EXACT)); - - child = add_html_tag(child, "b"); - child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT)); - - child = add_html_tag(res.value, "u"); - child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "u", XMLNode::EXACT)); - - - res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " end ", XMLNode::EXACT)); - - XMLNode* xliff = create_string_node(res, "blah"); - - string oldString = res.value->ToString(XLIFF_NAMESPACES); - string newString = xliff->ToString(XLIFF_NAMESPACES); - - if (false) { - printf("OLD=\"%s\"\n", oldString.c_str()); - printf("NEW=\"%s\"\n", newString.c_str()); - } - - const char* const EXPECTED_OLD - = "<something> begin <b>b</b><i>i<b>b</b></i><u>u</u> end </something>"; - if (oldString != EXPECTED_OLD) { - fprintf(stderr, "oldString mismatch:\n"); - fprintf(stderr, " expected='%s'\n", EXPECTED_OLD); - fprintf(stderr, " actual='%s'\n", oldString.c_str()); - err |= 1; - } - - const char* const EXPECTED_NEW - = "<blah xml:space=\"preserve\"> begin <g ctype=\"bold\">b</g>" - "<g ctype=\"italic\">i<g ctype=\"bold\">b</g></g><g ctype=\"underline\">u</g>" - " end </blah>"; - if (newString != EXPECTED_NEW) { - fprintf(stderr, "newString mismatch:\n"); - fprintf(stderr, " expected='%s'\n", EXPECTED_NEW); - fprintf(stderr, " actual='%s'\n", newString.c_str()); - err |= 1; - } - - if (err != 0) { - fprintf(stderr, "create_string_node_test failed\n"); - } - return err; -} - -int -XLIFFFile_test() -{ - bool all = true; - int err = 0; - - if (all) err |= Parse_test(); - if (all) err |= create_string_node_test(); - - return err; -} - diff --git a/tools/localize/XMLHandler.cpp b/tools/localize/XMLHandler.cpp deleted file mode 100644 index 3fab211..0000000 --- a/tools/localize/XMLHandler.cpp +++ /dev/null @@ -1,793 +0,0 @@ -#include "XMLHandler.h" - -#include <algorithm> -#include <expat.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -#define NS_SEPARATOR 1 -#define MORE_INDENT " " - -static string -xml_text_escape(const string& s) -{ - string result; - const size_t N = s.length(); - for (size_t i=0; i<N; i++) { - char c = s[i]; - switch (c) { - case '<': - result += "<"; - break; - case '>': - result += ">"; - break; - case '&': - result += "&"; - break; - default: - result += c; - break; - } - } - return result; -} - -static string -xml_attr_escape(const string& s) -{ - string result; - const size_t N = s.length(); - for (size_t i=0; i<N; i++) { - char c = s[i]; - switch (c) { - case '\"': - result += """; - break; - default: - result += c; - break; - } - } - return result; -} - -XMLNamespaceMap::XMLNamespaceMap() -{ -} - -XMLNamespaceMap::XMLNamespaceMap(char const*const* nspaces) - -{ - while (*nspaces) { - m_map[nspaces[1]] = nspaces[0]; - nspaces += 2; - } -} - -string -XMLNamespaceMap::Get(const string& ns) const -{ - if (ns == "xml") { - return ns; - } - map<string,string>::const_iterator it = m_map.find(ns); - if (it == m_map.end()) { - return ""; - } else { - return it->second; - } -} - -string -XMLNamespaceMap::GetPrefix(const string& ns) const -{ - if (ns == "") { - return ""; - } - map<string,string>::const_iterator it = m_map.find(ns); - if (it != m_map.end()) { - if (it->second == "") { - return ""; - } else { - return it->second + ":"; - } - } else { - return ":"; // invalid - } -} - -void -XMLNamespaceMap::AddToAttributes(vector<XMLAttribute>* attrs) const -{ - map<string,string>::const_iterator it; - for (it=m_map.begin(); it!=m_map.end(); it++) { - if (it->second == "xml") { - continue; - } - XMLAttribute attr; - if (it->second == "") { - attr.name = "xmlns"; - } else { - attr.name = "xmlns:"; - attr.name += it->second; - } - attr.value = it->first; - attrs->push_back(attr); - } -} - -XMLAttribute::XMLAttribute() -{ -} - -XMLAttribute::XMLAttribute(const XMLAttribute& that) - :ns(that.ns), - name(that.name), - value(that.value) -{ -} - -XMLAttribute::XMLAttribute(string n, string na, string v) - :ns(n), - name(na), - value(v) -{ -} - -XMLAttribute::~XMLAttribute() -{ -} - -int -XMLAttribute::Compare(const XMLAttribute& that) const -{ - if (ns != that.ns) { - return ns < that.ns ? -1 : 1; - } - if (name != that.name) { - return name < that.name ? -1 : 1; - } - return 0; -} - -string -XMLAttribute::Find(const vector<XMLAttribute>& list, const string& ns, const string& name, - const string& def) -{ - const size_t N = list.size(); - for (size_t i=0; i<N; i++) { - const XMLAttribute& attr = list[i]; - if (attr.ns == ns && attr.name == name) { - return attr.value; - } - } - return def; -} - -struct xml_handler_data { - vector<XMLHandler*> stack; - XML_Parser parser; - vector<vector<XMLAttribute>*> attributes; - string filename; -}; - -XMLNode::XMLNode() -{ -} - -XMLNode::~XMLNode() -{ -// for_each(m_children.begin(), m_children.end(), delete_object<XMLNode>); -} - -XMLNode* -XMLNode::Clone() const -{ - switch (m_type) { - case ELEMENT: { - XMLNode* e = XMLNode::NewElement(m_pos, m_ns, m_name, m_attrs, m_pretty); - const size_t N = m_children.size(); - for (size_t i=0; i<N; i++) { - e->m_children.push_back(m_children[i]->Clone()); - } - return e; - } - case TEXT: { - return XMLNode::NewText(m_pos, m_text, m_pretty); - } - default: - return NULL; - } -} - -XMLNode* -XMLNode::NewElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, int pretty) -{ - XMLNode* node = new XMLNode(); - node->m_type = ELEMENT; - node->m_pretty = pretty; - node->m_pos = pos; - node->m_ns = ns; - node->m_name = name; - node->m_attrs = attrs; - return node; -} - -XMLNode* -XMLNode::NewText(const SourcePos& pos, const string& text, int pretty) -{ - XMLNode* node = new XMLNode(); - node->m_type = TEXT; - node->m_pretty = pretty; - node->m_pos = pos; - node->m_text = text; - return node; -} - -void -XMLNode::SetPrettyRecursive(int value) -{ - m_pretty = value; - const size_t N = m_children.size(); - for (size_t i=0; i<N; i++) { - m_children[i]->SetPrettyRecursive(value); - } -} - -string -XMLNode::ContentsToString(const XMLNamespaceMap& nspaces) const -{ - return contents_to_string(nspaces, ""); -} - -string -XMLNode::ToString(const XMLNamespaceMap& nspaces) const -{ - return to_string(nspaces, ""); -} - -string -XMLNode::OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const -{ - return open_tag_to_string(nspaces, "", pretty); -} - -string -XMLNode::contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const -{ - string result; - const size_t N = m_children.size(); - for (size_t i=0; i<N; i++) { - const XMLNode* child = m_children[i]; - switch (child->Type()) { - case ELEMENT: - if (m_pretty == PRETTY) { - result += '\n'; - result += indent; - } - case TEXT: - result += child->to_string(nspaces, indent); - break; - } - } - return result; -} - -string -trim_string(const string& str) -{ - const char* p = str.c_str(); - while (*p && isspace(*p)) { - p++; - } - const char* q = str.c_str() + str.length() - 1; - while (q > p && isspace(*q)) { - q--; - } - q++; - return string(p, q-p); -} - -string -XMLNode::open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent, int pretty) const -{ - if (m_type != ELEMENT) { - return ""; - } - string result = "<"; - result += nspaces.GetPrefix(m_ns); - result += m_name; - - vector<XMLAttribute> attrs = m_attrs; - - sort(attrs.begin(), attrs.end()); - - const size_t N = attrs.size(); - for (size_t i=0; i<N; i++) { - const XMLAttribute& attr = attrs[i]; - if (i == 0 || m_pretty == EXACT || pretty == EXACT) { - result += ' '; - } - else { - result += "\n"; - result += indent; - result += MORE_INDENT; - result += MORE_INDENT; - } - result += nspaces.GetPrefix(attr.ns); - result += attr.name; - result += "=\""; - result += xml_attr_escape(attr.value); - result += '\"'; - } - - if (m_children.size() > 0) { - result += '>'; - } else { - result += " />"; - } - return result; -} - -string -XMLNode::to_string(const XMLNamespaceMap& nspaces, const string& indent) const -{ - switch (m_type) - { - case TEXT: { - if (m_pretty == EXACT) { - return xml_text_escape(m_text); - } else { - return xml_text_escape(trim_string(m_text)); - } - } - case ELEMENT: { - string result = open_tag_to_string(nspaces, indent, PRETTY); - - if (m_children.size() > 0) { - result += contents_to_string(nspaces, indent + MORE_INDENT); - - if (m_pretty == PRETTY && m_children.size() > 0) { - result += '\n'; - result += indent; - } - - result += "</"; - result += nspaces.GetPrefix(m_ns); - result += m_name; - result += '>'; - } - return result; - } - default: - return ""; - } -} - -string -XMLNode::CollapseTextContents() const -{ - if (m_type == TEXT) { - return m_text; - } - else if (m_type == ELEMENT) { - string result; - - const size_t N=m_children.size(); - for (size_t i=0; i<N; i++) { - result += m_children[i]->CollapseTextContents(); - } - - return result; - } - else { - return ""; - } -} - -vector<XMLNode*> -XMLNode::GetElementsByName(const string& ns, const string& name) const -{ - vector<XMLNode*> result; - const size_t N=m_children.size(); - for (size_t i=0; i<N; i++) { - XMLNode* child = m_children[i]; - if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) { - result.push_back(child); - } - } - return result; -} - -XMLNode* -XMLNode::GetElementByNameAt(const string& ns, const string& name, size_t index) const -{ - vector<XMLNode*> result; - const size_t N=m_children.size(); - for (size_t i=0; i<N; i++) { - XMLNode* child = m_children[i]; - if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) { - if (index == 0) { - return child; - } else { - index--; - } - } - } - return NULL; -} - -size_t -XMLNode::CountElementsByName(const string& ns, const string& name) const -{ - size_t result = 0; - const size_t N=m_children.size(); - for (size_t i=0; i<N; i++) { - XMLNode* child = m_children[i]; - if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) { - result++; - } - } - return result; -} - -string -XMLNode::GetAttribute(const string& ns, const string& name, const string& def) const -{ - return XMLAttribute::Find(m_attrs, ns, name, def); -} - -static void -parse_namespace(const char* data, string* ns, string* name) -{ - const char* p = strchr(data, NS_SEPARATOR); - if (p != NULL) { - ns->assign(data, p-data); - name->assign(p+1); - } else { - ns->assign(""); - name->assign(data); - } -} - -static void -convert_attrs(const char** in, vector<XMLAttribute>* out) -{ - while (*in) { - XMLAttribute attr; - parse_namespace(in[0], &attr.ns, &attr.name); - attr.value = in[1]; - out->push_back(attr); - in += 2; - } -} - -static bool -list_contains(const vector<XMLHandler*>& stack, XMLHandler* handler) -{ - const size_t N = stack.size(); - for (size_t i=0; i<N; i++) { - if (stack[i] == handler) { - return true; - } - } - return false; -} - -static void XMLCALL -start_element_handler(void *userData, const char *name, const char **attrs) -{ - xml_handler_data* data = (xml_handler_data*)userData; - - XMLHandler* handler = data->stack[data->stack.size()-1]; - - SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser)); - string nsString; - string nameString; - XMLHandler* next = handler; - vector<XMLAttribute> attributes; - - parse_namespace(name, &nsString, &nameString); - convert_attrs(attrs, &attributes); - - handler->OnStartElement(pos, nsString, nameString, attributes, &next); - - if (next == NULL) { - next = handler; - } - - if (next != handler) { - next->elementPos = pos; - next->elementNamespace = nsString; - next->elementName = nameString; - next->elementAttributes = attributes; - } - - data->stack.push_back(next); -} - -static void XMLCALL -end_element_handler(void *userData, const char *name) -{ - xml_handler_data* data = (xml_handler_data*)userData; - - XMLHandler* handler = data->stack[data->stack.size()-1]; - data->stack.pop_back(); - - SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser)); - - if (!list_contains(data->stack, handler)) { - handler->OnDone(pos); - if (data->stack.size() > 1) { - // not top one - delete handler; - } - } - - handler = data->stack[data->stack.size()-1]; - - string nsString; - string nameString; - - parse_namespace(name, &nsString, &nameString); - - handler->OnEndElement(pos, nsString, nameString); -} - -static void XMLCALL -text_handler(void *userData, const XML_Char *s, int len) -{ - xml_handler_data* data = (xml_handler_data*)userData; - XMLHandler* handler = data->stack[data->stack.size()-1]; - SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser)); - handler->OnText(pos, string(s, len)); -} - -static void XMLCALL -comment_handler(void *userData, const char *comment) -{ - xml_handler_data* data = (xml_handler_data*)userData; - XMLHandler* handler = data->stack[data->stack.size()-1]; - SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser)); - handler->OnComment(pos, string(comment)); -} - -bool -XMLHandler::ParseFile(const string& filename, XMLHandler* handler) -{ - char buf[16384]; - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - SourcePos(filename, -1).Error("Unable to open file for read: %s", strerror(errno)); - return false; - } - - XML_Parser parser = XML_ParserCreateNS(NULL, NS_SEPARATOR); - xml_handler_data state; - state.stack.push_back(handler); - state.parser = parser; - state.filename = filename; - - XML_SetUserData(parser, &state); - XML_SetElementHandler(parser, start_element_handler, end_element_handler); - XML_SetCharacterDataHandler(parser, text_handler); - XML_SetCommentHandler(parser, comment_handler); - - ssize_t len; - bool done; - do { - len = read(fd, buf, sizeof(buf)); - done = len < (ssize_t)sizeof(buf); - if (len < 0) { - SourcePos(filename, -1).Error("Error reading file: %s\n", strerror(errno)); - close(fd); - return false; - } - if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { - SourcePos(filename, (int)XML_GetCurrentLineNumber(parser)).Error( - "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser))); - close(fd); - return false; - } - } while (!done); - - XML_ParserFree(parser); - - close(fd); - - return true; -} - -bool -XMLHandler::ParseString(const string& filename, const string& text, XMLHandler* handler) -{ - XML_Parser parser = XML_ParserCreateNS(NULL, NS_SEPARATOR); - xml_handler_data state; - state.stack.push_back(handler); - state.parser = parser; - state.filename = filename; - - XML_SetUserData(parser, &state); - XML_SetElementHandler(parser, start_element_handler, end_element_handler); - XML_SetCharacterDataHandler(parser, text_handler); - XML_SetCommentHandler(parser, comment_handler); - - if (XML_Parse(parser, text.c_str(), text.size(), true) == XML_STATUS_ERROR) { - SourcePos(filename, (int)XML_GetCurrentLineNumber(parser)).Error( - "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser))); - return false; - } - - XML_ParserFree(parser); - - return true; -} - -XMLHandler::XMLHandler() -{ -} - -XMLHandler::~XMLHandler() -{ -} - -int -XMLHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next) -{ - return 0; -} - -int -XMLHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name) -{ - return 0; -} - -int -XMLHandler::OnText(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -XMLHandler::OnComment(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -XMLHandler::OnDone(const SourcePos& pos) -{ - return 0; -} - -TopElementHandler::TopElementHandler(const string& ns, const string& name, XMLHandler* next) - :m_ns(ns), - m_name(name), - m_next(next) -{ -} - -int -TopElementHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next) -{ - *next = m_next; - return 0; -} - -int -TopElementHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name) -{ - return 0; -} - -int -TopElementHandler::OnText(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -TopElementHandler::OnDone(const SourcePos& pos) -{ - return 0; -} - - -NodeHandler::NodeHandler(XMLNode* root, int pretty) - :m_root(root), - m_pretty(pretty) -{ - if (root != NULL) { - m_nodes.push_back(root); - } -} - -NodeHandler::~NodeHandler() -{ -} - -int -NodeHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next) -{ - int pretty; - if (XMLAttribute::Find(attrs, XMLNS_XMLNS, "space", "") == "preserve") { - pretty = XMLNode::EXACT; - } else { - if (m_root == NULL) { - pretty = m_pretty; - } else { - pretty = m_nodes[m_nodes.size()-1]->Pretty(); - } - } - XMLNode* n = XMLNode::NewElement(pos, ns, name, attrs, pretty); - if (m_root == NULL) { - m_root = n; - } else { - m_nodes[m_nodes.size()-1]->EditChildren().push_back(n); - } - m_nodes.push_back(n); - return 0; -} - -int -NodeHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name) -{ - m_nodes.pop_back(); - return 0; -} - -int -NodeHandler::OnText(const SourcePos& pos, const string& text) -{ - if (m_root == NULL) { - return 1; - } - XMLNode* n = XMLNode::NewText(pos, text, m_nodes[m_nodes.size()-1]->Pretty()); - m_nodes[m_nodes.size()-1]->EditChildren().push_back(n); - return 0; -} - -int -NodeHandler::OnComment(const SourcePos& pos, const string& text) -{ - return 0; -} - -int -NodeHandler::OnDone(const SourcePos& pos) -{ - return 0; -} - -XMLNode* -NodeHandler::ParseFile(const string& filename, int pretty) -{ - NodeHandler handler(NULL, pretty); - if (!XMLHandler::ParseFile(filename, &handler)) { - fprintf(stderr, "error parsing file: %s\n", filename.c_str()); - return NULL; - } - return handler.Root(); -} - -XMLNode* -NodeHandler::ParseString(const string& filename, const string& text, int pretty) -{ - NodeHandler handler(NULL, pretty); - if (!XMLHandler::ParseString(filename, text, &handler)) { - fprintf(stderr, "error parsing file: %s\n", filename.c_str()); - return NULL; - } - return handler.Root(); -} - - diff --git a/tools/localize/XMLHandler.h b/tools/localize/XMLHandler.h deleted file mode 100644 index 1130710..0000000 --- a/tools/localize/XMLHandler.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef XML_H -#define XML_H - -#include "SourcePos.h" - -#include <string> -#include <vector> -#include <map> - -#define XMLNS_XMLNS "http://www.w3.org/XML/1998/namespace" - -using namespace std; - -string trim_string(const string& str); - -struct XMLAttribute -{ - string ns; - string name; - string value; - - XMLAttribute(); - XMLAttribute(const XMLAttribute& that); - XMLAttribute(string ns, string name, string value); - ~XMLAttribute(); - - int Compare(const XMLAttribute& that) const; - - inline bool operator<(const XMLAttribute& that) const { return Compare(that) < 0; } - inline bool operator<=(const XMLAttribute& that) const { return Compare(that) <= 0; } - inline bool operator==(const XMLAttribute& that) const { return Compare(that) == 0; } - inline bool operator!=(const XMLAttribute& that) const { return Compare(that) != 0; } - inline bool operator>=(const XMLAttribute& that) const { return Compare(that) >= 0; } - inline bool operator>(const XMLAttribute& that) const { return Compare(that) > 0; } - - static string Find(const vector<XMLAttribute>& list, - const string& ns, const string& name, const string& def); -}; - -class XMLNamespaceMap -{ -public: - XMLNamespaceMap(); - XMLNamespaceMap(char const*const* nspaces); - string Get(const string& ns) const; - string GetPrefix(const string& ns) const; - void AddToAttributes(vector<XMLAttribute>* attrs) const; -private: - map<string,string> m_map; -}; - -struct XMLNode -{ -public: - enum { - EXACT = 0, - PRETTY = 1 - }; - - enum { - ELEMENT = 0, - TEXT = 1 - }; - - static XMLNode* NewElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, int pretty); - static XMLNode* NewText(const SourcePos& pos, const string& text, int pretty); - - ~XMLNode(); - - // a deep copy - XMLNode* Clone() const; - - inline int Type() const { return m_type; } - inline int Pretty() const { return m_pretty; } - void SetPrettyRecursive(int value); - string ContentsToString(const XMLNamespaceMap& nspaces) const; - string ToString(const XMLNamespaceMap& nspaces) const; - string OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const; - - string CollapseTextContents() const; - - inline const SourcePos& Position() const { return m_pos; } - - // element - inline string Namespace() const { return m_ns; } - inline string Name() const { return m_name; } - inline void SetName(const string& ns, const string& n) { m_ns = ns; m_name = n; } - inline const vector<XMLAttribute>& Attributes() const { return m_attrs; } - inline vector<XMLAttribute>& EditAttributes() { return m_attrs; } - inline const vector<XMLNode*>& Children() const { return m_children; } - inline vector<XMLNode*>& EditChildren() { return m_children; } - vector<XMLNode*> GetElementsByName(const string& ns, const string& name) const; - XMLNode* GetElementByNameAt(const string& ns, const string& name, size_t index) const; - size_t CountElementsByName(const string& ns, const string& name) const; - string GetAttribute(const string& ns, const string& name, const string& def) const; - - // text - inline string Text() const { return m_text; } - -private: - XMLNode(); - XMLNode(const XMLNode&); - - string contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const; - string to_string(const XMLNamespaceMap& nspaces, const string& indent) const; - string open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent, - int pretty) const; - - int m_type; - int m_pretty; - SourcePos m_pos; - - // element - string m_ns; - string m_name; - vector<XMLAttribute> m_attrs; - vector<XMLNode*> m_children; - - // text - string m_text; -}; - -class XMLHandler -{ -public: - // information about the element that started us - SourcePos elementPos; - string elementNamespace; - string elementName; - vector<XMLAttribute> elementAttributes; - - XMLHandler(); - virtual ~XMLHandler(); - - XMLHandler* parent; - - virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next); - virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name); - virtual int OnText(const SourcePos& pos, const string& text); - virtual int OnComment(const SourcePos& pos, const string& text); - virtual int OnDone(const SourcePos& pos); - - static bool ParseFile(const string& filename, XMLHandler* handler); - static bool ParseString(const string& filename, const string& text, XMLHandler* handler); -}; - -class TopElementHandler : public XMLHandler -{ -public: - TopElementHandler(const string& ns, const string& name, XMLHandler* next); - - virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next); - virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name); - virtual int OnText(const SourcePos& pos, const string& text); - virtual int OnDone(const SourcePos& endPos); - -private: - string m_ns; - string m_name; - XMLHandler* m_next; -}; - -class NodeHandler : public XMLHandler -{ -public: - // after it's done, you own everything created and added to root - NodeHandler(XMLNode* root, int pretty); - ~NodeHandler(); - - virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name, - const vector<XMLAttribute>& attrs, XMLHandler** next); - virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name); - virtual int OnText(const SourcePos& pos, const string& text); - virtual int OnComment(const SourcePos& pos, const string& text); - virtual int OnDone(const SourcePos& endPos); - - inline XMLNode* Root() const { return m_root; } - - static XMLNode* ParseFile(const string& filename, int pretty); - static XMLNode* ParseString(const string& filename, const string& text, int pretty); - -private: - XMLNode* m_root; - int m_pretty; - vector<XMLNode*> m_nodes; -}; - -template <class T> -static void delete_object(T* obj) -{ - delete obj; -} - -#endif // XML_H diff --git a/tools/localize/XMLHandler_test.cpp b/tools/localize/XMLHandler_test.cpp deleted file mode 100644 index 1c81c0c..0000000 --- a/tools/localize/XMLHandler_test.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "XMLHandler.h" -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> - -const char *const NS_MAP[] = { - "xml", XMLNS_XMLNS, - NULL, NULL -}; - -const XMLNamespaceMap NO_NAMESPACES(NS_MAP); - -char const*const EXPECTED_EXACT = - "<ASDF>\n" - " <a id=\"system\" old-cl=\"1\" new-cl=\"43019\">\n" - " <app dir=\"apps/common\" />\n" - " </a>\n" - " <a id=\"samples\" old-cl=\"1\" new-cl=\"43019\">asdf\n" - " <app dir=\"samples/NotePad\" />\n" - " <app dir=\"samples/LunarLander\" />\n" - " <something>a<b>,</b>b </something>\n" - " <exact xml:space=\"preserve\">a<b>,</b>b </exact>\n" - " </a>\n" - "</ASDF>\n"; - -char const*const EXPECTED_PRETTY = - "<ASDF>\n" - " <a id=\"system\"\n" - " old-cl=\"1\"\n" - " new-cl=\"43019\">\n" - " <app dir=\"apps/common\" />\n" - " </a>\n" - " <a id=\"samples\"\n" - " old-cl=\"1\"\n" - " new-cl=\"43019\">asdf\n" - " <app dir=\"samples/NotePad\" />\n" - " <app dir=\"samples/LunarLander\" />\n" - " <something>a\n" - " <b>,\n" - " </b>b \n" - " </something>\n" - " <exact xml:space=\"preserve\">a<b>,</b>b </exact>\n" - " </a>\n" - "</ASDF>\n"; - -static string -read_file(const string& filename) -{ - char buf[1024]; - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - return ""; - } - string result; - while (true) { - ssize_t len = read(fd, buf, sizeof(buf)-1); - buf[len] = '\0'; - if (len <= 0) { - break; - } - result.append(buf, len); - } - close(fd); - return result; -} - -static int -ParseFile_EXACT_test() -{ - XMLNode* root = NodeHandler::ParseFile("testdata/xml.xml", XMLNode::EXACT); - if (root == NULL) { - return 1; - } - string result = root->ToString(NO_NAMESPACES); - delete root; - //printf("[[%s]]\n", result.c_str()); - return result == EXPECTED_EXACT; -} - -static int -ParseFile_PRETTY_test() -{ - XMLNode* root = NodeHandler::ParseFile("testdata/xml.xml", XMLNode::PRETTY); - if (root == NULL) { - return 1; - } - string result = root->ToString(NO_NAMESPACES); - delete root; - //printf("[[%s]]\n", result.c_str()); - return result == EXPECTED_PRETTY; -} - -static int -ParseString_EXACT_test() -{ - string text = read_file("testdata/xml.xml"); - XMLNode* root = NodeHandler::ParseString("testdata/xml.xml", text, XMLNode::EXACT); - if (root == NULL) { - return 1; - } - string result = root->ToString(NO_NAMESPACES); - delete root; - //printf("[[%s]]\n", result.c_str()); - return result == EXPECTED_EXACT; -} - -static int -ParseString_PRETTY_test() -{ - string text = read_file("testdata/xml.xml"); - XMLNode* root = NodeHandler::ParseString("testdata/xml.xml", text, XMLNode::PRETTY); - if (root == NULL) { - return 1; - } - string result = root->ToString(NO_NAMESPACES); - delete root; - //printf("[[%s]]\n", result.c_str()); - return result == EXPECTED_PRETTY; -} - -int -XMLHandler_test() -{ - int err = 0; - bool all = true; - - if (all) err |= ParseFile_EXACT_test(); - if (all) err |= ParseFile_PRETTY_test(); - if (all) err |= ParseString_EXACT_test(); - if (all) err |= ParseString_PRETTY_test(); - - return err; -} diff --git a/tools/localize/XMLNode.h b/tools/localize/XMLNode.h deleted file mode 100644 index bfb9f55..0000000 --- a/tools/localize/XMLNode.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef XMLNODE_H -#define XMLNODE_H - -#include <string> - -using namespace std; - -struct XMLAttribute -{ - string ns; - string name; - string value; - - static string Find(const vector<XMLAttribute>& list, - const string& ns, const string& name, const string& def); -}; - - -#endif // XMLNODE_H diff --git a/tools/localize/file_utils.cpp b/tools/localize/file_utils.cpp deleted file mode 100644 index bb82a9c..0000000 --- a/tools/localize/file_utils.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include "file_utils.h" -#include "Perforce.h" -#include <sys/fcntl.h> -#include <sys/stat.h> -#include <errno.h> -#include <host/Directories.h> -#include "log.h" - -string -translated_file_name(const string& file, const string& locale) -{ - const char* str = file.c_str(); - const char* p = str + file.length(); - const char* rest = NULL; - const char* values = p; - - while (p > str) { - p--; - if (*p == '/') { - rest = values; - values = p; - if (0 == strncmp("values", values+1, rest-values-1)) { - break; - } - } - } - values++; - - string result(str, values-str); - result.append(values, rest-values); - - string language, region; - if (locale == "") { - language = ""; - region = ""; - } - else if (!split_locale(locale, &language, ®ion)) { - return ""; - } - - if (language != "") { - result += '-'; - result += language; - } - if (region != "") { - result += "-r"; - result += region; - } - - result += rest; - - return result; -} - -ValuesFile* -get_values_file(const string& filename, const Configuration& configuration, - int version, const string& versionString, bool printOnFailure) -{ - int err; - string text; - - log_printf("get_values_file filename=%s\n", filename.c_str()); - err = Perforce::GetFile(filename, versionString, &text, printOnFailure); - if (err != 0 || text == "") { - return NULL; - } - - ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version, - versionString); - if (result == NULL) { - fprintf(stderr, "unable to parse file: %s\n", filename.c_str()); - exit(1); - } - return result; -} - -ValuesFile* -get_local_values_file(const string& filename, const Configuration& configuration, - int version, const string& versionString, bool printOnFailure) -{ - int err; - string text; - char buf[2049]; - int fd; - ssize_t amt; - - fd = open(filename.c_str(), O_RDONLY); - if (fd == -1) { - fprintf(stderr, "unable to open file: %s\n", filename.c_str()); - return NULL; - } - - while ((amt = read(fd, buf, sizeof(buf)-1)) > 0) { - text.append(buf, amt); - } - - close(fd); - - if (text == "") { - return NULL; - } - - ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version, - versionString); - if (result == NULL) { - fprintf(stderr, "unable to parse file: %s\n", filename.c_str()); - exit(1); - } - return result; -} - -void -print_file_status(size_t j, size_t J, const string& message) -{ - printf("\r%s file %zd of %zd...", message.c_str(), j, J); - fflush(stdout); -} - -int -write_to_file(const string& filename, const string& text) -{ - mkdirs(parent_dir(filename).c_str()); - int fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); - if (fd < 0) { - fprintf(stderr, "unable to open file for write (%s): %s\n", strerror(errno), - filename.c_str()); - return -1; - } - - ssize_t amt = write(fd, text.c_str(), text.length()); - - close(fd); - - if (amt < 0) { - return amt; - } - return amt == (ssize_t)text.length() ? 0 : -1; -} - - diff --git a/tools/localize/file_utils.h b/tools/localize/file_utils.h deleted file mode 100644 index 3b3fa21..0000000 --- a/tools/localize/file_utils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef FILE_UTILS_H -#define FILE_UTILS_H - -#include "ValuesFile.h" -#include "Configuration.h" -#include <string> - -using namespace std; - -string translated_file_name(const string& file, const string& locale); - -ValuesFile* get_values_file(const string& filename, const Configuration& configuration, - int version, const string& versionString, bool printOnFailure); -ValuesFile* get_local_values_file(const string& filename, const Configuration& configuration, - int version, const string& versionString, bool printOnFailure); - -void print_file_status(size_t j, size_t J, const string& message = "Reading"); -int write_to_file(const string& filename, const string& text); - - -#endif // FILE_UTILS_H diff --git a/tools/localize/localize.cpp b/tools/localize/localize.cpp deleted file mode 100644 index c0d84cc..0000000 --- a/tools/localize/localize.cpp +++ /dev/null @@ -1,767 +0,0 @@ -#include "SourcePos.h" -#include "ValuesFile.h" -#include "XLIFFFile.h" -#include "Perforce.h" -#include "merge_res_and_xliff.h" -#include "localize.h" -#include "file_utils.h" -#include "res_check.h" -#include "xmb.h" - -#include <host/pseudolocalize.h> - -#include <stdlib.h> -#include <stdarg.h> -#include <sstream> -#include <stdio.h> -#include <string.h> - -using namespace std; - -FILE* g_logFile = NULL; - -int test(); - -int -read_settings(const string& filename, map<string,Settings>* result, const string& rootDir) -{ - XMLNode* root = NodeHandler::ParseFile(filename, XMLNode::PRETTY); - if (root == NULL) { - SourcePos(filename, -1).Error("Error reading file."); - return 1; - } - - // <configuration> - vector<XMLNode*> configNodes = root->GetElementsByName("", "configuration"); - const size_t I = configNodes.size(); - for (size_t i=0; i<I; i++) { - const XMLNode* configNode = configNodes[i]; - - Settings settings; - settings.id = configNode->GetAttribute("", "id", ""); - if (settings.id == "") { - configNode->Position().Error("<configuration> needs an id attribute."); - delete root; - return 1; - } - - settings.oldVersion = configNode->GetAttribute("", "old-cl", ""); - - settings.currentVersion = configNode->GetAttribute("", "new-cl", ""); - if (settings.currentVersion == "") { - configNode->Position().Error("<configuration> needs a new-cl attribute."); - delete root; - return 1; - } - - // <app> - vector<XMLNode*> appNodes = configNode->GetElementsByName("", "app"); - - const size_t J = appNodes.size(); - for (size_t j=0; j<J; j++) { - const XMLNode* appNode = appNodes[j]; - - string dir = appNode->GetAttribute("", "dir", ""); - if (dir == "") { - appNode->Position().Error("<app> needs a dir attribute."); - delete root; - return 1; - } - - settings.apps.push_back(dir); - } - - // <reject> - vector<XMLNode*> rejectNodes = configNode->GetElementsByName("", "reject"); - - const size_t K = rejectNodes.size(); - for (size_t k=0; k<K; k++) { - const XMLNode* rejectNode = rejectNodes[k]; - - Reject reject; - - reject.file = rejectNode->GetAttribute("", "file", ""); - if (reject.file == "") { - rejectNode->Position().Error("<reject> needs a file attribute."); - delete root; - return 1; - } - string f = reject.file; - reject.file = rootDir; - reject.file += '/'; - reject.file += f; - - reject.name = rejectNode->GetAttribute("", "name", ""); - if (reject.name == "") { - rejectNode->Position().Error("<reject> needs a name attribute."); - delete root; - return 1; - } - - reject.comment = trim_string(rejectNode->CollapseTextContents()); - - settings.reject.push_back(reject); - } - - (*result)[settings.id] = settings; - } - - delete root; - return 0; -} - - -static void -ValuesFile_to_XLIFFFile(const ValuesFile* values, XLIFFFile* xliff, const string& englishFilename) -{ - const set<StringResource>& strings = values->GetStrings(); - for (set<StringResource>::const_iterator it=strings.begin(); it!=strings.end(); it++) { - StringResource res = *it; - res.file = englishFilename; - xliff->AddStringResource(res); - } -} - -static bool -contains_reject(const Settings& settings, const string& file, const TransUnit& tu) -{ - const string name = tu.id; - const vector<Reject>& reject = settings.reject; - const size_t I = reject.size(); - for (size_t i=0; i<I; i++) { - const Reject& r = reject[i]; - if (r.file == file && r.name == name) { - return true; - } - } - return false; -} - -/** - * If it's been rejected, then we keep whatever info we have. - * - * Implements this truth table: - * - * S AT AS Keep - * ----------------------- - * 0 0 0 0 (this case can't happen) - * 0 0 1 0 (it was there, never translated, and removed) - * 0 1 0 0 (somehow it got translated, but it was removed) - * 0 1 1 0 (it was removed after having been translated) - * - * 1 0 0 1 (it was just added) - * 1 0 1 1 (it was added, has been changed, but it never got translated) - * 1 1 0 1 (somehow it got translated, but we don't know based on what) - * 1 1 1 0/1 (it's in both. 0 if S=AS b/c there's no need to retranslate if they're - * the same. 1 if S!=AS because S changed, so it should be retranslated) - * - * The first four are cases where, whatever happened in the past, the string isn't there - * now, so it shouldn't be in the XLIFF file. - * - * For cases 4 and 5, the string has never been translated, so get it translated. - * - * For case 6, it's unclear where the translated version came from, so we're conservative - * and send it back for them to have another shot at. - * - * For case 7, we have some data. We have two choices. We could rely on the translator's - * translation memory or tools to notice that the strings haven't changed, and populate the - * <target> field themselves. Or if the string hasn't changed since last time, we can just - * not even tell them about it. As the project nears the end, it will be convenient to see - * the xliff files reducing in size, so we pick the latter. Obviously, if the string has - * changed, then we need to get it retranslated. - */ -bool -keep_this_trans_unit(const string& file, const TransUnit& unit, void* cookie) -{ - const Settings* settings = reinterpret_cast<const Settings*>(cookie); - - if (contains_reject(*settings, file, unit)) { - return true; - } - - if (unit.source.id == "") { - return false; - } - if (unit.altTarget.id == "" || unit.altSource.id == "") { - return true; - } - return unit.source.value->ContentsToString(XLIFF_NAMESPACES) - != unit.altSource.value->ContentsToString(XLIFF_NAMESPACES); -} - -int -validate_config(const string& settingsFile, const map<string,Settings>& settings, - const string& config) -{ - if (settings.find(config) == settings.end()) { - SourcePos(settingsFile, -1).Error("settings file does not contain setting: %s\n", - config.c_str()); - return 1; - } - return 0; -} - -int -validate_configs(const string& settingsFile, const map<string,Settings>& settings, - const vector<string>& configs) -{ - int err = 0; - for (size_t i=0; i<configs.size(); i++) { - string config = configs[i]; - err |= validate_config(settingsFile, settings, config); - } - return err; -} - -int -select_files(vector<string> *resFiles, const string& config, - const map<string,Settings>& settings, const string& rootDir) -{ - int err; - vector<vector<string> > allResFiles; - vector<string> configs; - configs.push_back(config); - err = select_files(&allResFiles, configs, settings, rootDir); - if (err == 0) { - *resFiles = allResFiles[0]; - } - return err; -} - -int -select_files(vector<vector<string> > *allResFiles, const vector<string>& configs, - const map<string,Settings>& settings, const string& rootDir) -{ - int err; - printf("Selecting files..."); - fflush(stdout); - - for (size_t i=0; i<configs.size(); i++) { - const string& config = configs[i]; - const Settings& setting = settings.find(config)->second; - - vector<string> resFiles; - err = Perforce::GetResourceFileNames(setting.currentVersion, rootDir, - setting.apps, &resFiles, true); - if (err != 0) { - fprintf(stderr, "error with perforce. bailing\n"); - return err; - } - - allResFiles->push_back(resFiles); - } - return 0; -} - -static int -do_export(const string& settingsFile, const string& rootDir, const string& outDir, - const string& targetLocale, const vector<string>& configs) -{ - bool success = true; - int err; - - if (false) { - printf("settingsFile=%s\n", settingsFile.c_str()); - printf("rootDir=%s\n", rootDir.c_str()); - printf("outDir=%s\n", outDir.c_str()); - for (size_t i=0; i<configs.size(); i++) { - printf("config[%zd]=%s\n", i, configs[i].c_str()); - } - } - - map<string,Settings> settings; - err = read_settings(settingsFile, &settings, rootDir); - if (err != 0) { - return err; - } - - err = validate_configs(settingsFile, settings, configs); - if (err != 0) { - return err; - } - - vector<vector<string> > allResFiles; - err = select_files(&allResFiles, configs, settings, rootDir); - if (err != 0) { - return err; - } - - size_t totalFileCount = 0; - for (size_t i=0; i<allResFiles.size(); i++) { - totalFileCount += allResFiles[i].size(); - } - totalFileCount *= 3; // we try all 3 versions of the file - - size_t fileProgress = 0; - vector<Stats> stats; - vector<pair<string,XLIFFFile*> > xliffs; - - for (size_t i=0; i<configs.size(); i++) { - const string& config = configs[i]; - const Settings& setting = settings[config]; - - if (false) { - fprintf(stderr, "Configuration: %s (%zd of %zd)\n", config.c_str(), i+1, - configs.size()); - fprintf(stderr, " Old CL: %s\n", setting.oldVersion.c_str()); - fprintf(stderr, " Current CL: %s\n", setting.currentVersion.c_str()); - } - - Configuration english; - english.locale = "en_US"; - Configuration translated; - translated.locale = targetLocale; - XLIFFFile* xliff = XLIFFFile::Create(english, translated, setting.currentVersion); - - const vector<string>& resFiles = allResFiles[i]; - const size_t J = resFiles.size(); - for (size_t j=0; j<J; j++) { - string resFile = resFiles[j]; - - // parse the files into a ValuesFile - // pull out the strings and add them to the XLIFFFile - - // current file - print_file_status(++fileProgress, totalFileCount); - ValuesFile* currentFile = get_values_file(resFile, english, CURRENT_VERSION, - setting.currentVersion, true); - if (currentFile != NULL) { - ValuesFile_to_XLIFFFile(currentFile, xliff, resFile); - //printf("currentFile=[%s]\n", currentFile->ToString().c_str()); - } else { - fprintf(stderr, "error reading file %s@%s\n", resFile.c_str(), - setting.currentVersion.c_str()); - success = false; - } - - // old file - print_file_status(++fileProgress, totalFileCount); - ValuesFile* oldFile = get_values_file(resFile, english, OLD_VERSION, - setting.oldVersion, false); - if (oldFile != NULL) { - ValuesFile_to_XLIFFFile(oldFile, xliff, resFile); - //printf("oldFile=[%s]\n", oldFile->ToString().c_str()); - } - - // translated version - // (get the head of the tree for the most recent translation, but it's considered - // the old one because the "current" one hasn't been made yet, and this goes into - // the <alt-trans> tag if necessary - print_file_status(++fileProgress, totalFileCount); - string transFilename = translated_file_name(resFile, targetLocale); - ValuesFile* transFile = get_values_file(transFilename, translated, OLD_VERSION, - setting.currentVersion, false); - if (transFile != NULL) { - ValuesFile_to_XLIFFFile(transFile, xliff, resFile); - } - - delete currentFile; - delete oldFile; - delete transFile; - } - - Stats beforeFilterStats = xliff->GetStats(config); - - // run through the XLIFFFile and strip out TransUnits that have identical - // old and current source values and are not in the reject list, or just - // old values and no source values - xliff->Filter(keep_this_trans_unit, (void*)&setting); - - Stats afterFilterStats = xliff->GetStats(config); - afterFilterStats.totalStrings = beforeFilterStats.totalStrings; - - // add the reject comments - for (vector<Reject>::const_iterator reject = setting.reject.begin(); - reject != setting.reject.end(); reject++) { - TransUnit* tu = xliff->EditTransUnit(reject->file, reject->name); - tu->rejectComment = reject->comment; - } - - // config-locale-current_cl.xliff - stringstream filename; - if (outDir != "") { - filename << outDir << '/'; - } - filename << config << '-' << targetLocale << '-' << setting.currentVersion << ".xliff"; - xliffs.push_back(pair<string,XLIFFFile*>(filename.str(), xliff)); - - stats.push_back(afterFilterStats); - } - - // today is a good day to die - if (!success || SourcePos::HasErrors()) { - return 1; - } - - // write the XLIFF files - printf("\nWriting %zd file%s...\n", xliffs.size(), xliffs.size() == 1 ? "" : "s"); - for (vector<pair<string,XLIFFFile*> >::iterator it = xliffs.begin(); it != xliffs.end(); it++) { - const string& filename = it->first; - XLIFFFile* xliff = it->second; - string text = xliff->ToString(); - write_to_file(filename, text); - } - - // the stats - printf("\n" - " to without total\n" - " config files translate comments strings\n" - "-----------------------------------------------------------------------\n"); - Stats totals; - totals.config = "total"; - totals.files = 0; - totals.toBeTranslated = 0; - totals.noComments = 0; - totals.totalStrings = 0; - for (vector<Stats>::iterator it=stats.begin(); it!=stats.end(); it++) { - string cfg = it->config; - if (cfg.length() > 20) { - cfg.resize(20); - } - printf(" %-20s %-9zd %-9zd %-9zd %-19zd\n", cfg.c_str(), it->files, - it->toBeTranslated, it->noComments, it->totalStrings); - totals.files += it->files; - totals.toBeTranslated += it->toBeTranslated; - totals.noComments += it->noComments; - totals.totalStrings += it->totalStrings; - } - if (stats.size() > 1) { - printf("-----------------------------------------------------------------------\n" - " %-20s %-9zd %-9zd %-9zd %-19zd\n", totals.config.c_str(), totals.files, - totals.toBeTranslated, totals.noComments, totals.totalStrings); - } - printf("\n"); - return 0; -} - -struct PseudolocalizeSettings { - XLIFFFile* xliff; - bool expand; -}; - - -string -pseudolocalize_string(const string& source, const PseudolocalizeSettings* settings) -{ - return pseudolocalize_string(source); -} - -static XMLNode* -pseudolocalize_xml_node(const XMLNode* source, const PseudolocalizeSettings* settings) -{ - if (source->Type() == XMLNode::TEXT) { - return XMLNode::NewText(source->Position(), pseudolocalize_string(source->Text(), settings), - source->Pretty()); - } else { - XMLNode* target; - if (source->Namespace() == XLIFF_XMLNS && source->Name() == "g") { - // XXX don't translate these - target = XMLNode::NewElement(source->Position(), source->Namespace(), - source->Name(), source->Attributes(), source->Pretty()); - } else { - target = XMLNode::NewElement(source->Position(), source->Namespace(), - source->Name(), source->Attributes(), source->Pretty()); - } - - const vector<XMLNode*>& children = source->Children(); - const size_t I = children.size(); - for (size_t i=0; i<I; i++) { - target->EditChildren().push_back(pseudolocalize_xml_node(children[i], settings)); - } - - return target; - } -} - -void -pseudolocalize_trans_unit(const string&file, TransUnit* unit, void* cookie) -{ - const PseudolocalizeSettings* settings = (PseudolocalizeSettings*)cookie; - - const StringResource& source = unit->source; - StringResource* target = &unit->target; - *target = source; - - target->config = settings->xliff->TargetConfig(); - - delete target->value; - target->value = pseudolocalize_xml_node(source.value, settings); -} - -int -pseudolocalize_xliff(XLIFFFile* xliff, bool expand) -{ - PseudolocalizeSettings settings; - - settings.xliff = xliff; - settings.expand = expand; - xliff->Map(pseudolocalize_trans_unit, &settings); - return 0; -} - -static int -do_pseudo(const string& infile, const string& outfile, bool expand) -{ - int err; - - XLIFFFile* xliff = XLIFFFile::Parse(infile); - if (xliff == NULL) { - return 1; - } - - pseudolocalize_xliff(xliff, expand); - - err = write_to_file(outfile, xliff->ToString()); - - delete xliff; - - return err; -} - -void -log_printf(const char *fmt, ...) -{ - int ret; - va_list ap; - - if (g_logFile != NULL) { - va_start(ap, fmt); - ret = vfprintf(g_logFile, fmt, ap); - va_end(ap); - fflush(g_logFile); - } -} - -void -close_log_file() -{ - if (g_logFile != NULL) { - fclose(g_logFile); - } -} - -void -open_log_file(const char* file) -{ - g_logFile = fopen(file, "w"); - printf("log file: %s -- %p\n", file, g_logFile); - atexit(close_log_file); -} - -static int -usage() -{ - fprintf(stderr, - "usage: localize export OPTIONS CONFIGS...\n" - " REQUIRED OPTIONS\n" - " --settings SETTINGS The settings file to use. See CONFIGS below.\n" - " --root TREE_ROOT The location in Perforce of the files. e.g. //device\n" - " --target LOCALE The target locale. See LOCALES below.\n" - "\n" - " OPTIONAL OPTIONS\n" - " --out DIR Directory to put the output files. Defaults to the\n" - " current directory if not supplied. Files are\n" - " named as follows:\n" - " CONFIG-LOCALE-CURRENT_CL.xliff\n" - "\n" - "\n" - "usage: localize import XLIFF_FILE...\n" - "\n" - "Import a translated XLIFF file back into the tree.\n" - "\n" - "\n" - "usage: localize xlb XMB_FILE VALUES_FILES...\n" - "\n" - "Read resource files from the tree file and write the corresponding XLB file\n" - "\n" - "Supply all of the android resource files (values files) to export after that.\n" - "\n" - "\n" - "\n" - "CONFIGS\n" - "\n" - "LOCALES\n" - "Locales are specified in the form en_US They will be processed correctly\n" - "to locate the resouce files in the tree.\n" - "\n" - "\n" - "usage: localize pseudo OPTIONS INFILE [OUTFILE]\n" - " OPTIONAL OPTIONS\n" - " --big Pad strings so they get longer.\n" - "\n" - "Read INFILE, an XLIFF file, and output a pseudotranslated version of that file. If\n" - "OUTFILE is specified, the results are written there; otherwise, the results are\n" - "written back to INFILE.\n" - "\n" - "\n" - "usage: localize rescheck FILES...\n" - "\n" - "Reads the base strings and prints warnings about bad resources from the given files.\n" - "\n"); - return 1; -} - -int -main(int argc, const char** argv) -{ - //open_log_file("log.txt"); - //g_logFile = stdout; - - if (argc == 2 && 0 == strcmp(argv[1], "--test")) { - return test(); - } - - if (argc < 2) { - return usage(); - } - - int index = 1; - - if (0 == strcmp("export", argv[index])) { - string settingsFile; - string rootDir; - string outDir; - string baseLocale = "en"; - string targetLocale; - string language, region; - vector<string> configs; - - index++; - while (index < argc) { - if (0 == strcmp("--settings", argv[index])) { - settingsFile = argv[index+1]; - index += 2; - } - else if (0 == strcmp("--root", argv[index])) { - rootDir = argv[index+1]; - index += 2; - } - else if (0 == strcmp("--out", argv[index])) { - outDir = argv[index+1]; - index += 2; - } - else if (0 == strcmp("--target", argv[index])) { - targetLocale = argv[index+1]; - index += 2; - } - else if (argv[index][0] == '-') { - fprintf(stderr, "unknown argument %s\n", argv[index]); - return usage(); - } - else { - break; - } - } - for (; index<argc; index++) { - configs.push_back(argv[index]); - } - - if (settingsFile == "" || rootDir == "" || configs.size() == 0 || targetLocale == "") { - return usage(); - } - if (!split_locale(targetLocale, &language, ®ion)) { - fprintf(stderr, "illegal --target locale: '%s'\n", targetLocale.c_str()); - return usage(); - } - - - return do_export(settingsFile, rootDir, outDir, targetLocale, configs); - } - else if (0 == strcmp("import", argv[index])) { - vector<string> xliffFilenames; - - index++; - for (; index<argc; index++) { - xliffFilenames.push_back(argv[index]); - } - - return do_merge(xliffFilenames); - } - else if (0 == strcmp("xlb", argv[index])) { - string outfile; - vector<string> resFiles; - - index++; - if (argc < index+1) { - return usage(); - } - - outfile = argv[index]; - - index++; - for (; index<argc; index++) { - resFiles.push_back(argv[index]); - } - - return do_xlb_export(outfile, resFiles); - } - else if (0 == strcmp("pseudo", argv[index])) { - string infile; - string outfile; - bool big = false; - - index++; - while (index < argc) { - if (0 == strcmp("--big", argv[index])) { - big = true; - index += 1; - } - else if (argv[index][0] == '-') { - fprintf(stderr, "unknown argument %s\n", argv[index]); - return usage(); - } - else { - break; - } - } - - if (index == argc-1) { - infile = argv[index]; - outfile = argv[index]; - } - else if (index == argc-2) { - infile = argv[index]; - outfile = argv[index+1]; - } - else { - fprintf(stderr, "unknown argument %s\n", argv[index]); - return usage(); - } - - return do_pseudo(infile, outfile, big); - } - else if (0 == strcmp("rescheck", argv[index])) { - vector<string> files; - - index++; - while (index < argc) { - if (argv[index][0] == '-') { - fprintf(stderr, "unknown argument %s\n", argv[index]); - return usage(); - } - else { - break; - } - } - for (; index<argc; index++) { - files.push_back(argv[index]); - } - - if (files.size() == 0) { - return usage(); - } - - return do_rescheck(files); - } - else { - return usage(); - } - - if (SourcePos::HasErrors()) { - SourcePos::PrintErrors(stderr); - return 1; - } - - return 0; -} - diff --git a/tools/localize/localize.h b/tools/localize/localize.h deleted file mode 100644 index 615d14e..0000000 --- a/tools/localize/localize.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef LOCALIZE_H -#define LOCALIZE_H - -#include "XLIFFFile.h" - -#include <map> -#include <string> - -using namespace std; - -struct Reject -{ - string file; - string name; - string comment; -}; - -struct Settings -{ - string id; - string oldVersion; - string currentVersion; - vector<string> apps; - vector<Reject> reject; -}; - -int read_settings(const string& filename, map<string,Settings>* result, const string& rootDir); -string translated_file_name(const string& file, const string& locale); -bool keep_this_trans_unit(const string& file, const TransUnit& unit, void* cookie); -int validate_config(const string& settingsFile, const map<string,Settings>& settings, - const string& configs); -int validate_configs(const string& settingsFile, const map<string,Settings>& settings, - const vector<string>& configs); -int select_files(vector<string> *resFiles, const string& config, - const map<string,Settings>& settings, const string& rootDir); -int select_files(vector<vector<string> > *allResFiles, const vector<string>& configs, - const map<string,Settings>& settings, const string& rootDir); - - -#endif // LOCALIZE_H diff --git a/tools/localize/localize_test.cpp b/tools/localize/localize_test.cpp deleted file mode 100644 index 63d904c..0000000 --- a/tools/localize/localize_test.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "XLIFFFile.h" -#include "ValuesFile.h" -#include "localize.h" - -int pseudolocalize_xliff(XLIFFFile* xliff, bool expand); - -static int -test_filename(const string& file, const string& locale, const string& expected) -{ - string result = translated_file_name(file, locale); - if (result != expected) { - fprintf(stderr, "translated_file_name test failed\n"); - fprintf(stderr, " locale='%s'\n", locale.c_str()); - fprintf(stderr, " expected='%s'\n", expected.c_str()); - fprintf(stderr, " result='%s'\n", result.c_str()); - return 1; - } else { - if (false) { - fprintf(stderr, "translated_file_name test passed\n"); - fprintf(stderr, " locale='%s'\n", locale.c_str()); - fprintf(stderr, " expected='%s'\n", expected.c_str()); - fprintf(stderr, " result='%s'\n", result.c_str()); - } - return 0; - } -} - -static int -translated_file_name_test() -{ - bool all = true; - int err = 0; - - if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz_ZZ", - "//device/samples/NotePad/res/values-zz-rZZ/strings.xml"); - - if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz", - "//device/samples/NotePad/res/values-zz/strings.xml"); - - if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "", - "//device/samples/NotePad/res/values/strings.xml"); - - return err; -} - -bool -return_false(const string&, const TransUnit& unit, void* cookie) -{ - return false; -} - -static int -delete_trans_units() -{ - XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff"); - if (xliff == NULL) { - printf("couldn't read file\n"); - return 1; - } - if (false) { - printf("XLIFF was [[%s]]\n", xliff->ToString().c_str()); - } - - xliff->Filter(return_false, NULL); - - if (false) { - printf("XLIFF is [[%s]]\n", xliff->ToString().c_str()); - - set<StringResource> const& strings = xliff->GetStringResources(); - printf("strings.size=%zd\n", strings.size()); - for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { - const StringResource& str = *it; - printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(), - str.value->ContentsToString(ANDROID_NAMESPACES).c_str(), - str.pos.ToString().c_str(), str.file.c_str(), str.version, - str.versionString.c_str()); - } - } - - return 0; -} - -static int -filter_trans_units() -{ - XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff"); - if (xliff == NULL) { - printf("couldn't read file\n"); - return 1; - } - - if (false) { - printf("XLIFF was [[%s]]\n", xliff->ToString().c_str()); - } - - Settings setting; - xliff->Filter(keep_this_trans_unit, &setting); - - if (false) { - printf("XLIFF is [[%s]]\n", xliff->ToString().c_str()); - - set<StringResource> const& strings = xliff->GetStringResources(); - printf("strings.size=%zd\n", strings.size()); - for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { - const StringResource& str = *it; - printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(), - str.value->ContentsToString(ANDROID_NAMESPACES).c_str(), - str.pos.ToString().c_str(), str.file.c_str(), str.version, - str.versionString.c_str()); - } - } - - return 0; -} - -static int -settings_test() -{ - int err; - map<string,Settings> settings; - map<string,Settings>::iterator it; - - err = read_settings("testdata/config.xml", &settings, "//asdf"); - if (err != 0) { - return err; - } - - if (false) { - for (it=settings.begin(); it!=settings.end(); it++) { - const Settings& setting = it->second; - printf("CONFIG:\n"); - printf(" id='%s'\n", setting.id.c_str()); - printf(" oldVersion='%s'\n", setting.oldVersion.c_str()); - printf(" currentVersion='%s'\n", setting.currentVersion.c_str()); - int i=0; - for (vector<string>::const_iterator app=setting.apps.begin(); - app!=setting.apps.end(); app++) { - printf(" apps[%02d]='%s'\n", i, app->c_str()); - i++; - } - i=0; - for (vector<Reject>::const_iterator reject=setting.reject.begin(); - reject!=setting.reject.end(); reject++) { - i++; - printf(" reject[%02d]=('%s','%s','%s')\n", i, reject->file.c_str(), - reject->name.c_str(), reject->comment.c_str()); - } - } - } - - for (it=settings.begin(); it!=settings.end(); it++) { - const Settings& setting = it->second; - if (it->first != setting.id) { - fprintf(stderr, "it->first='%s' setting.id='%s'\n", it->first.c_str(), - setting.id.c_str()); - err |= 1; - } - } - - - return err; -} - -static int -test_one_pseudo(bool big, const char* expected) -{ - XLIFFFile* xliff = XLIFFFile::Parse("testdata/pseudo.xliff"); - if (xliff == NULL) { - printf("couldn't read file\n"); - return 1; - } - if (false) { - printf("XLIFF was [[%s]]\n", xliff->ToString().c_str()); - } - - pseudolocalize_xliff(xliff, big); - string newString = xliff->ToString(); - delete xliff; - - if (false) { - printf("XLIFF is [[%s]]\n", newString.c_str()); - } - - if (false && newString != expected) { - fprintf(stderr, "xliff didn't translate as expected\n"); - fprintf(stderr, "newString=[[%s]]\n", newString.c_str()); - fprintf(stderr, "expected=[[%s]]\n", expected); - return 1; - } - - return 0; -} - -static int -pseudolocalize_test() -{ - int err = 0; - - err |= test_one_pseudo(false, ""); - //err |= test_one_pseudo(true, ""); - - return err; -} - -int -localize_test() -{ - bool all = true; - int err = 0; - - if (all) err |= translated_file_name_test(); - if (all) err |= delete_trans_units(); - if (all) err |= filter_trans_units(); - if (all) err |= settings_test(); - if (all) err |= pseudolocalize_test(); - - return err; -} - diff --git a/tools/localize/log.h b/tools/localize/log.h deleted file mode 100644 index 4a5fa7f..0000000 --- a/tools/localize/log.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef LOG_H -#define LOG_H - -void log_printf(const char* fmt, ...); - -#endif // LOG_H - diff --git a/tools/localize/merge_res_and_xliff.cpp b/tools/localize/merge_res_and_xliff.cpp deleted file mode 100644 index 58a6554..0000000 --- a/tools/localize/merge_res_and_xliff.cpp +++ /dev/null @@ -1,391 +0,0 @@ -#include "merge_res_and_xliff.h" - -#include "file_utils.h" -#include "Perforce.h" -#include "log.h" - -static set<StringResource>::const_iterator -find_id(const set<StringResource>& s, const string& id, int index) -{ - for (set<StringResource>::const_iterator it = s.begin(); it != s.end(); it++) { - if (it->id == id && it->index == index) { - return it; - } - } - return s.end(); -} - -static set<StringResource>::const_iterator -find_in_xliff(const set<StringResource>& s, const string& filename, const string& id, int index, - int version, const Configuration& config) -{ - for (set<StringResource>::const_iterator it = s.begin(); it != s.end(); it++) { - if (it->file == filename && it->id == id && it->index == index && it->version == version - && it->config == config) { - return it; - } - } - return s.end(); -} - - -static void -printit(const set<StringResource>& s, const set<StringResource>::const_iterator& it) -{ - if (it == s.end()) { - printf("(none)\n"); - } else { - printf("id=%s index=%d config=%s file=%s value='%s'\n", it->id.c_str(), it->index, - it->config.ToString().c_str(), it->file.c_str(), - it->value->ToString(ANDROID_NAMESPACES).c_str()); - } -} - -StringResource -convert_resource(const StringResource& s, const string& file, const Configuration& config, - int version, const string& versionString) -{ - return StringResource(s.pos, file, config, s.id, s.index, s.value ? s.value->Clone() : NULL, - version, versionString, s.comment); -} - -static bool -resource_has_contents(const StringResource& res) -{ - XMLNode* value = res.value; - if (value == NULL) { - return false; - } - string contents = value->ContentsToString(ANDROID_NAMESPACES); - return contents != ""; -} - -ValuesFile* -merge_res_and_xliff(const ValuesFile* en_currentFile, - const ValuesFile* xx_currentFile, const ValuesFile* xx_oldFile, - const string& filename, const XLIFFFile* xliffFile) -{ - bool success = true; - - Configuration en_config = xliffFile->SourceConfig(); - Configuration xx_config = xliffFile->TargetConfig(); - string currentVersion = xliffFile->CurrentVersion(); - - ValuesFile* result = new ValuesFile(xx_config); - - set<StringResource> en_cur = en_currentFile->GetStrings(); - set<StringResource> xx_cur = xx_currentFile->GetStrings(); - set<StringResource> xx_old = xx_oldFile->GetStrings(); - set<StringResource> xliff = xliffFile->GetStringResources(); - - // for each string in en_current - for (set<StringResource>::const_iterator en_c = en_cur.begin(); - en_c != en_cur.end(); en_c++) { - set<StringResource>::const_iterator xx_c = find_id(xx_cur, en_c->id, en_c->index); - set<StringResource>::const_iterator xx_o = find_id(xx_old, en_c->id, en_c->index); - set<StringResource>::const_iterator xlf = find_in_xliff(xliff, en_c->file, en_c->id, - en_c->index, CURRENT_VERSION, xx_config); - - if (false) { - printf("\nen_c: "); printit(en_cur, en_c); - printf("xx_c: "); printit(xx_cur, xx_c); - printf("xx_o: "); printit(xx_old, xx_o); - printf("xlf: "); printit(xliff, xlf); - } - - // if it changed between xx_old and xx_current, use xx_current - // (someone changed it by hand) - if (xx_o != xx_old.end() && xx_c != xx_cur.end()) { - string xx_o_value = xx_o->value->ToString(ANDROID_NAMESPACES); - string xx_c_value = xx_c->value->ToString(ANDROID_NAMESPACES); - if (xx_o_value != xx_c_value && xx_c_value != "") { - StringResource r(convert_resource(*xx_c, filename, xx_config, - CURRENT_VERSION, currentVersion)); - if (resource_has_contents(r)) { - result->AddString(r); - } - continue; - } - } - - // if it is present in xliff, use that - // (it just got translated) - if (xlf != xliff.end() && xlf->value->ToString(ANDROID_NAMESPACES) != "") { - StringResource r(convert_resource(*xlf, filename, xx_config, - CURRENT_VERSION, currentVersion)); - if (resource_has_contents(r)) { - result->AddString(r); - } - } - - // if it is present in xx_current, use that - // (it was already translated, and not retranslated) - // don't filter out empty strings if they were added by hand, the above code just - // guarantees that this tool never adds an empty one. - if (xx_c != xx_cur.end()) { - StringResource r(convert_resource(*xx_c, filename, xx_config, - CURRENT_VERSION, currentVersion)); - result->AddString(r); - } - - // othwerwise, leave it out. The resource fall-through code will use the English - // one at runtime, and the xliff export code will pick it up for translation next time. - } - - if (success) { - return result; - } else { - delete result; - return NULL; - } -} - - -struct MergedFile { - XLIFFFile* xliff; - string xliffFilename; - string original; - string translated; - ValuesFile* en_current; - ValuesFile* xx_current; - ValuesFile* xx_old; - ValuesFile* xx_new; - string xx_new_text; - string xx_new_filename; - bool new_file; - bool deleted_file; - - MergedFile(); - MergedFile(const MergedFile&); -}; - -struct compare_filenames { - bool operator()(const MergedFile& lhs, const MergedFile& rhs) const - { - return lhs.original < rhs.original; - } -}; - -MergedFile::MergedFile() - :xliff(NULL), - xliffFilename(), - original(), - translated(), - en_current(NULL), - xx_current(NULL), - xx_old(NULL), - xx_new(NULL), - xx_new_text(), - xx_new_filename(), - new_file(false), - deleted_file(false) -{ -} - -MergedFile::MergedFile(const MergedFile& that) - :xliff(that.xliff), - xliffFilename(that.xliffFilename), - original(that.original), - translated(that.translated), - en_current(that.en_current), - xx_current(that.xx_current), - xx_old(that.xx_old), - xx_new(that.xx_new), - xx_new_text(that.xx_new_text), - xx_new_filename(that.xx_new_filename), - new_file(that.new_file), - deleted_file(that.deleted_file) -{ -} - - -typedef set<MergedFile, compare_filenames> MergedFileSet; - -int -do_merge(const vector<string>& xliffFilenames) -{ - int err = 0; - MergedFileSet files; - - printf("\rPreparing..."); fflush(stdout); - string currentChange = Perforce::GetCurrentChange(true); - - // for each xliff, make a MergedFile record and do a little error checking - for (vector<string>::const_iterator xliffFilename=xliffFilenames.begin(); - xliffFilename!=xliffFilenames.end(); xliffFilename++) { - XLIFFFile* xliff = XLIFFFile::Parse(*xliffFilename); - if (xliff == NULL) { - fprintf(stderr, "localize import: unable to read file %s\n", xliffFilename->c_str()); - err = 1; - continue; - } - - set<string> xf = xliff->Files(); - for (set<string>::const_iterator f=xf.begin(); f!=xf.end(); f++) { - MergedFile mf; - mf.xliff = xliff; - mf.xliffFilename = *xliffFilename; - mf.original = *f; - mf.translated = translated_file_name(mf.original, xliff->TargetConfig().locale); - log_printf("mf.translated=%s mf.original=%s locale=%s\n", mf.translated.c_str(), - mf.original.c_str(), xliff->TargetConfig().locale.c_str()); - - if (files.find(mf) != files.end()) { - fprintf(stderr, "%s: duplicate string resources for file %s\n", - xliffFilename->c_str(), f->c_str()); - fprintf(stderr, "%s: previously defined here.\n", - files.find(mf)->xliffFilename.c_str()); - err = 1; - continue; - } - files.insert(mf); - } - } - - size_t deletedFileCount = 0; - size_t J = files.size() * 3; - size_t j = 1; - // Read all of the files from perforce. - for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) { - MergedFile* file = const_cast<MergedFile*>(&(*mf)); - // file->en_current - print_file_status(j++, J); - file->en_current = get_values_file(file->original, file->xliff->SourceConfig(), - CURRENT_VERSION, currentChange, true); - if (file->en_current == NULL) { - // deleted file - file->deleted_file = true; - deletedFileCount++; - continue; - } - - // file->xx_current; - print_file_status(j++, J); - file->xx_current = get_values_file(file->translated, file->xliff->TargetConfig(), - CURRENT_VERSION, currentChange, false); - if (file->xx_current == NULL) { - file->xx_current = new ValuesFile(file->xliff->TargetConfig()); - file->new_file = true; - } - - // file->xx_old (note that the xliff's current version is our old version, because that - // was the current version when it was exported) - print_file_status(j++, J); - file->xx_old = get_values_file(file->translated, file->xliff->TargetConfig(), - OLD_VERSION, file->xliff->CurrentVersion(), false); - if (file->xx_old == NULL) { - file->xx_old = new ValuesFile(file->xliff->TargetConfig()); - file->new_file = true; - } - } - - // merge them - for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) { - MergedFile* file = const_cast<MergedFile*>(&(*mf)); - if (file->deleted_file) { - continue; - } - file->xx_new = merge_res_and_xliff(file->en_current, file->xx_current, file->xx_old, - file->original, file->xliff); - } - - // now is a good time to stop if there was an error - if (err != 0) { - return err; - } - - // locate the files - j = 1; - for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) { - MergedFile* file = const_cast<MergedFile*>(&(*mf)); - print_file_status(j++, J, "Locating"); - - file->xx_new_filename = Perforce::Where(file->translated, true); - if (file->xx_new_filename == "") { - fprintf(stderr, "\nWas not able to determine the location of depot file %s\n", - file->translated.c_str()); - err = 1; - } - } - - if (err != 0) { - return err; - } - - // p4 edit the files - // only do this if it changed - no need to submit files that haven't changed meaningfully - vector<string> filesToEdit; - vector<string> filesToAdd; - vector<string> filesToDelete; - for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) { - MergedFile* file = const_cast<MergedFile*>(&(*mf)); - if (file->deleted_file) { - filesToDelete.push_back(file->xx_new_filename); - continue; - } - string xx_current_text = file->xx_current->ToString(); - string xx_new_text = file->xx_new->ToString(); - if (xx_current_text != xx_new_text) { - if (file->xx_new->GetStrings().size() == 0) { - file->deleted_file = true; - filesToDelete.push_back(file->xx_new_filename); - } else { - file->xx_new_text = xx_new_text; - if (file->new_file) { - filesToAdd.push_back(file->xx_new_filename); - } else { - filesToEdit.push_back(file->xx_new_filename); - } - } - } - } - if (filesToAdd.size() == 0 && filesToEdit.size() == 0 && deletedFileCount == 0) { - printf("\nAll of the files are the same. Nothing to change.\n"); - return 0; - } - if (filesToEdit.size() > 0) { - printf("\np4 editing files...\n"); - if (0 != Perforce::EditFiles(filesToEdit, true)) { - return 1; - } - } - - - printf("\n"); - - for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) { - MergedFile* file = const_cast<MergedFile*>(&(*mf)); - if (file->deleted_file) { - continue; - } - if (file->xx_new_text != "" && file->xx_new_filename != "") { - if (0 != write_to_file(file->xx_new_filename, file->xx_new_text)) { - err = 1; - } - } - } - - if (err != 0) { - return err; - } - - if (filesToAdd.size() > 0) { - printf("p4 adding %zd new files...\n", filesToAdd.size()); - err = Perforce::AddFiles(filesToAdd, true); - } - - if (filesToDelete.size() > 0) { - printf("p4 deleting %zd removed files...\n", filesToDelete.size()); - err = Perforce::DeleteFiles(filesToDelete, true); - } - - if (err != 0) { - return err; - } - - printf("\n" - "Theoretically, this merge was successfull. Next you should\n" - "review the diffs, get a code review, and submit it. Enjoy.\n\n"); - return 0; -} - diff --git a/tools/localize/merge_res_and_xliff.h b/tools/localize/merge_res_and_xliff.h deleted file mode 100644 index acf2fff..0000000 --- a/tools/localize/merge_res_and_xliff.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MERGE_RES_AND_XLIFF_H -#define MERGE_RES_AND_XLIFF_H - -#include "ValuesFile.h" -#include "XLIFFFile.h" - -ValuesFile* merge_res_and_xliff(const ValuesFile* en_current, - const ValuesFile* xx_current, const ValuesFile* xx_old, - const string& filename, const XLIFFFile* xliff); - -int do_merge(const vector<string>& xliffFilenames); - -#endif // MERGE_RES_AND_XLIFF_H diff --git a/tools/localize/merge_res_and_xliff_test.cpp b/tools/localize/merge_res_and_xliff_test.cpp deleted file mode 100644 index 5a2b0f4..0000000 --- a/tools/localize/merge_res_and_xliff_test.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "merge_res_and_xliff.h" - - -int -merge_test() -{ - Configuration english; - english.locale = "en_US"; - Configuration translated; - translated.locale = "zz_ZZ"; - - ValuesFile* en_current = ValuesFile::ParseFile("testdata/merge_en_current.xml", english, - CURRENT_VERSION, "3"); - if (en_current == NULL) { - fprintf(stderr, "merge_test: unable to read testdata/merge_en_current.xml\n"); - return 1; - } - - ValuesFile* xx_current = ValuesFile::ParseFile("testdata/merge_xx_current.xml", translated, - CURRENT_VERSION, "3"); - if (xx_current == NULL) { - fprintf(stderr, "merge_test: unable to read testdata/merge_xx_current.xml\n"); - return 1; - } - ValuesFile* xx_old = ValuesFile::ParseFile("testdata/merge_xx_old.xml", translated, - OLD_VERSION, "2"); - if (xx_old == NULL) { - fprintf(stderr, "merge_test: unable to read testdata/merge_xx_old.xml\n"); - return 1; - } - - XLIFFFile* xliff = XLIFFFile::Parse("testdata/merge.xliff"); - - ValuesFile* result = merge_res_and_xliff(en_current, xx_current, xx_old, - "//device/tools/localize/testdata/res/values/strings.xml", xliff); - - if (result == NULL) { - fprintf(stderr, "merge_test: result is NULL\n"); - return 1; - } - - printf("======= RESULT =======\n%s===============\n", result->ToString().c_str()); - - return 0; -} - - diff --git a/tools/localize/res_check.cpp b/tools/localize/res_check.cpp deleted file mode 100644 index 0fab98a..0000000 --- a/tools/localize/res_check.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "res_check.h" -#include "localize.h" -#include "file_utils.h" -#include "ValuesFile.h" - -#include <stdio.h> - -static int check_file(const ValuesFile* file); -static int check_value(const SourcePos& pos, const XMLNode* value); -static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0); - -int -do_rescheck(const vector<string>& files) -{ - int err; - - Configuration english; - english.locale = "en_US"; - - for (size_t i=0; i<files.size(); i++) { - const string filename = files[i]; - ValuesFile* valuesFile = get_local_values_file(filename, english, CURRENT_VERSION, - "0", true); - if (valuesFile != NULL) { - err |= check_file(valuesFile); - delete valuesFile; - } else { - err |= 1; - } - } - - return err; -} - -static int -check_file(const ValuesFile* file) -{ - int err = 0; - set<StringResource> strings = file->GetStrings(); - for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { - XMLNode* value = it->value; - if (value != NULL) { - err |= check_value(it->pos, value); - } - } - return err; -} - -static bool -contains_percent(const string& str) -{ - const size_t len = str.length(); - for (size_t i=0; i<len; i++) { - char c = str[i]; - if (c == '%') { - return true; - } - } - return false; -} - -static int -check_value(const SourcePos& pos, const XMLNode* value) -{ - int err = 0; - err |= scan_for_unguarded_format(pos, value); - return err; -} - -static bool -is_xliff_block(const string& ns, const string& name) -{ - if (ns == XLIFF_XMLNS) { - return name == "g"; - } else { - return false; - } -} - -static int -scan_for_unguarded_format(const SourcePos& pos, const string& string) -{ - bool containsPercent = contains_percent(string); - if (containsPercent) { - pos.Error("unguarded percent: '%s'\n", string.c_str()); - } - return 0; -} - -static int -scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth) -{ - if (value->Type() == XMLNode::ELEMENT) { - int err = 0; - if (depth == 0 || !is_xliff_block(value->Namespace(), value->Name())) { - const vector<XMLNode*>& children = value->Children(); - for (size_t i=0; i<children.size(); i++) { - err |= scan_for_unguarded_format(pos, children[i], depth+1); - } - } - return err; - } else { - return scan_for_unguarded_format(pos, value->Text()); - } -} - diff --git a/tools/localize/res_check.h b/tools/localize/res_check.h deleted file mode 100644 index 86e7ce6..0000000 --- a/tools/localize/res_check.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef RESCHECK_H -#define RESCHECK_H - -#include <map> -#include <string> -#include <vector> - -using namespace std; - -int do_rescheck(const vector<string>& files); - -#endif // RESCHECK_H diff --git a/tools/localize/test.cpp b/tools/localize/test.cpp deleted file mode 100644 index 5fa2c17..0000000 --- a/tools/localize/test.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "SourcePos.h" -#include <stdio.h> - -int ValuesFile_test(); -int XLIFFFile_test(); -int XMLHandler_test(); -int Perforce_test(); -int localize_test(); -int merge_test(); - -int -test() -{ - bool all = true; - int err = 0; - - if (all) err |= XMLHandler_test(); - if (all) err |= ValuesFile_test(); - if (all) err |= XLIFFFile_test(); - if (all) err |= Perforce_test(); - if (all) err |= localize_test(); - if (all) err |= merge_test(); - - if (err != 0) { - fprintf(stderr, "some tests failed\n"); - } else { - fprintf(stderr, "all tests passed\n"); - } - - return err; -} diff --git a/tools/localize/testdata/config.xml b/tools/localize/testdata/config.xml deleted file mode 100644 index affa140..0000000 --- a/tools/localize/testdata/config.xml +++ /dev/null @@ -1,15 +0,0 @@ -<localize-config> - <configuration id="system" - old-cl="1" - new-cl="43019"> - <app dir="apps/common" /> - </configuration> - <configuration id="samples" - old-cl="24801" - new-cl="43019"> - <app dir="samples/NotePad" /> - <reject file="samples/NotePad/res/values/strings.xml" name="string:menu_delete"> - QA says this sounds <b>rude</b>. - </reject> - </configuration> -</localize-config> diff --git a/tools/localize/testdata/import.xliff b/tools/localize/testdata/import.xliff deleted file mode 100644 index b99b739..0000000 --- a/tools/localize/testdata/import.xliff +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" - version="1.2" - > - <file datatype="x-android-res" - original="//device/tools/localize/testdata/res/values/strings.xml" - product-version="1.0" - date="08:10:54 12/07/07 PST" - source-language="en_US" - product-name="kila" - target-language="zz_ZZ" - build-num="44391" - > - <body> - <trans-unit id="string:changed_in_xx"> - <source>aaa</source> - <target>AAA</target> - </trans-unit> - <trans-unit id="string:first_translation"> - <source>bbb</source> - <target>BBB</target> - </trans-unit> - <trans-unit id="string:deleted_string"> - <source>ddd</source> - <target>DDDD</target> - </trans-unit> - <trans-unit id="array:0:growing_array"> - <source>1-One</source> - <target>1-oNE</target> - </trans-unit> - <trans-unit id="array:1:growing_array"> - <source>1-Two</source> - <target>1-tWO</target> - </trans-unit> - <trans-unit id="array:2:growing_array"> - <source>1-Three</source> - <target>1-tHREE</target> - </trans-unit> - <trans-unit id="array:0:shrinking_array"> - <source>2-One</source> - <target>2-oNE</target> - </trans-unit> - <trans-unit id="array:1:shrinking_array"> - <source>2-Two</source> - <target>2-tWO</target> - </trans-unit> - <trans-unit id="array:2:shrinking_array"> - <source>2-Three</source> - <target>2-tHREE</target> - </trans-unit> - <trans-unit id="array:3:shrinking_array"> - <source>2-Four</source> - <target>2-fOUR</target> - </trans-unit> - <trans-unit id="array:0:deleted_array"> - <source>4-One</source> - <target>4-oNE</target> - </trans-unit> - <trans-unit id="array:1:deleted_array"> - <source>4-Two</source> - <target>4-tWO</target> - </trans-unit> - <trans-unit id="array:2:deleted_array"> - <source>4-Three</source> - <target>4-tHREE</target> - </trans-unit> - - </body> - </file> -</xliff> - - diff --git a/tools/localize/testdata/merge.xliff b/tools/localize/testdata/merge.xliff deleted file mode 100644 index 2b78c45..0000000 --- a/tools/localize/testdata/merge.xliff +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" - version="1.2" - > - <file datatype="x-android-res" - original="testdata/merge_en_current.xml" - product-version="1.0" - date="08:10:54 12/07/07 PST" - source-language="en-US" - product-name="kila" - target-language="zz-ZZ" - build-num="44391" - > - <body> - <trans-unit id="string:changed_in_xx"> - <source>aaa</source> - <target>AAA</target> - </trans-unit> - <trans-unit id="string:first_translation"> - <source>bbb</source> - <target>BBB</target> - </trans-unit> - <trans-unit id="string:deleted_string"> - <source>ddd</source> - <target>DDDD</target> - </trans-unit> - <trans-unit id="array:0:growing_array"> - <source>1-One</source> - <target>1-oNE</target> - </trans-unit> - <trans-unit id="array:1:growing_array"> - <source>1-Two</source> - <target>1-tWO</target> - </trans-unit> - <trans-unit id="array:2:growing_array"> - <source>1-Three</source> - <target>1-tHREE</target> - </trans-unit> - <trans-unit id="array:0:shrinking_array"> - <source>2-One</source> - <target>2-oNE</target> - </trans-unit> - <trans-unit id="array:1:shrinking_array"> - <source>2-Two</source> - <target>2-tWO</target> - </trans-unit> - <trans-unit id="array:2:shrinking_array"> - <source>2-Three</source> - <target>2-tHREE</target> - </trans-unit> - <trans-unit id="array:3:shrinking_array"> - <source>2-Four</source> - <target>2-fOUR</target> - </trans-unit> - <trans-unit id="array:0:deleted_array"> - <source>4-One</source> - <target>4-oNE</target> - </trans-unit> - <trans-unit id="array:1:deleted_array"> - <source>4-Two</source> - <target>4-tWO</target> - </trans-unit> - <trans-unit id="array:2:deleted_array"> - <source>4-Three</source> - <target>4-tHREE</target> - </trans-unit> - - </body> - </file> -</xliff> - - diff --git a/tools/localize/testdata/merge_en_current.xml b/tools/localize/testdata/merge_en_current.xml deleted file mode 100644 index 6a11e68..0000000 --- a/tools/localize/testdata/merge_en_current.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">aaa</string> - <string name="first_translation">bbb</string> - <string name="previously_translated">ccc</string> - <string name="new_string">ccc</string> - - <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string> - - <array name="growing_array"> - <!-- somebody wrote a comment! --> - <item>1-One</item> - <item>1-Two</item> - <item>1-Three</item> - <item>1-Four</item> - </array> - <array name="shrinking_array"> - <!-- somebody wrote a comment! --> - <item>2-One</item> - <item>2-Two</item> - <item>2-Three</item> - </array> - <array name="new_array"> - <!-- somebody wrote a comment! --> - <item>3-One</item> - <item>3-Two</item> - <item>3-Three</item> - </array> -</resources> diff --git a/tools/localize/testdata/merge_en_old.xml b/tools/localize/testdata/merge_en_old.xml deleted file mode 100644 index 933f98e..0000000 --- a/tools/localize/testdata/merge_en_old.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">aaa</string> - <string name="first_translation">bbb</string> - <string name="previously_translated">ccc</string> - <string name="deleted_string">ddd</string> - - <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string> - - <array name="growing_array"> - <!-- somebody wrote a comment! --> - <item>1-One</item> - <item>1-Two</item> - <item>1-Three</item> - </array> - <array name="shrinking_array"> - <!-- somebody wrote a comment! --> - <item>2-One</item> - <item>2-Two</item> - <item>2-Three</item> - <item>2-Four</item> - </array> - <array name="deleted_array"> - <!-- somebody wrote a comment! --> - <item>4-One</item> - <item>4-Two</item> - <item>4-Three</item> - </array> -</resources> - diff --git a/tools/localize/testdata/merge_xx_current.xml b/tools/localize/testdata/merge_xx_current.xml deleted file mode 100644 index c2a783d..0000000 --- a/tools/localize/testdata/merge_xx_current.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">AAAA</string> - <string name="previously_translated">CCC</string> -</resources> - - diff --git a/tools/localize/testdata/merge_xx_old.xml b/tools/localize/testdata/merge_xx_old.xml deleted file mode 100644 index 9d3a7d8..0000000 --- a/tools/localize/testdata/merge_xx_old.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">aaa</string> - <string name="previously_translated">CCC</string> -</resources> - diff --git a/tools/localize/testdata/pseudo.xliff b/tools/localize/testdata/pseudo.xliff deleted file mode 100644 index 5b44f86..0000000 --- a/tools/localize/testdata/pseudo.xliff +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" - version="1.2" - > - <file datatype="x-android-res" - original="//device/tools/localization/tests/res/values/strings.xml" - product-version="1.0" - date="08:10:54 12/07/07 PST" - source-language="en-US" - product-name="kila" - target-language="zz-ZZ" - build-num="32138" - > - <body> - <trans-unit id="string:complex"> - <source>First <g id="string:complex:0" ctype="underline">underline</g>, <g id="string:complex:1" ctype="italic">italic<g id="string:complex:2" ctype="bold">italicbold</g></g> End </source> - </trans-unit> - <trans-unit id="string:complex-quoted"> - <source xml:space="preserve">First <g id="string:complex-quoted:0" ctype="underline">underline</g>, <g id="string:complex-quoted:1" ctype="italic">italic<g id="string:complex-quoted:2" ctype="bold">italicbold</g></g> End</source> - </trans-unit> - <trans-unit id="string:simple"> - <source>Simple</source> - </trans-unit> - <trans-unit id="array:0:simple"> - <source>Simple</source> - </trans-unit> - <trans-unit id="array:1:simple"> - <source>Simple</source> - </trans-unit> - <trans-unit id="string:simple-quoted"> - <source xml:space="preserve"> Quote</source> - <alt-trans> - <source xml:lang="en" xml:space="preserve"> OLD Quote</source> - <target xml:lang="xx"> OLD Ờũỡŧę</target> - </alt-trans> - </trans-unit> - </body> - </file> -</xliff> - diff --git a/tools/localize/testdata/res/values-zz-rZZ/strings.xml b/tools/localize/testdata/res/values-zz-rZZ/strings.xml deleted file mode 100644 index c2a783d..0000000 --- a/tools/localize/testdata/res/values-zz-rZZ/strings.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">AAAA</string> - <string name="previously_translated">CCC</string> -</resources> - - diff --git a/tools/localize/testdata/res/values/strings.xml b/tools/localize/testdata/res/values/strings.xml deleted file mode 100644 index 6a11e68..0000000 --- a/tools/localize/testdata/res/values/strings.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="changed_in_xx">aaa</string> - <string name="first_translation">bbb</string> - <string name="previously_translated">ccc</string> - <string name="new_string">ccc</string> - - <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string> - - <array name="growing_array"> - <!-- somebody wrote a comment! --> - <item>1-One</item> - <item>1-Two</item> - <item>1-Three</item> - <item>1-Four</item> - </array> - <array name="shrinking_array"> - <!-- somebody wrote a comment! --> - <item>2-One</item> - <item>2-Two</item> - <item>2-Three</item> - </array> - <array name="new_array"> - <!-- somebody wrote a comment! --> - <item>3-One</item> - <item>3-Two</item> - <item>3-Three</item> - </array> -</resources> diff --git a/tools/localize/testdata/strip_xliff.xliff b/tools/localize/testdata/strip_xliff.xliff deleted file mode 100644 index 9254cf2..0000000 --- a/tools/localize/testdata/strip_xliff.xliff +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" - version="1.2" - > - <file datatype="x-android-res" - original="//device/tools/localization/tests/res/values/strings.xml" - product-version="1.0" - date="08:10:54 12/07/07 PST" - source-language="en-US" - product-name="kila" - target-language="zz-ZZ" - build-num="32138" - > - <body> - - <trans-unit id="string:string-000-0"> - </trans-unit> - <trans-unit id="string:string-001-0"> - <alt-trans> - <source xml:lang="en" xml:space="preserve">source</source> - </alt-trans> - </trans-unit> - <trans-unit id="string:string-010-0"> - <alt-trans> - <target xml:lang="zz" xml:space="preserve">target</target> - </alt-trans> - </trans-unit> - <trans-unit id="string:string-011-0"> - <alt-trans> - <source xml:lang="en" xml:space="preserve">source</source> - <target xml:lang="zz" xml:space="preserve">target</target> - </alt-trans> - </trans-unit> - - <trans-unit id="string:string-100-1"> - <source xml:space="preserve">source</source> - </trans-unit> - <trans-unit id="string:string-101-1"> - <source xml:space="preserve">source</source> - <alt-trans> - <source xml:lang="en" xml:space="preserve">source</source> - </alt-trans> - </trans-unit> - <trans-unit id="string:string-110-1"> - <source xml:space="preserve">source</source> - <alt-trans> - <target xml:lang="zz" xml:space="preserve">target</target> - </alt-trans> - </trans-unit> - - <trans-unit id="string:string-111-0"> - <source xml:space="preserve">source</source> - <alt-trans> - <source xml:lang="en" xml:space="preserve">source</source> - <target xml:lang="zz" xml:space="preserve">target</target> - </alt-trans> - </trans-unit> - <trans-unit id="string:string-111-1"> - <source xml:space="preserve">source</source> - <alt-trans> - <source xml:lang="en" xml:space="preserve">alt-source</source> - <target xml:lang="zz" xml:space="preserve">target</target> - </alt-trans> - </trans-unit> - - </body> - </file> -</xliff> - - diff --git a/tools/localize/testdata/values/strings.xml b/tools/localize/testdata/values/strings.xml deleted file mode 100644 index 5e8d43d..0000000 --- a/tools/localize/testdata/values/strings.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="test1">Discard</string> - <!-- comment --> - <string name="test2">a<b>b<i>c</i></b>d</string> - <string name="test3">a<xliff:g a="b" xliff:a="asdf">bBb</xliff:g>C</string> - - <!-- Email address types from android.provider.Contacts --> - <array name="emailAddressTypes"> - <!-- somebody wrote a comment! --> - <item>Email</item> - <item>Home</item> - <item>Work</item> - <item>Other\u2026</item> - </array> -</resources> diff --git a/tools/localize/testdata/xliff1.xliff b/tools/localize/testdata/xliff1.xliff deleted file mode 100644 index 55a8d8e..0000000 --- a/tools/localize/testdata/xliff1.xliff +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" - version="1.2" - > - <file datatype="x-android-res" - original="//device/tools/localization/tests/res/values/strings.xml" - product-version="1.0" - date="08:10:54 12/07/07 PST" - source-language="en-US" - product-name="kila" - target-language="zz-ZZ" - build-num="32138" - > - <body> - <trans-unit id="string:complex"> - <source>First <g id="string:complex:0" ctype="underline">underline</g>, <g id="string:complex:1" ctype="italic">italic<g id="string:complex:2" ctype="bold">italicbold</g></g> End </source> - <target>Ḟịṙṩŧ , Ḛŋḋ </target> - </trans-unit> - <trans-unit id="string:complex-quoted"> - <source xml:space="preserve">First <g id="string:complex-quoted:0" ctype="underline">underline</g>, <g id="string:complex-quoted:1" ctype="italic">italic<g id="string:complex-quoted:2" ctype="bold">italicbold</g></g> End</source> - <target>Ḟịṙṩŧ , Ḛŋḋ</target> - </trans-unit> - <trans-unit id="string:simple"> - <source>Simple</source> - <target>Ṩịṃṕļę</target> - </trans-unit> - <trans-unit id="array:0:simple"> - <source>Simple</source> - <target>Ṩịṃṕļę</target> - </trans-unit> - <trans-unit id="array:1:simple"> - <source>Simple</source> - <target>Ṩịṃṕļę</target> - </trans-unit> - <trans-unit id="string:simple-quoted"> - <source xml:space="preserve"> Quote</source> - <target> Ờũỡŧę</target> - <alt-trans> - <source xml:lang="en" xml:space="preserve"> OLD Quote</source> - <target xml:lang="xx"> OLD Ờũỡŧę</target> - </alt-trans> - </trans-unit> - </body> - </file> -</xliff> - diff --git a/tools/localize/testdata/xml.xml b/tools/localize/testdata/xml.xml deleted file mode 100644 index ef930d0..0000000 --- a/tools/localize/testdata/xml.xml +++ /dev/null @@ -1,16 +0,0 @@ -<ASDF> - <a id="system" - old-cl="1" - new-cl="43019"> - <app dir="apps/common" /> - </a> - <a id="samples" - old-cl="1" - new-cl="43019">asdf - <app dir="samples/NotePad" /> - <app dir="samples/LunarLander" /> - <something>a<b>,</b>b </something> - <exact xml:space="preserve">a<b>,</b>b </exact> - </a> -</ASDF> - diff --git a/tools/localize/xmb.cpp b/tools/localize/xmb.cpp deleted file mode 100644 index 236705f..0000000 --- a/tools/localize/xmb.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "xmb.h" - -#include "file_utils.h" -#include "localize.h" -#include "ValuesFile.h" -#include "XMLHandler.h" -#include "XLIFFFile.h" - -#include <map> - -using namespace std; - -const char *const NS_MAP[] = { - "xml", XMLNS_XMLNS, - NULL, NULL -}; - -set<string> g_tags; - -static string -strip_newlines(const string& str) -{ - string res; - const size_t N = str.length(); - for (size_t i=0; i<N; i++) { - char c = str[i]; - if (c != '\n' && c != '\r') { - res += c; - } else { - res += ' '; - } - } - return res; -} - -static int -rename_id_attribute(XMLNode* node) -{ - vector<XMLAttribute>& attrs = node->EditAttributes(); - const size_t I = attrs.size(); - for (size_t i=0; i<I; i++) { - XMLAttribute attr = attrs[i]; - if (attr.name == "id") { - attr.name = "name"; - attrs.erase(attrs.begin()+i); - attrs.push_back(attr); - return 0; - } - } - return 1; -} - -static int -convert_xliff_to_ph(XMLNode* node, int* phID) -{ - int err = 0; - if (node->Type() == XMLNode::ELEMENT) { - if (node->Namespace() == XLIFF_XMLNS) { - g_tags.insert(node->Name()); - node->SetName("", "ph"); - - err = rename_id_attribute(node); - if (err != 0) { - char name[30]; - (*phID)++; - sprintf(name, "id-%d", *phID); - node->EditAttributes().push_back(XMLAttribute("", "name", name)); - err = 0; - } - } - vector<XMLNode*>& children = node->EditChildren(); - const size_t I = children.size(); - for (size_t i=0; i<I; i++) { - err |= convert_xliff_to_ph(children[i], phID); - } - } - return err; -} - -XMLNode* -resource_to_xmb_msg(const StringResource& res) -{ - // the msg element - vector<XMLAttribute> attrs; - string name = res.pos.file; - name += ":"; - name += res.TypedID(); - attrs.push_back(XMLAttribute("", "name", name)); - attrs.push_back(XMLAttribute("", "desc", strip_newlines(res.comment))); - attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve")); - XMLNode* msg = XMLNode::NewElement(res.pos, "", "msg", attrs, XMLNode::EXACT); - - // the contents are in xliff/html, convert it to xliff - int err = 0; - XMLNode* value = res.value; - string tag = value->Name(); - int phID = 0; - for (vector<XMLNode*>::const_iterator it=value->Children().begin(); - it!=value->Children().end(); it++) { - err |= convert_html_to_xliff(*it, tag, msg, &phID); - } - - if (err != 0) { - return NULL; - } - - // and then convert that to xmb - for (vector<XMLNode*>::iterator it=msg->EditChildren().begin(); - it!=msg->EditChildren().end(); it++) { - err |= convert_xliff_to_ph(*it, &phID); - } - - if (err == 0) { - return msg; - } else { - return NULL; - } -} - -int -do_xlb_export(const string& outfile, const vector<string>& resFiles) -{ - int err = 0; - - size_t totalFileCount = resFiles.size(); - - Configuration english; - english.locale = "en_US"; - - set<StringResource> allResources; - - const size_t J = resFiles.size(); - for (size_t j=0; j<J; j++) { - string resFile = resFiles[j]; - - ValuesFile* valuesFile = get_local_values_file(resFile, english, CURRENT_VERSION, "", true); - if (valuesFile != NULL) { - set<StringResource> resources = valuesFile->GetStrings(); - allResources.insert(resources.begin(), resources.end()); - } else { - fprintf(stderr, "error reading file %s\n", resFile.c_str()); - } - - delete valuesFile; - } - - // Construct the XLB xml - vector<XMLAttribute> attrs; - attrs.push_back(XMLAttribute("", "locale", "en")); - XMLNode* localizationbundle = XMLNode::NewElement(GENERATED_POS, "", "localizationbundle", - attrs, XMLNode::PRETTY); - - for (set<StringResource>::iterator it=allResources.begin(); it!=allResources.end(); it++) { - XMLNode* msg = resource_to_xmb_msg(*it); - if (msg) { - localizationbundle->EditChildren().push_back(msg); - } else { - err = 1; - } - } - -#if 0 - for (set<string>::iterator it=g_tags.begin(); it!=g_tags.end(); it++) { - printf("tag: %s\n", it->c_str()); - } - printf("err=%d\n", err); -#endif - if (err == 0) { - FILE* f = fopen(outfile.c_str(), "wb"); - if (f == NULL) { - fprintf(stderr, "can't open outputfile: %s\n", outfile.c_str()); - return 1; - } - fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - fprintf(f, "%s\n", localizationbundle->ToString(NS_MAP).c_str()); - fclose(f); - } - - return err; -} - diff --git a/tools/localize/xmb.h b/tools/localize/xmb.h deleted file mode 100644 index 96492b1..0000000 --- a/tools/localize/xmb.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef XMB_H -#define XMB_H - -#include <string> -#include <vector> - -using namespace std; - -int do_xlb_export(const string& outFile, const vector<string>& resFiles); - -#endif // XMB_H diff --git a/tools/makekeycodes/Android.mk b/tools/makekeycodes/Android.mk deleted file mode 100644 index 401d44e..0000000 --- a/tools/makekeycodes/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2005 The Android Open Source Project - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - makekeycodes.cpp - -LOCAL_MODULE := makekeycodes - -include $(BUILD_HOST_EXECUTABLE) - - diff --git a/tools/makekeycodes/makekeycodes.cpp b/tools/makekeycodes/makekeycodes.cpp deleted file mode 100644 index 16df774..0000000 --- a/tools/makekeycodes/makekeycodes.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include <stdio.h> -#include <ui/KeycodeLabels.h> - -int -main(int argc, char** argv) -{ - // TODO: Add full copyright. - printf("// Copyright (C) 2008 The Android Open Source Project\n"); - printf("//\n"); - printf("// This file is generated by makekeycodes from the definitions.\n"); - printf("// in includes/ui/KeycodeLabels.h.\n"); - printf("//\n"); - printf("// If you modify this, your changes will be overwritten.\n"); - printf("\n"); - printf("pacakge android.os;\n"); - printf("\n"); - printf("public class KeyEvent\n"); - printf("{\n"); - - for (int i=0; KEYCODES[i].literal != NULL; i++) { - printf(" public static final int KEYCODE_%s = 0x%08x;\n", - KEYCODES[i].literal, KEYCODES[i].value); - } - - printf("\n"); - for (int i=0; FLAGS[i].literal != NULL; i++) { - printf(" public static final int MODIFIER_%s = 0x%08x;\n", - FLAGS[i].literal, FLAGS[i].value); - } - - printf("}\n"); - return 0; -} diff --git a/tools/preload/20080522.compiled b/tools/preload/20080522.compiled Binary files differdeleted file mode 100644 index a2af422..0000000 --- a/tools/preload/20080522.compiled +++ /dev/null diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk deleted file mode 100644 index d3457fe..0000000 --- a/tools/preload/Android.mk +++ /dev/null @@ -1,11 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := *.java - -LOCAL_MODULE:= preload - -include $(BUILD_HOST_JAVA_LIBRARY) - -include $(call all-subdir-makefiles) diff --git a/tools/preload/ClassRank.java b/tools/preload/ClassRank.java deleted file mode 100644 index 3699b89..0000000 --- a/tools/preload/ClassRank.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Comparator; - -/** - * Ranks classes for preloading based on how long their operations took - * and how early the operations happened. Higher ranked classes come first. - */ -class ClassRank implements Comparator<Operation> { - - /** - * Increase this number to add more weight to classes which were loaded - * earlier. - */ - static final int SEQUENCE_WEIGHT = 500; // 5 ms - - static final int BUCKET_SIZE = 5; - - public int compare(Operation a, Operation b) { - // Higher ranked operations should come first. - int result = rankOf(b) - rankOf(a); - if (result != 0) { - return result; - } - - // Make sure we don't drop one of two classes w/ the same rank. - // If a load and an initialization have the same rank, it's OK - // to treat the operations equally. - return a.loadedClass.name.compareTo(b.loadedClass.name); - } - - /** Ranks the given operation. */ - private static int rankOf(Operation o) { - return o.medianExclusiveTimeMicros() - + SEQUENCE_WEIGHT / (o.index / BUCKET_SIZE + 1); - } -} - - diff --git a/tools/preload/Compile.java b/tools/preload/Compile.java deleted file mode 100644 index 67258ef..0000000 --- a/tools/preload/Compile.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -/** - * Parses and analyzes a log, pulling our PRELOAD information. If you have - * an emulator or device running in the background, this class will use it - * to measure and record the memory usage of each class. - * - * TODO: Should analyze lines and select substring dynamically (instead of hardcoded 19) - */ -public class Compile { - - public static void main(String[] args) throws IOException { - if (args.length != 2) { - System.err.println("Usage: Compile [log file] [output file]"); - System.exit(0); - } - - Root root = new Root(); - - List<Record> records = new ArrayList<Record>(); - - BufferedReader in = new BufferedReader(new InputStreamReader( - new FileInputStream(args[0]))); - - String line; - int lineNumber = 0; - while ((line = in.readLine()) != null) { - lineNumber++; - if (line.startsWith("I/PRELOAD")) { - try { - String clipped = line.substring(19); - records.add(new Record(clipped, lineNumber)); - } catch (RuntimeException e) { - throw new RuntimeException( - "Exception while recording line " + lineNumber + ": " + line, e); - } - } - } - - for (Record record : records) { - root.indexProcess(record); - } - - for (Record record : records) { - root.indexClassOperation(record); - } - - in.close(); - - root.toFile(args[1]); - } -} diff --git a/tools/preload/LoadedClass.java b/tools/preload/LoadedClass.java deleted file mode 100644 index 5782807..0000000 --- a/tools/preload/LoadedClass.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -/** - * A loaded class. - */ -class LoadedClass implements Serializable, Comparable<LoadedClass> { - - private static final long serialVersionUID = 0; - - /** Class name. */ - final String name; - - /** Load operations. */ - final List<Operation> loads = new ArrayList<Operation>(); - - /** Static initialization operations. */ - final List<Operation> initializations = new ArrayList<Operation>(); - - /** Memory usage gathered by loading only this class in its own VM. */ - MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE; - - /** - * Whether or not this class was loaded in the system class loader. - */ - final boolean systemClass; - - /** Whether or not this class will be preloaded. */ - boolean preloaded; - - /** Constructs a new class. */ - LoadedClass(String name, boolean systemClass) { - this.name = name; - this.systemClass = systemClass; - } - - void measureMemoryUsage() { - this.memoryUsage = MemoryUsage.forClass(name); - } - - int mlt = -1; - - /** Median time to load this class. */ - int medianLoadTimeMicros() { - if (mlt != -1) { - return mlt; - } - - return mlt = calculateMedian(loads); - } - - int mit = -1; - - /** Median time to initialize this class. */ - int medianInitTimeMicros() { - if (mit != -1) { - return mit; - } - - return mit = calculateMedian(initializations); - } - - /** Calculates the median duration for a list of operations. */ - private static int calculateMedian(List<Operation> operations) { - int size = operations.size(); - if (size == 0) { - return 0; - } - - int[] times = new int[size]; - for (int i = 0; i < size; i++) { - times[i] = operations.get(i).exclusiveTimeMicros(); - } - - Arrays.sort(times); - int middle = size / 2; - if (size % 2 == 1) { - // Odd - return times[middle]; - } else { - // Even -- average the two. - return (times[middle - 1] + times[middle]) / 2; - } - } - - /** - * Counts loads by apps. - */ - int appLoads() { - return operationsByApps(loads); - } - - /** - * Counts inits by apps. - */ - int appInits() { - return operationsByApps(initializations); - } - - /** - * Counts number of app operations in the given list. - */ - private static int operationsByApps(List<Operation> operations) { - int byApps = 0; - for (Operation operation : operations) { - if (operation.process.isApplication()) { - byApps++; - } - } - return byApps; - } - - public int compareTo(LoadedClass o) { - return name.compareTo(o.name); - } - - @Override - public String toString() { - return name; - } - - /** - * Returns true if this class's initialization causes the given class to - * initialize. - */ - public boolean initializes(LoadedClass clazz, Set<LoadedClass> visited) { - // Avoid infinite recursion. - if (!visited.add(this)) { - return false; - } - - if (clazz == this) { - return true; - } - - for (Operation initialization : initializations) { - if (initialization.loadedClass.initializes(clazz, visited)) { - return true; - } - } - - return false; - } -} diff --git a/tools/preload/MemoryUsage.java b/tools/preload/MemoryUsage.java deleted file mode 100644 index e5dfb2a..0000000 --- a/tools/preload/MemoryUsage.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.Serializable; -import java.io.IOException; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Memory usage information. - */ -class MemoryUsage implements Serializable { - - private static final long serialVersionUID = 0; - - static final MemoryUsage NOT_AVAILABLE = new MemoryUsage(); - - static int errorCount = 0; - static final int MAXIMUM_ERRORS = 10; // give up after this many fails - - final int nativeSharedPages; - final int javaSharedPages; - final int otherSharedPages; - final int nativePrivatePages; - final int javaPrivatePages; - final int otherPrivatePages; - - final int allocCount; - final int allocSize; - final int freedCount; - final int freedSize; - final long nativeHeapSize; - - public MemoryUsage(String line) { - String[] parsed = line.split(","); - - nativeSharedPages = Integer.parseInt(parsed[1]); - javaSharedPages = Integer.parseInt(parsed[2]); - otherSharedPages = Integer.parseInt(parsed[3]); - nativePrivatePages = Integer.parseInt(parsed[4]); - javaPrivatePages = Integer.parseInt(parsed[5]); - otherPrivatePages = Integer.parseInt(parsed[6]); - allocCount = Integer.parseInt(parsed[7]); - allocSize = Integer.parseInt(parsed[8]); - freedCount = Integer.parseInt(parsed[9]); - freedSize = Integer.parseInt(parsed[10]); - nativeHeapSize = Long.parseLong(parsed[11]); - } - - MemoryUsage() { - nativeSharedPages = -1; - javaSharedPages = -1; - otherSharedPages = -1; - nativePrivatePages = -1; - javaPrivatePages = -1; - otherPrivatePages = -1; - - allocCount = -1; - allocSize = -1; - freedCount = -1; - freedSize = -1; - nativeHeapSize = -1; - } - - MemoryUsage(int nativeSharedPages, - int javaSharedPages, - int otherSharedPages, - int nativePrivatePages, - int javaPrivatePages, - int otherPrivatePages, - int allocCount, - int allocSize, - int freedCount, - int freedSize, - long nativeHeapSize) { - this.nativeSharedPages = nativeSharedPages; - this.javaSharedPages = javaSharedPages; - this.otherSharedPages = otherSharedPages; - this.nativePrivatePages = nativePrivatePages; - this.javaPrivatePages = javaPrivatePages; - this.otherPrivatePages = otherPrivatePages; - this.allocCount = allocCount; - this.allocSize = allocSize; - this.freedCount = freedCount; - this.freedSize = freedSize; - this.nativeHeapSize = nativeHeapSize; - } - - MemoryUsage subtract(MemoryUsage baseline) { - return new MemoryUsage( - nativeSharedPages - baseline.nativeSharedPages, - javaSharedPages - baseline.javaSharedPages, - otherSharedPages - baseline.otherSharedPages, - nativePrivatePages - baseline.nativePrivatePages, - javaPrivatePages - baseline.javaPrivatePages, - otherPrivatePages - baseline.otherPrivatePages, - allocCount - baseline.allocCount, - allocSize - baseline.allocSize, - freedCount - baseline.freedCount, - freedSize - baseline.freedSize, - nativeHeapSize - baseline.nativeHeapSize); - } - - int javaHeapSize() { - return allocSize - freedSize; - } - - int javaPagesInK() { - return (javaSharedPages + javaPrivatePages) * 4; - } - - int nativePagesInK() { - return (nativeSharedPages + nativePrivatePages) * 4; - } - int otherPagesInK() { - return (otherSharedPages + otherPrivatePages) * 4; - } - - /** - * Was this information available? - */ - boolean isAvailable() { - return nativeSharedPages != -1; - } - - /** - * Measures baseline memory usage. - */ - static MemoryUsage baseline() { - return forClass(null); - } - - private static final String CLASS_PATH = "-Xbootclasspath" - + ":/system/framework/core.jar" - + ":/system/framework/ext.jar" - + ":/system/framework/framework.jar" - + ":/system/framework/framework-tests.jar" - + ":/system/framework/services.jar" - + ":/system/framework/loadclass.jar"; - - private static final String[] GET_DIRTY_PAGES = { - "adb", "-e", "shell", "dalvikvm", CLASS_PATH, "LoadClass" }; - - /** - * Measures memory usage for the given class. - */ - static MemoryUsage forClass(String className) { - - // This is a coarse approximation for determining that no device is connected, - // or that the communication protocol has changed, but we'll keep going and stop whining. - if (errorCount >= MAXIMUM_ERRORS) { - return NOT_AVAILABLE; - } - - MeasureWithTimeout measurer = new MeasureWithTimeout(className); - - new Thread(measurer).start(); - - synchronized (measurer) { - if (measurer.memoryUsage == null) { - // Wait up to 10s. - try { - measurer.wait(30000); - } catch (InterruptedException e) { - System.err.println("Interrupted waiting for measurement."); - e.printStackTrace(); - return NOT_AVAILABLE; - } - - // If it's still null. - if (measurer.memoryUsage == null) { - System.err.println("Timed out while measuring " - + className + "."); - return NOT_AVAILABLE; - } - } - - System.err.println("Got memory usage for " + className + "."); - return measurer.memoryUsage; - } - } - - static class MeasureWithTimeout implements Runnable { - - final String className; - MemoryUsage memoryUsage = null; - - MeasureWithTimeout(String className) { - this.className = className; - } - - public void run() { - MemoryUsage measured = measure(); - - synchronized (this) { - memoryUsage = measured; - notifyAll(); - } - } - - private MemoryUsage measure() { - String[] commands = GET_DIRTY_PAGES; - if (className != null) { - List<String> commandList = new ArrayList<String>( - GET_DIRTY_PAGES.length + 1); - commandList.addAll(Arrays.asList(commands)); - commandList.add(className); - commands = commandList.toArray(new String[commandList.size()]); - } - - try { - final Process process = Runtime.getRuntime().exec(commands); - - final InputStream err = process.getErrorStream(); - - // Send error output to stderr. - Thread errThread = new Thread() { - @Override - public void run() { - copy(err, System.err); - } - }; - errThread.setDaemon(true); - errThread.start(); - - BufferedReader in = new BufferedReader( - new InputStreamReader(process.getInputStream())); - String line = in.readLine(); - if (line == null || !line.startsWith("DECAFBAD,")) { - System.err.println("Got bad response for " + className - + ": " + line); - errorCount += 1; - return NOT_AVAILABLE; - } - - in.close(); - err.close(); - process.destroy(); - - return new MemoryUsage(line); - } catch (IOException e) { - System.err.println("Error getting stats for " - + className + "."); - e.printStackTrace(); - return NOT_AVAILABLE; - } - } - - } - - /** - * Copies from one stream to another. - */ - private static void copy(InputStream in, OutputStream out) { - byte[] buffer = new byte[1024]; - int read; - try { - while ((read = in.read(buffer)) > -1) { - out.write(buffer, 0, read); - } - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/tools/preload/Operation.java b/tools/preload/Operation.java deleted file mode 100644 index 4f1938e..0000000 --- a/tools/preload/Operation.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.List; -import java.util.ArrayList; -import java.io.Serializable; - -/** - * An operation with a duration. Could represent a class load or initialization. - */ -class Operation implements Serializable { - - private static final long serialVersionUID = 0; - - /** - * Type of operation. - */ - enum Type { - LOAD, INIT - } - - /** Process this operation occurred in. */ - final Proc process; - - /** Start time for this operation. */ - final long startTimeNanos; - - /** Index of this operation relative to its process. */ - final int index; - - /** Type of operation. */ - final Type type; - - /** End time for this operation. */ - long endTimeNanos = -1; - - /** The class that this operation loaded or initialized. */ - final LoadedClass loadedClass; - - /** Other operations that occurred during this one. */ - final List<Operation> subops = new ArrayList<Operation>(); - - /** Constructs a new operation. */ - Operation(Proc process, LoadedClass loadedClass, long startTimeNanos, - int index, Type type) { - this.process = process; - this.loadedClass = loadedClass; - this.startTimeNanos = startTimeNanos; - this.index = index; - this.type = type; - } - - /** - * Returns how long this class initialization and all the nested class - * initializations took. - */ - private long inclusiveTimeNanos() { - if (endTimeNanos == -1) { - throw new IllegalStateException("End time hasn't been set yet: " - + loadedClass.name); - } - - return endTimeNanos - startTimeNanos; - } - - /** - * Returns how long this class initialization took. - */ - int exclusiveTimeMicros() { - long exclusive = inclusiveTimeNanos(); - - for (Operation child : subops) { - exclusive -= child.inclusiveTimeNanos(); - } - - if (exclusive < 0) { - throw new AssertionError(loadedClass.name); - } - - return nanosToMicros(exclusive); - } - - /** Gets the median time that this operation took across all processes. */ - int medianExclusiveTimeMicros() { - switch (type) { - case LOAD: return loadedClass.medianLoadTimeMicros(); - case INIT: return loadedClass.medianInitTimeMicros(); - default: throw new AssertionError(); - } - } - - /** - * Converts nanoseconds to microseconds. - * - * @throws RuntimeException if overflow occurs - */ - private static int nanosToMicros(long nanos) { - long micros = nanos / 1000; - int microsInt = (int) micros; - if (microsInt != micros) { - throw new RuntimeException("Integer overflow: " + nanos); - } - return microsInt; - } - - /** - * Primarily for debugger support - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(type.toString()); - sb.append(' '); - sb.append(loadedClass.toString()); - if (subops.size() > 0) { - sb.append(" ("); - sb.append(subops.size()); - sb.append(" sub ops)"); - } - return sb.toString(); - } - -} diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java deleted file mode 100644 index 554966b..0000000 --- a/tools/preload/Policy.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * This is not instantiated - we just provide data for other classes to use - */ -public class Policy { - - /** - * This location (in the build system) of the preloaded-classes file. - */ - private static final String PRELOADED_CLASS_FILE = "frameworks/base/preloaded-classes"; - - /** - * The internal process name of the system process. Note, this also shows up as - * "system_process", e.g. in ddms. - */ - private static final String SYSTEM_SERVER_PROCESS_NAME = "system_server"; - - /** - * Names of non-application processes - these will not be checked for preloaded classes. - * - * TODO: Replace this hardcoded list with a walk up the parent chain looking for zygote. - */ - private static final Set<String> NOT_FROM_ZYGOTE = new HashSet<String>(Arrays.asList( - "zygote", - "dexopt", - "unknown", - SYSTEM_SERVER_PROCESS_NAME, - "com.android.development", - "app_process" // am & other shell commands - )); - - /** - * Long running services. These are restricted in their contribution to the preloader - * because their launch time is less critical. - */ - private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList( - SYSTEM_SERVER_PROCESS_NAME, - "com.android.acore", - // Commented out to make sure DefaultTimeZones gets preloaded. - // "com.android.phone", - "com.google.process.content", - "android.process.media" - )); - - /** - * Classes which we shouldn't load from the Zygote. - */ - private static final Set<String> EXCLUDED_CLASSES = new HashSet<String>(Arrays.asList( - // Binders - "android.app.AlarmManager", - "android.app.SearchManager", - "android.os.FileObserver", - "com.android.server.PackageManagerService$AppDirObserver", - - // Threads - "android.os.AsyncTask", - "android.pim.ContactsAsyncHelper", - "java.lang.ProcessManager" - - )); - - /** - * No constructor - use static methods only - */ - private Policy() {} - - /** - * Returns the path/file name of the preloaded classes file that will be written - * by WritePreloadedClassFile. - */ - public static String getPreloadedClassFileName() { - return PRELOADED_CLASS_FILE; - } - - /** - * Reports if a given process name was created from zygote - */ - public static boolean isFromZygote(String processName) { - return !NOT_FROM_ZYGOTE.contains(processName); - } - - /** - * Reports if the given process name is a "long running" process or service - */ - public static boolean isService(String processName) { - return SERVICES.contains(processName); - } - - /** - * Reports if the given class should never be preloaded - */ - public static boolean isPreloadableClass(String className) { - return !EXCLUDED_CLASSES.contains(className); - } -} diff --git a/tools/preload/PrintCsv.java b/tools/preload/PrintCsv.java deleted file mode 100644 index 9f2a318..0000000 --- a/tools/preload/PrintCsv.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.IOException; -import java.io.FileInputStream; -import java.io.ObjectInputStream; -import java.io.BufferedInputStream; - -/** - * Prints raw information in CSV format. - */ -public class PrintCsv { - - public static void main(String[] args) - throws IOException, ClassNotFoundException { - if (args.length != 1) { - System.err.println("Usage: PrintCsv [compiled log file]"); - System.exit(0); - } - - Root root = Root.fromFile(args[0]); - - System.out.println("Name" - + ",Preloaded" - + ",Median Load Time (us)" - + ",Median Init Time (us)" - + ",Load Count" - + ",Init Count" - + ",Managed Heap (B)" - + ",Native Heap (B)" - + ",Managed Pages (kB)" - + ",Native Pages (kB)" - + ",Other Pages (kB)"); - - MemoryUsage baseline = root.baseline; - - for (LoadedClass loadedClass : root.loadedClasses.values()) { - if (!loadedClass.systemClass) { - continue; - } - - System.out.print(loadedClass.name); - System.out.print(','); - System.out.print(loadedClass.preloaded); - System.out.print(','); - System.out.print(loadedClass.medianLoadTimeMicros()); - System.out.print(','); - System.out.print(loadedClass.medianInitTimeMicros()); - System.out.print(','); - System.out.print(loadedClass.loads.size()); - System.out.print(','); - System.out.print(loadedClass.initializations.size()); - - if (loadedClass.memoryUsage.isAvailable()) { - MemoryUsage subtracted - = loadedClass.memoryUsage.subtract(baseline); - - System.out.print(','); - System.out.print(subtracted.javaHeapSize()); - System.out.print(','); - System.out.print(subtracted.nativeHeapSize); - System.out.print(','); - System.out.print(subtracted.javaPagesInK()); - System.out.print(','); - System.out.print(subtracted.nativePagesInK()); - System.out.print(','); - System.out.print(subtracted.otherPagesInK()); - - } else { - System.out.print(",n/a,n/a,n/a,n/a,n/a"); - } - - System.out.println(); - } - } -} diff --git a/tools/preload/PrintPsTree.java b/tools/preload/PrintPsTree.java deleted file mode 100644 index 22701fa..0000000 --- a/tools/preload/PrintPsTree.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.IOException; -import java.io.FileInputStream; -import java.io.ObjectInputStream; -import java.io.BufferedInputStream; - -/** - * Prints raw information in CSV format. - */ -public class PrintPsTree { - - public static void main(String[] args) - throws IOException, ClassNotFoundException { - if (args.length != 1) { - System.err.println("Usage: PrintCsv [compiled log file]"); - System.exit(0); - } - - FileInputStream fin = new FileInputStream(args[0]); - ObjectInputStream oin = new ObjectInputStream( - new BufferedInputStream(fin)); - - Root root = (Root) oin.readObject(); - - for (Proc proc : root.processes.values()) { - if (proc.parent == null) { - proc.print(); - } - } - } -} diff --git a/tools/preload/Proc.java b/tools/preload/Proc.java deleted file mode 100644 index 22697f8..0000000 --- a/tools/preload/Proc.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Set; -import java.util.HashSet; -import java.util.Arrays; -import java.util.List; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Map; -import java.util.HashMap; -import java.util.Collections; -import java.util.TreeSet; -import java.io.Serializable; - -/** - * A Dalvik process. - */ -class Proc implements Serializable { - - private static final long serialVersionUID = 0; - - /** - * Default percentage of time to cut off of app class loading times. - */ - static final int PERCENTAGE_TO_PRELOAD = 75; - - /** - * Maximum number of classes to preload for a given process. - */ - static final int MAX_TO_PRELOAD = 100; - - /** Parent process. */ - final Proc parent; - - /** Process ID. */ - final int id; - - /** - * Name of this process. We may not have the correct name at first, i.e. - * some classes could have been loaded before the process name was set. - */ - String name; - - /** Child processes. */ - final List<Proc> children = new ArrayList<Proc>(); - - /** Maps thread ID to operation stack. */ - transient final Map<Integer, LinkedList<Operation>> stacks - = new HashMap<Integer, LinkedList<Operation>>(); - - /** Number of operations. */ - int operationCount; - - /** Sequential list of operations that happened in this process. */ - final List<Operation> operations = new ArrayList<Operation>(); - - /** List of past process names. */ - final List<String> nameHistory = new ArrayList<String>(); - - /** Constructs a new process. */ - Proc(Proc parent, int id) { - this.parent = parent; - this.id = id; - } - - /** Sets name of this process. */ - void setName(String name) { - if (!name.equals(this.name)) { - if (this.name != null) { - nameHistory.add(this.name); - } - this.name = name; - } - } - - /** - * Returns the percentage of time we should cut by preloading for this - * app. - */ - int percentageToPreload() { - return PERCENTAGE_TO_PRELOAD; - } - - /** - * Returns a list of classes which should be preloaded. - * - * @param takeAllClasses forces all classes to be taken (irrespective of ranking) - */ - List<LoadedClass> highestRankedClasses(boolean takeAllClasses) { - if (!isApplication()) { - return Collections.emptyList(); - } - - // Sort by rank. - Operation[] ranked = new Operation[operations.size()]; - ranked = operations.toArray(ranked); - Arrays.sort(ranked, new ClassRank()); - - // The percentage of time to save by preloading. - int timeToSave = totalTimeMicros() * percentageToPreload() / 100; - int timeSaved = 0; - - boolean service = Policy.isService(this.name); - - List<LoadedClass> highest = new ArrayList<LoadedClass>(); - for (Operation operation : ranked) { - - // These are actual ranking decisions, which can be overridden - if (!takeAllClasses) { - if (highest.size() >= MAX_TO_PRELOAD) { - System.out.println(name + " got " - + (timeSaved * 100 / timeToSave) + "% through"); - break; - } - - if (timeSaved >= timeToSave) { - break; - } - } - - // The remaining rules apply even to wired-down processes - if (!Policy.isPreloadableClass(operation.loadedClass.name)) { - continue; - } - - if (!operation.loadedClass.systemClass) { - continue; - } - - // Only load java.* class for services. - if (!service || operation.loadedClass.name.startsWith("java.")) { - highest.add(operation.loadedClass); - } - - // For services, still count the time even if it's not in java.* - timeSaved += operation.medianExclusiveTimeMicros(); - } - - return highest; - } - - /** - * Total time spent class loading and initializing. - */ - int totalTimeMicros() { - int totalTime = 0; - for (Operation operation : operations) { - totalTime += operation.medianExclusiveTimeMicros(); - } - return totalTime; - } - - /** - * Returns true if this process is an app. - * - * TODO: Replace the hardcoded list with a walk up the parent chain looking for zygote. - */ - public boolean isApplication() { - return Policy.isFromZygote(name); - } - - /** - * Starts an operation. - * - * @param threadId thread the operation started in - * @param loadedClass class operation happened to - * @param time the operation started - */ - void startOperation(int threadId, LoadedClass loadedClass, long time, - Operation.Type type) { - Operation o = new Operation( - this, loadedClass, time, operationCount++, type); - operations.add(o); - - LinkedList<Operation> stack = stacks.get(threadId); - if (stack == null) { - stack = new LinkedList<Operation>(); - stacks.put(threadId, stack); - } - - if (!stack.isEmpty()) { - stack.getLast().subops.add(o); - } - - stack.add(o); - } - - /** - * Ends an operation. - * - * @param threadId thread the operation ended in - * @param loadedClass class operation happened to - * @param time the operation ended - */ - Operation endOperation(int threadId, String className, - LoadedClass loadedClass, long time) { - LinkedList<Operation> stack = stacks.get(threadId); - - if (stack == null || stack.isEmpty()) { - didNotStart(className); - return null; - } - - Operation o = stack.getLast(); - if (loadedClass != o.loadedClass) { - didNotStart(className); - return null; - } - - stack.removeLast(); - - o.endTimeNanos = time; - return o; - } - - /** - * Prints an error indicating that we saw the end of an operation but not - * the start. A bug in the logging framework which results in dropped logs - * causes this. - */ - private static void didNotStart(String name) { - System.err.println("Warning: An operation ended on " + name - + " but it never started!"); - } - - /** - * Prints this process tree to stdout. - */ - void print() { - print(""); - } - - /** - * Prints a child proc to standard out. - */ - private void print(String prefix) { - System.out.println(prefix + "id=" + id + ", name=" + name); - for (Proc child : children) { - child.print(prefix + " "); - } - } - - @Override - public String toString() { - return this.name; - } -} diff --git a/tools/preload/Record.java b/tools/preload/Record.java deleted file mode 100644 index b2be4d4..0000000 --- a/tools/preload/Record.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * One line from the loaded-classes file. - */ -class Record { - - enum Type { - /** Start of initialization. */ - START_LOAD, - - /** End of initialization. */ - END_LOAD, - - /** Start of initialization. */ - START_INIT, - - /** End of initialization. */ - END_INIT - } - - /** Parent process ID. */ - final int ppid; - - /** Process ID. */ - final int pid; - - /** Thread ID. */ - final int tid; - - /** Process name. */ - final String processName; - - /** Class loader pointer. */ - final int classLoader; - - /** Type of record. */ - final Type type; - - /** Name of loaded class. */ - final String className; - - /** Record time (ns). */ - final long time; - - /** Source file line# */ - int sourceLineNumber; - - /** - * Parses a line from the loaded-classes file. - */ - Record(String line, int lineNum) { - char typeChar = line.charAt(0); - switch (typeChar) { - case '>': type = Type.START_LOAD; break; - case '<': type = Type.END_LOAD; break; - case '+': type = Type.START_INIT; break; - case '-': type = Type.END_INIT; break; - default: throw new AssertionError("Bad line: " + line); - } - - sourceLineNumber = lineNum; - - line = line.substring(1); - String[] parts = line.split(":"); - - ppid = Integer.parseInt(parts[0]); - pid = Integer.parseInt(parts[1]); - tid = Integer.parseInt(parts[2]); - - processName = decode(parts[3]).intern(); - - classLoader = Integer.parseInt(parts[4]); - className = vmTypeToLanguage(decode(parts[5])).intern(); - - time = Long.parseLong(parts[6]); - } - - /** - * Decode any escaping that may have been written to the log line. - * - * Supports unicode-style escaping: \\uXXXX = character in hex - * - * @param rawField the field as it was written into the log - * @result the same field with any escaped characters replaced - */ - String decode(String rawField) { - String result = rawField; - int offset = result.indexOf("\\u"); - while (offset >= 0) { - String before = result.substring(0, offset); - String escaped = result.substring(offset+2, offset+6); - String after = result.substring(offset+6); - - result = String.format("%s%c%s", before, Integer.parseInt(escaped, 16), after); - - // find another but don't recurse - offset = result.indexOf("\\u", offset + 1); - } - return result; - } - - /** - * Converts a VM-style name to a language-style name. - */ - String vmTypeToLanguage(String typeName) { - // if the typename is (null), just return it as-is. This is probably in dexopt and - // will be discarded anyway. NOTE: This corresponds to the case in dalvik/vm/oo/Class.c - // where dvmLinkClass() returns false and we clean up and exit. - if ("(null)".equals(typeName)) { - return typeName; - } - - if (!typeName.startsWith("L") || !typeName.endsWith(";") ) { - throw new AssertionError("Bad name: " + typeName + " in line " + sourceLineNumber); - } - - typeName = typeName.substring(1, typeName.length() - 1); - return typeName.replace("/", "."); - } -} diff --git a/tools/preload/Root.java b/tools/preload/Root.java deleted file mode 100644 index 949f9b7..0000000 --- a/tools/preload/Root.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.Serializable; -import java.io.IOException; -import java.io.Writer; -import java.io.BufferedWriter; -import java.io.OutputStreamWriter; -import java.io.FileOutputStream; -import java.io.FileInputStream; -import java.io.ObjectInputStream; -import java.io.BufferedInputStream; -import java.io.ObjectOutputStream; -import java.io.BufferedOutputStream; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.TreeSet; -import java.util.Arrays; -import java.nio.charset.Charset; - -/** - * Root of our data model. - */ -public class Root implements Serializable { - - private static final long serialVersionUID = 0; - - /** pid -> Proc */ - final Map<Integer, Proc> processes = new HashMap<Integer, Proc>(); - - /** Class name -> LoadedClass */ - final Map<String, LoadedClass> loadedClasses - = new HashMap<String, LoadedClass>(); - - final MemoryUsage baseline = MemoryUsage.baseline(); - - /** - * Records class loads and initializations. - */ - void indexClassOperation(Record record) { - Proc process = processes.get(record.pid); - - // Ignore dexopt output. It loads applications classes through the - // system class loader and messes us up. - if (record.processName.equals("dexopt")) { - return; - } - - String name = record.className; - LoadedClass loadedClass = loadedClasses.get(name); - Operation o = null; - - switch (record.type) { - case START_LOAD: - case START_INIT: - if (loadedClass == null) { - loadedClass = new LoadedClass( - name, record.classLoader == 0); - if (loadedClass.systemClass) { - // Only measure memory for classes in the boot - // classpath. - loadedClass.measureMemoryUsage(); - } - loadedClasses.put(name, loadedClass); - } - break; - - case END_LOAD: - case END_INIT: - o = process.endOperation(record.tid, record.className, - loadedClass, record.time); - if (o == null) { - return; - } - } - - switch (record.type) { - case START_LOAD: - process.startOperation(record.tid, loadedClass, record.time, - Operation.Type.LOAD); - break; - - case START_INIT: - process.startOperation(record.tid, loadedClass, record.time, - Operation.Type.INIT); - break; - - case END_LOAD: - loadedClass.loads.add(o); - break; - - case END_INIT: - loadedClass.initializations.add(o); - break; - } - } - - /** - * Indexes information about the process from the given record. - */ - void indexProcess(Record record) { - Proc proc = processes.get(record.pid); - - if (proc == null) { - // Create a new process object. - Proc parent = processes.get(record.ppid); - proc = new Proc(parent, record.pid); - processes.put(proc.id, proc); - if (parent != null) { - parent.children.add(proc); - } - } - - proc.setName(record.processName); - } - - /** - * Writes this graph to a file. - */ - void toFile(String fileName) throws IOException { - FileOutputStream out = new FileOutputStream(fileName); - ObjectOutputStream oout = new ObjectOutputStream( - new BufferedOutputStream(out)); - - System.err.println("Writing object model..."); - - oout.writeObject(this); - - oout.close(); - - System.err.println("Done!"); - } - - /** - * Reads Root from a file. - */ - static Root fromFile(String fileName) - throws IOException, ClassNotFoundException { - FileInputStream fin = new FileInputStream(fileName); - ObjectInputStream oin = new ObjectInputStream( - new BufferedInputStream(fin)); - - Root root = (Root) oin.readObject(); - - oin.close(); - - return root; - } -} diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java deleted file mode 100644 index d87b1f0..0000000 --- a/tools/preload/WritePreloadedClassFile.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.BufferedWriter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -/** - * Writes /frameworks/base/preloaded-classes. Also updates LoadedClass.preloaded - * fields and writes over compiled log file. - */ -public class WritePreloadedClassFile { - - public static void main(String[] args) throws IOException, ClassNotFoundException { - - // Process command-line arguments first - List<String> wiredProcesses = new ArrayList<String>(); - String inputFileName = null; - int argOffset = 0; - try { - while ("--preload-all-process".equals(args[argOffset])) { - argOffset++; - wiredProcesses.add(args[argOffset++]); - } - - inputFileName = args[argOffset++]; - } catch (RuntimeException e) { - System.err.println("Usage: WritePreloadedClassFile " + - "[--preload-all-process process-name] " + - "[compiled log file]"); - System.exit(0); - } - - Root root = Root.fromFile(inputFileName); - - for (LoadedClass loadedClass : root.loadedClasses.values()) { - loadedClass.preloaded = false; - } - - Writer out = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(Policy.getPreloadedClassFileName()), - Charset.forName("US-ASCII"))); - - out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n"); - out.write("# Automatically generated by /frameworks/base/tools/preload.\n"); - out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD + ", weight=" - + ClassRank.SEQUENCE_WEIGHT - + ", bucket_size=" + ClassRank.BUCKET_SIZE - + "\n"); - for (String wiredProcess : wiredProcesses) { - out.write("# forcing classes loaded by: " + wiredProcess + "\n"); - } - - Set<LoadedClass> highestRanked = new TreeSet<LoadedClass>(); - for (Proc proc : root.processes.values()) { - // test to see if this is one of the wired-down ("take all classes") processes - boolean isWired = wiredProcesses.contains(proc.name); - - List<LoadedClass> highestForProc = proc.highestRankedClasses(isWired); - - System.out.println(proc.name + ": " + highestForProc.size()); - - for (LoadedClass loadedClass : highestForProc) { - loadedClass.preloaded = true; - } - highestRanked.addAll(highestForProc); - } - - for (LoadedClass loadedClass : highestRanked) { - out.write(loadedClass.name); - out.write('\n'); - } - - out.close(); - - System.out.println(highestRanked.size() - + " classes will be preloaded."); - - // Update data to reflect LoadedClass.preloaded changes. - root.toFile(inputFileName); - } -} diff --git a/tools/preload/loadclass/Android.mk b/tools/preload/loadclass/Android.mk deleted file mode 100644 index 435699d..0000000 --- a/tools/preload/loadclass/Android.mk +++ /dev/null @@ -1,8 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_MODULE := loadclass - -include $(BUILD_JAVA_LIBRARY) diff --git a/tools/preload/loadclass/LoadClass.java b/tools/preload/loadclass/LoadClass.java deleted file mode 100644 index 471cc84..0000000 --- a/tools/preload/loadclass/LoadClass.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.util.Log; -import android.os.Debug; - -/** - * Loads a class, runs the garbage collector, and prints showmap output. - * - * <p>Usage: dalvikvm LoadClass [class name] - */ -class LoadClass { - - public static void main(String[] args) { - System.loadLibrary("android_runtime"); - - if (registerNatives() < 0) { - throw new RuntimeException("Error registering natives."); - } - - Debug.startAllocCounting(); - - if (args.length > 0) { - try { - Class.forName(args[0]); - } catch (ClassNotFoundException e) { - Log.w("LoadClass", e); - return; - } - } - - System.gc(); - - int allocCount = Debug.getGlobalAllocCount(); - int allocSize = Debug.getGlobalAllocSize(); - int freedCount = Debug.getGlobalFreedCount(); - int freedSize = Debug.getGlobalFreedSize(); - long nativeHeapSize = Debug.getNativeHeapSize(); - - Debug.stopAllocCounting(); - - StringBuilder response = new StringBuilder("DECAFBAD"); - - int[] pages = new int[6]; - Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo(); - Debug.getMemoryInfo(memoryInfo); - response.append(',').append(memoryInfo.nativeSharedDirty); - response.append(',').append(memoryInfo.dalvikSharedDirty); - response.append(',').append(memoryInfo.otherSharedDirty); - response.append(',').append(memoryInfo.nativePrivateDirty); - response.append(',').append(memoryInfo.dalvikPrivateDirty); - response.append(',').append(memoryInfo.otherPrivateDirty); - - response.append(',').append(allocCount); - response.append(',').append(allocSize); - response.append(',').append(freedCount); - response.append(',').append(freedSize); - response.append(',').append(nativeHeapSize); - - System.out.println(response.toString()); - } - - /** - * Registers native functions. See AndroidRuntime.cpp. - */ - static native int registerNatives(); -} diff --git a/tools/preload/preload.iml b/tools/preload/preload.iml deleted file mode 100644 index d1fab57..0000000 --- a/tools/preload/preload.iml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module relativePaths="true" type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="false"> - <output url="file:///tmp/preload/" /> - <exclude-output /> - <output-test url="file:///tmp/preload/" /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntryProperties /> - </component> -</module> - diff --git a/tools/preload/preload.ipr b/tools/preload/preload.ipr deleted file mode 100644 index c5613ad..0000000 --- a/tools/preload/preload.ipr +++ /dev/null @@ -1,467 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project relativePaths="false" version="4"> - <component name="AntConfiguration"> - <defaultAnt bundledAnt="true" /> - </component> - <component name="BuildJarProjectSettings"> - <option name="BUILD_JARS_ON_MAKE" value="false" /> - </component> - <component name="ChangeBrowserSettings"> - <option name="MAIN_SPLITTER_PROPORTION" value="0.3" /> - <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" /> - <option name="USE_DATE_BEFORE_FILTER" value="false" /> - <option name="USE_DATE_AFTER_FILTER" value="false" /> - <option name="USE_CHANGE_BEFORE_FILTER" value="false" /> - <option name="USE_CHANGE_AFTER_FILTER" value="false" /> - <option name="DATE_BEFORE" value="" /> - <option name="DATE_AFTER" value="" /> - <option name="CHANGE_BEFORE" value="" /> - <option name="CHANGE_AFTER" value="" /> - <option name="USE_USER_FILTER" value="false" /> - <option name="USER" value="" /> - </component> - <component name="CodeStyleProjectProfileManger"> - <option name="PROJECT_PROFILE" /> - <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> - </component> - <component name="CodeStyleSettingsManager"> - <option name="PER_PROJECT_SETTINGS" /> - <option name="USE_PER_PROJECT_SETTINGS" value="false" /> - </component> - <component name="CompilerConfiguration"> - <option name="DEFAULT_COMPILER" value="Javac" /> - <option name="DEPLOY_AFTER_MAKE" value="0" /> - <resourceExtensions> - <entry name=".+\.(properties|xml|html|dtd|tld)" /> - <entry name=".+\.(gif|png|jpeg|jpg)" /> - </resourceExtensions> - <wildcardResourcePatterns> - <entry name="?*.properties" /> - <entry name="?*.xml" /> - <entry name="?*.gif" /> - <entry name="?*.png" /> - <entry name="?*.jpeg" /> - <entry name="?*.jpg" /> - <entry name="?*.html" /> - <entry name="?*.dtd" /> - <entry name="?*.tld" /> - </wildcardResourcePatterns> - </component> - <component name="Cvs2Configuration"> - <option name="PRUNE_EMPTY_DIRECTORIES" value="true" /> - <option name="MERGING_MODE" value="0" /> - <option name="MERGE_WITH_BRANCH1_NAME" value="HEAD" /> - <option name="MERGE_WITH_BRANCH2_NAME" value="HEAD" /> - <option name="RESET_STICKY" value="false" /> - <option name="CREATE_NEW_DIRECTORIES" value="true" /> - <option name="DEFAULT_TEXT_FILE_SUBSTITUTION" value="kv" /> - <option name="PROCESS_UNKNOWN_FILES" value="false" /> - <option name="PROCESS_DELETED_FILES" value="false" /> - <option name="PROCESS_IGNORED_FILES" value="false" /> - <option name="RESERVED_EDIT" value="false" /> - <option name="CHECKOUT_DATE_OR_REVISION_SETTINGS"> - <value> - <option name="BRANCH" value="" /> - <option name="DATE" value="" /> - <option name="USE_BRANCH" value="false" /> - <option name="USE_DATE" value="false" /> - </value> - </option> - <option name="UPDATE_DATE_OR_REVISION_SETTINGS"> - <value> - <option name="BRANCH" value="" /> - <option name="DATE" value="" /> - <option name="USE_BRANCH" value="false" /> - <option name="USE_DATE" value="false" /> - </value> - </option> - <option name="SHOW_CHANGES_REVISION_SETTINGS"> - <value> - <option name="BRANCH" value="" /> - <option name="DATE" value="" /> - <option name="USE_BRANCH" value="false" /> - <option name="USE_DATE" value="false" /> - </value> - </option> - <option name="SHOW_OUTPUT" value="false" /> - <option name="ADD_WATCH_INDEX" value="0" /> - <option name="REMOVE_WATCH_INDEX" value="0" /> - <option name="UPDATE_KEYWORD_SUBSTITUTION" /> - <option name="MAKE_NEW_FILES_READONLY" value="false" /> - <option name="SHOW_CORRUPTED_PROJECT_FILES" value="0" /> - <option name="TAG_AFTER_PROJECT_COMMIT" value="false" /> - <option name="OVERRIDE_EXISTING_TAG_FOR_PROJECT" value="true" /> - <option name="TAG_AFTER_PROJECT_COMMIT_NAME" value="" /> - <option name="CLEAN_COPY" value="false" /> - </component> - <component name="DependenciesAnalyzeManager"> - <option name="myForwardDirection" value="false" /> - </component> - <component name="DependencyValidationManager"> - <option name="SKIP_IMPORT_STATEMENTS" value="false" /> - </component> - <component name="EclipseCompilerSettings"> - <option name="DEBUGGING_INFO" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="true" /> - <option name="DEPRECATION" value="false" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - <option name="MAXIMUM_HEAP_SIZE" value="128" /> - </component> - <component name="EclipseEmbeddedCompilerSettings"> - <option name="DEBUGGING_INFO" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="true" /> - <option name="DEPRECATION" value="false" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - <option name="MAXIMUM_HEAP_SIZE" value="128" /> - </component> - <component name="EntryPointsManager"> - <entry_points version="2.0" /> - </component> - <component name="ExportToHTMLSettings"> - <option name="PRINT_LINE_NUMBERS" value="false" /> - <option name="OPEN_IN_BROWSER" value="false" /> - <option name="OUTPUT_DIRECTORY" /> - </component> - <component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" /> - <component name="InspectionProjectProfileManager"> - <option name="PROJECT_PROFILE" value="Project Default" /> - <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> - <scopes /> - <profiles> - <profile version="1.0" is_locked="false"> - <option name="myName" value="Project Default" /> - <option name="myLocal" value="false" /> - <inspection_tool class="JavaDoc" level="WARNING" enabled="false"> - <option name="TOP_LEVEL_CLASS_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="INNER_CLASS_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="METHOD_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" /> - </value> - </option> - <option name="FIELD_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="IGNORE_DEPRECATED" value="false" /> - <option name="IGNORE_JAVADOC_PERIOD" value="true" /> - <option name="myAdditionalJavadocTags" value="" /> - </inspection_tool> - <inspection_tool class="OnDemandImport" level="WARNING" enabled="true" /> - <inspection_tool class="SamePackageImport" level="WARNING" enabled="true" /> - <inspection_tool class="JavaLangImport" level="WARNING" enabled="true" /> - <inspection_tool class="RedundantImport" level="WARNING" enabled="true" /> - <inspection_tool class="UnusedImport" level="WARNING" enabled="true" /> - </profile> - </profiles> - <list size="0" /> - </component> - <component name="JavacSettings"> - <option name="DEBUGGING_INFO" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="false" /> - <option name="DEPRECATION" value="true" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - <option name="MAXIMUM_HEAP_SIZE" value="128" /> - </component> - <component name="JavadocGenerationManager"> - <option name="OUTPUT_DIRECTORY" /> - <option name="OPTION_SCOPE" value="protected" /> - <option name="OPTION_HIERARCHY" value="true" /> - <option name="OPTION_NAVIGATOR" value="true" /> - <option name="OPTION_INDEX" value="true" /> - <option name="OPTION_SEPARATE_INDEX" value="true" /> - <option name="OPTION_DOCUMENT_TAG_USE" value="false" /> - <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" /> - <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" /> - <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" /> - <option name="OPTION_DEPRECATED_LIST" value="true" /> - <option name="OTHER_OPTIONS" value="" /> - <option name="HEAP_SIZE" /> - <option name="LOCALE" /> - <option name="OPEN_IN_BROWSER" value="true" /> - </component> - <component name="JikesSettings"> - <option name="JIKES_PATH" value="" /> - <option name="DEBUGGING_INFO" value="true" /> - <option name="DEPRECATION" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="false" /> - <option name="IS_EMACS_ERRORS_MODE" value="true" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - </component> - <component name="LogConsolePreferences"> - <option name="FILTER_ERRORS" value="false" /> - <option name="FILTER_WARNINGS" value="false" /> - <option name="FILTER_INFO" value="true" /> - <option name="CUSTOM_FILTER" /> - </component> - <component name="Palette2"> - <group name="Swing"> - <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> - </item> - <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> - </item> - <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> - <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> - <initial-values> - <property name="text" value="Button" /> - </initial-values> - </item> - <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="RadioButton" /> - </initial-values> - </item> - <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="CheckBox" /> - </initial-values> - </item> - <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="Label" /> - </initial-values> - </item> - <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> - <preferred-size width="200" height="200" /> - </default-constraints> - </item> - <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> - <preferred-size width="200" height="200" /> - </default-constraints> - </item> - <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> - </item> - <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> - <preferred-size width="-1" height="20" /> - </default-constraints> - </item> - <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> - </item> - <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> - </item> - </group> - </component> - <component name="PerforceChangeBrowserSettings"> - <option name="USE_CLIENT_FILTER" value="true" /> - <option name="CLIENT" value="" /> - </component> - <component name="ProjectFileVersion" converted="true" /> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" /> - </modules> - </component> - <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK"> - <output url="file:///tmp/preload" /> - </component> - <component name="RmicSettings"> - <option name="IS_EANABLED" value="false" /> - <option name="DEBUGGING_INFO" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="false" /> - <option name="GENERATE_IIOP_STUBS" value="false" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - </component> - <component name="StarteamConfiguration"> - <option name="SERVER" value="" /> - <option name="PORT" value="49201" /> - <option name="USER" value="" /> - <option name="PASSWORD" value="" /> - <option name="PROJECT" value="" /> - <option name="VIEW" value="" /> - <option name="ALTERNATIVE_WORKING_PATH" value="" /> - <option name="LOCK_ON_CHECKOUT" value="false" /> - <option name="UNLOCK_ON_CHECKIN" value="false" /> - </component> - <component name="Struts Assistant"> - <option name="showInputs" value="true" /> - <option name="resources"> - <value> - <option name="strutsPath" /> - <option name="strutsHelp" /> - </value> - </option> - <option name="selectedTaglibs" /> - <option name="selectedTaglibs" /> - <option name="myStrutsValidationEnabled" value="true" /> - <option name="myTilesValidationEnabled" value="true" /> - <option name="myValidatorValidationEnabled" value="true" /> - <option name="myReportErrorsAsWarnings" value="true" /> - </component> - <component name="SvnChangesBrowserSettings"> - <option name="USE_AUTHOR_FIELD" value="true" /> - <option name="AUTHOR" value="" /> - <option name="LOCATION" value="" /> - <option name="USE_PROJECT_SETTINGS" value="true" /> - <option name="USE_ALTERNATE_LOCATION" value="false" /> - </component> - <component name="SvnConfiguration"> - <option name="USER" value="" /> - <option name="PASSWORD" value="" /> - <option name="PROCESS_UNRESOLVED" value="false" /> - <option name="LAST_MERGED_REVISION" /> - <option name="UPDATE_RUN_STATUS" value="false" /> - <option name="UPDATE_RECURSIVELY" value="true" /> - <option name="MERGE_DRY_RUN" value="false" /> - </component> - <component name="VCS.FileViewConfiguration"> - <option name="SELECTED_STATUSES" value="DEFAULT" /> - <option name="SELECTED_COLUMNS" value="DEFAULT" /> - <option name="SHOW_FILTERS" value="true" /> - <option name="CUSTOMIZE_VIEW" value="true" /> - <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" /> - </component> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="Perforce" /> - </component> - <component name="VssConfiguration"> - <option name="CLIENT_PATH" value="" /> - <option name="SRCSAFEINI_PATH" value="" /> - <option name="USER_NAME" value="" /> - <option name="PWD" value="" /> - <option name="VSS_IS_INITIALIZED" value="false" /> - <CheckoutOptions> - <option name="COMMENT" value="" /> - <option name="DO_NOT_GET_LATEST_VERSION" value="false" /> - <option name="REPLACE_WRITABLE" value="false" /> - <option name="RECURSIVE" value="false" /> - </CheckoutOptions> - <CheckinOptions> - <option name="COMMENT" value="" /> - <option name="KEEP_CHECKED_OUT" value="false" /> - <option name="RECURSIVE" value="false" /> - </CheckinOptions> - <AddOptions> - <option name="STORE_ONLY_LATEST_VERSION" value="false" /> - <option name="CHECK_OUT_IMMEDIATELY" value="false" /> - <option name="FILE_TYPE" value="0" /> - </AddOptions> - <UndocheckoutOptions> - <option name="MAKE_WRITABLE" value="false" /> - <option name="REPLACE_LOCAL_COPY" value="0" /> - <option name="RECURSIVE" value="false" /> - </UndocheckoutOptions> - <GetOptions> - <option name="REPLACE_WRITABLE" value="0" /> - <option name="MAKE_WRITABLE" value="false" /> - <option name="ANSWER_NEGATIVELY" value="false" /> - <option name="ANSWER_POSITIVELY" value="false" /> - <option name="RECURSIVE" value="false" /> - <option name="VERSION" /> - </GetOptions> - <VssConfigurableExcludedFilesTag /> - </component> - <component name="antWorkspaceConfiguration"> - <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" /> - <option name="FILTER_TARGETS" value="false" /> - </component> - <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1"> - <option name="myLastEditedConfigurable" /> - </component> - <component name="com.intellij.jsf.UserDefinedFacesConfigs"> - <option name="USER_DEFINED_CONFIGS"> - <value> - <list size="0" /> - </value> - </option> - </component> - <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="" version="1"> - <option name="myPlainMode" value="false" /> - <option name="myLastEditedConfigurable" /> - </component> - <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1"> - <option name="myLastEditedConfigurable" /> - </component> - <component name="uidesigner-configuration"> - <option name="INSTRUMENT_CLASSES" value="true" /> - <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" /> - <option name="DEFAULT_LAYOUT_MANAGER" value="GridLayoutManager" /> - </component> -</project> - |