diff options
Diffstat (limited to 'tools')
24 files changed, 159 insertions, 351 deletions
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 77df6e5..c53f7f1 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -37,7 +37,7 @@ public: mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false), mUpdate(false), mExtending(false), mRequireLocalization(false), mPseudolocalize(false), - mValues(false), + mUTF8(false), mEncodingSpecified(false), mValues(false), mCompressionMethod(0), mOutputAPKFile(NULL), mAssetSourceDir(NULL), mProguardFile(NULL), mAndroidManifestFile(NULL), mPublicOutputFile(NULL), @@ -76,6 +76,10 @@ public: void setRequireLocalization(bool val) { mRequireLocalization = val; } bool getPseudolocalize(void) const { return mPseudolocalize; } void setPseudolocalize(bool val) { mPseudolocalize = val; } + bool getUTF8(void) const { return mUTF8; } + void setUTF8(bool val) { mUTF8 = val; } + bool getEncodingSpecified(void) const { return mEncodingSpecified; } + void setEncodingSpecified(bool val) { mEncodingSpecified = val; } bool getValues(void) const { return mValues; } void setValues(bool val) { mValues = val; } int getCompressionMethod(void) const { return mCompressionMethod; } @@ -112,7 +116,12 @@ public: void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); } const char* getMinSdkVersion() const { return mMinSdkVersion; } - void setMinSdkVersion(const char* val) { mMinSdkVersion = val; } + void setMinSdkVersion(const char* val) { + mMinSdkVersion = val; + if (!mEncodingSpecified) { + setUTF8(isUTF8Available()); + } + } const char* getTargetSdkVersion() const { return mTargetSdkVersion; } void setTargetSdkVersion(const char* val) { mTargetSdkVersion = val; } const char* getMaxSdkVersion() const { return mMaxSdkVersion; } @@ -163,6 +172,8 @@ private: bool mExtending; bool mRequireLocalization; bool mPseudolocalize; + bool mUTF8; + bool mEncodingSpecified; bool mValues; int mCompressionMethod; bool mJunkPath; @@ -194,6 +205,20 @@ private: /* misc stuff */ int mPackageCount; #endif + + /* UTF-8 is only available on APIs 7 or above or + * SDK levels that have code names. + */ + bool isUTF8Available() { + char *end; + int minSdkNum = (int)strtol(mMinSdkVersion, &end, 0); + if (*end == '\0') { + if (minSdkNum < 7) { + return false; + } + } + return true; + } }; #endif // __BUNDLE_H diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 3a30c0a..5d345e6 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -412,6 +412,7 @@ int doDump(Bundle* bundle) } tree.restart(); printXMLBlock(&tree); + tree.uninit(); delete asset; asset = NULL; } diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 0b51ad8..1e6b52e 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -59,7 +59,7 @@ void usage(void) " [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n" " [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n" " [--max-sdk-version VAL] [--app-version VAL] \\\n" - " [--app-version-name TEXT] [--custom-package VAL] \\\n" + " [--app-version-name TEXT] [--custom-package VAL] [--utf16] \\\n" " [-I base-package [-I base-package ...]] \\\n" " [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n" " [-S resource-sources [-S resource-sources ...]] " @@ -122,7 +122,8 @@ void usage(void) " be stored compressed in the .apk. An empty string means to not\n" " compress any files at all.\n" " --min-sdk-version\n" - " inserts android:minSdkVersion in to manifest.\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" " --target-sdk-version\n" " inserts android:targetSdkVersion in to manifest.\n" " --max-sdk-version\n" @@ -134,7 +135,10 @@ void usage(void) " --version-name\n" " inserts android:versionName in to manifest.\n" " --custom-package\n" - " generates R.java into a different package.\n"); + " generates R.java into a different package.\n" + " --utf16\n" + " changes default encoding for resources to UTF-16. Only useful when API\n" + " level is set to 7 or higher where the default encoding is UTF-8.\n"); } /* @@ -429,6 +433,9 @@ int main(int argc, char* const argv[]) goto bail; } bundle.setCustomPackage(argv[0]); + } else if (strcmp(cp, "-utf16") == 0) { + bundle.setEncodingSpecified(true); + bundle.setUTF8(false); } else { fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp); wantUsage = true; diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 02b46aa..ae8f242 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -171,7 +171,8 @@ static sp<AaptFile> getResourceFile(const sp<AaptAssets>& assets, bool makeIfNec NULL, String8()); } -static status_t parsePackage(const sp<AaptAssets>& assets, const sp<AaptGroup>& grp) +static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets, + const sp<AaptGroup>& grp) { if (grp->getFiles().size() != 1) { fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n", @@ -215,6 +216,22 @@ static status_t parsePackage(const sp<AaptAssets>& assets, const sp<AaptGroup>& assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len))); + String16 uses_sdk16("uses-sdk"); + while ((code=block.next()) != ResXMLTree::END_DOCUMENT + && code != ResXMLTree::BAD_DOCUMENT) { + if (code == ResXMLTree::START_TAG) { + if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) { + ssize_t minSdkIndex = block.indexOfAttribute("android", + "minSdkVersion"); + if (minSdkIndex >= 0) { + String8 minSdkString = String8( + block.getAttributeStringValue(minSdkIndex, &len)); + bundle->setMinSdkVersion(minSdkString.string()); + } + } + } + } + return NO_ERROR; } @@ -597,7 +614,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) return UNKNOWN_ERROR; } - status_t err = parsePackage(assets, androidManifestFile); + status_t err = parsePackage(bundle, assets, androidManifestFile); if (err != NO_ERROR) { return err; } @@ -613,6 +630,12 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) NOISY(printf("Found %d included resource packages\n", (int)table.size())); + // Standard flags for compiled XML and optional UTF-8 encoding + int xmlFlags = XML_COMPILE_STANDARD_RESOURCE; + if (bundle->getUTF8()) { + xmlFlags |= XML_COMPILE_UTF8; + } + // -------------------------------------------------------------- // First, gather all resource information. // -------------------------------------------------------------- @@ -763,7 +786,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) ResourceDirIterator it(layouts, String8("layout")); while ((err=it.next()) == NO_ERROR) { String8 src = it.getFile()->getPrintableSource(); - err = compileXmlFile(assets, it.getFile(), &table); + err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); if (err == NO_ERROR) { ResXMLTree block; block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true); @@ -782,7 +805,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) if (anims != NULL) { ResourceDirIterator it(anims, String8("anim")); while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); + err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); if (err != NO_ERROR) { hasErrors = true; } @@ -797,7 +820,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) if (xmls != NULL) { ResourceDirIterator it(xmls, String8("xml")); while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); + err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); if (err != NO_ERROR) { hasErrors = true; } @@ -819,7 +842,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) if (colors != NULL) { ResourceDirIterator it(colors, String8("color")); while ((err=it.next()) == NO_ERROR) { - err = compileXmlFile(assets, it.getFile(), &table); + err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); if (err != NO_ERROR) { hasErrors = true; } @@ -835,7 +858,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) ResourceDirIterator it(menus, String8("menu")); while ((err=it.next()) == NO_ERROR) { String8 src = it.getFile()->getPrintableSource(); - err = compileXmlFile(assets, it.getFile(), &table); + err = compileXmlFile(assets, it.getFile(), &table, xmlFlags); if (err != NO_ERROR) { hasErrors = true; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 19b9b01..a9cbd11 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -39,6 +39,10 @@ status_t compileXmlFile(const sp<AaptAssets>& assets, root->removeWhitespace(false, NULL); } + if ((options&XML_COMPILE_UTF8) != 0) { + root->setUTF8(true); + } + bool hasErrors = false; if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { @@ -2505,7 +2509,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) // Iterate through all data, collecting all values (strings, // references, etc). - StringPool valueStrings; + StringPool valueStrings = StringPool(false, bundle->getUTF8()); for (pi=0; pi<N; pi++) { sp<Package> p = mOrderedPackages.itemAt(pi); if (p->getTypes().size() == 0) { @@ -2513,8 +2517,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) continue; } - StringPool typeStrings; - StringPool keyStrings; + StringPool typeStrings = StringPool(false, bundle->getUTF8()); + StringPool keyStrings = StringPool(false, bundle->getUTF8()); const size_t N = p->getOrderedTypes().size(); for (size_t ti=0; ti<N; ti++) { diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index caa01b3..cfa75a71 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -24,6 +24,7 @@ enum { XML_COMPILE_COMPACT_WHITESPACE = 1<<2, XML_COMPILE_STRIP_WHITESPACE = 1<<3, XML_COMPILE_STRIP_RAW_VALUES = 1<<4, + XML_COMPILE_UTF8 = 1<<5, XML_COMPILE_STANDARD_RESOURCE = XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp index 715170a..ec58591 100644 --- a/tools/aapt/StringPool.cpp +++ b/tools/aapt/StringPool.cpp @@ -30,8 +30,8 @@ void printStringPool(const ResStringPool* pool) } } -StringPool::StringPool(bool sorted) - : mSorted(sorted), mValues(-1), mIdents(-1) +StringPool::StringPool(bool sorted, bool utf8) + : mSorted(sorted), mUTF8(utf8), mValues(-1), mIdents(-1) { } @@ -165,6 +165,16 @@ sp<AaptFile> StringPool::createStringBlock() return err == NO_ERROR ? pool : NULL; } +#define ENCODE_LENGTH(str, chrsz, strSize) \ +{ \ + size_t maxMask = 1 << ((chrsz*8)-1); \ + size_t maxSize = maxMask-1; \ + if (strSize > maxSize) { \ + *str++ = maxMask | ((strSize>>(chrsz*8))&maxSize); \ + } \ + *str++ = strSize; \ +} + status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) { // Allow appending. Sorry this is a little wacky. @@ -213,28 +223,53 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) return NO_MEMORY; } + const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(char16_t); + size_t strPos = 0; for (i=0; i<STRINGS; i++) { entry& ent = mEntries.editItemAt(i); const size_t strSize = (ent.value.size()); - const size_t lenSize = strSize > 0x7fff ? sizeof(uint32_t) : sizeof(uint16_t); - const size_t totalSize = lenSize + ((strSize+1)*sizeof(uint16_t)); + const size_t lenSize = strSize > (size_t)(1<<((charSize*8)-1))-1 ? + charSize*2 : charSize; + + String8 encStr; + if (mUTF8) { + encStr = String8(ent.value); + } + + const size_t encSize = mUTF8 ? encStr.size() : 0; + const size_t encLenSize = mUTF8 ? + (encSize > (size_t)(1<<((charSize*8)-1))-1 ? + charSize*2 : charSize) : 0; ent.offset = strPos; - uint16_t* dat = (uint16_t*)pool->editData(preSize + strPos + totalSize); + + const size_t totalSize = lenSize + encLenSize + + ((mUTF8 ? encSize : strSize)+1)*charSize; + + void* dat = (void*)pool->editData(preSize + strPos + totalSize); if (dat == NULL) { fprintf(stderr, "ERROR: Out of memory for string pool\n"); return NO_MEMORY; } - dat += (preSize+strPos)/sizeof(uint16_t); - if (lenSize > sizeof(uint16_t)) { - *dat = htods(0x8000 | ((strSize>>16)&0x7fff)); - dat++; + dat = (uint8_t*)dat + preSize + strPos; + if (mUTF8) { + uint8_t* strings = (uint8_t*)dat; + + ENCODE_LENGTH(strings, sizeof(uint8_t), strSize) + + ENCODE_LENGTH(strings, sizeof(uint8_t), encSize) + + strncpy((char*)strings, encStr, encSize+1); + } else { + uint16_t* strings = (uint16_t*)dat; + + ENCODE_LENGTH(strings, sizeof(uint16_t), strSize) + + strcpy16_htod(strings, ent.value); } - *dat++ = htods(strSize); - strcpy16_htod(dat, ent.value); - strPos += lenSize + (strSize+1)*sizeof(uint16_t); + strPos += totalSize; } // Pad ending string position up to a uint32_t boundary. @@ -312,6 +347,9 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) if (mSorted) { header->flags |= htodl(ResStringPool_header::SORTED_FLAG); } + if (mUTF8) { + header->flags |= htodl(ResStringPool_header::UTF8_FLAG); + } header->stringsStart = htodl(preSize); header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0); diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h index 9082b37..7275259 100644 --- a/tools/aapt/StringPool.h +++ b/tools/aapt/StringPool.h @@ -68,8 +68,11 @@ public: * lookup with ResStringPool::indexOfString() (O(log n)), at the expense * of support for styled string entries (which requires the same string * be included multiple times in the pool). + * + * If 'utf8' is true, strings will be encoded with UTF-8 instead of + * left in Java's native UTF-16. */ - explicit StringPool(bool sorted = false); + explicit StringPool(bool sorted = false, bool utf8 = false); /** * Add a new string to the pool. If mergeDuplicates is true, thenif @@ -123,6 +126,7 @@ public: private: const bool mSorted; + const bool mUTF8; // Raw array of unique strings, in some arbitrary order. Vector<entry> mEntries; // Array of indices into mEntries, in the order they were diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp index d4d2a45..036dde4 100644 --- a/tools/aapt/XMLNode.cpp +++ b/tools/aapt/XMLNode.cpp @@ -478,6 +478,7 @@ XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2 , mFilename(filename) , mStartLineNumber(0) , mEndLineNumber(0) + , mUTF8(false) { if (isNamespace) { mNamespacePrefix = s1; @@ -837,7 +838,7 @@ status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets, status_t XMLNode::flatten(const sp<AaptFile>& dest, bool stripComments, bool stripRawValues) const { - StringPool strings; + StringPool strings = StringPool(false, mUTF8); Vector<uint32_t> resids; // First collect just the strings for attribute names that have a diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h index a9bea43..dc92fa7 100644 --- a/tools/aapt/XMLNode.h +++ b/tools/aapt/XMLNode.h @@ -124,6 +124,8 @@ public: void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL); + void setUTF8(bool val) { mUTF8 = val; } + status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table); status_t assignResourceIds(const sp<AaptAssets>& assets, @@ -189,6 +191,9 @@ private: String8 mFilename; int32_t mStartLineNumber; int32_t mEndLineNumber; + + // Encode compiled XML with UTF-8 StringPools? + bool mUTF8; }; #endif 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 2df9219..990498f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge; -import com.android.internal.util.XmlUtils; +import com.android.common.XmlUtils; import com.android.layoutlib.api.ILayoutBridge; import com.android.layoutlib.api.ILayoutLog; import com.android.layoutlib.api.ILayoutResult; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java index b5b7ceb..791e53b 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java @@ -60,6 +60,7 @@ public class BridgeConstants { public final static String REFERENCE_STYLE = RES_STYLE + "/"; public final static String REFERENCE_NULL = "@null"; + public final static String MATCH_PARENT = "match_parent"; public final static String FILL_PARENT = "fill_parent"; public final static String WRAP_CONTENT = "wrap_content"; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java index 1fafef4..6358abb 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java @@ -239,8 +239,9 @@ public final class BridgeResources extends Resources { String v = value.getValue(); if (v != null) { - if (v.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; + if (v.equals(BridgeConstants.MATCH_PARENT) || + v.equals(BridgeConstants.FILL_PARENT)) { + return LayoutParams.MATCH_PARENT; } else if (v.equals(BridgeConstants.WRAP_CONTENT)) { return LayoutParams.WRAP_CONTENT; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java index 957f737..efd222e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java @@ -16,7 +16,7 @@ package com.android.layoutlib.bridge; -import com.android.internal.util.XmlUtils; +import com.android.common.XmlUtils; import com.android.layoutlib.api.IResourceValue; import com.android.layoutlib.api.IStyleResourceValue; @@ -392,8 +392,8 @@ public final class BridgeTypedArray extends TypedArray { if (s == null) { return defValue; - } else if (s.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; + } else if (s.equals(BridgeConstants.MATCH_PARENT)) { + return LayoutParams.MATCH_PARENT; } else if (s.equals(BridgeConstants.WRAP_CONTENT)) { return LayoutParams.WRAP_CONTENT; } @@ -460,8 +460,8 @@ public final class BridgeTypedArray extends TypedArray { if (s == null) { return defValue; - } else if (s.equals(BridgeConstants.FILL_PARENT)) { - return LayoutParams.FILL_PARENT; + } else if (s.equals(BridgeConstants.MATCH_PARENT)) { + return LayoutParams.MATCH_PARENT; } else if (s.equals(BridgeConstants.WRAP_CONTENT)) { return LayoutParams.WRAP_CONTENT; } diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml index 554f541..b8fc947 100644 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml +++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml @@ -17,8 +17,8 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" + android:layout_width="match_parent" + android:layout_height="match_parent" android:orientation="vertical" > <Button @@ -31,8 +31,8 @@ </Button> <View android:id="@+id/surface" - android:layout_width="fill_parent" - android:layout_height="fill_parent" + android:layout_width="match_parent" + android:layout_height="match_parent" android:layout_weight="2" /> <TextView @@ -40,7 +40,7 @@ android:paddingLeft="2dip" android:layout_weight="0" android:background="@drawable/black" - android:layout_width="fill_parent" + android:layout_width="match_parent" android:layout_height="wrap_content" android:lines="1" android:gravity="center_vertical|center_horizontal" diff --git a/tools/preload/20080522.compiled b/tools/preload/20080522.compiled Binary files differnew file mode 100644 index 0000000..a2af422 --- /dev/null +++ b/tools/preload/20080522.compiled diff --git a/tools/preload/20090922.compiled b/tools/preload/20090811.compiled Binary files differindex fc66405..6dbeca0 100644 --- a/tools/preload/20090922.compiled +++ b/tools/preload/20090811.compiled diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk index 65b7d1a..f325870 100644 --- a/tools/preload/Android.mk +++ b/tools/preload/Android.mk @@ -8,7 +8,6 @@ LOCAL_SRC_FILES := \ MemoryUsage.java \ Operation.java \ Policy.java \ - PrintBugReports.java \ PrintCsv.java \ PrintHtmlDiff.java \ PrintPsTree.java \ diff --git a/tools/preload/LoadedClass.java b/tools/preload/LoadedClass.java index 02cff10..86e5dfc 100644 --- a/tools/preload/LoadedClass.java +++ b/tools/preload/LoadedClass.java @@ -15,11 +15,7 @@ */ import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * A loaded class. @@ -54,30 +50,6 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> { this.systemClass = systemClass; } - /** - * Returns true if this class was loaded by more than one proc. - */ - boolean isSharable() { - Set<String> procNames = new HashSet<String>(); - for (Operation load : loads) { - if (load.process.fromZygote()) { - procNames.add(load.process.name); - if (procNames.size() > 1) { - return true; - } - } - } - for (Operation init : initializations) { - if (init.process.fromZygote()) { - procNames.add(init.process.name); - if (procNames.size() > 1) { - return true; - } - } - } - return false; - } - void measureMemoryUsage() { this.memoryUsage = MemoryUsage.forClass(name); } diff --git a/tools/preload/PrintBugReports.java b/tools/preload/PrintBugReports.java deleted file mode 100644 index a6d4187..0000000 --- a/tools/preload/PrintBugReports.java +++ /dev/null @@ -1,272 +0,0 @@ -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.io.DataInputStream; -import java.io.FileInputStream; -import java.util.Map; -import java.util.List; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Set; -import java.util.TreeSet; -import java.util.Iterator; - -/** - * Prints HTML reports that can be attached to bugs. - */ -public class PrintBugReports { - - private static final String DIR = "out/preload"; - private static boolean PRINT_MEMORY_USAGE = false; - - private static final Comparator<LoadedClass> DEFAULT_ORDER - = new Comparator<LoadedClass>() { - public int compare(LoadedClass a, LoadedClass b) { - // Longest load time first. - int diff = b.medianTimeMicros() - a.medianTimeMicros(); - if (diff != 0) { - return diff; - } - - return a.name.compareTo(b.name); - } - }; - - public static void main(String[] args) - throws IOException, ClassNotFoundException { - Root root = Root.fromFile(args[0]); - String baseUrl = ""; - if (args.length > 1) { - baseUrl = args[1]; - } - - new File(DIR).mkdirs(); - - Map<String, List<Proc>> procsByName = new HashMap<String, List<Proc>>(); - for (Proc proc : root.processes.values()) { - if (proc.fromZygote()) { - List<Proc> procs = procsByName.get(proc.name); - if (procs == null) { - procs = new ArrayList<Proc>(); - procsByName.put(proc.name, procs); - } - procs.add(proc); - } - } - - Set<LoadedClass> coreClasses = new TreeSet<LoadedClass>(DEFAULT_ORDER); - Set<LoadedClass> frameworkClasses = new TreeSet<LoadedClass>(DEFAULT_ORDER); - - for (List<Proc> procs : procsByName.values()) { - Proc first = procs.get(0); - Set<LoadedClass> classes = new TreeSet<LoadedClass>(DEFAULT_ORDER); - Set<LoadedClass> sharedClasses - = new TreeSet<LoadedClass>(DEFAULT_ORDER); - for (Proc proc : procs) { - for (Operation operation : proc.operations) { - LoadedClass clazz = operation.loadedClass; - if (clazz.isSharable() && clazz.systemClass) { - if (clazz.name.startsWith("dalvik") - || clazz.name.startsWith("org") - || clazz.name.startsWith("java")) { - coreClasses.add(clazz); - } else { - frameworkClasses.add(clazz); - } - sharedClasses.add(clazz); - } else { - classes.add(clazz); - } - } - } - printApplicationHtml(first.name, root.baseline, classes, - sharedClasses); - } - - printHtml("core", root.baseline, coreClasses); - printHtml("framework", root.baseline, frameworkClasses); - - PrintStream out = new PrintStream(DIR + "/toc.html"); - out.println("<html><body>"); - out.println("<a href='" + baseUrl - + "/core.html'>core</a><br/>"); - out.println("<a href='" + baseUrl - + "/framework.html'>framework</a><br/>"); - - for (String s : new TreeSet<String>(procsByName.keySet())) { - out.println("<a href='" + baseUrl + "/" - + s + ".html'>" + s + "</a><br/>"); - } - out.println("</body></html>"); - out.close(); - } - - static void printApplicationHtml(String name, MemoryUsage baseline, - Iterable<LoadedClass> classes, Iterable<LoadedClass> sharedClasses) - throws IOException { - PrintStream out = new PrintStream(DIR + "/" + name + ".html"); - - printHeader(name, out); - out.println("<body>"); - out.println("<h1><tt>" + name + "</tt></h1>"); - out.println("<p><i>Click a column header to sort by that column.</i></p>"); - - out.println("<p><a href=\"#shared\">Shared Classes</a></p>"); - - out.println("<h3>Application-Specific Classes</h3>"); - - out.println("<p>These classes were loaded only by " + name + ". If" - + " the value of the <i>Preloaded</i> column is <i>yes</i> or " - + " <i>no</i>, the class is in the boot classpath; if it's not" - + " part of the published API, consider" - + " moving it into the APK.</p>"); - - printTable(out, baseline, classes, false); - - out.println("<p><a href=\"#\">Top</a></p>"); - - out.println("<a name=\"shared\"/><h3>Shared Classes</h3>"); - - out.println("<p>These classes are in the boot classpath. They are used" - + " by " + name + " as well as others."); - - printTable(out, baseline, sharedClasses, true); - - out.println("</body></html>"); - out.close(); - } - - static void printHtml(String name, MemoryUsage baseline, - Iterable<LoadedClass> classes) - throws IOException { - PrintStream out = new PrintStream(DIR + "/" + name + ".html"); - - printHeader(name, out); - out.println("<body>"); - out.println("<h1><tt>" + name + "</tt></h1>"); - out.println("<p><i>Click a column header to sort by that column.</i></p>"); - - printTable(out, baseline, classes, true); - - out.println("</body></html>"); - out.close(); - } - - private static void printHeader(String name, PrintStream out) - throws IOException { - out.println("<html><head>"); - out.println("<title>" + name + "</title>"); - out.println("<style>"); - out.println("a, th, td, h1, h3, p { font-family: arial }"); - out.println("th, td { font-size: small }"); - out.println("</style>"); - out.println("<script language=\"javascript\">"); - out.write(SCRIPT); - out.println("</script>"); - out.println("</head>"); - } - - static void printTable(PrintStream out, MemoryUsage baseline, - Iterable<LoadedClass> classes, boolean showProcNames) { - out.println("<p><table border=\"1\" cellpadding=\"5\"" - + " class=\"sortable\" cellspacing=\"0\">"); - - out.println("<thead bgcolor=\"#eeeeee\"><tr>"); - out.println("<th>Name</th>"); - out.println("<th>Preloaded</th>"); - out.println("<th>Total Time (us)</th>"); - out.println("<th>Load Time (us)</th>"); - out.println("<th>Init Time (us)</th>"); - if (PRINT_MEMORY_USAGE) { - out.println("<th>Total Heap (B)</th>"); - out.println("<th>Dalvik Heap (B)</th>"); - out.println("<th>Native Heap (B)</th>"); - out.println("<th>Total Pages (kB)</th>"); - out.println("<th>Dalvik Pages (kB)</th>"); - out.println("<th>Native Pages (kB)</th>"); - out.println("<th>Other Pages (kB)</th>"); - } - if (showProcNames) { - out.println("<th>Loaded by</th>"); - } - out.println("</tr></thead>"); - - for (LoadedClass clazz : classes) { - out.println("<tr>"); - out.println("<td>" + clazz.name + "</td>"); - - out.println("<td>" + ((clazz.systemClass) - ? ((clazz.preloaded) ? "yes" : "no") : "n/a") + "</td>"); - - out.println("<td>" + clazz.medianTimeMicros() + "</td>"); - out.println("<td>" + clazz.medianLoadTimeMicros() + "</td>"); - out.println("<td>" + clazz.medianInitTimeMicros() + "</td>"); - - if (PRINT_MEMORY_USAGE) { - if (clazz.memoryUsage.isAvailable()) { - MemoryUsage subtracted - = clazz.memoryUsage.subtract(baseline); - - long totalHeap = subtracted.javaHeapSize() - + subtracted.nativeHeapSize; - out.println("<td>" + totalHeap + "</td>"); - out.println("<td>" + subtracted.javaHeapSize() + "</td>"); - out.println("<td>" + subtracted.nativeHeapSize + "</td>"); - - out.println("<td>" + subtracted.totalPages() + "</td>"); - out.println("<td>" + subtracted.javaPagesInK() + "</td>"); - out.println("<td>" + subtracted.nativePagesInK() + "</td>"); - out.println("<td>" + subtracted.otherPagesInK() + "</td>"); - } else { - for (int i = 0; i < 7; i++) { - out.println("<td> </td>"); - } - } - } - - if (showProcNames) { - out.println("<td>"); - Set<String> procNames = new TreeSet<String>(); - for (Operation op : clazz.loads) { - procNames.add(op.process.name); - } - for (Operation op : clazz.initializations) { - procNames.add(op.process.name); - } - if (procNames.size() <= 3) { - for (String name : procNames) { - out.print(name + "<br/>"); - } - } else { - Iterator<String> i = procNames.iterator(); - out.print(i.next() + "<br/>"); - out.print(i.next() + "<br/>"); - out.print("...and " + (procNames.size() - 2) - + " others."); - } - out.println("</td>"); - } - - out.println("</tr>"); - } - - out.println("</table></p>"); - } - - static byte[] SCRIPT; - static { - try { - File script = new File( - "frameworks/base/tools/preload/sorttable.js"); - int length = (int) script.length(); - SCRIPT = new byte[length]; - DataInputStream in = new DataInputStream( - new FileInputStream(script)); - in.readFully(SCRIPT); - in.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/tools/preload/Root.java b/tools/preload/Root.java index 3f12dea..0bc29bf 100644 --- a/tools/preload/Root.java +++ b/tools/preload/Root.java @@ -46,8 +46,7 @@ public class Root implements Serializable { final Map<String, LoadedClass> loadedClasses = new HashMap<String, LoadedClass>(); -// MemoryUsage baseline = MemoryUsage.baseline(); - MemoryUsage baseline = MemoryUsage.NOT_AVAILABLE; + MemoryUsage baseline = MemoryUsage.baseline(); /** * Records class loads and initializations. @@ -74,7 +73,7 @@ public class Root implements Serializable { if (loadedClass.systemClass) { // Only measure memory for classes in the boot // classpath. -// loadedClass.measureMemoryUsage(); + loadedClass.measureMemoryUsage(); } loadedClasses.put(name, loadedClass); } diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java index 757d17d3..96c539b 100644 --- a/tools/preload/WritePreloadedClassFile.java +++ b/tools/preload/WritePreloadedClassFile.java @@ -32,7 +32,7 @@ public class WritePreloadedClassFile { /** * Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us. */ - static final int MIN_LOAD_TIME_MICROS = 1000; + static final int MIN_LOAD_TIME_MICROS = 1250; public static void main(String[] args) throws IOException, ClassNotFoundException { diff --git a/tools/preload/preload.ipr b/tools/preload/preload.ipr index dddca3b..0c9621c 100644 --- a/tools/preload/preload.ipr +++ b/tools/preload/preload.ipr @@ -364,7 +364,7 @@ </component> <component name="ProjectFileVersion" converted="true" /> <component name="ProjectKey"> - <option name="state" value="project:///Volumes/Android/eclair/frameworks/base/tools/preload/preload.ipr" /> + <option name="state" value="project:///Volumes/Android/donut/frameworks/base/tools/preload/preload.ipr" /> </component> <component name="ProjectModuleManager"> <modules> diff --git a/tools/preload/sorttable.js b/tools/preload/sorttable.js index f03859e..25bccb2 100644 --- a/tools/preload/sorttable.js +++ b/tools/preload/sorttable.js @@ -6,7 +6,7 @@ Instructions: Download this file - Add <script src="sorttable.js"> to your HTML + Add <script src="sorttable.js"></script> to your HTML Add class="sortable" to any table you'd like to make sortable Click on the headers to sort @@ -88,7 +88,6 @@ sorttable = { } // make it clickable to sort headrow[i].sorttable_columnindex = i; - headrow[i].style.cursor = "pointer"; headrow[i].sorttable_tbody = table.tBodies[0]; dean_addEvent(headrow[i],"click", function(e) { |