diff options
Diffstat (limited to 'tools')
48 files changed, 694 insertions, 337 deletions
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 5c110549d35d..38bfa00d7564 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -1798,6 +1798,11 @@ void* AaptFile::editData(size_t size) return buf; } +void* AaptFile::editDataInRange(size_t offset, size_t size) +{ + return (void*)(((uint8_t*) editData(offset + size)) + offset); +} + void* AaptFile::editData(size_t* outSize) { if (outSize) { @@ -2378,6 +2383,9 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle) current->setFullResPaths(mFullResPaths); } count = current->slurpResourceTree(bundle, String8(res)); + if (i > 0 && count > 0) { + count = current->filter(bundle); + } if (count < 0) { totalCount = count; diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index 336d08ba77b8..82dda5ff04d3 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -251,6 +251,7 @@ public: size_t getSize() const { return mDataSize; } void* editData(size_t size); void* editData(size_t* outSize = NULL); + void* editDataInRange(size_t offset, size_t size); void* padData(size_t wordSize); status_t writeData(const void* data, size_t size); void clearData(); diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 26b10a65f79d..d2eccbe8aa01 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -51,7 +51,7 @@ public: mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false), mUpdate(false), mExtending(false), mRequireLocalization(false), mPseudolocalize(false), - mWantUTF16(false), mValues(false), + mWantUTF16(false), mValues(false), mIncludeMetaData(false), mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL), mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL), mAutoAddOverlay(false), mGenDependencies(false), @@ -59,10 +59,12 @@ public: mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL), mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL), - mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL), - mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL), - mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL), + mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL), + mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), + mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false), + mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL), mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL), + mBuildSharedLibrary(false), mArgc(0), mArgv(NULL) {} ~Bundle(void) {} @@ -98,6 +100,8 @@ public: void setWantUTF16(bool val) { mWantUTF16 = val; } bool getValues(void) const { return mValues; } void setValues(bool val) { mValues = val; } + bool getIncludeMetaData(void) const { return mIncludeMetaData; } + void setIncludeMetaData(bool val) { mIncludeMetaData = val; } int getCompressionMethod(void) const { return mCompressionMethod; } void setCompressionMethod(int val) { mCompressionMethod = val; } bool getJunkPath(void) const { return mJunkPath; } @@ -114,6 +118,8 @@ public: void setGenDependencies(bool val) { mGenDependencies = val; } bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; } void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; } + bool getErrorOnMissingConfigEntry() { return mErrorOnMissingConfigEntry; } + void setErrorOnMissingConfigEntry(bool val) { mErrorOnMissingConfigEntry = val; } bool getUTF16StringsOption() { return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO); @@ -161,6 +167,8 @@ public: void setVersionCode(const char* val) { mVersionCode = val; } const char* getVersionName() const { return mVersionName; } void setVersionName(const char* val) { mVersionName = val; } + bool getReplaceVersion() { return mReplaceVersion; } + void setReplaceVersion(bool val) { mReplaceVersion = val; } const char* getCustomPackage() const { return mCustomPackage; } void setCustomPackage(const char* val) { mCustomPackage = val; } const char* getExtraPackages() const { return mExtraPackages; } @@ -181,6 +189,8 @@ public: void setSingleCrunchInputFile(const char* val) { mSingleCrunchInputFile = val; } const char* getSingleCrunchOutputFile() const { return mSingleCrunchOutputFile; } void setSingleCrunchOutputFile(const char* val) { mSingleCrunchOutputFile = val; } + bool getBuildSharedLibrary() const { return mBuildSharedLibrary; } + void setBuildSharedLibrary(bool val) { mBuildSharedLibrary = val; } /* * Set and get the file specification. @@ -252,6 +262,7 @@ private: bool mPseudolocalize; bool mWantUTF16; bool mValues; + bool mIncludeMetaData; int mCompressionMethod; bool mJunkPath; const char* mOutputAPKFile; @@ -259,7 +270,6 @@ private: const char* mInstrumentationPackageNameOverride; bool mAutoAddOverlay; bool mGenDependencies; - const char* mAssetSourceDir; const char* mCrunchedOutputDir; const char* mProguardFile; const char* mAndroidManifestFile; @@ -280,6 +290,7 @@ private: const char* mMaxSdkVersion; const char* mVersionCode; const char* mVersionName; + bool mReplaceVersion; const char* mCustomPackage; const char* mExtraPackages; const char* mMaxResVersion; @@ -288,9 +299,11 @@ private: const char* mProduct; bool mUseCrunchCache; bool mErrorOnFailedInsert; + bool mErrorOnMissingConfigEntry; const char* mOutputTextSymbols; const char* mSingleCrunchInputFile; const char* mSingleCrunchOutputFile; + bool mBuildSharedLibrary; /* file specification */ int mArgc; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index fe8bb688e172..44b8340af770 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -25,8 +25,9 @@ using namespace android; */ int doVersion(Bundle* bundle) { - if (bundle->getFileSpecCount() != 0) + if (bundle->getFileSpecCount() != 0) { printf("(ignoring extra arguments)\n"); + } printf("Android Asset Packaging Tool, v0.2\n"); return 0; @@ -46,13 +47,14 @@ ZipFile* openReadOnly(const char* fileName) zip = new ZipFile; result = zip->open(fileName, ZipFile::kOpenReadOnly); if (result != NO_ERROR) { - if (result == NAME_NOT_FOUND) + if (result == NAME_NOT_FOUND) { fprintf(stderr, "ERROR: '%s' not found\n", fileName); - else if (result == PERMISSION_DENIED) + } else if (result == PERMISSION_DENIED) { fprintf(stderr, "ERROR: '%s' access denied\n", fileName); - else + } else { fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n", fileName); + } delete zip; return NULL; } @@ -73,8 +75,9 @@ ZipFile* openReadWrite(const char* fileName, bool okayToCreate) int flags; flags = ZipFile::kOpenReadWrite; - if (okayToCreate) + if (okayToCreate) { flags |= ZipFile::kOpenCreate; + } zip = new ZipFile; result = zip->open(fileName, flags); @@ -94,12 +97,13 @@ bail: */ const char* compressionName(int method) { - if (method == ZipEntry::kCompressStored) + if (method == ZipEntry::kCompressStored) { return "Stored"; - else if (method == ZipEntry::kCompressDeflated) + } else if (method == ZipEntry::kCompressDeflated) { return "Deflated"; - else + } else { return "Unknown"; + } } /* @@ -107,10 +111,11 @@ const char* compressionName(int method) */ int calcPercent(long uncompressedLen, long compressedLen) { - if (!uncompressedLen) + if (!uncompressedLen) { return 0; - else + } else { return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5); + } } /* @@ -135,8 +140,9 @@ int doList(Bundle* bundle) zipFileName = bundle->getFileSpecEntry(0); zip = openReadOnly(zipFileName); - if (zip == NULL) + if (zip == NULL) { goto bail; + } int count, i; @@ -248,7 +254,9 @@ String8 getAttribute(const ResXMLTree& tree, const char* ns, 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"; + if (outError != NULL) { + *outError = "attribute is not a string value"; + } return String8(); } } @@ -266,7 +274,9 @@ static String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* o 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"; + if (outError != NULL) { + *outError = "attribute is not a string value"; + } return String8(); } } @@ -286,7 +296,9 @@ static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, if (tree.getAttributeValue(idx, &value) != NO_ERROR) { if (value.dataType < Res_value::TYPE_FIRST_INT || value.dataType > Res_value::TYPE_LAST_INT) { - if (outError != NULL) *outError = "attribute is not an integer value"; + if (outError != NULL) { + *outError = "attribute is not an integer value"; + } return defValue; } } @@ -307,7 +319,9 @@ static int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXM } if (value.dataType < Res_value::TYPE_FIRST_INT || value.dataType > Res_value::TYPE_LAST_INT) { - if (outError != NULL) *outError = "attribute is not an integer value"; + if (outError != NULL) { + *outError = "attribute is not an integer value"; + } return defValue; } } @@ -330,7 +344,9 @@ static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& } resTable->resolveReference(&value, 0); if (value.dataType != Res_value::TYPE_STRING) { - if (outError != NULL) *outError = "attribute is not a string value"; + if (outError != NULL) { + *outError = "attribute is not a string value"; + } return String8(); } } @@ -340,6 +356,49 @@ static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& return str ? String8(str, len) : String8(); } +static void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable, + const ResXMLTree& tree, uint32_t attrRes, String8* outError) +{ + ssize_t idx = indexOfAttribute(tree, attrRes); + if (idx < 0) { + if (outError != NULL) { + *outError = "attribute could not be found"; + } + return; + } + if (tree.getAttributeValue(idx, value) != NO_ERROR) { + if (value->dataType == Res_value::TYPE_REFERENCE) { + resTable->resolveReference(value, 0); + } + // The attribute was found and was resolved if need be. + return; + } + if (outError != NULL) { + *outError = "error getting resolved resource attribute"; + } +} + +static void printResolvedResourceAttribute(const ResTable* resTable, const ResXMLTree& tree, + uint32_t attrRes, String8 attrLabel, String8* outError) +{ + Res_value value; + getResolvedResourceAttribute(&value, resTable, tree, attrRes, outError); + if (*outError != "") { + *outError = "error print resolved resource attribute"; + return; + } + if (value.dataType == Res_value::TYPE_STRING) { + String8 result = getResolvedAttribute(resTable, tree, attrRes, outError); + printf("%s='%s'", attrLabel.string(), + ResTable::normalizeForOutput(result.string()).string()); + } else if (Res_value::TYPE_FIRST_INT <= value.dataType && + value.dataType <= Res_value::TYPE_LAST_INT) { + printf("%s='%d'", attrLabel.string(), value.data); + } else { + printf("%s='0x%x'", attrLabel.string(), (int)value.data); + } +} + // These are attribute resource constants for the platform, as found // in android.R.attr enum { @@ -349,6 +408,7 @@ enum { PERMISSION_ATTR = 0x01010006, RESOURCE_ATTR = 0x01010025, DEBUGGABLE_ATTR = 0x0101000f, + VALUE_ATTR = 0x01010024, VERSION_CODE_ATTR = 0x0101021b, VERSION_NAME_ATTR = 0x0101021c, SCREEN_ORIENTATION_ATTR = 0x0101001e, @@ -378,7 +438,7 @@ enum { BANNER_ATTR = 0x10103f2, }; -const char *getComponentName(String8 &pkgName, String8 &componentName) { +String8 getComponentName(String8 &pkgName, String8 &componentName) { ssize_t idx = componentName.find("."); String8 retStr(pkgName); if (idx == 0) { @@ -387,9 +447,9 @@ const char *getComponentName(String8 &pkgName, String8 &componentName) { retStr += "."; retStr += componentName; } else { - return componentName.string(); + return componentName; } - return retStr.string(); + return retStr; } static void printCompatibleScreens(ResXMLTree& tree) { @@ -428,6 +488,29 @@ static void printCompatibleScreens(ResXMLTree& tree) { printf("\n"); } +static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) { + printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string()); + if (maxSdkVersion != -1) { + printf(" maxSdkVersion='%d'", maxSdkVersion); + } + printf("\n"); + + if (optional) { + printf("optional-permission: name='%s'", + ResTable::normalizeForOutput(name.string()).string()); + if (maxSdkVersion != -1) { + printf(" maxSdkVersion='%d'", maxSdkVersion); + } + printf("\n"); + } +} + +static void printUsesImpliedPermission(const String8& name, const String8& reason) { + printf("uses-implied-permission: name='%s' reason='%s'\n", + ResTable::normalizeForOutput(name.string()).string(), + ResTable::normalizeForOutput(reason.string()).string()); +} + Vector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost, String8 *outError = NULL) { @@ -635,7 +718,7 @@ int doDump(Bundle* bundle) goto bail; } String8 pkg = getAttribute(tree, NULL, "package", NULL); - printf("package: %s\n", pkg.string()); + printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string()); } else if (depth == 2 && tag == "permission") { String8 error; String8 name = getAttribute(tree, NAME_ATTR, &error); @@ -643,7 +726,8 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR: %s\n", error.string()); goto bail; } - printf("permission: %s\n", name.string()); + printf("permission: %s\n", + ResTable::normalizeForOutput(name.string()).string()); } else if (depth == 2 && tag == "uses-permission") { String8 error; String8 name = getAttribute(tree, NAME_ATTR, &error); @@ -651,11 +735,9 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR: %s\n", error.string()); goto bail; } - printf("uses-permission: %s\n", name.string()); - int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); - if (!req) { - printf("optional-permission: %s\n", name.string()); - } + printUsesPermission(name, + getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, + getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); } } } else if (strcmp("badging", option) == 0) { @@ -668,7 +750,9 @@ int doDump(Bundle* bundle) const size_t NC = configs.size(); for (size_t i=0; i<NC; i++) { int dens = configs[i].density; - if (dens == 0) dens = 160; + if (dens == 0) { + dens = 160; + } densities.add(dens); } @@ -802,7 +886,8 @@ int doDump(Bundle* bundle) printf("supports-input: '"); const size_t N = supportedInput.size(); for (size_t i=0; i<N; i++) { - printf("%s", supportedInput[i].string()); + printf("%s", ResTable::normalizeForOutput( + supportedInput[i].string()).string()); if (i != N - 1) { printf("' '"); } else { @@ -815,25 +900,27 @@ int doDump(Bundle* bundle) withinSupportsInput = false; } else if (depth < 3) { if (withinActivity && isMainActivity) { - const char *aName = getComponentName(pkg, activityName); + String8 aName(getComponentName(pkg, activityName)); if (isLauncherActivity) { printf("launchable-activity:"); - if (aName != NULL) { - printf(" name='%s' ", aName); + if (aName.length() > 0) { + printf(" name='%s' ", + ResTable::normalizeForOutput(aName.string()).string()); } printf(" label='%s' icon='%s'\n", - activityLabel.string(), - activityIcon.string()); + ResTable::normalizeForOutput(activityLabel.string()).string(), + ResTable::normalizeForOutput(activityIcon.string()).string()); } if (isLeanbackLauncherActivity) { printf("leanback-launchable-activity:"); - if (aName != NULL) { - printf(" name='%s' ", aName); + if (aName.length() > 0) { + printf(" name='%s' ", + ResTable::normalizeForOutput(aName.string()).string()); } printf(" label='%s' icon='%s' banner='%s'\n", - activityLabel.string(), - activityIcon.string(), - activityBanner.string()); + ResTable::normalizeForOutput(activityLabel.string()).string(), + ResTable::normalizeForOutput(activityIcon.string()).string(), + ResTable::normalizeForOutput(activityBanner.string()).string()); } } if (!hasIntentFilter) { @@ -890,7 +977,8 @@ int doDump(Bundle* bundle) goto bail; } pkg = getAttribute(tree, NULL, "package", NULL); - printf("package: name='%s' ", pkg.string()); + printf("package: name='%s' ", + ResTable::normalizeForOutput(pkg.string()).string()); int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error); if (error != "") { fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string()); @@ -906,7 +994,8 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string()); goto bail; } - printf("versionName='%s'\n", versionName.string()); + printf("versionName='%s'\n", + ResTable::normalizeForOutput(versionName.string()).string()); } else if (depth == 2) { withinApplication = false; if (tag == "application") { @@ -921,13 +1010,14 @@ int doDump(Bundle* bundle) if (llabel != "") { if (localeStr == NULL || strlen(localeStr) == 0) { label = llabel; - printf("application-label:'%s'\n", llabel.string()); + printf("application-label:'%s'\n", + ResTable::normalizeForOutput(llabel.string()).string()); } else { if (label == "") { label = llabel; } printf("application-label-%s:'%s'\n", localeStr, - llabel.string()); + ResTable::normalizeForOutput(llabel.string()).string()); } } } @@ -939,7 +1029,8 @@ int doDump(Bundle* bundle) assets.setConfiguration(tmpConfig); String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error); if (icon != "") { - printf("application-icon-%d:'%s'\n", densities[i], icon.string()); + printf("application-icon-%d:'%s'\n", densities[i], + ResTable::normalizeForOutput(icon.string()).string()); } } assets.setConfiguration(config); @@ -954,8 +1045,9 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string()); goto bail; } - printf("application: label='%s' ", label.string()); - printf("icon='%s'\n", icon.string()); + printf("application: label='%s' ", + ResTable::normalizeForOutput(label.string()).string()); + printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string()); if (testOnly != 0) { printf("testOnly='%d'\n", testOnly); } @@ -979,7 +1071,8 @@ int doDump(Bundle* bundle) goto bail; } if (name == "Donut") targetSdk = 4; - printf("sdkVersion:'%s'\n", name.string()); + printf("sdkVersion:'%s'\n", + ResTable::normalizeForOutput(name.string()).string()); } else if (code != -1) { targetSdk = code; printf("sdkVersion:'%d'\n", code); @@ -998,7 +1091,8 @@ int doDump(Bundle* bundle) goto bail; } if (name == "Donut" && targetSdk < 4) targetSdk = 4; - printf("targetSdkVersion:'%s'\n", name.string()); + printf("targetSdkVersion:'%s'\n", + ResTable::normalizeForOutput(name.string()).string()); } else if (code != -1) { if (targetSdk < code) { targetSdk = code; @@ -1103,7 +1197,8 @@ int doDump(Bundle* bundle) specScreenLandscapeFeature = true; } printf("uses-feature%s:'%s'\n", - req ? "" : "-not-required", name.string()); + req ? "" : "-not-required", + ResTable::normalizeForOutput(name.string()).string()); } else { int vers = getIntegerAttribute(tree, GL_ES_VERSION_ATTR, &error); @@ -1161,12 +1256,11 @@ int doDump(Bundle* bundle) } else if (name == "android.permission.WRITE_CALL_LOG") { hasWriteCallLogPermission = true; } - printf("uses-permission:'%s'\n", name.string()); - int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); - if (!req) { - printf("optional-permission:'%s'\n", name.string()); - } - } else { + + printUsesPermission(name, + getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0, + getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1)); + } else { fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); goto bail; @@ -1174,7 +1268,8 @@ int doDump(Bundle* bundle) } else if (tag == "uses-package") { String8 name = getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { - printf("uses-package:'%s'\n", name.string()); + printf("uses-package:'%s'\n", + ResTable::normalizeForOutput(name.string()).string()); } else { fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); @@ -1183,7 +1278,8 @@ int doDump(Bundle* bundle) } else if (tag == "original-package") { String8 name = getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { - printf("original-package:'%s'\n", name.string()); + printf("original-package:'%s'\n", + ResTable::normalizeForOutput(name.string()).string()); } else { fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); @@ -1192,7 +1288,8 @@ int doDump(Bundle* bundle) } else if (tag == "supports-gl-texture") { String8 name = getAttribute(tree, NAME_ATTR, &error); if (name != "" && error == "") { - printf("supports-gl-texture:'%s'\n", name.string()); + printf("supports-gl-texture:'%s'\n", + ResTable::normalizeForOutput(name.string()).string()); } else { fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); @@ -1207,7 +1304,8 @@ int doDump(Bundle* bundle) String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error); if (publicKey != "" && error == "") { printf("package-verifier: name='%s' publicKey='%s'\n", - name.string(), publicKey.string()); + ResTable::normalizeForOutput(name.string()).string(), + ResTable::normalizeForOutput(publicKey.string()).string()); } } } @@ -1276,7 +1374,8 @@ int doDump(Bundle* bundle) int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1); printf("uses-library%s:'%s'\n", - req ? "" : "-not-required", libraryName.string()); + req ? "" : "-not-required", ResTable::normalizeForOutput( + libraryName.string()).string()); } else if (tag == "receiver") { withinReceiver = true; receiverName = getAttribute(tree, NAME_ATTR, &error); @@ -1302,8 +1401,8 @@ int doDump(Bundle* bundle) serviceName = getAttribute(tree, NAME_ATTR, &error); if (error != "") { - fprintf(stderr, "ERROR getting 'android:name' attribute for" - " service: %s\n", error.string()); + fprintf(stderr, "ERROR getting 'android:name' attribute for " + "service:%s\n", error.string()); goto bail; } @@ -1322,15 +1421,39 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR getting 'android:permission' attribute for" " service '%s': %s\n", serviceName.string(), error.string()); } - } - } else if (withinSupportsInput && tag == "input-type") { - String8 name = getAttribute(tree, NAME_ATTR, &error); - if (name != "" && error == "") { - supportedInput.add(name); - } else { - fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", - error.string()); - goto bail; + } else if (bundle->getIncludeMetaData() && tag == "meta-data") { + String8 metaDataName = getAttribute(tree, NAME_ATTR, &error); + if (error != "") { + fprintf(stderr, "ERROR getting 'android:name' attribute for " + "meta-data:%s\n", error.string()); + goto bail; + } + printf("meta-data: name='%s' ", + ResTable::normalizeForOutput(metaDataName.string()).string()); + printResolvedResourceAttribute(&res, tree, VALUE_ATTR, String8("value"), + &error); + if (error != "") { + // Try looking for a RESOURCE_ATTR + error = ""; + printResolvedResourceAttribute(&res, tree, RESOURCE_ATTR, + String8("resource"), &error); + if (error != "") { + fprintf(stderr, "ERROR getting 'android:value' or " + "'android:resource' attribute for " + "meta-data:%s\n", error.string()); + goto bail; + } + } + printf("\n"); + } else if (withinSupportsInput && tag == "input-type") { + String8 name = getAttribute(tree, NAME_ATTR, &error); + if (name != "" && error == "") { + supportedInput.add(name); + } else { + fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", + error.string()); + goto bail; + } } } } else if (depth == 4) { @@ -1387,14 +1510,16 @@ int doDump(Bundle* bundle) } } } - } else if ((depth == 5) && withinIntentFilter){ + } else if ((depth == 5) && withinIntentFilter) { String8 action; if (tag == "action") { action = getAttribute(tree, NAME_ATTR, &error); if (error != "") { - fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string()); + fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", + error.string()); goto bail; } + if (withinActivity) { if (action == "android.intent.action.MAIN") { isMainActivity = true; @@ -1429,7 +1554,8 @@ int doDump(Bundle* bundle) if (tag == "category") { String8 category = getAttribute(tree, NAME_ATTR, &error); if (error != "") { - fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string()); + fprintf(stderr, "ERROR getting 'name' attribute: %s\n", + error.string()); goto bail; } if (withinActivity) { @@ -1446,15 +1572,15 @@ int doDump(Bundle* bundle) // Pre-1.6 implicitly granted permission compatibility logic if (targetSdk < 4) { if (!hasWriteExternalStoragePermission) { - printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n"); - printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \ - "'targetSdkVersion < 4'\n"); + printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE")); + printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"), + String8("targetSdkVersion < 4")); hasWriteExternalStoragePermission = true; } if (!hasReadPhoneStatePermission) { - printf("uses-permission:'android.permission.READ_PHONE_STATE'\n"); - printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \ - "'targetSdkVersion < 4'\n"); + printUsesPermission(String8("android.permission.READ_PHONE_STATE")); + printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"), + String8("targetSdkVersion < 4")); } } @@ -1463,22 +1589,22 @@ int doDump(Bundle* bundle) // do this (regardless of target API version) because we can't have // an app with write permission but not read permission. if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { - printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n"); - printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \ - "'requested WRITE_EXTERNAL_STORAGE'\n"); + printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE")); + printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"), + String8("requested WRITE_EXTERNAL_STORAGE")); } // Pre-JellyBean call log permission compatibility. if (targetSdk < 16) { if (!hasReadCallLogPermission && hasReadContactsPermission) { - printf("uses-permission:'android.permission.READ_CALL_LOG'\n"); - printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \ - "'targetSdkVersion < 16 and requested READ_CONTACTS'\n"); + printUsesPermission(String8("android.permission.READ_CALL_LOG")); + printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"), + String8("targetSdkVersion < 16 and requested READ_CONTACTS")); } if (!hasWriteCallLogPermission && hasWriteContactsPermission) { - printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n"); - printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \ - "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n"); + printUsesPermission(String8("android.permission.WRITE_CALL_LOG")); + printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"), + String8("targetSdkVersion < 16 and requested WRITE_CONTACTS")); } } @@ -1503,7 +1629,7 @@ int doDump(Bundle* bundle) printf("uses-implied-feature:'android.hardware.camera'," \ "'requested android.hardware.camera.autofocus feature'\n"); } else if (hasCameraPermission) { - // if app wants to use camera but didn't request the feature, we infer + // if app wants to use camera but didn't request the feature, we infer // that it meant to, and further that it wants autofocus // (which was the 1.0 - 1.5 behavior) printf("uses-feature:'android.hardware.camera'\n"); @@ -1656,7 +1782,9 @@ int doDump(Bundle* bundle) if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0 && requiresSmallestWidthDp > 0) { int compatWidth = compatibleWidthLimitDp; - if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp; + if (compatWidth <= 0) { + compatWidth = requiresSmallestWidthDp; + } if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) { smallScreen = -1; } else { @@ -1701,10 +1829,18 @@ int doDump(Bundle* bundle) || compatibleWidthLimitDp > 0) ? -1 : 0; } printf("supports-screens:"); - if (smallScreen != 0) printf(" 'small'"); - if (normalScreen != 0) printf(" 'normal'"); - if (largeScreen != 0) printf(" 'large'"); - if (xlargeScreen != 0) printf(" 'xlarge'"); + if (smallScreen != 0) { + printf(" 'small'"); + } + if (normalScreen != 0) { + printf(" 'normal'"); + } + if (largeScreen != 0) { + printf(" 'large'"); + } + if (xlargeScreen != 0) { + printf(" 'xlarge'"); + } printf("\n"); printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false"); if (requiresSmallestWidthDp > 0) { @@ -1740,7 +1876,8 @@ int doDump(Bundle* bundle) if (dir->getFileCount() > 0) { printf("native-code:"); for (size_t i=0; i<dir->getFileCount(); i++) { - printf(" '%s'", dir->getFileName(i).string()); + printf(" '%s'", ResTable::normalizeForOutput( + dir->getFileName(i).string()).string()); } printf("\n"); } @@ -1813,7 +1950,8 @@ int doAdd(Bundle* bundle) } else { if (bundle->getJunkPath()) { String8 storageName = String8(fileName).getPathLeaf(); - printf(" '%s' as '%s'...\n", fileName, storageName.string()); + printf(" '%s' as '%s'...\n", fileName, + ResTable::normalizeForOutput(storageName.string()).string()); result = zip->add(fileName, storageName.string(), bundle->getCompressionMethod(), NULL); } else { @@ -1823,12 +1961,13 @@ int doAdd(Bundle* bundle) } if (result != NO_ERROR) { fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName); - if (result == NAME_NOT_FOUND) + if (result == NAME_NOT_FOUND) { fprintf(stderr, ": file not found\n"); - else if (result == ALREADY_EXISTS) + } else if (result == ALREADY_EXISTS) { fprintf(stderr, ": already exists in archive\n"); - else + } else { fprintf(stderr, "\n"); + } goto bail; } } @@ -2093,7 +2232,7 @@ bail: * * POSTCONDITIONS * Destination directory will be updated to match the PNG files in - * the source directory. + * the source directory. */ int doCrunch(Bundle* bundle) { diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp index db74831d096d..12f5b92ab3fa 100644 --- a/tools/aapt/Images.cpp +++ b/tools/aapt/Images.cpp @@ -81,6 +81,12 @@ struct image_info png_bytepp allocRows; }; +static void log_warning(png_structp png_ptr, png_const_charp warning_message) +{ + const char* imageName = (const char*) png_get_error_ptr(png_ptr); + fprintf(stderr, "%s: libpng warning: %s\n", imageName, warning_message); +} + static void read_png(const char* imageName, png_structp read_ptr, png_infop read_info, image_info* outImageInfo) @@ -89,6 +95,8 @@ static void read_png(const char* imageName, int bit_depth, interlace_type, compression_type; int i; + png_set_error_fn(read_ptr, const_cast<char*>(imageName), + NULL /* use default errorfn */, log_warning); png_read_info(read_ptr, read_info); png_get_IHDR(read_ptr, read_info, &outImageInfo->width, @@ -119,6 +127,8 @@ static void read_png(const char* imageName, if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(read_ptr); + png_set_interlace_handling(read_ptr); + png_read_update_info(read_ptr, read_info); outImageInfo->rows = (png_bytepp)malloc( @@ -931,7 +941,7 @@ static void analyze_image(const char *imageName, image_info &imageInfo, int gray gg = *row++; bb = *row++; aa = *row++; - + if (isGrayscale) { *out++ = rr; } else { diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index d1d3deb0106b..1cf4783a8de9 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -47,7 +47,7 @@ void usage(void) " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n" " List contents of Zip-compatible archive.\n\n", gProgName); fprintf(stderr, - " %s d[ump] [--values] WHAT file.{apk} [asset [asset ...]]\n" + " %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\n" " strings Print the contents of the resource table string pool in the APK.\n" " badging Print the label and icon for the app declared in APK.\n" " permissions Print the permissions from the APK.\n" @@ -138,6 +138,8 @@ void usage(void) " --debug-mode\n" " inserts android:debuggable=\"true\" in to the application node of the\n" " manifest, making the application debuggable even on production devices.\n" + " --include-meta-data\n" + " when used with \"dump badging\" also includes meta-data tags.\n" " --min-sdk-version\n" " inserts android:minSdkVersion in to manifest. If the version is 7 or\n" " higher, the default encoding for resources will be in UTF-8.\n" @@ -151,6 +153,11 @@ void usage(void) " inserts android:versionCode in to manifest.\n" " --version-name\n" " inserts android:versionName in to manifest.\n" + " --replace-version\n" + " If --version-code and/or --version-name are specified, these\n" + " values will replace any value already in the manifest. By\n" + " default, nothing is changed if the manifest already defines\n" + " these attributes.\n" " --custom-package\n" " generates R.java into a different package.\n" " --extra-packages\n" @@ -183,11 +190,16 @@ void usage(void) " Make the resources ID non constant. This is required to make an R java class\n" " that does not contain the final value but is used to make reusable compiled\n" " libraries that need to access resources.\n" + " --shared-lib\n" + " Make a shared library resource package that can be loaded by an application\n" + " at runtime to access the libraries resources. Implies --non-constant-id.\n" " --error-on-failed-insert\n" " Forces aapt to return an error if it fails to insert values into the manifest\n" " with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n" " and --version-name.\n" " Insertion typically fails if the manifest already defines the attribute.\n" + " --error-on-missing-config-entry\n" + " Forces aapt to return an error if it fails to find an entry for a configuration.\n" " --output-text-symbols\n" " Generates a text file containing the resource symbols of the R class in the\n" " specified folder.\n" @@ -528,8 +540,12 @@ int main(int argc, char* const argv[]) goto bail; } bundle.setVersionName(argv[0]); + } else if (strcmp(cp, "-replace-version") == 0) { + bundle.setReplaceVersion(true); } else if (strcmp(cp, "-values") == 0) { bundle.setValues(true); + } else if (strcmp(cp, "-include-meta-data") == 0) { + bundle.setIncludeMetaData(true); } else if (strcmp(cp, "-custom-package") == 0) { argc--; argv++; @@ -583,6 +599,8 @@ int main(int argc, char* const argv[]) bundle.setAutoAddOverlay(true); } else if (strcmp(cp, "-error-on-failed-insert") == 0) { bundle.setErrorOnFailedInsert(true); + } else if (strcmp(cp, "-error-on-missing-config-entry") == 0) { + bundle.setErrorOnMissingConfigEntry(true); } else if (strcmp(cp, "-output-text-symbols") == 0) { argc--; argv++; @@ -603,6 +621,9 @@ int main(int argc, char* const argv[]) bundle.setProduct(argv[0]); } else if (strcmp(cp, "-non-constant-id") == 0) { bundle.setNonConstantId(true); + } else if (strcmp(cp, "-shared-lib") == 0) { + bundle.setNonConstantId(true); + bundle.setBuildSharedLibrary(true); } else if (strcmp(cp, "-no-crunch") == 0) { bundle.setUseCrunchCache(true); } else if (strcmp(cp, "-ignore-assets") == 0) { diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 4d29ff7a53f4..6d9d62ebb5a2 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -470,7 +470,7 @@ static int validateAttr(const String8& path, const ResTable& table, value.data); return ATTR_NOT_FOUND; } - + pool = table.getTableStringBlock(strIdx); #if 0 if (pool != NULL) { @@ -676,13 +676,15 @@ static bool applyFileOverlay(Bundle *bundle, } /* - * Inserts an attribute in a given node, only if the attribute does not - * exist. + * Inserts an attribute in a given node. * If errorOnFailedInsert is true, and the attribute already exists, returns false. - * Returns true otherwise, even if the attribute already exists. + * If replaceExisting is true, the attribute will be updated if it already exists. + * Returns true otherwise, even if the attribute already exists, and does not modify + * the existing attribute's value. */ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, - const char* attr8, const char* value, bool errorOnFailedInsert) + const char* attr8, const char* value, bool errorOnFailedInsert, + bool replaceExisting) { if (value == NULL) { return true; @@ -691,7 +693,16 @@ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, const String16 ns(ns8); const String16 attr(attr8); - if (node->getAttribute(ns, attr) != NULL) { + XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr); + if (existingEntry != NULL) { + if (replaceExisting) { + NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);" + " overwriting existing value from manifest.\n", + String8(attr).string(), String8(ns).string())); + existingEntry->string = String16(value); + return true; + } + if (errorOnFailedInsert) { fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" " cannot insert new value %s.\n", @@ -706,11 +717,23 @@ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, // don't stop the build. return true; } - + node->addAttribute(ns, attr, String16(value)); return true; } +/* + * Inserts an attribute in a given node, only if the attribute does not + * exist. + * If errorOnFailedInsert is true, and the attribute already exists, returns false. + * Returns true otherwise, even if the attribute already exists. + */ +bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, + const char* attr8, const char* value, bool errorOnFailedInsert) +{ + return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false); +} + static void fullyQualifyClassName(const String8& package, sp<XMLNode> node, const String16& attrName) { XMLNode::attribute_entry* attr = node->editAttribute( @@ -748,16 +771,17 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root) } bool errorOnFailedInsert = bundle->getErrorOnFailedInsert(); + bool replaceVersion = bundle->getReplaceVersion(); if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode", - bundle->getVersionCode(), errorOnFailedInsert)) { + bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; } if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName", - bundle->getVersionName(), errorOnFailedInsert)) { + bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; } - + if (bundle->getMinSdkVersion() != NULL || bundle->getTargetSdkVersion() != NULL || bundle->getMaxSdkVersion() != NULL) { @@ -766,7 +790,7 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root) vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk")); root->insertChildAt(vers, 0); } - + if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion", bundle->getMinSdkVersion(), errorOnFailedInsert)) { return UNKNOWN_ERROR; @@ -841,7 +865,7 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root) } } } - + return NO_ERROR; } @@ -925,7 +949,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) // -------------------------------------------------------------- // resType -> leafName -> group - KeyedVector<String8, sp<ResourceTypeSet> > *resources = + KeyedVector<String8, sp<ResourceTypeSet> > *resources = new KeyedVector<String8, sp<ResourceTypeSet> >; collect_files(assets, resources); @@ -957,7 +981,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) // now go through any resource overlays and collect their files sp<AaptAssets> current = assets->getOverlay(); while(current.get()) { - KeyedVector<String8, sp<ResourceTypeSet> > *resources = + KeyedVector<String8, sp<ResourceTypeSet> > *resources = new KeyedVector<String8, sp<ResourceTypeSet> >; current->setResources(resources); collect_files(current, resources); @@ -1060,7 +1084,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) // compile resources current = assets; while(current.get()) { - KeyedVector<String8, sp<ResourceTypeSet> > *resources = + KeyedVector<String8, sp<ResourceTypeSet> > *resources = current->getResources(); ssize_t index = resources->indexOfKey(String8("values")); @@ -1069,7 +1093,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) ssize_t res; while ((res=it.next()) == NO_ERROR) { sp<AaptFile> file = it.getFile(); - res = compileResourceFile(bundle, assets, file, it.getParams(), + res = compileResourceFile(bundle, assets, file, it.getParams(), (current!=assets), &table); if (res != NO_ERROR) { hasErrors = true; @@ -1254,7 +1278,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) if (table.validateLocalizations()) { hasErrors = true; } - + if (hasErrors) { return UNKNOWN_ERROR; } @@ -1287,7 +1311,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) ResTable finalResTable; sp<AaptFile> resFile; - + if (table.hasResources()) { sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); err = table.addSymbols(symbols); @@ -1319,9 +1343,10 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) table.writePublicDefinitions(String16(assets->getPackage()), fp); fclose(fp); } - + // Read resources back in, finalResTable.add(resFile->getData(), resFile->getSize()); + #if 0 NOISY( printf("Generated resources:\n"); @@ -1329,7 +1354,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) ) #endif } - + // 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 @@ -1424,7 +1449,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) 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", + fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", manifestPath.string(), block.getLineNumber(), String8(block.getElementName(&len)).string()); hasErrors = true; @@ -1582,7 +1607,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) return err; } } - + return err; } @@ -1704,7 +1729,7 @@ static status_t writeLayoutClasses( NA = idents.size(); bool deprecated = false; - + String16 comment = symbols->getComment(realClassName); fprintf(fp, "%s/** ", indentStr); if (comment.size() > 0) { @@ -1787,7 +1812,7 @@ static status_t writeLayoutClasses( if (deprecated) { fprintf(fp, "%s@Deprecated\n", indentStr); } - + fprintf(fp, "%spublic static final int[] %s = {\n" "%s", @@ -1832,9 +1857,9 @@ static status_t writeLayoutClasses( //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; - + bool deprecated = false; - + fprintf(fp, "%s/**\n", indentStr); if (comment.size() > 0) { String8 cmt(comment); diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp index e03f4f668a1e..d60a07fc243b 100644 --- a/tools/aapt/ResourceIdCache.cpp +++ b/tools/aapt/ResourceIdCache.cpp @@ -98,10 +98,10 @@ uint32_t ResourceIdCache::store(const android::String16& package, void ResourceIdCache::dump() { printf("ResourceIdCache dump:\n"); - printf("Size: %ld\n", mIdMap.size()); - printf("Hits: %ld\n", mHits); - printf("Misses: %ld\n", mMisses); - printf("(Collisions: %ld)\n", mCollisions); + printf("Size: %zd\n", mIdMap.size()); + printf("Hits: %zd\n", mHits); + printf("Misses: %zd\n", mMisses); + printf("(Collisions: %zd)\n", mCollisions); } } diff --git a/tools/aapt/ResourceIdCache.h b/tools/aapt/ResourceIdCache.h index e6bcda273844..3acdee1bedfc 100644 --- a/tools/aapt/ResourceIdCache.h +++ b/tools/aapt/ResourceIdCache.h @@ -6,18 +6,20 @@ #ifndef RESOURCE_ID_CACHE_H #define RESOURCE_ID_CACHE_H +#include <utils/String16.h> + namespace android { class ResourceIdCache { public: - static uint32_t lookup(const android::String16& package, - const android::String16& type, - const android::String16& name, + static uint32_t lookup(const String16& package, + const String16& type, + const String16& name, bool onlyPublic); - static uint32_t store(const android::String16& package, - const android::String16& type, - const android::String16& name, + static uint32_t store(const String16& package, + const String16& type, + const String16& name, bool onlyPublic, uint32_t resId); diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 0b1f98536dda..0fb26068dcf8 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -1673,7 +1673,7 @@ status_t compileResourceFile(Bundle* bundle, ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage) : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false), - mIsAppPackage(!bundle->getExtending()), + mIsAppPackage(!bundle->getExtending()), mIsSharedLibrary(bundle->getBuildSharedLibrary()), mNumLocal(0), mBundle(bundle) { @@ -1695,8 +1695,9 @@ status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets 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)); + const 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. @@ -1722,7 +1723,7 @@ status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets } } if (id != 0) { - NOISY(printf("Including package %s with ID=%d\n", + NOISY(fprintf(stderr, "Including package %s with ID=%d\n", String8(name).string(), id)); sp<Package> p = new Package(name, id); mPackages.add(name, p); @@ -2687,6 +2688,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) bool useUTF8 = !bundle->getUTF16StringsOption(); + // The libraries this table references. + Vector<sp<Package> > libraryPackages; + // Iterate through all data, collecting all values (strings, // references, etc). StringPool valueStrings(useUTF8); @@ -2694,8 +2698,22 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) for (pi=0; pi<N; pi++) { sp<Package> p = mOrderedPackages.itemAt(pi); if (p->getTypes().size() == 0) { - // Empty, skip! + // Empty, this is an imported package being used as + // a shared library. We do not flatten this package. + if (p->getAssignedId() != 0x01 && p->getName() != String16("android")) { + // This is not the base Android package, and it is a library + // so we must add a reference to the library when flattening. + libraryPackages.add(p); + } continue; + } else if (p->getAssignedId() == 0x00) { + if (!bundle->getBuildSharedLibrary()) { + fprintf(stderr, "ERROR: Package %s can not have ID=0x00 unless building a shared library.", + String8(p->getName()).string()); + return UNKNOWN_ERROR; + } + // If this is a shared library, we also include ourselves as an entry. + libraryPackages.add(p); } StringPool typeStrings(useUTF8); @@ -2778,7 +2796,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) } ssize_t strAmt = 0; - + // Now build the array of package chunks. Vector<sp<AaptFile> > flatPackages; for (pi=0; pi<N; pi++) { @@ -2827,6 +2845,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) return amt; } + err = flattenLibraryTable(data, libraryPackages); + if (err != NO_ERROR) { + fprintf(stderr, "ERROR: failed to write library table\n"); + return err; + } + // 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. @@ -2996,13 +3020,21 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) tHeader->header.size = htodl(data->getSize()-typeStart); } + bool missing_entry = false; + const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ? + "error" : "warning"; for (size_t i = 0; i < N; ++i) { if (!validResources[i]) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); - fprintf(stderr, "warning: no entries written for %s/%s\n", + fprintf(stderr, "%s: no entries written for %s/%s\n", log_prefix, String8(typeName).string(), String8(c->getName()).string()); + missing_entry = true; } } + if (bundle->getErrorOnMissingConfigEntry() && missing_entry) { + fprintf(stderr, "Error: Missing entries, quit!\n"); + return NOT_ENOUGH_DATA; + } } // Fill in the rest of the package information. @@ -3045,7 +3077,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) 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()); @@ -3070,6 +3102,38 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) return NO_ERROR; } +status_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) { + // Write out the library table if necessary + if (libs.size() > 0) { + NOISY(fprintf(stderr, "Writing library reference table\n")); + + const size_t libStart = dest->getSize(); + const size_t count = libs.size(); + ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange(libStart, sizeof(ResTable_lib_header)); + + memset(libHeader, 0, sizeof(*libHeader)); + libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE); + libHeader->header.headerSize = htods(sizeof(*libHeader)); + libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count)); + libHeader->count = htodl(count); + + // Write the library entries + for (size_t i = 0; i < count; i++) { + const size_t entryStart = dest->getSize(); + sp<Package> libPackage = libs[i]; + NOISY(fprintf(stderr, " Entry %s -> 0x%02x\n", + String8(libPackage->getName()).string(), + (uint8_t)libPackage->getAssignedId())); + + ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange(entryStart, sizeof(ResTable_lib_entry)); + memset(entry, 0, sizeof(*entry)); + entry->packageId = htodl(libPackage->getAssignedId()); + strcpy16_htod(entry->packageName, libPackage->getName().string()); + } + } + return NO_ERROR; +} + void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) { fprintf(fp, @@ -3839,7 +3903,7 @@ sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) return NULL; } mHaveAppPackage = true; - p = new Package(package, 127); + p = new Package(package, mIsSharedLibrary ? 0 : 127); } else { p = new Package(package, mNextPackageId); } diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index 75005cd18f12..ec8fd175e161 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -224,6 +224,7 @@ public: status_t validateLocalizations(void); status_t flatten(Bundle*, const sp<AaptFile>& dest); + status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs); void writePublicDefinitions(const String16& package, FILE* fp); @@ -546,6 +547,7 @@ private: uint32_t mNextPackageId; bool mHaveAppPackage; bool mIsAppPackage; + bool mIsSharedLibrary; size_t mNumLocal; SourcePos mCurrentXmlPos; Bundle* mBundle; diff --git a/tools/aapt/printapk.cpp b/tools/aapt/printapk.cpp index 4cf73d81294b..def6e2e683fc 100644 --- a/tools/aapt/printapk.cpp +++ b/tools/aapt/printapk.cpp @@ -115,8 +115,8 @@ main(int argc, char** argv) 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)); + const String16 ch = res.getBasePackageName(bpIndex); + String8 s = String8(ch); printf(" [%3d] %s\n", (int)bpIndex, s.string()); } #endif diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index a84d743d0ebf..9c1867e14a8f 100644 --- a/tools/aidl/aidl.cpp +++ b/tools/aidl/aidl.cpp @@ -207,7 +207,7 @@ check_filename(const char* filename, const char* package, buffer_type* name) p = strchr(name->data, '.'); len = p ? p-name->data : strlen(name->data); expected.append(name->data, len); - + expected += ".aidl"; len = fn.length(); @@ -473,7 +473,7 @@ check_method(const char* filename, int kind, method_type* m) err = 1; goto next; } - + if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) { fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n", filename, m->type.type.lineno, index, @@ -536,7 +536,7 @@ check_method(const char* filename, int kind, method_type* m) filename, m->name.lineno, index, arg->name.data); err = 1; } - + next: index++; arg = arg->next; @@ -797,7 +797,7 @@ parse_preprocessed_file(const string& filename) //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno, // type, packagename, classname); document_item_type* doc; - + if (0 == strcmp("parcelable", type)) { user_data_type* parcl = (user_data_type*)malloc( sizeof(user_data_type)); @@ -1104,13 +1104,13 @@ preprocess_aidl(const Options& options) } // write preprocessed file - int fd = open( options.outputFileName.c_str(), + 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 +#else S_IRUSR|S_IWUSR|S_IRGRP); -#endif +#endif if (fd == -1) { fprintf(stderr, "aidl: could not open file for write: %s\n", options.outputFileName.c_str()); diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk index 1fa9615f6620..cb68340b3f5e 100644 --- a/tools/layoutlib/Android.mk +++ b/tools/layoutlib/Android.mk @@ -53,6 +53,7 @@ include $(BUILD_SYSTEM)/base_rules.mk $(LOCAL_BUILT_MODULE): $(built_core_dep) \ $(built_framework_dep) \ $(built_ext_dep) \ + $(built_ext_data) \ $(built_layoutlib_create_jar) $(hide) echo "host layoutlib_create: $@" $(hide) mkdir -p $(dir $@) diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath index 2e4274da5afd..aef3efa0452e 100644 --- a/tools/layoutlib/bridge/.classpath +++ b/tools/layoutlib/bridge/.classpath @@ -1,12 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry excluding="org/kxml2/io/" kind="src" path="src"/> + <classpathentry kind="src" path="tests/src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/> + <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java index 224eac601ae1..4603b6362b0e 100644 --- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java +++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java @@ -48,6 +48,20 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate; } @LayoutlibDelegate + /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName, + int numParams) { + // TODO: return the right thing. + return 0; + } + + @LayoutlibDelegate + /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName, + int numParams) { + // TODO: return the right thing. + return 0; + } + + @LayoutlibDelegate /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) { // do nothing } @@ -56,4 +70,40 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate; /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) { // do nothing } + + @LayoutlibDelegate + /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1, + int arg2) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1, + int arg2, int arg3, int arg4) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallMultipleIntMethod(Object target, long methodID, + int[] args) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1, + float arg2) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1, + float arg2, float arg3, float arg4) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID, + float[] args) { + // do nothing + } } diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java index 879445297ed4..dd573be4a1fe 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java @@ -51,6 +51,7 @@ public final class BridgeResources extends Resources { private BridgeContext mContext; private IProjectCallback mProjectCallback; private boolean[] mPlatformResourceFlag = new boolean[1]; + private TypedValue mTmpValue = new TypedValue(); /** * Simpler wrapper around FileInputStream. This is used when the input stream represent @@ -154,6 +155,11 @@ public final class BridgeResources extends Resources { @Override public Drawable getDrawable(int id) throws NotFoundException { + return getDrawable(id, null); + } + + @Override + public Drawable getDrawable(int id, Theme theme) { Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java index 446d139b2161..cc621c431372 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java @@ -52,13 +52,13 @@ public final class BridgeTypedArray extends TypedArray { private final BridgeContext mContext; private final boolean mPlatformFile; - private ResourceValue[] mResourceData; - private String[] mNames; - private boolean[] mIsFramework; + private final ResourceValue[] mResourceData; + private final String[] mNames; + private final boolean[] mIsFramework; public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len, boolean platformFile) { - super(null, null, null, 0); + super(resources, null, null, 0); mBridgeResources = resources; mContext = context; mPlatformFile = platformFile; @@ -81,8 +81,8 @@ public final class BridgeTypedArray extends TypedArray { } /** - * Seals the array after all calls to {@link #bridgeSetValue(int, String, ResourceValue)} have - * been done. + * Seals the array after all calls to + * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done. * <p/>This allows to compute the list of non default values, permitting * {@link #getIndexCount()} to return the proper value. */ @@ -252,7 +252,7 @@ public final class BridgeTypedArray extends TypedArray { for (String keyword : keywords) { Integer i = map.get(keyword.trim()); if (i != null) { - result |= i.intValue(); + result |= i; } else { Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, String.format( @@ -731,7 +731,7 @@ public final class BridgeTypedArray extends TypedArray { } // not a direct id valid reference? resolve it - Integer idValue = null; + Integer idValue; if (resValue.isFramework()) { idValue = Bridge.getResourceId(resValue.getResourceType(), @@ -742,7 +742,7 @@ public final class BridgeTypedArray extends TypedArray { } if (idValue != null) { - return idValue.intValue(); + return idValue; } Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE, @@ -753,6 +753,12 @@ public final class BridgeTypedArray extends TypedArray { return defValue; } + @Override + public int getThemeAttributeId(int index, int defValue) { + // TODO: Get the right Theme Attribute ID to enable caching of the drawables. + return defValue; + } + /** * Retrieve the Drawable for the attribute at <var>index</var>. This * gets the resource ID of the selected attribute, and uses @@ -854,6 +860,7 @@ public final class BridgeTypedArray extends TypedArray { */ @Override public boolean hasValue(int index) { + //noinspection SimplifiableIfStatement if (index < 0 || index >= mResourceData.length) { return false; } diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java new file mode 100644 index 000000000000..112250d01d4d --- /dev/null +++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 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.content.res; + +import java.util.Locale; + +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import com.ibm.icu.util.ULocale; + +/** + * Delegate used to provide new implementation of a select few methods of {@link Resources} + * + * Through the layoutlib_create tool, the original methods of Resources have been replaced + * by calls to methods of the same name in this delegate class. + * + */ +public class Resources_Delegate { + + @LayoutlibDelegate + /*package*/ static String localeToLanguageTag(Resources res, Locale locale) { + return ULocale.forLocale(locale).toLanguageTag(); + } +} diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index 89d7e238593f..701613611e34 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -518,7 +518,8 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha) { + /*package*/ static void nativeSetAlphaAndPremultiplied(long nativeBitmap, boolean hasAlpha, + boolean isPremul) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java index 73d274c1d32b..bb05d45725e2 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java @@ -344,7 +344,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static long native_saveLayer(long nativeCanvas, RectF bounds, + /*package*/ static int native_saveLayer(long nativeCanvas, RectF bounds, long paint, int layerFlags) { // get the delegate from the native int. Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas); @@ -361,7 +361,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static long native_saveLayer(long nativeCanvas, float l, + /*package*/ static int native_saveLayer(long nativeCanvas, float l, float t, float r, float b, long paint, int layerFlags) { // get the delegate from the native int. @@ -380,7 +380,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static long native_saveLayerAlpha(long nativeCanvas, + /*package*/ static int native_saveLayerAlpha(long nativeCanvas, RectF bounds, int alpha, int layerFlags) { // get the delegate from the native int. @@ -393,7 +393,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static long native_saveLayerAlpha(long nativeCanvas, float l, + /*package*/ static int native_saveLayerAlpha(long nativeCanvas, float l, float t, float r, float b, int alpha, int layerFlags) { // get the delegate from the native int. @@ -975,8 +975,10 @@ public final class Canvas_Delegate { @LayoutlibDelegate /*package*/ static void native_drawText(long nativeCanvas, final char[] text, final int index, final int count, - final float startX, final float startY, final int flags, long paint) { + final float startX, final float startY, final int flags, long paint, + long typeface) { + // TODO: use typeface. draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/, new GcSnapshot.Drawable() { @Override @@ -1006,30 +1008,31 @@ public final class Canvas_Delegate { @LayoutlibDelegate /*package*/ static void native_drawText(long nativeCanvas, String text, - int start, int end, float x, float y, final int flags, long paint) { + int start, int end, float x, float y, final int flags, long paint, + long typeface) { int count = end - start; char[] buffer = TemporaryBuffer.obtain(count); TextUtils.getChars(text, start, end, buffer, 0); - native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint); + native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface); } @LayoutlibDelegate /*package*/ static void native_drawTextRun(long nativeCanvas, String text, int start, int end, int contextStart, int contextEnd, - float x, float y, int flags, long paint) { + float x, float y, int flags, long paint, long typeface) { int count = end - start; char[] buffer = TemporaryBuffer.obtain(count); TextUtils.getChars(text, start, end, buffer, 0); - native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint); + native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface); } @LayoutlibDelegate /*package*/ static void native_drawTextRun(long nativeCanvas, char[] text, int start, int count, int contextStart, int contextCount, - float x, float y, int flags, long paint) { - native_drawText(nativeCanvas, text, start, count, x, y, flags, paint); + float x, float y, int flags, long paint, long typeface) { + native_drawText(nativeCanvas, text, start, count, x, y, flags, paint, typeface); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java index d6b3da19a6d8..bf03a5edef5f 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java @@ -56,7 +56,7 @@ public abstract class ColorFilter_Delegate { // ---- native methods ---- @LayoutlibDelegate - /*package*/ static void finalizer(long native_instance, long nativeColorFilter) { + /*package*/ static void destroyFilter(long native_instance) { sManager.removeJavaReferenceFor(native_instance); } diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java index ca8f45077523..9aac2bd97a21 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java @@ -60,11 +60,5 @@ public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate { return sManager.addNewDelegate(newDelegate); } - @LayoutlibDelegate - /*package*/ static long nColorMatrixFilter(long nativeFilter, float[] array) { - // pass - return 0; - } - // ---- Private delegate/helper methods ---- } diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java index defaac34d237..501d55cb9878 100644 --- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java @@ -60,11 +60,5 @@ public class LightingColorFilter_Delegate extends ColorFilter_Delegate { return sManager.addNewDelegate(newDelegate); } - @LayoutlibDelegate - /*package*/ static int nCreateLightingFilter(long nativeFilter, int mul, int add) { - // pass - return 0; - } - // ---- Private delegate/helper methods ---- } diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java index 7007b7187407..de2e5922f0bf 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java @@ -688,7 +688,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getStyle(long native_object) { + /*package*/ static int native_getStyle(long native_object) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); if (delegate == null) { @@ -710,7 +710,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getStrokeCap(long native_object) { + /*package*/ static int native_getStrokeCap(long native_object) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); if (delegate == null) { @@ -732,7 +732,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getStrokeJoin(long native_object) { + /*package*/ static int native_getStrokeJoin(long native_object) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); if (delegate == null) { @@ -889,7 +889,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getTextAlign(long native_object) { + /*package*/ static int native_getTextAlign(long native_object) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); if (delegate == null) { @@ -922,7 +922,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getTextWidths(long native_object, char[] text, int index, + /*package*/ static int native_getTextWidths(long native_object, char[] text, int index, int count, int bidiFlags, float[] widths) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); @@ -964,14 +964,14 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getTextWidths(long native_object, String text, int start, + /*package*/ static int native_getTextWidths(long native_object, String text, int start, int end, int bidiFlags, float[] widths) { return native_getTextWidths(native_object, text.toCharArray(), start, end - start, bidiFlags, widths); } @LayoutlibDelegate - /* package */static long native_getTextGlyphs(long native_object, String text, int start, + /* package */static int native_getTextGlyphs(long native_object, String text, int start, int end, int contextStart, int contextEnd, int flags, char[] glyphs) { // FIXME return 0; @@ -1012,7 +1012,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, char[] text, + /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text, int contextStart, int contextLength, int flags, int offset, int cursorOpt) { // FIXME Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, @@ -1021,7 +1021,7 @@ public class Paint_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, String text, + /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) { // FIXME Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index 6f6ef204e699..b23540825798 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -142,7 +142,14 @@ public final class Path_Delegate { } @LayoutlibDelegate - /*package*/ static long native_getFillType(long nPath) { + /*package*/ static boolean native_isConvex(long nPath) { + Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + "Path.isConvex is not supported.", null, null); + return true; + } + + @LayoutlibDelegate + /*package*/ static int native_getFillType(long nPath) { Path_Delegate pathDelegate = sManager.getDelegate(nPath); if (pathDelegate == null) { return 0; @@ -484,6 +491,11 @@ public final class Path_Delegate { sManager.removeJavaReferenceFor(nPath); } + @LayoutlibDelegate + /*package*/ static float[] native_approximate(long nPath, float error) { + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null); + return new float[0]; + } // ---- Private helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java index 6049919d6cb5..1bc30333ce86 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java @@ -60,12 +60,5 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate { return sManager.addNewDelegate(newDelegate); } - @LayoutlibDelegate - /*package*/ static long nCreatePorterDuffFilter(long nativeFilter, int srcColor, - int porterDuffMode) { - // pass - return 0; - } - // ---- Private delegate/helper methods ---- } diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java index ea23649a0d23..edb7025b7cd7 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java @@ -275,21 +275,20 @@ public class Region_Delegate { } @LayoutlibDelegate - /*package*/ static boolean nativeSetRegion(long native_dst, long native_src) { + /*package*/ static void nativeSetRegion(long native_dst, long native_src) { Region_Delegate dstRegion = sManager.getDelegate(native_dst); if (dstRegion == null) { - return true; + return; } Region_Delegate srcRegion = sManager.getDelegate(native_src); if (srcRegion == null) { - return true; + return; } dstRegion.mArea.reset(); dstRegion.mArea.add(srcRegion.mArea); - return true; } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java index 941f1ce6ef22..cdbe2004cdea 100644 --- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java +++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java @@ -125,10 +125,11 @@ public final class BridgeInflater extends LayoutInflater { } @Override - public View createViewFromTag(View parent, String name, AttributeSet attrs) { + public View createViewFromTag(View parent, String name, AttributeSet attrs, + boolean inheritContext) { View view = null; try { - view = super.createViewFromTag(parent, name, attrs); + view = super.createViewFromTag(parent, name, attrs, inheritContext); } catch (InflateException e) { // try to load the class from using the custom view loader try { diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index dd2cbc10d203..743a26c6c60c 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -458,44 +458,8 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public IBinder getFocusedWindowToken() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setInputFilter(IInputFilter filter) throws RemoteException { - // TODO Auto-generated method stub - } - - @Override - public void getWindowFrame(IBinder token, Rect outFrame) { - // TODO Auto-generated method stub - } - - @Override - public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) { - // TODO Auto-generated method stub - } - - @Override - public void setMagnificationSpec(MagnificationSpec spec) { - // TODO Auto-generated method stub - } - - @Override - public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) { - // TODO Auto-generated method stub - return null; - } - - @Override public boolean isRotationFrozen() throws RemoteException { // TODO Auto-generated method stub return false; } - - @Override - public void setTouchExplorationEnabled(boolean enabled) { - } } diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java index 3db3a1b0857b..7a73fae516b7 100644 --- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java @@ -48,9 +48,9 @@ public class LayoutInflater_Delegate { * This implementation just records the merge status before calling the default implementation. */ @LayoutlibDelegate - /*package*/ static void rInflate(LayoutInflater thisInflater, - XmlPullParser parser, View parent, final AttributeSet attrs, - boolean finishInflate) throws XmlPullParserException, IOException { + /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser, + View parent, final AttributeSet attrs, boolean finishInflate, boolean inheritContext) + throws XmlPullParserException, IOException { if (finishInflate == false) { // this is a merge rInflate! @@ -61,7 +61,7 @@ public class LayoutInflater_Delegate { // ---- START DEFAULT IMPLEMENTATION. - thisInflater.rInflate_Original(parser, parent, attrs, finishInflate); + thisInflater.rInflate_Original(parser, parent, attrs, finishInflate, inheritContext); // ---- END DEFAULT IMPLEMENTATION. @@ -74,10 +74,8 @@ public class LayoutInflater_Delegate { } @LayoutlibDelegate - public static void parseInclude( - LayoutInflater thisInflater, - XmlPullParser parser, View parent, AttributeSet attrs) - throws XmlPullParserException, IOException { + public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser, View parent, + AttributeSet attrs, boolean inheritContext) throws XmlPullParserException, IOException { int type; @@ -113,9 +111,11 @@ public class LayoutInflater_Delegate { if (TAG_MERGE.equals(childName)) { // Inflate all children. - thisInflater.rInflate(childParser, parent, childAttrs, false); + thisInflater.rInflate(childParser, parent, childAttrs, false, + inheritContext); } else { - final View view = thisInflater.createViewFromTag(parent, childName, childAttrs); + final View view = thisInflater.createViewFromTag(parent, childName, + childAttrs, inheritContext); final ViewGroup group = (ViewGroup) parent; // We try to load the layout params set in the <include /> tag. If @@ -151,7 +151,7 @@ public class LayoutInflater_Delegate { } // Inflate all children. - thisInflater.rInflate(childParser, view, childAttrs, true); + thisInflater.rInflate(childParser, view, childAttrs, true, true); // Attempt to override the included layout's android:id with the // one set on the <include /> tag itself. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java index 01740b16a0bb..89288bfdddf9 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java @@ -135,6 +135,7 @@ public final class BridgeContentProvider implements IContentProvider { return null; } + @Override public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException { return null; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java index 3cf5ed515fda..66e67db58d71 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java @@ -209,6 +209,17 @@ public class BridgeIInputMethodManager implements IInputMethodManager { } @Override + public int getInputMethodWindowVisibleHeight() throws RemoteException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void notifyTextCommitted() throws RemoteException { + // TODO Auto-generated method stub + } + + @Override public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException { // TODO Auto-generated method stub diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java index 281337c5caa1..3414b3e13db8 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java @@ -39,7 +39,7 @@ public class BridgePowerManager implements IPowerManager { } @Override - public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3) + public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4) throws RemoteException { // pass for now. } @@ -111,7 +111,7 @@ public class BridgePowerManager implements IPowerManager { } @Override - public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1) throws RemoteException { + public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1, String arg2) throws RemoteException { // pass for now. } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index bcd08eb47070..86797e56a660 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -87,7 +87,7 @@ abstract class CustomBar extends LinearLayout { } } - private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction, + private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction, String[] pathOut, boolean tryOtherDensities) { // current density Density density = densityInOut[0]; @@ -111,10 +111,10 @@ abstract class CustomBar extends LinearLayout { return stream; } } - } - // couldn't find resource with direction qualifier. try without. - if (direction != null) { - return getIcon(iconName, densityInOut, null, pathOut, true); + // couldn't find resource with direction qualifier. try without. + if (direction != null) { + return getIcon(iconName, densityInOut, null, pathOut, true); + } } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java index 84e676ed4bbd..112c267616f8 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java @@ -17,7 +17,6 @@ package com.android.layoutlib.bridge.bars; import com.android.resources.Density; -import com.android.layoutlib.bridge.Bridge; import org.xmlpull.v1.XmlPullParserException; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index 3692d967e9af..1498044d4262 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -33,7 +33,6 @@ public class StatusBar extends CustomBar { public StatusBar(Context context, Density density, int direction, boolean RtlEnabled) throws XmlPullParserException { // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar. - super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml"); // FIXME: use FILL_H? diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java index 53e1640c9ae7..a2a8aa96b155 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java @@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.util; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.GrowingArrayUtils; import android.util.SparseArray; @@ -59,10 +60,8 @@ public class SparseWeakArray<E> { * number of mappings. */ public SparseWeakArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); - - mKeys = new long[initialCapacity]; - mValues = new WeakReference[initialCapacity]; + mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity); + mValues = new WeakReference[mKeys.length]; mSize = 0; } @@ -142,18 +141,6 @@ public class SparseWeakArray<E> { mGarbage = false; mSize = o; - - int newSize = ArrayUtils.idealLongArraySize(mSize); - if (newSize < mKeys.length) { - long[] nkeys = new long[newSize]; - WeakReference<?>[] nvalues = new WeakReference[newSize]; - - System.arraycopy(mKeys, 0, nkeys, 0, newSize); - System.arraycopy(mValues, 0, nvalues, 0, newSize); - - mKeys = nkeys; - mValues = nvalues; - } } /** @@ -182,28 +169,8 @@ public class SparseWeakArray<E> { i = ~binarySearch(mKeys, 0, mSize, key); } - if (mSize >= mKeys.length) { - int n = ArrayUtils.idealLongArraySize(mSize + 1); - - long[] nkeys = new long[n]; - WeakReference<?>[] nvalues = new WeakReference[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - if (mSize - i != 0) { - // Log.e("SparseArray", "move " + (mSize - i)); - System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); - System.arraycopy(mValues, i, mValues, i + 1, mSize - i); - } - - mKeys[i] = key; - mValues[i] = new WeakReference(value); + mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key); + mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value)); mSize++; } } @@ -321,24 +288,9 @@ public class SparseWeakArray<E> { gc(); } - int pos = mSize; - if (pos >= mKeys.length) { - int n = ArrayUtils.idealLongArraySize(pos + 1); - - long[] nkeys = new long[n]; - WeakReference<?>[] nvalues = new WeakReference[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - mKeys[pos] = key; - mValues[pos] = new WeakReference(value); - mSize = pos + 1; + mKeys = GrowingArrayUtils.append(mKeys, mSize, key); + mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value)); + mSize++; } private boolean hasReclaimedRefs() { diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java index 998b08b1b359..b16b4aa0d0df 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java @@ -18,6 +18,7 @@ package libcore.icu; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import com.ibm.icu.text.DateTimePatternGenerator; +import com.ibm.icu.util.Currency; import com.ibm.icu.util.ULocale; import java.util.Locale; @@ -117,6 +118,11 @@ public class ICU_Delegate { } @LayoutlibDelegate + /*package*/ static int getCurrencyNumericCode(String currencyCode) { + return Currency.getInstance(currencyCode).getNumericCode(); + } + + @LayoutlibDelegate /*package*/ static String getCurrencySymbol(String locale, String currencyCode) { return ""; } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java index d3218dbd5bd3..274516ca7b16 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java @@ -121,6 +121,15 @@ public class TestDelegates extends TestCase { Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(), parameters); + // check the return type of the methods match. + assertTrue( + String.format("Delegate method %1$s.%2$s does not match the corresponding " + + "framework method which returns %3$s", + delegateClass.getName(), + getMethodName(delegateMethod), + originalMethod.getReturnType().getName()), + delegateMethod.getReturnType() == originalMethod.getReturnType()); + // check that the method has the annotation assertNotNull( String.format( 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 index 9a31705d0a3a..3e75c9ebc477 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java @@ -632,8 +632,8 @@ public class AsmAnalyzer { // field instruction @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { - // name is the field's name. - considerName(name); + // owner is the class that declares the field. + considerName(owner); // desc is the field's descriptor (see Type). considerDesc(desc); } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index 79aa642b7024..42360388f53b 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -125,6 +125,7 @@ public final class CreateInfo implements ICreateInfo { "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;", "android.content.res.Resources$Theme#obtainStyledAttributes", "android.content.res.Resources$Theme#resolveAttribute", + "android.content.res.Resources#localeToLanguageTag", "android.content.res.TypedArray#getValueAt", "android.graphics.BitmapFactory#finishDecode", "android.os.Handler#sendMessageAtTime", diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java index c988c7099cb8..2016c0e3b990 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java @@ -527,7 +527,8 @@ public class DependencyFinder { // field instruction @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { - // name is the field's name. + // owner is the class that declares the field. + considerName(owner); // desc is the field's descriptor (see Type). considerDesc(desc); } 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 index a79fba19d216..2ef3d5f3f1ea 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java @@ -114,6 +114,7 @@ public class Main { "android.os.*", // for android.os.Handler "android.database.ContentObserver", // for Digital clock "com.android.i18n.phonenumbers.*", // for TextView with autolink attribute + "android.app.DatePickerDialog", // b.android.com/28318 }, excludeClasses, new String[] { 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 index 7ec0d389be87..78e2c4899c1b 100644 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java +++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java @@ -83,6 +83,7 @@ public class AsmAnalyzerTest { "mock_android.dummy.InnerTest$MyStaticInnerClass", "mock_android.dummy.InnerTest$NotStaticInner1", "mock_android.dummy.InnerTest$NotStaticInner2", + "mock_android.util.EmptyArray", "mock_android.view.View", "mock_android.view.ViewGroup", "mock_android.view.ViewGroup$LayoutParams", @@ -217,15 +218,16 @@ public class AsmAnalyzerTest { 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); + ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", 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.util.EmptyArray", "mock_android.view.ViewGroup", - "mock_android.widget.TableLayout$LayoutParams", + "mock_android.widget.LinearLayout$LayoutParams", }, out_deps.keySet().toArray()); @@ -255,7 +257,7 @@ public class AsmAnalyzerTest { assertArrayEquals(new String[] { }, out_deps.keySet().toArray()); assertArrayEquals(new String[] { - "mock_android.widget.TableLayout", + "mock_android.widget.LinearLayout", }, keep.keySet().toArray()); } } diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar Binary files differindex 8dd04812a866..c6ca3c47afee 100644 --- a/tools/layoutlib/create/tests/data/mock_android.jar +++ b/tools/layoutlib/create/tests/data/mock_android.jar diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java b/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java new file mode 100644 index 000000000000..aaeebf641cc2 --- /dev/null +++ b/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java @@ -0,0 +1,24 @@ +/* + * 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.util; + +import java.lang.JavaClass; + +public class EmptyArray { + + public static final Object[] OBJECT = new Object[0]; +} diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java index 3870a63d9782..af56c4bfe3da 100644 --- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java @@ -16,11 +16,13 @@ package mock_android.widget; +import mock_android.util.EmptyArray; import mock_android.view.ViewGroup; public class LinearLayout extends ViewGroup { - public class LayoutParams extends mock_android.view.ViewGroup.LayoutParams { + Object[] mObjects = EmptyArray.OBJECT; + public class LayoutParams extends MarginLayoutParams { } |