summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt/AaptAssets.cpp5
-rw-r--r--tools/aapt/Bundle.h3
-rw-r--r--tools/aapt/Command.cpp12
-rw-r--r--tools/aapt/Images.cpp7
-rw-r--r--tools/aapt/Main.cpp19
-rw-r--r--tools/aapt/Package.cpp19
-rw-r--r--tools/aapt/Resource.cpp4
-rw-r--r--tools/aapt/ResourceTable.cpp157
-rw-r--r--tools/aapt/ResourceTable.h17
-rw-r--r--tools/aapt/XMLNode.cpp30
-rw-r--r--tools/aapt/XMLNode.h2
-rw-r--r--tools/layoutlib/Android.mk9
-rw-r--r--tools/layoutlib/api/.classpath3
-rw-r--r--tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java52
-rw-r--r--tools/layoutlib/bridge/.classpath6
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Paint.java25
-rw-r--r--tools/layoutlib/bridge/src/android/view/BridgeInflater.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java206
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java34
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java5
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java4
-rw-r--r--tools/layoutlib/create/.classpath2
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java2
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java2
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java16
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java17
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java10
29 files changed, 548 insertions, 126 deletions
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index d07e4de..027662d 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -78,7 +78,7 @@ static bool isHidden(const char *root, const char *path)
// Skip CVS but don't chatter about it.
return true;
} else if (strcasecmp(path, "thumbs.db") == 0
- || strcasecmp(path, "picassa.ini") == 0) {
+ || strcasecmp(path, "picasa.ini") == 0) {
// Skip suspected image indexes files.
type = "index";
} else if (path[strlen(path)-1] == '~') {
@@ -695,6 +695,9 @@ bool AaptGroupEntry::getKeysHiddenName(const char* name,
} else if (strcmp(name, "keyshidden") == 0) {
mask = out->MASK_KEYSHIDDEN;
value = out->KEYSHIDDEN_YES;
+ } else if (strcmp(name, "keyssoft") == 0) {
+ mask = out->MASK_KEYSHIDDEN;
+ value = out->KEYSHIDDEN_SOFT;
}
if (mask != 0) {
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 1d7b3ad..99fac2f 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -94,6 +94,8 @@ public:
void addPackageInclude(const char* file) { mPackageIncludes.add(file); }
const android::Vector<const char*>& getJarFiles() const { return mJarFiles; }
void addJarFile(const char* file) { mJarFiles.add(file); }
+ const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }
+ void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }
/*
* Set and get the file specification.
@@ -144,6 +146,7 @@ private:
android::String8 mConfigurations;
android::Vector<const char*> mPackageIncludes;
android::Vector<const char*> mJarFiles;
+ android::Vector<const char*> mNoCompressExtensions;
/* file specification */
int mArgc;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index c02e2c0..9f75d4b 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -586,6 +586,18 @@ int doDump(Bundle* bundle)
activityIcon.string());
}
}
+ printf("locales:");
+ Vector<String8> locales;
+ res.getLocales(&locales);
+ const size_t N = locales.size();
+ for (size_t i=0; i<N; i++) {
+ const char* localeStr = locales[i].string();
+ if (localeStr == NULL || strlen(localeStr) == 0) {
+ localeStr = "--_--";
+ }
+ printf(" '%s'", localeStr);
+ }
+ printf("\n");
} else if (strcmp("configurations", option) == 0) {
Vector<ResTable_config> configs;
res.getConfigurations(&configs);
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 4a766d1..9d5937c 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -562,10 +562,16 @@ getout:
static void checkNinePatchSerialization(Res_png_9patch* inPatch, void * data)
{
+ if (sizeof(void*) != sizeof(int32_t)) {
+ // can't deserialize on a non-32 bit system
+ return;
+ }
size_t patchSize = inPatch->serializedSize();
void * newData = malloc(patchSize);
memcpy(newData, data, patchSize);
Res_png_9patch* outPatch = inPatch->deserialize(newData);
+ // deserialization is done in place, so outPatch == newData
+ assert(outPatch == newData);
assert(outPatch->numXDivs == inPatch->numXDivs);
assert(outPatch->numYDivs == inPatch->numYDivs);
assert(outPatch->paddingLeft == inPatch->paddingLeft);
@@ -581,6 +587,7 @@ static void checkNinePatchSerialization(Res_png_9patch* inPatch, void * data)
for (int i = 0; i < outPatch->numColors; i++) {
assert(outPatch->colors[i] == inPatch->colors[i]);
}
+ free(newData);
}
static bool patch_equals(Res_png_9patch& patch1, Res_png_9patch& patch2) {
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index d86ad47..a1978da 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -46,6 +46,7 @@ void usage(void)
" List contents of Zip-compatible archive.\n\n", gProgName);
fprintf(stderr,
" %s d[ump] WHAT file.{apk} [asset [asset ...]]\n"
+ " badging Print the label and icon for the app declared in APK.\n"
" permissions Print the permissions from the APK.\n"
" resources Print the resource table from the APK.\n"
" configurations Print the configurations in the APK.\n"
@@ -53,6 +54,7 @@ void usage(void)
" xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName);
fprintf(stderr,
" %s p[ackage] [-f][-u][-m][-v][-x][-M AndroidManifest.xml] \\\n"
+ " [-0 extension [-0 extension ...]] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-P public-definitions-file] \\\n"
" [-S resource-sources] [-F apk-file] [-J R-file-dir] \\\n"
@@ -106,7 +108,9 @@ void usage(void)
" -M specify full path to AndroidManifest.xml to include in zip\n"
" -P specify where to output public resource definitions\n"
" -S directory in which to find resources\n"
- " -0 don't compress files we're adding\n");
+ " -0 specifies an additional extension for which such files will not\n"
+ " be stored compressed in the .apk. An empty string means to not\n"
+ " compress any files at all.\n");
}
/*
@@ -303,7 +307,18 @@ int main(int argc, char* const argv[])
bundle.setResourceSourceDir(argv[0]);
break;
case '0':
- bundle.setCompressionMethod(ZipEntry::kCompressStored);
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '-e' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ if (argv[0][0] != 0) {
+ bundle.addNoCompressExtension(argv[0]);
+ } else {
+ bundle.setCompressionMethod(ZipEntry::kCompressStored);
+ }
break;
default:
fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index 23f641a..0df4606 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -34,7 +34,7 @@ ssize_t processAssets(Bundle* bundle, ZipFile* zip,
const sp<AaptDir>& dir, const AaptGroupEntry& ge);
bool processFile(Bundle* bundle, ZipFile* zip,
const sp<AaptGroup>& group, const sp<AaptFile>& file);
-bool okayToCompress(const String8& pathName);
+bool okayToCompress(Bundle* bundle, const String8& pathName);
ssize_t processJarFiles(Bundle* bundle, ZipFile* zip);
/*
@@ -327,7 +327,7 @@ bool processFile(Bundle* bundle, ZipFile* zip,
} else if (!hasData) {
/* don't compress certain files, e.g. PNGs */
int compressionMethod = bundle->getCompressionMethod();
- if (!okayToCompress(storageName)) {
+ if (!okayToCompress(bundle, storageName)) {
compressionMethod = ZipEntry::kCompressStored;
}
result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod,
@@ -365,7 +365,7 @@ bool processFile(Bundle* bundle, ZipFile* zip,
* Determine whether or not we want to try to compress this file based
* on the file extension.
*/
-bool okayToCompress(const String8& pathName)
+bool okayToCompress(Bundle* bundle, const String8& pathName)
{
String8 ext = pathName.getPathExtension();
int i;
@@ -378,6 +378,19 @@ bool okayToCompress(const String8& pathName)
return false;
}
+ const android::Vector<const char*>& others(bundle->getNoCompressExtensions());
+ for (i = 0; i < (int)others.size(); i++) {
+ const char* str = others[i];
+ int pos = pathName.length() - strlen(str);
+ if (pos < 0) {
+ continue;
+ }
+ const char* path = pathName.string();
+ if (strcasecmp(path + pos, str) == 0) {
+ return false;
+ }
+ }
+
return true;
}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 0826b32..fd6ddb5 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -916,6 +916,10 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
}
}
+ if (table.validateLocalizations()) {
+ hasErrors = true;
+ }
+
if (hasErrors) {
return UNKNOWN_ERROR;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 6fe196a..3641458 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -638,6 +638,7 @@ status_t compileResourceFile(Bundle* bundle,
const String16 string16("string");
const String16 drawable16("drawable");
const String16 color16("color");
+ const String16 bool16("bool");
const String16 integer16("integer");
const String16 dimen16("dimen");
const String16 style16("style");
@@ -671,6 +672,10 @@ status_t compileResourceFile(Bundle* bundle,
const String16 many16("many");
const String16 quantityMany16("^many");
+ // useful attribute names and special values
+ const String16 name16("name");
+ const String16 translatable16("translatable");
+ const String16 false16("false");
const String16 myPackage(assets->getPackage());
@@ -950,6 +955,45 @@ status_t compileResourceFile(Bundle* bundle,
}
curIsStyled = true;
} else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
+ // Note the existence and locale of every string we process
+ char rawLocale[16];
+ curParams.getLocale(rawLocale);
+ String8 locale(rawLocale);
+ String16 name;
+ String16 translatable;
+
+ size_t n = block.getAttributeCount();
+ for (size_t i = 0; i < n; i++) {
+ size_t length;
+ const uint16_t* attr = block.getAttributeName(i, &length);
+ if (strcmp16(attr, name16.string()) == 0) {
+ name.setTo(block.getAttributeStringValue(i, &length));
+ } else if (strcmp16(attr, translatable16.string()) == 0) {
+ translatable.setTo(block.getAttributeStringValue(i, &length));
+ }
+ }
+
+ if (name.size() > 0) {
+ if (translatable == false16) {
+ // Untranslatable strings must only exist in the default [empty] locale
+ if (locale.size() > 0) {
+ fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
+ " in locale '%s'\n", String8(name).string(),
+ bundle->getResourceSourceDir(),
+ locale.string());
+ // hasErrors = localHasErrors = true;
+ } else {
+ // Intentionally empty block:
+ //
+ // Don't add untranslatable strings to the localization table; that
+ // way if we later see localizations of them, they'll be flagged as
+ // having no default translation.
+ }
+ } else {
+ outTable->addLocalization(name, locale);
+ }
+ }
+
curTag = &string16;
curType = string16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
@@ -963,6 +1007,10 @@ status_t compileResourceFile(Bundle* bundle,
curTag = &color16;
curType = color16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
+ } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
+ curTag = &bool16;
+ curType = bool16;
+ curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
} else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
curTag = &integer16;
curType = integer16;
@@ -1553,17 +1601,26 @@ inline uint32_t ResourceTable::getResId(const sp<Package>& p,
uint32_t ResourceTable::getResId(const String16& package,
const String16& type,
- const String16& name) const
+ const String16& name,
+ bool onlyPublic) const
{
sp<Package> p = mPackages.valueFor(package);
if (p == NULL) return 0;
// First look for this in the included resources...
+ uint32_t specFlags = 0;
uint32_t rid = mAssets->getIncludedResources()
.identifierForName(name.string(), name.size(),
type.string(), type.size(),
- package.string(), package.size());
+ package.string(), package.size(),
+ &specFlags);
if (rid != 0) {
+ if (onlyPublic) {
+ if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+ return 0;
+ }
+ }
+
if (Res_INTERNALID(rid)) {
return rid;
}
@@ -1584,7 +1641,8 @@ uint32_t ResourceTable::getResId(const String16& package,
uint32_t ResourceTable::getResId(const String16& ref,
const String16* defType,
const String16* defPackage,
- const char** outErrorMsg) const
+ const char** outErrorMsg,
+ bool onlyPublic) const
{
String16 package, type, name;
if (!ResTable::expandResourceRef(
@@ -1603,7 +1661,7 @@ uint32_t ResourceTable::getResId(const String16& ref,
String8(name).string()));
return 0;
}
- uint32_t res = getResId(package, type, name);
+ uint32_t res = getResId(package, type, name, onlyPublic);
NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
String8(package).string(), String8(type).string(),
String8(name).string(), res));
@@ -2036,6 +2094,93 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
}
+void
+ResourceTable::addLocalization(const String16& name, const String8& locale)
+{
+ mLocalizations[name].insert(locale);
+}
+
+
+/*!
+ * Flag various sorts of localization problems. '+' indicates checks already implemented;
+ * '-' indicates checks that will be implemented in the future.
+ *
+ * + A localized string for which no default-locale version exists => warning
+ * + A string for which no version in an explicitly-requested locale exists => warning
+ * + A localized translation of an translateable="false" string => warning
+ * - A localized string not provided in every locale used by the table
+ */
+status_t
+ResourceTable::validateLocalizations(void)
+{
+ status_t err = NO_ERROR;
+ const String8 defaultLocale;
+
+ // For all strings...
+ for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
+ nameIter != mLocalizations.end();
+ nameIter++) {
+ const set<String8>& configSet = nameIter->second; // naming convenience
+
+ // Look for strings with no default localization
+ if (configSet.count(defaultLocale) == 0) {
+ fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
+ String8(nameIter->first).string(), mBundle->getResourceSourceDir());
+ for (set<String8>::iterator locales = configSet.begin();
+ locales != configSet.end();
+ locales++) {
+ fprintf(stdout, " %s", (*locales).string());
+ }
+ fprintf(stdout, "\n");
+ // !!! TODO: throw an error here in some circumstances
+ }
+
+ // Check that all requested localizations are present for this string
+ if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
+ const char* allConfigs = mBundle->getConfigurations();
+ const char* start = allConfigs;
+ const char* comma;
+
+ do {
+ String8 config;
+ comma = strchr(start, ',');
+ if (comma != NULL) {
+ config.setTo(start, comma - start);
+ start = comma + 1;
+ } else {
+ config.setTo(start);
+ }
+
+ // don't bother with the pseudolocale "zz_ZZ"
+ if (config != "zz_ZZ") {
+ if (configSet.find(config) == configSet.end()) {
+ // okay, no specific localization found. it's possible that we are
+ // requiring a specific regional localization [e.g. de_DE] but there is an
+ // available string in the generic language localization [e.g. de];
+ // consider that string to have fulfilled the localization requirement.
+ String8 region(config.string(), 2);
+ if (configSet.find(region) == configSet.end()) {
+ // TODO: force an error if there is no default to fall back to
+ if (configSet.count(defaultLocale) == 0) {
+ fprintf(stdout, "aapt: warning: "
+ "*** string '%s' has no default or required localization "
+ "for '%s' in %s\n",
+ String8(nameIter->first).string(),
+ config.string(),
+ mBundle->getResourceSourceDir());
+ //err = UNKNOWN_ERROR;
+ }
+ }
+ }
+ }
+ } while (comma != NULL);
+ }
+ }
+
+ return err;
+}
+
+
status_t
ResourceFilter::parse(const char* arg)
{
@@ -2187,6 +2332,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
}
const size_t N = c->getEntries().size();
for (size_t ei=0; ei<N; ei++) {
+ ConfigDescription config = c->getEntries().keyAt(ei);
+ if (!filter.match(config)) {
+ continue;
+ }
sp<Entry> e = c->getEntries().valueAt(ei);
if (e == NULL) {
continue;
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index b36234d..fff4f49 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -10,6 +10,11 @@
#include "StringPool.h"
#include "SourcePos.h"
+#include <set>
+#include <map>
+
+using namespace std;
+
class ResourceTable;
enum {
@@ -136,12 +141,14 @@ public:
uint32_t getResId(const String16& package,
const String16& type,
- const String16& name) const;
+ const String16& name,
+ bool onlyPublic = false) const;
uint32_t getResId(const String16& ref,
const String16* defType = NULL,
const String16* defPackage = NULL,
- const char** outErrorMsg = NULL) const;
+ const char** outErrorMsg = NULL,
+ bool onlyPublic = false) const;
static bool isValidResourceName(const String16& s);
@@ -155,6 +162,8 @@ public:
status_t assignResourceIds();
status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
+ void addLocalization(const String16& name, const String8& locale);
+ status_t validateLocalizations(void);
status_t flatten(Bundle*, const sp<AaptFile>& dest);
@@ -491,7 +500,6 @@ private:
String16 mAssetsPackage;
sp<AaptAssets> mAssets;
- DefaultKeyedVector<String16, DefaultKeyedVector<String16, uint32_t> > mPublicNames;
DefaultKeyedVector<String16, sp<Package> > mPackages;
Vector<sp<Package> > mOrderedPackages;
uint32_t mNextPackageId;
@@ -500,6 +508,9 @@ private:
size_t mNumLocal;
SourcePos mCurrentXmlPos;
Bundle* mBundle;
+
+ // key = string resource name, value = set of locales in which that name is defined
+ map<String16, set<String8> > mLocalizations;
};
class ResourceFilter
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 8f45959..2ea453c 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -21,6 +21,7 @@
const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/";
const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android";
+const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/";
const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
const char* const ALLOWED_XLIFF_ELEMENTS[] = {
@@ -43,15 +44,27 @@ bool isWhitespace(const char16_t* str)
}
static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);
+static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);
-String16 getNamespaceResourcePackage(String16 namespaceUri)
+String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic)
{
//printf("%s starts with %s?\n", String8(namespaceUri).string(),
// String8(RESOURCES_PREFIX).string());
- if (!namespaceUri.startsWith(RESOURCES_PREFIX)) return String16();
+ size_t prefixSize;
+ bool isPublic = true;
+ if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
+ prefixSize = RESOURCES_PREFIX.size();
+ } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {
+ isPublic = false;
+ prefixSize = RESOURCES_PRV_PREFIX.size();
+ } else {
+ if (outIsPublic) *outIsPublic = isPublic; // = true
+ return String16();
+ }
+
//printf("YES!\n");
- const size_t prefixSize = RESOURCES_PREFIX.size();
//printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());
+ if (outIsPublic) *outIsPublic = isPublic;
return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
}
@@ -715,15 +728,18 @@ status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
for (size_t i=0; i<N; i++) {
const attribute_entry& e = mAttributes.itemAt(i);
if (e.ns.size() <= 0) continue;
- String16 pkg(getNamespaceResourcePackage(e.ns));
- NOISY(printf("Elem %s %s=\"%s\": namespace %s ===> %s\n",
+ bool nsIsPublic;
+ String16 pkg(getNamespaceResourcePackage(e.ns, &nsIsPublic));
+ NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
String8(getElementName()).string(),
String8(e.name).string(),
String8(e.string).string(),
- String8(e.ns).string(), String8(pkg).string()));
+ String8(e.ns).string(),
+ (nsIsPublic) ? "public" : "private",
+ String8(pkg).string()));
if (pkg.size() <= 0) continue;
uint32_t res = table != NULL
- ? table->getResId(e.name, &attr, &pkg, &errorMsg)
+ ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)
: assets->getIncludedResources().
identifierForName(e.name.string(), e.name.size(),
attr.string(), attr.size(),
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index 8c4243c..86548a2 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -17,7 +17,7 @@ extern const char* const RESOURCES_ANDROID_NAMESPACE;
bool isWhitespace(const char16_t* str);
-String16 getNamespaceResourcePackage(String16 namespaceUri);
+String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic = NULL);
status_t parseStyledString(Bundle* bundle,
const char* fileName,
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index b1bd465..6d606a9 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -35,11 +35,6 @@ built_core_dep := \
built_core_classes := \
$(call intermediates-dir-for,JAVA_LIBRARIES,core)/classes.jar
-built_policy_dep := \
- $(call intermediates-dir-for,JAVA_LIBRARIES,android.policy)/javalib.jar
-built_policy_classes := \
- $(call intermediates-dir-for,JAVA_LIBRARIES,android.policy)/classes.jar
-
built_layoutlib_create_jar := $(call intermediates-dir-for, \
JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
@@ -56,7 +51,6 @@ include $(BUILD_SYSTEM)/base_rules.mk
$(LOCAL_BUILT_MODULE): $(built_core_dep) \
$(built_framework_dep) \
- $(built_policy_dep) \
$(built_layoutlib_create_jar)
@echo "host layoutlib_create: $@"
@mkdir -p $(dir $@)
@@ -64,8 +58,7 @@ $(LOCAL_BUILT_MODULE): $(built_core_dep) \
$(hide) java -jar $(built_layoutlib_create_jar) \
$@ \
$(built_core_classes) \
- $(built_framework_classes) \
- $(built_policy_classes)
+ $(built_framework_classes)
#
diff --git a/tools/layoutlib/api/.classpath b/tools/layoutlib/api/.classpath
index 14535b7..a09ce5f 100644
--- a/tools/layoutlib/api/.classpath
+++ b/tools/layoutlib/api/.classpath
@@ -2,7 +2,6 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="var" path="DEVICE_SRC/extlibs/kxml2/lib/xmlpull_1_1_3_1.jar"/>
- <classpathentry kind="var" path="DEVICE_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/DEVICE_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
index d67f0e1..0810d29 100644
--- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
+++ b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
@@ -21,17 +21,65 @@ import java.util.Map;
/**
* Entry point of the Layout Lib. Implementations of this interface provide a method to compute
* and render a layout.
+ * <p/>
+ * <p/>{@link #getApiLevel()} gives the ability to know which methods are available.
+ * <p/>
+ * Changes in API level 2:
+ * <ul>
+ * <li>{@link #getApiLevel()}</li>
+ * <li>{@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)},
+ * deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, String, Map, Map, IProjectCallback, ILayoutLog)}.</li>
+ * </ul>
*/
public interface ILayoutBridge {
+
+ final int API_CURRENT = 2;
+
+ /**
+ * Returns the API level of the layout library.
+ * While no methods will ever be removed, some may become deprecated, and some new ones
+ * will appear.
+ */
+ int getApiLevel();
/**
* Initializes the Bridge object.
* @param fontOsLocation the location of the fonts.
* @param enumValueMap map attrName => { map enumFlagName => Integer value }.
* @return true if success.
+ * @since 1
*/
boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap);
+ /**
+ * Computes and renders a layout
+ * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the
+ * layout file.
+ * @param projectKey An Object identifying the project. This is used for the cache mechanism.
+ * @param screenWidth
+ * @param screenHeight
+ * @param themeName The name of the theme to use.
+ * @param isProjectTheme true if the theme is a project theme, false if it is a framework theme.
+ * @param projectResources the resources of the project. The map contains (String, map) pairs
+ * where the string is the type of the resource reference used in the layout file, and the
+ * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
+ * and the value is the resource value.
+ * @param frameworkResources the framework resources. The map contains (String, map) pairs
+ * where the string is the type of the resource reference used in the layout file, and the map
+ * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
+ * value is the resource value.
+ * @param projectCallback The {@link IProjectCallback} object to get information from
+ * the project.
+ * @param logger the object responsible for displaying warning/errors to the user.
+ * @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @since 2
+ */
+ ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback projectCallback, ILayoutLog logger);
/**
* Computes and renders a layout
@@ -54,7 +102,10 @@ public interface ILayoutBridge {
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
* @return an {@link ILayoutResult} object that contains the result of the layout.
+ * @deprecated Use {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
+ * @since 1
*/
+ @Deprecated
ILayoutResult computeLayout(IXmlPullParser layoutDescription,
Object projectKey,
int screenWidth, int screenHeight, String themeName,
@@ -69,6 +120,7 @@ public interface ILayoutBridge {
* <p/>The cache is not configuration dependent and should only be cleared when a
* resource changes (at this time only bitmaps and 9 patches go into the cache).
* @param objectKey the key for the project.
+ * @since 1
*/
void clearCaches(Object projectKey);
}
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 946c438..175a98b 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -4,9 +4,9 @@
<classpathentry kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="var" path="DEVICE_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/DEVICE_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
- <classpathentry kind="var" path="DEVICE_FRAMEWORK/layoutlib.jar" sourcepath="/DEVICE_SRC/java/android"/>
- <classpathentry kind="var" path="DEVICE_FRAMEWORK/ninepatch.jar" sourcepath="/DEVICE_SRC/tools/ninepatch"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/layoutlib.jar" sourcepath="/ANDROID_SRC/frameworks/base/core/java"/>
+ <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_SRC/development/tools/ninepatch/src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint.java b/tools/layoutlib/bridge/src/android/graphics/Paint.java
index 27276c5..13cc62d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint.java
@@ -45,15 +45,24 @@ public class Paint extends _Original_Paint {
new AffineTransform(), true, true);
private java.awt.FontMetrics mMetrics;
- public static final int ANTI_ALIAS_FLAG = _Original_Paint.ANTI_ALIAS_FLAG;
- public static final int FILTER_BITMAP_FLAG = _Original_Paint.FILTER_BITMAP_FLAG;
- public static final int DITHER_FLAG = _Original_Paint.DITHER_FLAG;
- public static final int UNDERLINE_TEXT_FLAG = _Original_Paint.UNDERLINE_TEXT_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int ANTI_ALIAS_FLAG = _Original_Paint.ANTI_ALIAS_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int FILTER_BITMAP_FLAG = _Original_Paint.FILTER_BITMAP_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int DITHER_FLAG = _Original_Paint.DITHER_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int UNDERLINE_TEXT_FLAG = _Original_Paint.UNDERLINE_TEXT_FLAG;
+ @SuppressWarnings("hiding")
public static final int STRIKE_THRU_TEXT_FLAG = _Original_Paint.STRIKE_THRU_TEXT_FLAG;
- public static final int FAKE_BOLD_TEXT_FLAG = _Original_Paint.FAKE_BOLD_TEXT_FLAG;
- public static final int LINEAR_TEXT_FLAG = _Original_Paint.LINEAR_TEXT_FLAG;
- public static final int SUBPIXEL_TEXT_FLAG = _Original_Paint.SUBPIXEL_TEXT_FLAG;
- public static final int DEV_KERN_TEXT_FLAG = _Original_Paint.DEV_KERN_TEXT_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int FAKE_BOLD_TEXT_FLAG = _Original_Paint.FAKE_BOLD_TEXT_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int LINEAR_TEXT_FLAG = _Original_Paint.LINEAR_TEXT_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int SUBPIXEL_TEXT_FLAG = _Original_Paint.SUBPIXEL_TEXT_FLAG;
+ @SuppressWarnings("hiding")
+ public static final int DEV_KERN_TEXT_FLAG = _Original_Paint.DEV_KERN_TEXT_FLAG;
public static class FontMetrics extends _Original_Paint.FontMetrics {
}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index a0c0c2b..0910d79 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -66,7 +66,6 @@ public final class BridgeInflater extends LayoutInflater {
mConstructorArgs[0] = context;
}
- @SuppressWarnings("unchecked")
@Override
public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
View view = null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 0afd9f9..b898192 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,10 +16,11 @@
package com.android.layoutlib.bridge;
-import com.android.layoutlib.api.IProjectCallback;
+import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.ILayoutBridge;
import com.android.layoutlib.api.ILayoutLog;
import com.android.layoutlib.api.ILayoutResult;
+import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
import com.android.layoutlib.api.IXmlPullParser;
@@ -29,8 +30,6 @@ import com.android.ninepatch.NinePatch;
import com.android.tools.layoutlib.create.OverrideMethod;
import com.android.tools.layoutlib.create.OverrideMethod.MethodListener;
-import org.xmlpull.v1.XmlPullParser;
-
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Region;
@@ -39,16 +38,16 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
-
-import com.android.internal.util.XmlUtils;
-
import android.util.TypedValue;
import android.view.BridgeInflater;
import android.view.IWindow;
import android.view.IWindowSession;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
+import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.AttachInfo;
@@ -65,14 +64,18 @@ import java.util.Map;
/**
* Main entry point of the LayoutLib Bridge.
* <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #computeLayout(XmlPullParser, int, int, boolean, Map)}.
+ * {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
*/
public final class Bridge implements ILayoutBridge {
private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-
- private ILayoutLog mLogger;
+
+ public static class StaticMethodNotImplementedException extends RuntimeException {
+ public StaticMethodNotImplementedException(String msg) {
+ super(msg);
+ }
+ }
/**
* Maps from id to resource name/type.
@@ -100,7 +103,7 @@ public final class Bridge implements ILayoutBridge {
private static Map<String, Map<String, Integer>> sEnumValueMap;
private final static MethodListener sNullMethodListener = new MethodListener() {
- public void onInvoke(String signature, Object caller) {
+ public void onInvoke(String signature, boolean isNative, Object caller) {
// pass
}
};
@@ -124,6 +127,9 @@ public final class Bridge implements ILayoutBridge {
}
};
+ /** Logger defined during a compute layout operation. */
+ private static ILayoutLog sLogger = sDefaultLogger;
+
private final static String[] IGNORED_STATIC_METHODS = new String[] {
"android.content.res.AssetManager#init()V",
"android.content.res.AssetManager#deleteTheme(I)V",
@@ -135,6 +141,14 @@ public final class Bridge implements ILayoutBridge {
"android.view.animation.Transformation#<init>()V",
"android.view.animation.Transformation#clear()V",
};
+
+ /*
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
+ */
+ public int getApiLevel() {
+ return API_CURRENT;
+ }
/*
* (non-Javadoc)
@@ -156,14 +170,25 @@ public final class Bridge implements ILayoutBridge {
// set a the default listener for the rest of the static methods. It prints out
- // missing stub methods but only if the environment variable DEBUG_LAYOUT is set.
- if (System.getenv("DEBUG_LAYOUT") != null) {
- OverrideMethod.setDefaultListener(new MethodListener() {
- public void onInvoke(String signature, Object caller) {
- System.out.println("Missing Stub: " + signature);
+ // missing stub methods and then throws an exception for native methods if the
+ // environment variable DEBUG_LAYOUT is not defined.
+ OverrideMethod.setDefaultListener(new MethodListener() {
+ public void onInvoke(String signature, boolean isNative, Object caller) {
+ if (isNative) {
+ if (sLogger != null) {
+ sLogger.error("Missing Stub: " + signature +
+ (isNative ? " (native)" : ""));
+ }
+
+ if (System.getenv("DEBUG_LAYOUT") == null) {
+ // TODO throwing this exception doesn't seem that useful. It breaks
+ // the layout editor yet doesn't display anything meaningful to the
+ // user. Having the error in the console is just as useful.
+ throw new StaticMethodNotImplementedException(signature);
+ }
}
- });
- }
+ }
+ });
// load the fonts.
FontLoader fontLoader = FontLoader.create(fontOsLocation);
@@ -179,7 +204,7 @@ public final class Bridge implements ILayoutBridge {
// the internal version), and put the content in the maps.
try {
// WARNING: this only works because the class is already loaded, and therefore
- // the objects returned by Field.get() are the same as the onea used by
+ // the objects returned by Field.get() are the same as the ones used by
// the code accessing the R class.
// int[] does not implement equals/hashCode, and if the parsing used a different class
// loader for the R class, this would NOT work.
@@ -223,29 +248,48 @@ public final class Bridge implements ILayoutBridge {
}
/*
+ * For compatilibty purposes, we implement the old deprecated version of computeLayout.
* (non-Javadoc)
* @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
*/
+ @Deprecated
public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
Object projectKey,
int screenWidth, int screenHeight, String themeName,
Map<String, Map<String, IResourceValue>> projectResources,
Map<String, Map<String, IResourceValue>> frameworkResources,
IProjectCallback customViewLoader, ILayoutLog logger) {
- // DEBUG
- //long time1 = System.currentTimeMillis();
+ boolean isProjectTheme = false;
+ if (themeName.charAt(0) == '*') {
+ themeName = themeName.substring(1);
+ isProjectTheme = true;
+ }
+ return computeLayout(layoutDescription, projectKey, screenWidth, screenHeight, themeName, isProjectTheme,
+ projectResources, frameworkResources, customViewLoader, logger);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+ */
+ public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback customViewLoader, ILayoutLog logger) {
if (logger == null) {
logger = sDefaultLogger;
}
- mLogger = logger;
+ sLogger = logger;
// find the current theme and compute the style inheritance map
Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
new HashMap<IStyleResourceValue, IStyleResourceValue>();
- IStyleResourceValue currentTheme = computeStyleMaps(themeName,
+ IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme,
projectResources.get(BridgeConstants.RES_STYLE),
frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap);
@@ -278,11 +322,11 @@ public final class Bridge implements ILayoutBridge {
View view = inflater.inflate(parser, root);
// set the AttachInfo on the root view.
- AttachInfo info = new AttachInfo(new Handler());
+ AttachInfo info = new AttachInfo(new WindowSession(), new Window(),
+ new Handler(), null);
info.mHasWindowFocus = true;
info.mWindowVisibility = View.VISIBLE;
info.mInTouchMode = false; // this is so that we can display selections.
- info.mSession = new WindowSession();
root.dispatchAttachedToWindow(info, 0);
// get the background drawable
@@ -307,10 +351,6 @@ public final class Bridge implements ILayoutBridge {
root.draw(canvas);
canvas.dispose();
- // DEBUG
- //long time2 = System.currentTimeMillis();
- //System.out.println("Layout: " + (time2 - time1));
-
return new LayoutResult(visit(((ViewGroup)view).getChildAt(0), context),
canvas.getImage());
} catch (Throwable e) {
@@ -326,6 +366,9 @@ public final class Bridge implements ILayoutBridge {
// then return with an ERROR status and the message from the real exception
return new LayoutResult(ILayoutResult.ERROR,
t.getClass().getSimpleName() + ": " + t.getMessage());
+ } finally {
+ // Remove the global logger
+ sLogger = sDefaultLogger;
}
}
@@ -354,7 +397,6 @@ public final class Bridge implements ILayoutBridge {
/**
* Returns the name of a framework resource whose value is an int array.
* @param array
- * @return
*/
public static String resolveResourceValue(int[] array) {
return sRArrayMap.get(array);
@@ -388,7 +430,6 @@ public final class Bridge implements ILayoutBridge {
* bounds of all the views.
* @param view the root View
* @param context the context.
- * @return
*/
private ILayoutViewInfo visit(View view, BridgeContext context) {
if (view == null) {
@@ -417,15 +458,15 @@ public final class Bridge implements ILayoutBridge {
* @param themeName the name of the current theme. In order to differentiate project and
* platform themes sharing the same name, all project themes must be prepended with
* a '*' character.
+ * @param isProjectTheme Is this a project theme
* @param inProjectStyleMap the project style map
* @param inFrameworkStyleMap the framework style map
* @param outInheritanceMap the map of style inheritance. This is filled by the method
* @return the {@link IStyleResourceValue} matching <var>themeName</var>
*/
private IStyleResourceValue computeStyleMaps(
- String themeName,
- Map<String, IResourceValue> inProjectStyleMap,
- Map<String, IResourceValue> inFrameworkStyleMap,
+ String themeName, boolean isProjectTheme, Map<String,
+ IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
@@ -433,12 +474,9 @@ public final class Bridge implements ILayoutBridge {
IResourceValue theme = null;
// project theme names have been prepended with a *
- if (themeName.charAt(0) == '*') {
- themeName = themeName.substring(1);
+ if (isProjectTheme) {
theme = inProjectStyleMap.get(themeName);
- }
-
- if (theme == null) {
+ } else {
theme = inFrameworkStyleMap.get(themeName);
}
@@ -550,15 +588,13 @@ public final class Bridge implements ILayoutBridge {
return (IStyleResourceValue)parent;
}
- mLogger.error(String.format("Unable to resolve parent style name: ", parentName));
+ sLogger.error(String.format("Unable to resolve parent style name: ", parentName));
return null;
}
/**
- * Compute the name of the parent style, or <code>null</code> if the style is a root style.
- * @param styleName
- * @return
+ * Computes the name of the parent style, or <code>null</code> if the style is a root style.
*/
private String getParentName(String styleName) {
int index = styleName.lastIndexOf('.');
@@ -572,8 +608,6 @@ public final class Bridge implements ILayoutBridge {
/**
* Returns the top screen offset. This depends on whether the current theme defines the user
* of the title and status bars.
- * @param currentTheme
- * @param styleInheritanceMap
* @return the pixel height offset
*/
private int getScreenOffset(IStyleResourceValue currentTheme, BridgeContext context) {
@@ -705,61 +739,135 @@ public final class Bridge implements ILayoutBridge {
}
/**
- * Implementation of IWindowSession so that mSession is not null in the SurfaceView.
+ * Implementation of {@link IWindowSession} so that mSession is not null in
+ * the {@link SurfaceView}.
*/
private static final class WindowSession implements IWindowSession {
- public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3) throws RemoteException {
+ @SuppressWarnings("unused")
+ public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+ throws RemoteException {
// pass for now.
return 0;
}
+ @SuppressWarnings("unused")
public void finishDrawing(IWindow arg0) throws RemoteException {
// pass for now.
}
+ @SuppressWarnings("unused")
public void finishKey(IWindow arg0) throws RemoteException {
// pass for now.
}
+ @SuppressWarnings("unused")
public boolean getInTouchMode() throws RemoteException {
// pass for now.
return false;
}
+ @SuppressWarnings("unused")
public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
// pass for now.
return null;
}
+ @SuppressWarnings("unused")
public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
// pass for now.
return null;
}
+ @SuppressWarnings("unused")
public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
- Rect arg5, Rect arg6, Surface arg7) throws RemoteException {
+ boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Surface arg8)
+ throws RemoteException {
// pass for now.
return 0;
}
+ public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
public void remove(IWindow arg0) throws RemoteException {
// pass for now.
}
+ @SuppressWarnings("unused")
public void setInTouchMode(boolean arg0) throws RemoteException {
// pass for now.
}
+ @SuppressWarnings("unused")
public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
// pass for now.
}
+ public void setInsets(IWindow window, int touchable, Rect contentInsets,
+ Rect visibleInsets) {
+ // pass for now.
+ }
+
public IBinder asBinder() {
// pass for now.
return null;
}
-
- };
+ }
+
+ /**
+ * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+ */
+ private static final class Window implements IWindow {
+
+ @SuppressWarnings("unused")
+ public void dispatchAppVisibility(boolean arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void dispatchGetNewSurface() throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void dispatchKey(KeyEvent arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void dispatchPointer(MotionEvent arg0, long arg1) throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void dispatchTrackball(MotionEvent arg0, long arg1) throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
+ throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4)
+ throws RemoteException {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
+ public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
+ // pass for now.
+ }
+
+ public IBinder asBinder() {
+ // pass for now.
+ return null;
+ }
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 0a90160..cb9509b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -428,8 +428,12 @@ public final class BridgeContext extends Context {
* Searches for, and returns a {@link IResourceValue} by its reference.
* <p/>
* The reference format can be:
- * <pre>@[android:]resType/resName</pre>
- * <pre>?[android:]resType/resName</pre>
+ * <pre>@resType/resName</pre>
+ * <pre>@android:resType/resName</pre>
+ * <pre>@resType/android:resName</pre>
+ * <pre>?resType/resName</pre>
+ * <pre>?android:resType/resName</pre>
+ * <pre>?resType/android:resName</pre>
* Any other string format will return <code>null</code>.
* <p/>
* The actual format of a reference is <pre>@[namespace:]resType/resName</pre> but this method
@@ -478,6 +482,13 @@ public final class BridgeContext extends Context {
// it's just an item name.
referenceName = segments[0];
}
+
+ // now we look for android: in the referenceName in order to support format
+ // such as: ?attr/android:name
+ if (referenceName.startsWith(BridgeConstants.PREFIX_ANDROID)) {
+ frameworkOnly = true;
+ referenceName = referenceName.substring(BridgeConstants.PREFIX_ANDROID.length());
+ }
// Now look for the item in the theme, starting with the current one.
if (frameworkOnly) {
@@ -503,9 +514,16 @@ public final class BridgeContext extends Context {
reference = reference.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
}
- // at this point, value contains type/name (drawable/foo for instance)
+ // at this point, value contains type/[android:]name (drawable/foo for instance)
String[] segments = reference.split("\\/");
+ // now we look for android: in the resource name in order to support format
+ // such as: @drawable/android:name
+ if (segments[1].startsWith(BridgeConstants.PREFIX_ANDROID)) {
+ frameworkOnly = true;
+ segments[1] = segments[1].substring(BridgeConstants.PREFIX_ANDROID.length());
+ }
+
return findResValue(segments[0], segments[1], frameworkOnly);
}
@@ -518,8 +536,7 @@ public final class BridgeContext extends Context {
* @param resType the type of the resource
* @param resName the name of the resource
* @param frameworkOnly if <code>true</code>, the method does not search in the
- * project resources.
- * @return
+ * project resources
*/
private IResourceValue findResValue(String resType, String resName, boolean frameworkOnly) {
// map of IResouceValue for the given type
@@ -613,7 +630,6 @@ public final class BridgeContext extends Context {
* there's a field com.android.internal.R.styleable.View_xyz and the field value is the index
* that is used to reference the attribute later in the TypedArray.
*
- * @param classNames The parent class name where to look, e.g. "com.android.internal.R"
* @param attrs An attribute array reference given to obtainStyledAttributes.
* @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the
* attribute array. Returns null if nothing is found.
@@ -669,7 +685,7 @@ public final class BridgeContext extends Context {
/**
* Searches for the attribute referenced by its internal id.
*
- * @param attrs An attribute reference given to obtainStyledAttributes such as defStyle.
+ * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
* @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null
* if nothing is found.
*/
@@ -963,6 +979,7 @@ public final class BridgeContext extends Context {
}
+ @SuppressWarnings("unused")
@Override
public FileInputStream openFileInput(String arg0)
throws FileNotFoundException {
@@ -970,6 +987,7 @@ public final class BridgeContext extends Context {
return null;
}
+ @SuppressWarnings("unused")
@Override
public FileOutputStream openFileOutput(String arg0, int arg1)
throws FileNotFoundException {
@@ -1053,12 +1071,14 @@ public final class BridgeContext extends Context {
}
+ @SuppressWarnings("unused")
@Override
public void setWallpaper(Bitmap arg0) throws IOException {
// TODO Auto-generated method stub
}
+ @SuppressWarnings("unused")
@Override
public void setWallpaper(InputStream arg0) throws IOException {
// TODO Auto-generated method stub
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
index 8bd4ba8..6ab6e32 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
@@ -435,9 +435,8 @@ public final class BridgeResources extends Resources {
}
/**
- * Builds and throws a {@link NotFoundException} based on a resource id and a resource type.
+ * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource type.
* @param id the id of the resource
- * @param resType the type of the resource.
* @throws NotFoundException
*/
private void throwException(int id) throws NotFoundException {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
index 1b3d583..1bdd1cc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
@@ -40,7 +40,8 @@ import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
- * Implementation of the {@link IFontLoader} to provide {@link Font} object to the layout lib.
+ * Provides {@link Font} object to the layout lib.
+ * <p/>
* The fonts are loaded from the SDK directory. Family/style mapping is done by parsing the
* fonts.xml file located alongside the ttf files.
*/
@@ -247,6 +248,7 @@ public final class FontLoader {
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
+ @SuppressWarnings("unused")
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (mFontInfo != null) {
@@ -257,6 +259,7 @@ public final class FontLoader {
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
+ @SuppressWarnings("unused")
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if (localName.equals(NODE_LEVEL[mDepth-1])) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
index fb885a4..c4c5225 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
@@ -71,7 +71,7 @@ public final class LayoutResult implements ILayoutResult {
}
/**
- * Implementation of {@link ILayoutViewInfo}
+ * Implementation of {@link ILayoutResult.ILayoutViewInfo}
*/
public static final class LayoutViewInfo implements ILayoutViewInfo {
private final Object mKey;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
index 9c7abcf..fbdf8dc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
@@ -205,7 +205,7 @@ public final class ResourceHelper {
this.unit = unit;
this.scale = scale;
}
- };
+ }
private final static UnitEntry[] sUnitNames = new UnitEntry[] {
new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
@@ -222,8 +222,6 @@ public final class ResourceHelper {
/**
* Returns the raw value from the given string.
* This object is only valid until the next call on to {@link ResourceHelper}.
- * @param s
- * @return
*/
public static TypedValue getValue(String s) {
if (stringToFloat(s, mValue)) {
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
index fecb8d0..0c60f6a 100644
--- a/tools/layoutlib/create/.classpath
+++ b/tools/layoutlib/create/.classpath
@@ -4,6 +4,6 @@
<classpathentry excluding="mock_android/" kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="var" path="DEVICE_SRC/prebuilt/common/asm/asm-3.1.jar" sourcepath="/DEVICE_SRC/extlibs/asm-3.1/src"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index f1da42a..b4e2c2b 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -187,7 +187,7 @@ public class AsmGenerator {
for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
ClassReader cr = entry.getValue();
- byte[] b = transform(cr, false /* stubNativesOnly */);
+ byte[] b = transform(cr, true /* stubNativesOnly */);
String name = classNameToEntryPath(transformName(cr.getClassName()));
all.put(name, b);
}
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 9202e44..13443d5 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
@@ -68,7 +68,7 @@ public class Main {
"android.view.SurfaceView", "android.view._Original_SurfaceView",
},
new String[] { // methods deleted from their return type.
- "android.graphics.Paint", // class to delete method from
+ "android.graphics.Paint", // class to delete method from
"android.graphics.Paint$Align", // list of type identifying methods to delete
"android.graphics.Paint$Style",
"android.graphics.Paint$Join",
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
index 61dd151..b061a15 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
@@ -34,13 +34,14 @@ public final class OverrideMethod {
*
* @param signature The signature of the method being invoked, composed of the
* binary class name followed by the method descriptor (aka argument
- * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
+ * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
+ * @param isNative True if the method was a native method.
* @param caller The calling object. Null for static methods, "this" for instance methods.
*/
- public void onInvoke(String signature, Object caller);
+ public void onInvoke(String signature, boolean isNative, Object caller);
}
- /** Map of method overriden. */
+ /** Map of method overridden. */
private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>();
/** Default listener for all method not listed in sMethods. Nothing if null. */
private static MethodListener sDefaultListener = null;
@@ -77,15 +78,16 @@ public final class OverrideMethod {
*
* @param signature The signature of the method being invoked, composed of the
* binary class name followed by the method descriptor (aka argument
- * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
+ * types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
+ * @param isNative True if the method was a native method.
* @param caller The calling object. Null for static methods, "this" for instance methods.
*/
- public static void invoke(String signature, Object caller) {
+ public static void invoke(String signature, boolean isNative, Object caller) {
MethodListener i = sMethods.get(signature);
if (i != null) {
- i.onInvoke(signature, caller);
+ i.onInvoke(signature, isNative, caller);
} else if (sDefaultListener != null) {
- sDefaultListener.onInvoke(signature, caller);
+ sDefaultListener.onInvoke(signature, isNative, caller);
}
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
index 2450d4b..9bb64bd 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
@@ -46,13 +46,15 @@ class StubMethodAdapter implements MethodVisitor {
private boolean mMessageGenerated;
private final boolean mIsStatic;
+ private final boolean mIsNative;
public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
- String invokeSignature, boolean isStatic) {
+ String invokeSignature, boolean isStatic, boolean isNative) {
mParentVisitor = mv;
mReturnType = returnType;
mInvokeSignature = invokeSignature;
mIsStatic = isStatic;
+ mIsNative = isNative;
if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
mIsInitMethod = true;
@@ -61,20 +63,23 @@ class StubMethodAdapter implements MethodVisitor {
private void generateInvoke() {
/* Generates the code:
- * OverrideMethod.invoke("signature", this);
+ * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
*/
mParentVisitor.visitLdcInsn(mInvokeSignature);
+ // push true or false
+ mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
+ // push null or this
if (mIsStatic) {
- mParentVisitor.visitInsn(Opcodes.ACONST_NULL); // push null
+ mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
} else {
- mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); // push this
+ mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
}
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod",
"invoke",
- "(Ljava/lang/String;Ljava/lang/Object;)V");
+ "(Ljava/lang/String;ZLjava/lang/Object;)V");
}
-
+
private void generateReturn() {
/* Generates one of, depending on the return type:
* return;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
index a84353c..e294d56 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
@@ -130,17 +130,19 @@ class TransformClassAdapter extends ClassAdapter {
(mStubAll ||
(access & Opcodes.ACC_NATIVE) != 0) ||
mStubMethods.contains(methodSignature)) {
+
+ boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
+ boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
// remove abstract, final and native
access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
- boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-
String invokeSignature = methodSignature + desc;
- mLog.debug(" Stub: %s", invokeSignature);
+ mLog.debug(" Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
- return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature, isStatic);
+ return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
+ isStatic, isNative);
} else {
mLog.debug(" Keep: %s %s", name, desc);