diff options
Diffstat (limited to 'tools')
24 files changed, 891 insertions, 488 deletions
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 8e3a1c9..daeadc0 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -83,7 +83,7 @@ public: bool getForce(void) const { return mForce; } void setForce(bool val) { mForce = val; } void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; } - int getGrayscaleTolerance() { return mGrayscaleTolerance; } + int getGrayscaleTolerance() const { return mGrayscaleTolerance; } bool getMakePackageDirs(void) const { return mMakePackageDirs; } void setMakePackageDirs(bool val) { mMakePackageDirs = val; } bool getUpdate(void) const { return mUpdate; } @@ -166,14 +166,14 @@ public: void setExtraPackages(const char* val) { mExtraPackages = val; } const char* getMaxResVersion() const { return mMaxResVersion; } void setMaxResVersion(const char * val) { mMaxResVersion = val; } - bool getDebugMode() { return mDebugMode; } + bool getDebugMode() const { return mDebugMode; } void setDebugMode(bool val) { mDebugMode = val; } - bool getNonConstantId() { return mNonConstantId; } + bool getNonConstantId() const { return mNonConstantId; } void setNonConstantId(bool val) { mNonConstantId = val; } const char* getProduct() const { return mProduct; } void setProduct(const char * val) { mProduct = val; } void setUseCrunchCache(bool val) { mUseCrunchCache = val; } - bool getUseCrunchCache() { return mUseCrunchCache; } + bool getUseCrunchCache() const { return mUseCrunchCache; } /* * Set and get the file specification. diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index c79e243..689aa8e 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -636,6 +636,15 @@ int doDump(Bundle* bundle) bool hasWriteExternalStoragePermission = false; bool hasReadPhoneStatePermission = false; + // If an app requests write storage, they will also get read storage. + bool hasReadExternalStoragePermission = false; + + // Implement transition to read and write call log. + bool hasReadContactsPermission = false; + bool hasWriteContactsPermission = false; + bool hasReadCallLogPermission = false; + bool hasWriteCallLogPermission = false; + // This next group of variables is used to implement a group of // backward-compatibility heuristics necessitated by the addition of // some new uses-feature constants in 2.1 and 2.2. In most cases, the @@ -999,8 +1008,18 @@ int doDump(Bundle* bundle) hasTelephonyPermission = true; } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") { hasWriteExternalStoragePermission = true; + } else if (name == "android.permission.READ_EXTERNAL_STORAGE") { + hasReadExternalStoragePermission = true; } else if (name == "android.permission.READ_PHONE_STATE") { hasReadPhoneStatePermission = true; + } else if (name == "android.permission.READ_CONTACTS") { + hasReadContactsPermission = true; + } else if (name == "android.permission.WRITE_CONTACTS") { + hasWriteContactsPermission = true; + } else if (name == "android.permission.READ_CALL_LOG") { + hasReadCallLogPermission = true; + } else if (name == "android.permission.WRITE_CALL_LOG") { + hasWriteCallLogPermission = true; } printf("uses-permission:'%s'\n", name.string()); } else { @@ -1163,12 +1182,29 @@ int doDump(Bundle* bundle) if (targetSdk < 4) { if (!hasWriteExternalStoragePermission) { printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n"); + hasWriteExternalStoragePermission = true; } if (!hasReadPhoneStatePermission) { printf("uses-permission:'android.permission.READ_PHONE_STATE'\n"); } } + // If the application has requested WRITE_EXTERNAL_STORAGE, we will + // force them to always take READ_EXTERNAL_STORAGE as well. + if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) { + printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n"); + } + + // Pre-JellyBean call log permission compatibility. + if (targetSdk < 16) { + if (!hasReadCallLogPermission && hasReadContactsPermission) { + printf("uses-permission:'android.permission.READ_CALL_LOG'\n"); + } + if (!hasWriteCallLogPermission && hasWriteContactsPermission) { + printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n"); + } + } + /* The following blocks handle printing "inferred" uses-features, based * on whether related features or permissions are used by the app. * Note that the various spec*Feature variables denote whether the diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp index 6402e3c..9de685a 100644 --- a/tools/aapt/Images.cpp +++ b/tools/aapt/Images.cpp @@ -57,6 +57,13 @@ struct image_info bool is9Patch; Res_png_9patch info9Patch; + // Layout padding, if relevant + bool haveLayoutBounds; + int32_t layoutBoundsLeft; + int32_t layoutBoundsTop; + int32_t layoutBoundsRight; + int32_t layoutBoundsBottom; + png_uint_32 allocHeight; png_bytepp allocRows; }; @@ -129,33 +136,62 @@ static void read_png(const char* imageName, &interlace_type, &compression_type, NULL); } -static bool is_tick(png_bytep p, bool transparent, const char** outError) +#define COLOR_TRANSPARENT 0 +#define COLOR_WHITE 0xFFFFFFFF +#define COLOR_TICK 0xFF000000 +#define COLOR_LAYOUT_BOUNDS_TICK 0xFF0000FF + +enum { + TICK_TYPE_NONE, + TICK_TYPE_TICK, + TICK_TYPE_LAYOUT_BOUNDS, + TICK_TYPE_BOTH +}; + +static int tick_type(png_bytep p, bool transparent, const char** outError) { + png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + if (transparent) { if (p[3] == 0) { - return false; + return TICK_TYPE_NONE; + } + if (color == COLOR_LAYOUT_BOUNDS_TICK) { + return TICK_TYPE_LAYOUT_BOUNDS; } + if (color == COLOR_TICK) { + return TICK_TYPE_TICK; + } + + // Error cases if (p[3] != 0xff) { *outError = "Frame pixels must be either solid or transparent (not intermediate alphas)"; - return false; + return TICK_TYPE_NONE; } if (p[0] != 0 || p[1] != 0 || p[2] != 0) { - *outError = "Ticks in transparent frame must be black"; + *outError = "Ticks in transparent frame must be black or red"; } - return true; + return TICK_TYPE_TICK; } if (p[3] != 0xFF) { *outError = "White frame must be a solid color (no alpha)"; } - if (p[0] == 0xFF && p[1] == 0xFF && p[2] == 0xFF) { - return false; + if (color == COLOR_WHITE) { + return TICK_TYPE_NONE; + } + if (color == COLOR_TICK) { + return TICK_TYPE_TICK; } + if (color == COLOR_LAYOUT_BOUNDS_TICK) { + return TICK_TYPE_LAYOUT_BOUNDS; + } + if (p[0] != 0 || p[1] != 0 || p[2] != 0) { - *outError = "Ticks in white frame must be black"; - return false; + *outError = "Ticks in white frame must be black or red"; + return TICK_TYPE_NONE; } - return true; + return TICK_TYPE_TICK; } enum { @@ -175,7 +211,7 @@ static status_t get_horizontal_ticks( bool found = false; for (i=1; i<width-1; i++) { - if (is_tick(row+i*4, transparent, outError)) { + if (TICK_TYPE_TICK == tick_type(row+i*4, transparent, outError)) { if (state == TICK_START || (state == TICK_OUTSIDE_1 && multipleAllowed)) { *outLeft = i-1; @@ -224,7 +260,7 @@ static status_t get_vertical_ticks( bool found = false; for (i=1; i<height-1; i++) { - if (is_tick(rows[i]+offset, transparent, outError)) { + if (TICK_TYPE_TICK == tick_type(rows[i]+offset, transparent, outError)) { if (state == TICK_START || (state == TICK_OUTSIDE_1 && multipleAllowed)) { *outTop = i-1; @@ -262,6 +298,83 @@ static status_t get_vertical_ticks( return NO_ERROR; } +static status_t get_horizontal_layout_bounds_ticks( + png_bytep row, int width, bool transparent, bool required, + int32_t* outLeft, int32_t* outRight, const char** outError) +{ + int i; + *outLeft = *outRight = 0; + + // Look for left tick + if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + 4, transparent, outError)) { + // Starting with a layout padding tick + i = 1; + while (i < width - 1) { + (*outLeft)++; + i++; + int tick = tick_type(row + i * 4, transparent, outError); + if (tick != TICK_TYPE_LAYOUT_BOUNDS) { + break; + } + } + } + + // Look for right tick + if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + (width - 2) * 4, transparent, outError)) { + // Ending with a layout padding tick + i = width - 2; + while (i > 1) { + (*outRight)++; + i--; + int tick = tick_type(row+i*4, transparent, outError); + if (tick != TICK_TYPE_LAYOUT_BOUNDS) { + break; + } + } + } + + return NO_ERROR; +} + +static status_t get_vertical_layout_bounds_ticks( + png_bytepp rows, int offset, int height, bool transparent, bool required, + int32_t* outTop, int32_t* outBottom, const char** outError) +{ + int i; + *outTop = *outBottom = 0; + + // Look for top tick + if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[1] + offset, transparent, outError)) { + // Starting with a layout padding tick + i = 1; + while (i < height - 1) { + (*outTop)++; + i++; + int tick = tick_type(rows[i] + offset, transparent, outError); + if (tick != TICK_TYPE_LAYOUT_BOUNDS) { + break; + } + } + } + + // Look for bottom tick + if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[height - 2] + offset, transparent, outError)) { + // Ending with a layout padding tick + i = height - 2; + while (i > 1) { + (*outBottom)++; + i--; + int tick = tick_type(rows[i] + offset, transparent, outError); + if (tick != TICK_TYPE_LAYOUT_BOUNDS) { + break; + } + } + } + + return NO_ERROR; +} + + static uint32_t get_color( png_bytepp rows, int left, int top, int right, int bottom) { @@ -353,6 +466,9 @@ static status_t do_9patch(const char* imageName, image_info* image) image->info9Patch.paddingLeft = image->info9Patch.paddingRight = image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1; + image->layoutBoundsLeft = image->layoutBoundsRight = + image->layoutBoundsTop = image->layoutBoundsBottom = 0; + png_bytep p = image->rows[0]; bool transparent = p[3] == 0; bool hasColor = false; @@ -408,6 +524,25 @@ static status_t do_9patch(const char* imageName, image_info* image) goto getout; } + // Find left and right of layout padding... + get_horizontal_layout_bounds_ticks(image->rows[H-1], W, transparent, false, + &image->layoutBoundsLeft, + &image->layoutBoundsRight, &errorMsg); + + get_vertical_layout_bounds_ticks(image->rows, (W-1)*4, H, transparent, false, + &image->layoutBoundsTop, + &image->layoutBoundsBottom, &errorMsg); + + image->haveLayoutBounds = image->layoutBoundsLeft != 0 + || image->layoutBoundsRight != 0 + || image->layoutBoundsTop != 0 + || image->layoutBoundsBottom != 0; + + if (image->haveLayoutBounds) { + NOISY(printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft, image->layoutBoundsTop, + image->layoutBoundsRight, image->layoutBoundsBottom)); + } + // Copy patch data into image image->info9Patch.numXDivs = numXDivs; image->info9Patch.numYDivs = numYDivs; @@ -845,8 +980,9 @@ static void write_png(const char* imageName, int bit_depth, interlace_type, compression_type; int i; - png_unknown_chunk unknowns[1]; + png_unknown_chunk unknowns[2]; unknowns[0].data = NULL; + unknowns[1].data = NULL; png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * png_sizeof(png_bytep)); if (outRows == (png_bytepp) 0) { @@ -916,23 +1052,42 @@ static void write_png(const char* imageName, } if (imageInfo.is9Patch) { + int chunk_count = 1 + (imageInfo.haveLayoutBounds ? 1 : 0); + int p_index = imageInfo.haveLayoutBounds ? 1 : 0; + int b_index = 0; + png_byte *chunk_names = imageInfo.haveLayoutBounds + ? (png_byte*)"npLb\0npTc\0" + : (png_byte*)"npTc"; NOISY(printf("Adding 9-patch info...\n")); - strcpy((char*)unknowns[0].name, "npTc"); - unknowns[0].data = (png_byte*)imageInfo.info9Patch.serialize(); - unknowns[0].size = imageInfo.info9Patch.serializedSize(); + strcpy((char*)unknowns[p_index].name, "npTc"); + unknowns[p_index].data = (png_byte*)imageInfo.info9Patch.serialize(); + unknowns[p_index].size = imageInfo.info9Patch.serializedSize(); // TODO: remove the check below when everything works - checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[0].data); + checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[p_index].data); + + if (imageInfo.haveLayoutBounds) { + int chunk_size = sizeof(png_uint_32) * 4; + strcpy((char*)unknowns[b_index].name, "npLb"); + unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1); + memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size); + unknowns[b_index].size = chunk_size; + } + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - (png_byte*)"npTc", 1); - png_set_unknown_chunks(write_ptr, write_info, unknowns, 1); + chunk_names, chunk_count); + png_set_unknown_chunks(write_ptr, write_info, unknowns, chunk_count); // XXX I can't get this to work without forcibly changing // the location to what I want... which apparently is supposed // to be a private API, but everything else I have tried results // in the location being set to what I -last- wrote so I never // get written. :p png_set_unknown_chunk_location(write_ptr, write_info, 0, PNG_HAVE_PLTE); + if (imageInfo.haveLayoutBounds) { + png_set_unknown_chunk_location(write_ptr, write_info, 1, PNG_HAVE_PLTE); + } } + png_write_info(write_ptr, write_info); png_bytepp rows; @@ -954,6 +1109,7 @@ static void write_png(const char* imageName, } free(outRows); free(unknowns[0].data); + free(unknowns[1].data); png_get_IHDR(write_ptr, write_info, &width, &height, &bit_depth, &color_type, &interlace_type, @@ -964,7 +1120,7 @@ static void write_png(const char* imageName, compression_type)); } -status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets, +status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets, const sp<AaptFile>& file, String8* outNewLeafName) { String8 ext(file->getPath().getPathExtension()); @@ -1084,7 +1240,7 @@ bail: return error; } -status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest) +status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest) { png_structp read_ptr = NULL; png_infop read_info = NULL; diff --git a/tools/aapt/Images.h b/tools/aapt/Images.h index 4816905..91b6554 100644 --- a/tools/aapt/Images.h +++ b/tools/aapt/Images.h @@ -15,10 +15,10 @@ using android::String8; -status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets, +status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets, const sp<AaptFile>& file, String8* outNewLeafName); -status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest); +status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest); status_t postProcessImage(const sp<AaptAssets>& assets, ResourceTable* table, const sp<AaptFile>& file); diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 7eaf528..b9ec30c 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -14,6 +14,8 @@ #include "FileFinder.h" #include "CacheUpdater.h" +#include <utils/WorkQueue.h> + #if HAVE_PRINTF_ZD # define ZD "%zd" # define ZD_TYPE ssize_t @@ -24,6 +26,9 @@ #define NOISY(x) // x +// Number of threads to use for preprocessing images. +static const size_t MAX_THREADS = 4; + // ========================================================================== // ========================================================================== // ========================================================================== @@ -302,21 +307,52 @@ static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets, return hasErrors ? UNKNOWN_ERROR : NO_ERROR; } -static status_t preProcessImages(Bundle* bundle, const sp<AaptAssets>& assets, +class PreProcessImageWorkUnit : public WorkQueue::WorkUnit { +public: + PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets, + const sp<AaptFile>& file, volatile bool* hasErrors) : + mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) { + } + + virtual bool run() { + status_t status = preProcessImage(mBundle, mAssets, mFile, NULL); + if (status) { + *mHasErrors = true; + } + return true; // continue even if there are errors + } + +private: + const Bundle* mBundle; + sp<AaptAssets> mAssets; + sp<AaptFile> mFile; + volatile bool* mHasErrors; +}; + +static status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets, const sp<ResourceTypeSet>& set, const char* type) { - bool hasErrors = false; + volatile bool hasErrors = false; ssize_t res = NO_ERROR; if (bundle->getUseCrunchCache() == false) { + WorkQueue wq(MAX_THREADS, false); ResourceDirIterator it(set, String8(type)); - Vector<sp<AaptFile> > newNameFiles; - Vector<String8> newNamePaths; while ((res=it.next()) == NO_ERROR) { - res = preProcessImage(bundle, assets, it.getFile(), NULL); - if (res < NO_ERROR) { + PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit( + bundle, assets, it.getFile(), &hasErrors); + status_t status = wq.schedule(w); + if (status) { + fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status); hasErrors = true; + delete w; + break; } } + status_t status = wq.finish(); + if (status) { + fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status); + hasErrors = true; + } } return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 0c0b2ea..0195727 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2304,10 +2304,8 @@ bool ResourceTable::getAttributeFlags( const char16_t* end = name + nameLen; const char16_t* pos = name; - bool failed = false; - while (pos < end && !failed) { + while (pos < end) { const char16_t* start = pos; - end++; while (pos < end && *pos != '|') { pos++; } @@ -2333,9 +2331,7 @@ bool ResourceTable::getAttributeFlags( // Didn't find this flag identifier. return false; } - if (pos < end) { - pos++; - } + pos++; } return true; @@ -2602,7 +2598,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) // Iterate through all data, collecting all values (strings, // references, etc). - StringPool valueStrings = StringPool(false, useUTF8); + StringPool valueStrings(useUTF8); Vector<sp<Entry> > allEntries; for (pi=0; pi<N; pi++) { sp<Package> p = mOrderedPackages.itemAt(pi); @@ -2611,8 +2607,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) continue; } - StringPool typeStrings = StringPool(false, useUTF8); - StringPool keyStrings = StringPool(false, useUTF8); + StringPool typeStrings(useUTF8); + StringPool keyStrings(useUTF8); const size_t N = p->getOrderedTypes().size(); for (size_t ti=0; ti<N; ti++) { diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp index fe88e37..839eda5 100644 --- a/tools/aapt/StringPool.cpp +++ b/tools/aapt/StringPool.cpp @@ -9,6 +9,7 @@ #include <utils/ByteOrder.h> #include <utils/SortedVector.h> +#include <cutils/qsort_r_compat.h> #if HAVE_PRINTF_ZD # define ZD "%zd" @@ -71,14 +72,16 @@ String8 StringPool::entry::makeConfigsString() const { } int StringPool::entry::compare(const entry& o) const { - // Strings with styles go first, to reduce the size of the - // styles array. + // Strings with styles go first, to reduce the size of the styles array. + // We don't care about the relative order of these strings. if (hasStyles) { return o.hasStyles ? 0 : -1; } if (o.hasStyles) { return 1; } + + // Sort unstyled strings by type, then by logical configuration. int comp = configTypeName.compare(o.configTypeName); if (comp != 0) { return comp; @@ -98,39 +101,24 @@ int StringPool::entry::compare(const entry& o) const { return 0; } -StringPool::StringPool(bool sorted, bool utf8) - : mSorted(sorted), mUTF8(utf8), mValues(-1), mIdents(-1) -{ -} - -ssize_t StringPool::add(const String16& value, bool mergeDuplicates, - const String8* configTypeName, const ResTable_config* config) +StringPool::StringPool(bool utf8) : + mUTF8(utf8), mValues(-1) { - return add(String16(), value, mergeDuplicates, configTypeName, config); } ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans, const String8* configTypeName, const ResTable_config* config) { - ssize_t res = add(String16(), value, false, configTypeName, config); + ssize_t res = add(value, false, configTypeName, config); if (res >= 0) { addStyleSpans(res, spans); } return res; } -ssize_t StringPool::add(const String16& ident, const String16& value, +ssize_t StringPool::add(const String16& value, bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config) { - if (ident.size() > 0) { - ssize_t idx = mIdents.valueFor(ident); - if (idx >= 0) { - fprintf(stderr, "ERROR: Duplicate string identifier %s\n", - String8(mEntries[idx].value).string()); - return UNKNOWN_ERROR; - } - } - ssize_t vidx = mValues.indexOfKey(value); ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1; ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1; @@ -174,19 +162,15 @@ ssize_t StringPool::add(const String16& ident, const String16& value, } const bool first = vidx < 0; - if (first || !mergeDuplicates) { + const bool styled = (pos >= 0 && (size_t)pos < mEntryStyleArray.size()) ? + mEntryStyleArray[pos].spans.size() : 0; + if (first || styled || !mergeDuplicates) { pos = mEntryArray.add(eidx); if (first) { vidx = mValues.add(value, pos); } - if (!mSorted) { - entry& ent = mEntries.editItemAt(eidx); - ent.indices.add(pos); - } - } - - if (ident.size() > 0) { - mIdents.add(ident, vidx); + entry& ent = mEntries.editItemAt(eidx); + ent.indices.add(pos); } NOISY(printf("Adding string %s to pool: pos=%d eidx=%d vidx=%d\n", @@ -219,8 +203,6 @@ status_t StringPool::addStyleSpans(size_t idx, const Vector<entry_style_span>& s status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span) { - LOG_ALWAYS_FATAL_IF(mSorted, "Can't use styles with sorted string pools."); - // Place blank entries in the span array up to this index. while (mEntryStyleArray.size() <= idx) { mEntryStyleArray.add(); @@ -232,37 +214,16 @@ status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span) return NO_ERROR; } -size_t StringPool::size() const -{ - return mSorted ? mValues.size() : mEntryArray.size(); -} - -const StringPool::entry& StringPool::entryAt(size_t idx) const -{ - if (!mSorted) { - return mEntries[mEntryArray[idx]]; - } else { - return mEntries[mEntryArray[mValues.valueAt(idx)]]; - } -} - -size_t StringPool::countIdentifiers() const -{ - return mIdents.size(); -} - -int StringPool::config_sort(const size_t* lhs, const size_t* rhs, void* state) +int StringPool::config_sort(void* state, const void* lhs, const void* rhs) { StringPool* pool = (StringPool*)state; - const entry& lhe = pool->mEntries[pool->mEntryArray[*lhs]]; - const entry& rhe = pool->mEntries[pool->mEntryArray[*rhs]]; + const entry& lhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(lhs)]]; + const entry& rhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(rhs)]]; return lhe.compare(rhe); } void StringPool::sortByConfig() { - LOG_ALWAYS_FATAL_IF(mSorted, "Can't sort string pool containing identifiers."); - LOG_ALWAYS_FATAL_IF(mIdents.size() > 0, "Can't sort string pool containing identifiers."); LOG_ALWAYS_FATAL_IF(mOriginalPosToNewPos.size() > 0, "Can't sort string pool after already sorted."); const size_t N = mEntryArray.size(); @@ -272,13 +233,17 @@ void StringPool::sortByConfig() // At that point it maps from the new position in the array to the // original position the entry appeared. Vector<size_t> newPosToOriginalPos; - for (size_t i=0; i<mEntryArray.size(); i++) { + newPosToOriginalPos.setCapacity(N); + for (size_t i=0; i < N; i++) { newPosToOriginalPos.add(i); } // Sort the array. NOISY(printf("SORTING STRINGS BY CONFIGURATION...\n")); - newPosToOriginalPos.sort(config_sort, this); + // Vector::sort uses insertion sort, which is very slow for this data set. + // Use quicksort instead because we don't need a stable sort here. + qsort_r_compat(newPosToOriginalPos.editArray(), N, sizeof(size_t), this, config_sort); + //newPosToOriginalPos.sort(config_sort, this); NOISY(printf("DONE SORTING STRINGS BY CONFIGURATION.\n")); // Create the reverse mapping from the original position in the array @@ -430,7 +395,7 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) } } - const size_t ENTRIES = size(); + const size_t ENTRIES = mEntryArray.size(); // Now build the pool of unique strings. @@ -564,9 +529,6 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) header->header.size = htodl(pool->getSize()); header->stringCount = htodl(ENTRIES); header->styleCount = htodl(STYLES); - if (mSorted) { - header->flags |= htodl(ResStringPool_header::SORTED_FLAG); - } if (mUTF8) { header->flags |= htodl(ResStringPool_header::UTF8_FLAG); } @@ -576,33 +538,18 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool) // Write string index array. uint32_t* index = (uint32_t*)(header+1); - if (mSorted) { - for (i=0; i<ENTRIES; i++) { - entry& ent = const_cast<entry&>(entryAt(i)); - ent.indices.clear(); - ent.indices.add(i); - *index++ = htodl(ent.offset); - } - } else { - for (i=0; i<ENTRIES; i++) { - entry& ent = mEntries.editItemAt(mEntryArray[i]); - *index++ = htodl(ent.offset); - NOISY(printf("Writing entry #%d: \"%s\" ent=%d off=%d\n", i, - String8(ent.value).string(), - mEntryArray[i], ent.offset)); - } + for (i=0; i<ENTRIES; i++) { + entry& ent = mEntries.editItemAt(mEntryArray[i]); + *index++ = htodl(ent.offset); + NOISY(printf("Writing entry #%d: \"%s\" ent=%d off=%d\n", i, + String8(ent.value).string(), + mEntryArray[i], ent.offset)); } // Write style index array. - if (mSorted) { - for (i=0; i<STYLES; i++) { - LOG_ALWAYS_FATAL("Shouldn't be here!"); - } - } else { - for (i=0; i<STYLES; i++) { - *index++ = htodl(mEntryStyleArray[i].offset); - } + for (i=0; i<STYLES; i++) { + *index++ = htodl(mEntryStyleArray[i].offset); } return NO_ERROR; diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h index 86044ed..d501008 100644 --- a/tools/aapt/StringPool.h +++ b/tools/aapt/StringPool.h @@ -13,6 +13,7 @@ #include <androidfw/ResourceTypes.h> #include <utils/String16.h> #include <utils/TextOutput.h> +#include <utils/TypeHelpers.h> #include <sys/types.h> #include <sys/stat.h> @@ -79,16 +80,10 @@ public: }; /** - * If 'sorted' is true, then the final strings in the resource data - * structure will be generated in sorted order. This allow for fast - * lookup with ResStringPool::indexOfString() (O(log n)), at the expense - * of support for styled string entries (which requires the same string - * be included multiple times in the pool). - * * 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, bool utf8 = false); + explicit StringPool(bool utf8 = false); /** * Add a new string to the pool. If mergeDuplicates is true, thenif @@ -96,9 +91,7 @@ public: * otherwise, or if the value doesn't already exist, a new entry is * created. * - * Returns the index in the entry array of the new string entry. Note that - * if this string pool is sorted, the returned index will not be valid - * when the pool is finally written. + * Returns the index in the entry array of the new string entry. */ ssize_t add(const String16& value, bool mergeDuplicates = false, const String8* configTypeName = NULL, const ResTable_config* config = NULL); @@ -106,24 +99,14 @@ public: ssize_t add(const String16& value, const Vector<entry_style_span>& spans, const String8* configTypeName = NULL, const ResTable_config* config = NULL); - ssize_t add(const String16& ident, const String16& value, - bool mergeDuplicates = false, - const String8* configTypeName = NULL, const ResTable_config* config = NULL); - status_t addStyleSpan(size_t idx, const String16& name, uint32_t start, uint32_t end); status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans); status_t addStyleSpan(size_t idx, const entry_style_span& span); - size_t size() const; - - const entry& entryAt(size_t idx) const; - - size_t countIdentifiers() const; - // Sort the contents of the string block by the configuration associated // with each item. After doing this you can use mapOriginalPosToNewPos() - // to find out the new position given the position originall returned by + // to find out the new position given the position originally returned by // add(). void sortByConfig(); @@ -156,9 +139,8 @@ public: const Vector<size_t>* offsetsForString(const String16& val) const; private: - static int config_sort(const size_t* lhs, const size_t* rhs, void* state); + static int config_sort(void* state, const void* lhs, const void* rhs); - const bool mSorted; const bool mUTF8; // The following data structures represent the actual structures @@ -185,13 +167,18 @@ private: // Unique set of all the strings added to the pool, mapped to // the first index of mEntryArray where the value was added. DefaultKeyedVector<String16, ssize_t> mValues; - // Unique set of all (optional) identifiers of strings in the - // pool, mapping to indices in mEntries. - DefaultKeyedVector<String16, ssize_t> mIdents; // This array maps from the original position a string was placed at // in mEntryArray to its new position after being sorted with sortByConfig(). Vector<size_t> mOriginalPosToNewPos; }; +// The entry types are trivially movable because all fields they contain, including +// the vectors and strings, are trivially movable. +namespace android { + ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry); + ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style_span); + ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style); +}; + #endif diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp index 8d7acee..0dba950 100644 --- a/tools/aapt/XMLNode.cpp +++ b/tools/aapt/XMLNode.cpp @@ -973,7 +973,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(false, mUTF8); + StringPool strings(mUTF8); Vector<uint32_t> resids; // First collect just the strings for attribute names that have a diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp index 8057068..3994c31 100644 --- a/tools/aapt/ZipFile.cpp +++ b/tools/aapt/ZipFile.cpp @@ -20,8 +20,8 @@ #define LOG_TAG "zip" -#include <androidfw/ZipUtils.h> #include <utils/Log.h> +#include <utils/ZipUtils.h> #include "ZipFile.h" diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java index 7b672da..8794452 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java @@ -120,10 +120,8 @@ public final class BridgeResources extends Resources { mProjectCallback = projectCallback; } - public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile, - boolean platformStyleable, String styleableName) { - return new BridgeTypedArray(this, mContext, numEntries, platformFile, - platformStyleable, styleableName); + public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) { + return new BridgeTypedArray(this, mContext, numEntries, platformFile); } private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) { diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java index 8fdac02..cbc199a 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java @@ -16,7 +16,7 @@ package android.content.res; -import com.android.ide.common.rendering.api.DeclareStyleableResourceValue; +import com.android.ide.common.rendering.api.AttrResourceValue; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; @@ -51,28 +51,33 @@ public final class BridgeTypedArray extends TypedArray { private final BridgeResources mBridgeResources; private final BridgeContext mContext; private final boolean mPlatformFile; - private final boolean mPlatformStyleable; - private final String mStyleableName; private ResourceValue[] mResourceData; private String[] mNames; + private boolean[] mIsFramework; public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len, - boolean platformFile, boolean platformStyleable, String styleableName) { + boolean platformFile) { super(null, null, null, 0); mBridgeResources = resources; mContext = context; mPlatformFile = platformFile; - mPlatformStyleable = platformStyleable; - mStyleableName = styleableName; mResourceData = new ResourceValue[len]; mNames = new String[len]; + mIsFramework = new boolean[len]; } - /** A bridge-specific method that sets a value in the type array */ - public void bridgeSetValue(int index, String name, ResourceValue value) { + /** + * A bridge-specific method that sets a value in the type array + * @param index the index of the value in the TypedArray + * @param name the name of the attribute + * @param isFramework whether the attribute is in the android namespace. + * @param value the value of the attribute + */ + public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) { mResourceData[index] = value; mNames[index] = name; + mIsFramework[index] = isFramework; } /** @@ -213,8 +218,12 @@ public final class BridgeTypedArray extends TypedArray { return defValue; } + if (s == null) { + return defValue; + } + try { - return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue); + return XmlUtils.convertValueToInt(s, defValue); } catch (NumberFormatException e) { // pass } @@ -223,15 +232,14 @@ public final class BridgeTypedArray extends TypedArray { // Check for possible constants and try to find them. // Get the map of attribute-constant -> IntegerValue Map<String, Integer> map = null; - if (mPlatformStyleable) { + if (mIsFramework[index]) { map = Bridge.getEnumValues(mNames[index]); - } else if (mStyleableName != null) { + } else { // get the styleable matching the resolved name RenderResources res = mContext.getRenderResources(); - ResourceValue styleable = res.getProjectResource(ResourceType.DECLARE_STYLEABLE, - mStyleableName); - if (styleable instanceof DeclareStyleableResourceValue) { - map = ((DeclareStyleableResourceValue) styleable).getAttributeValues(mNames[index]); + ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]); + if (attr instanceof AttrResourceValue) { + map = ((AttrResourceValue) attr).getAttributeValues(); } } diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java index 945b3cd..5256b58 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java @@ -85,15 +85,18 @@ import java.io.InputStream; // ------ Native Delegates ------ @LayoutlibDelegate - /*package*/ static void nativeSetDefaultConfig(int nativeConfig) { - // pass + /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage, + Rect padding, Options opts) { + return nativeDecodeStream(is, storage, padding, opts, false, 1.f); } @LayoutlibDelegate - /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage, - Rect padding, Options opts) { + /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage, + Rect padding, Options opts, boolean applyScale, float scale) { Bitmap bm = null; + //TODO support rescaling + Density density = Density.MEDIUM; if (opts != null) { density = Density.getEnum(opts.inDensity); @@ -147,6 +150,13 @@ import java.io.InputStream; } @LayoutlibDelegate + /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts, + boolean applyScale, float scale) { + opts.inBitmap = null; + return null; + } + + @LayoutlibDelegate /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset, int length, Options opts) { opts.inBitmap = null; diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index eadec02..b76b8cf 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -524,7 +524,8 @@ public final class Bitmap_Delegate { int nativeInt = sManager.addNewDelegate(delegate); // and create/return a new Bitmap with it - return new Bitmap(nativeInt, null /* buffer */, isMutable, null /*ninePatchChunk*/, density); + return new Bitmap(nativeInt, null /* buffer */, isMutable, null /*ninePatchChunk*/, + density); } /** diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java new file mode 100644 index 0000000..14b84ef --- /dev/null +++ b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +/** + * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl} + * + * Through the layoutlib_create tool, the original methods of ViewRootImpl have been replaced + * by calls to methods of the same name in this delegate class. + * + */ +public class ViewRootImpl_Delegate { + + @LayoutlibDelegate + /*package*/ static boolean isInTouchMode() { + return false; // this allows displaying selection. + } +} diff --git a/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java b/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java new file mode 100644 index 0000000..0100dc5 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/internal/policy/PolicyManager.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.policy; + +import com.android.ide.common.rendering.api.LayoutLog; +import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.impl.RenderAction; + +import android.content.Context; +import android.view.BridgeInflater; +import android.view.FallbackEventHandler; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManagerPolicy; + +/** + * Custom implementation of PolicyManager that does nothing to run in LayoutLib. + * + */ +public class PolicyManager { + + public static Window makeNewWindow(Context context) { + // this will likely crash somewhere beyond so we log it. + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + "Call to PolicyManager.makeNewWindow is not supported", null); + return null; + } + + public static LayoutInflater makeNewLayoutInflater(Context context) { + return new BridgeInflater(context, RenderAction.getCurrentContext().getProjectCallback()); + } + + public static WindowManagerPolicy makeNewWindowManager() { + // this will likely crash somewhere beyond so we log it. + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + "Call to PolicyManager.makeNewWindowManager is not supported", null); + return null; + } + + public static FallbackEventHandler makeNewFallbackEventHandler(Context context) { + return new FallbackEventHandler() { + @Override + public void setView(View v) { + } + + @Override + public void preDispatchKeyEvent(KeyEvent event) { + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + return false; + } + }; + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index ff88209..66481fd 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -29,6 +29,7 @@ import com.android.ide.common.rendering.api.SessionParams; import com.android.layoutlib.bridge.impl.FontLoader; import com.android.layoutlib.bridge.impl.RenderDrawable; import com.android.layoutlib.bridge.impl.RenderSessionImpl; +import com.android.layoutlib.bridge.util.DynamicIdMap; import com.android.ninepatch.NinePatchChunk; import com.android.resources.ResourceType; import com.android.tools.layoutlib.create.MethodAdapter; @@ -78,7 +79,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { private final static ReentrantLock sLock = new ReentrantLock(); /** - * Maps from id to resource type/name. This is for android.R only. + * Maps from id to resource type/name. This is for com.android.internal.R */ private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<Integer, Pair<ResourceType, String>>(); @@ -89,11 +90,17 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(); /** * Reverse map compared to sRMap, resource type -> (resource name -> id). - * This is for android.R only. + * This is for com.android.internal.R. */ - private final static Map<ResourceType, Map<String, Integer>> sRFullMap = + private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class); + // framework resources are defined as 0x01XX#### where XX is the resource type (layout, + // drawable, etc...). Using FF as the type allows for 255 resource types before we get a + // collision which should be fine. + private final static int DYNAMIC_ID_SEED_START = 0x01ff0000; + private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START); + private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache = new HashMap<Object, Map<String, SoftReference<Bitmap>>>(); private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache = @@ -257,7 +264,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { ResourceType resType = ResourceType.getEnum(resTypeName); if (resType != null) { Map<String, Integer> fullMap = new HashMap<String, Integer>(); - sRFullMap.put(resType, fullMap); + sRevRMap.put(resType, fullMap); for (Field f : inner.getDeclaredFields()) { // only process static final fields. Since the final attribute may have @@ -459,7 +466,14 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { * does not match any resource. */ public static Pair<ResourceType, String> resolveResourceId(int value) { - return sRMap.get(value); + Pair<ResourceType, String> pair = sRMap.get(value); + if (pair == null) { + pair = sDynamicIds.resolveId(value); + if (pair == null) { + System.out.println(String.format("Missing id: %1$08X (%1$d)", value)); + } + } + return pair; } /** @@ -478,12 +492,17 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { * @return an {@link Integer} containing the resource id, or null if no resource were found. */ public static Integer getResourceId(ResourceType type, String name) { - Map<String, Integer> map = sRFullMap.get(type); + Map<String, Integer> map = sRevRMap.get(type); + Integer value = null; if (map != null) { - return map.get(name); + value = map.get(name); } - return null; + if (value == null) { + value = sDynamicIds.getId(type, name); + } + + return value; } /** @@ -598,6 +617,4 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch)); } } - - } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java index 529be97..f9f4b3a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java @@ -70,13 +70,13 @@ public class BridgeRenderSession extends RenderSession { @Override public Result getProperty(Object objectView, String propertyName) { - // TODO Auto-generated method stub + // pass return super.getProperty(objectView, propertyName); } @Override public Result setProperty(Object objectView, String propertyName, String propertyValue) { - // TODO Auto-generated method stub + // pass return super.setProperty(objectView, propertyName, propertyValue); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 58dc2d4..f9e48e2 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -60,6 +60,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.PowerManager; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; @@ -75,13 +76,11 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; import java.util.IdentityHashMap; +import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; /** * Custom implementation of Context/Activity to handle non compiled resources. @@ -246,15 +245,18 @@ public final class BridgeContext extends Context { public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) { Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid); + boolean isFrameworkRes = true; if (resourceInfo == null) { resourceInfo = mProjectCallback.resolveResourceId(resid); + isFrameworkRes = false; } if (resourceInfo == null) { return false; } - ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond()); + ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(), + isFrameworkRes); if (resolveRefs) { value = mRenderResources.resolveResValue(value); } @@ -314,12 +316,7 @@ public final class BridgeContext extends Context { if (isPlatformLayout == false && skipCallbackParser == false) { // check if the project callback can provide us with a custom parser. - ILayoutPullParser parser; - if (resource instanceof ResourceValue) { - parser = mProjectCallback.getParser((ResourceValue) resource); - } else { - parser = mProjectCallback.getParser(resource.getName()); - } + ILayoutPullParser parser = getParser(resource); if (parser != null) { BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser, @@ -392,6 +389,17 @@ public final class BridgeContext extends Context { return Pair.of(null, false); } + @SuppressWarnings("deprecation") + private ILayoutPullParser getParser(ResourceReference resource) { + ILayoutPullParser parser; + if (resource instanceof ResourceValue) { + parser = mProjectCallback.getParser((ResourceValue) resource); + } else { + parser = mProjectCallback.getParser(resource.getName()); + } + return parser; + } + // ------------ Context methods @Override @@ -431,6 +439,10 @@ public final class BridgeContext extends Context { return null; } + if (POWER_SERVICE.equals(service)) { + return new PowerManager(new BridgePowerManager(), new Handler()); + } + throw new UnsupportedOperationException("Unsupported Service: " + service); } @@ -519,12 +531,10 @@ public final class BridgeContext extends Context { return null; } - AtomicBoolean frameworkAttributes = new AtomicBoolean(); - AtomicReference<String> attrName = new AtomicReference<String>(); - TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes, attrName); + List<Pair<String, Boolean>> attributeList = searchAttrs(attrs); BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length, - isPlatformFile, frameworkAttributes.get(), attrName.get()); + isPlatformFile); // look for a custom style. String customStyle = null; @@ -550,14 +560,19 @@ public final class BridgeContext extends Context { if (defStyleAttr != 0) { // get the name from the int. - String defStyleName = searchAttr(defStyleAttr); + Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr); if (defaultPropMap != null) { + String defStyleName = defStyleAttribute.getFirst(); + if (defStyleAttribute.getSecond()) { + defStyleName = "android:" + defStyleName; + } defaultPropMap.put("style", defStyleName); } // look for the style in the current theme, and its parent: - ResourceValue item = mRenderResources.findItemInTheme(defStyleName); + ResourceValue item = mRenderResources.findItemInTheme(defStyleAttribute.getFirst(), + defStyleAttribute.getSecond()); if (item != null) { // item is a reference to a style entry. Search for it. @@ -570,19 +585,23 @@ public final class BridgeContext extends Context { } else { Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR, String.format( - "Failed to find style '%s' in current theme", defStyleName), + "Failed to find style '%s' in current theme", + defStyleAttribute.getFirst()), null /*data*/); } } else if (defStyleRes != 0) { + boolean isFrameworkRes = true; Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes); if (value == null) { value = mProjectCallback.resolveResourceId(defStyleRes); + isFrameworkRes = false; } if (value != null) { if (value.getFirst() == ResourceType.STYLE) { // look for the style in the current theme, and its parent: - ResourceValue item = mRenderResources.findItemInTheme(value.getSecond()); + ResourceValue item = mRenderResources.findItemInTheme(value.getSecond(), + isFrameworkRes); if (item != null) { if (item instanceof StyleResourceValue) { if (defaultPropMap != null) { @@ -614,26 +633,28 @@ public final class BridgeContext extends Context { } } - String namespace = BridgeConstants.NS_RESOURCES; - boolean useFrameworkNS = frameworkAttributes.get(); - if (useFrameworkNS == false) { - // need to use the application namespace - namespace = mProjectCallback.getNamespace(); - } + String appNamespace = mProjectCallback.getNamespace(); + + if (attributeList != null) { + for (int index = 0 ; index < attributeList.size() ; index++) { + Pair<String, Boolean> attribute = attributeList.get(index); - if (styleNameMap != null) { - for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { - int index = styleAttribute.getKey().intValue(); + if (attribute == null) { + continue; + } - String name = styleAttribute.getValue(); + String attrName = attribute.getFirst(); + boolean frameworkAttr = attribute.getSecond().booleanValue(); String value = null; if (set != null) { - value = set.getAttributeValue(namespace, name); + value = set.getAttributeValue( + frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace, + attrName); // if this is an app attribute, and the first get fails, try with the // new res-auto namespace as well - if (useFrameworkNS == false && value == null) { - value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, name); + if (frameworkAttr == false && value == null) { + value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName); } } @@ -644,18 +665,20 @@ public final class BridgeContext extends Context { // look for the value in the custom style first (and its parent if needed) if (customStyleValues != null) { - resValue = mRenderResources.findItemInStyle(customStyleValues, name); + resValue = mRenderResources.findItemInStyle(customStyleValues, + attrName, frameworkAttr); } // then look for the value in the default Style (and its parent if needed) if (resValue == null && defStyleValues != null) { - resValue = mRenderResources.findItemInStyle(defStyleValues, name); + resValue = mRenderResources.findItemInStyle(defStyleValues, + attrName, frameworkAttr); } // if the item is not present in the defStyle, we look in the main theme (and // its parent themes) if (resValue == null) { - resValue = mRenderResources.findItemInTheme(name); + resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr); } // if we found a value, we make sure this doesn't reference another value. @@ -663,18 +686,18 @@ public final class BridgeContext extends Context { if (resValue != null) { // put the first default value, before the resolution. if (defaultPropMap != null) { - defaultPropMap.put(name, resValue.getValue()); + defaultPropMap.put(attrName, resValue.getValue()); } resValue = mRenderResources.resolveResValue(resValue); } - ta.bridgeSetValue(index, name, resValue); + ta.bridgeSetValue(index, attrName, frameworkAttr, resValue); } else { // there is a value in the XML, but we need to resolve it in case it's // referencing another resource or a theme value. - ta.bridgeSetValue(index, name, - mRenderResources.resolveValue(null, name, value, isPlatformFile)); + ta.bridgeSetValue(index, attrName, frameworkAttr, + mRenderResources.resolveValue(null, attrName, value, isPlatformFile)); } } } @@ -700,23 +723,23 @@ public final class BridgeContext extends Context { private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs) throws Resources.NotFoundException { + List<Pair<String, Boolean>> attributes = searchAttrs(attrs); + BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length, - false, true, null); + false); // for each attribute, get its name so that we can search it in the style for (int i = 0 ; i < attrs.length ; i++) { - Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]); - if (resolvedResource != null) { - String attrName = resolvedResource.getSecond(); - // look for the value in the given style - ResourceValue resValue = mRenderResources.findItemInStyle(style, attrName); + Pair<String, Boolean> attribute = attributes.get(i); - if (resValue != null) { - // resolve it to make sure there are no references left. - ta.bridgeSetValue(i, attrName, mRenderResources.resolveResValue(resValue)); + // look for the value in the given style + ResourceValue resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(), + attribute.getSecond()); - resValue = mRenderResources.resolveResValue(resValue); - } + if (resValue != null) { + // resolve it to make sure there are no references left. + ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(), + mRenderResources.resolveResValue(resValue)); } } @@ -727,91 +750,52 @@ public final class BridgeContext extends Context { /** - * The input int[] attrs is one of com.android.internal.R.styleable fields where the name - * of the field is the style being referenced and the array contains one index per attribute. + * The input int[] attrs is a list of attributes. The returns a list of information about + * each attributes. The information is (name, isFramework) * <p/> - * searchAttrs() finds all the names of the attributes referenced so for example if - * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where - * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index - * that is used to reference the attribute later in the TypedArray. * * @param attrs An attribute array reference given to obtainStyledAttributes. - * @param outFrameworkFlag out value indicating if the attr array is a framework value - * @param outAttrName out value for the resolved attr name. - * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the - * attribute array. Returns null if nothing is found. + * @return List of attribute information. */ - private TreeMap<Integer,String> searchAttrs(int[] attrs, AtomicBoolean outFrameworkFlag, - AtomicReference<String> outAttrName) { - // get the name of the array from the framework resources - String arrayName = Bridge.resolveResourceId(attrs); - if (arrayName != null) { - // if we found it, get the name of each of the int in the array. - TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); - for (int i = 0 ; i < attrs.length ; i++) { - Pair<ResourceType, String> info = Bridge.resolveResourceId(attrs[i]); - if (info != null) { - attributes.put(i, info.getSecond()); - } else { - // FIXME Not sure what we should be doing here... - attributes.put(i, null); - } - } - - if (outFrameworkFlag != null) { - outFrameworkFlag.set(true); - } - if (outAttrName != null) { - outAttrName.set(arrayName); - } + private List<Pair<String, Boolean>> searchAttrs(int[] attrs) { + List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length); - return attributes; - } - - // if the name was not found in the framework resources, look in the project - // resources - arrayName = mProjectCallback.resolveResourceId(attrs); - if (arrayName != null) { - TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); - for (int i = 0 ; i < attrs.length ; i++) { - Pair<ResourceType, String> info = mProjectCallback.resolveResourceId(attrs[i]); - if (info != null) { - attributes.put(i, info.getSecond()); - } else { - // FIXME Not sure what we should be doing here... - attributes.put(i, null); - } + // for each attribute, get its name so that we can search it in the style + for (int i = 0 ; i < attrs.length ; i++) { + Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]); + boolean isFramework = false; + if (resolvedResource != null) { + isFramework = true; + } else { + resolvedResource = mProjectCallback.resolveResourceId(attrs[i]); } - if (outFrameworkFlag != null) { - outFrameworkFlag.set(false); - } - if (outAttrName != null) { - outAttrName.set(arrayName); + if (resolvedResource != null) { + results.add(Pair.of(resolvedResource.getSecond(), isFramework)); + } else { + results.add(null); } - - return attributes; } - return null; + return results; } /** * Searches for the attribute referenced by its internal id. * * @param attr An attribute reference given to obtainStyledAttributes such as defStyle. - * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null + * @return A (name, isFramework) pair describing the attribute if found. Returns null * if nothing is found. */ - public String searchAttr(int attr) { + public Pair<String, Boolean> searchAttr(int attr) { Pair<ResourceType, String> info = Bridge.resolveResourceId(attr); if (info != null) { - return info.getSecond(); + return Pair.of(info.getSecond(), Boolean.TRUE); } info = mProjectCallback.resolveResourceId(attr); if (info != null) { - return info.getSecond(); + return Pair.of(info.getSecond(), Boolean.FALSE); } return null; @@ -871,149 +855,149 @@ public final class BridgeContext extends Context { @Override public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) { - // TODO Auto-generated method stub + // pass return false; } @Override public int checkCallingOrSelfPermission(String arg0) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkCallingPermission(String arg0) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkCallingUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkPermission(String arg0, int arg1, int arg2) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) { - // TODO Auto-generated method stub + // pass return 0; } @Override public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, int arg4, int arg5) { - // TODO Auto-generated method stub + // pass return 0; } @Override public void clearWallpaper() { - // TODO Auto-generated method stub + // pass } @Override public Context createPackageContext(String arg0, int arg1) { - // TODO Auto-generated method stub + // pass return null; } @Override public String[] databaseList() { - // TODO Auto-generated method stub + // pass return null; } @Override public boolean deleteDatabase(String arg0) { - // TODO Auto-generated method stub + // pass return false; } @Override public boolean deleteFile(String arg0) { - // TODO Auto-generated method stub + // pass return false; } @Override public void enforceCallingOrSelfPermission(String arg0, String arg1) { - // TODO Auto-generated method stub + // pass } @Override public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1, String arg2) { - // TODO Auto-generated method stub + // pass } @Override public void enforceCallingPermission(String arg0, String arg1) { - // TODO Auto-generated method stub + // pass } @Override public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) { - // TODO Auto-generated method stub + // pass } @Override public void enforcePermission(String arg0, int arg1, int arg2, String arg3) { - // TODO Auto-generated method stub + // pass } @Override public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3, String arg4) { - // TODO Auto-generated method stub + // pass } @Override public void enforceUriPermission(Uri arg0, String arg1, String arg2, int arg3, int arg4, int arg5, String arg6) { - // TODO Auto-generated method stub + // pass } @Override public String[] fileList() { - // TODO Auto-generated method stub + // pass return null; } @Override public AssetManager getAssets() { - // TODO Auto-generated method stub + // pass return null; } @Override public File getCacheDir() { - // TODO Auto-generated method stub + // pass return null; } @Override public File getExternalCacheDir() { - // TODO Auto-generated method stub + // pass return null; } @@ -1027,49 +1011,49 @@ public final class BridgeContext extends Context { @Override public File getDatabasePath(String arg0) { - // TODO Auto-generated method stub + // pass return null; } @Override public File getDir(String arg0, int arg1) { - // TODO Auto-generated method stub + // pass return null; } @Override public File getFileStreamPath(String arg0) { - // TODO Auto-generated method stub + // pass return null; } @Override public File getFilesDir() { - // TODO Auto-generated method stub + // pass return null; } @Override public File getExternalFilesDir(String type) { - // TODO Auto-generated method stub + // pass return null; } @Override public String getPackageCodePath() { - // TODO Auto-generated method stub + // pass return null; } @Override public PackageManager getPackageManager() { - // TODO Auto-generated method stub + // pass return null; } @Override public String getPackageName() { - // TODO Auto-generated method stub + // pass return null; } @@ -1080,25 +1064,25 @@ public final class BridgeContext extends Context { @Override public String getPackageResourcePath() { - // TODO Auto-generated method stub + // pass return null; } @Override public File getSharedPrefsFile(String name) { - // TODO Auto-generated method stub + // pass return null; } @Override public SharedPreferences getSharedPreferences(String arg0, int arg1) { - // TODO Auto-generated method stub + // pass return null; } @Override public Drawable getWallpaper() { - // TODO Auto-generated method stub + // pass return null; } @@ -1114,81 +1098,81 @@ public final class BridgeContext extends Context { @Override public void grantUriPermission(String arg0, Uri arg1, int arg2) { - // TODO Auto-generated method stub + // pass } @Override public FileInputStream openFileInput(String arg0) throws FileNotFoundException { - // TODO Auto-generated method stub + // pass return null; } @Override public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException { - // TODO Auto-generated method stub + // pass return null; } @Override public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) { - // TODO Auto-generated method stub + // pass return null; } @Override public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2, DatabaseErrorHandler arg3) { - // TODO Auto-generated method stub + // pass return null; } @Override public Drawable peekWallpaper() { - // TODO Auto-generated method stub + // pass return null; } @Override public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) { - // TODO Auto-generated method stub + // pass return null; } @Override public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, String arg2, Handler arg3) { - // TODO Auto-generated method stub + // pass return null; } @Override public void removeStickyBroadcast(Intent arg0) { - // TODO Auto-generated method stub + // pass } @Override public void revokeUriPermission(Uri arg0, int arg1) { - // TODO Auto-generated method stub + // pass } @Override public void sendBroadcast(Intent arg0) { - // TODO Auto-generated method stub + // pass } @Override public void sendBroadcast(Intent arg0, String arg1) { - // TODO Auto-generated method stub + // pass } @Override public void sendOrderedBroadcast(Intent arg0, String arg1) { - // TODO Auto-generated method stub + // pass } @@ -1196,13 +1180,13 @@ public final class BridgeContext extends Context { public void sendOrderedBroadcast(Intent arg0, String arg1, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, Bundle arg6) { - // TODO Auto-generated method stub + // pass } @Override public void sendStickyBroadcast(Intent arg0) { - // TODO Auto-generated method stub + // pass } @@ -1210,68 +1194,79 @@ public final class BridgeContext extends Context { public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { - // TODO Auto-generated method stub + // pass } @Override public void setTheme(int arg0) { - // TODO Auto-generated method stub + // pass } @Override public void setWallpaper(Bitmap arg0) throws IOException { - // TODO Auto-generated method stub + // pass } @Override public void setWallpaper(InputStream arg0) throws IOException { - // TODO Auto-generated method stub + // pass } @Override public void startActivity(Intent arg0) { - // TODO Auto-generated method stub + // pass + } + @Override + public void startActivity(Intent arg0, Bundle arg1) { + // pass } @Override public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws IntentSender.SendIntentException { - // TODO Auto-generated method stub + // pass + } + + @Override + public void startIntentSender(IntentSender intent, + Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, + Bundle options) throws IntentSender.SendIntentException { + // pass } @Override public boolean startInstrumentation(ComponentName arg0, String arg1, Bundle arg2) { - // TODO Auto-generated method stub + // pass return false; } @Override public ComponentName startService(Intent arg0) { - // TODO Auto-generated method stub + // pass return null; } @Override public boolean stopService(Intent arg0) { - // TODO Auto-generated method stub + // pass return false; } @Override public void unbindService(ServiceConnection arg0) { - // TODO Auto-generated method stub + // pass } @Override public void unregisterReceiver(BroadcastReceiver arg0) { - // TODO Auto-generated method stub + // pass } @@ -1282,7 +1277,13 @@ public final class BridgeContext extends Context { @Override public void startActivities(Intent[] arg0) { - // TODO Auto-generated method stub + // pass + + } + + @Override + public void startActivities(Intent[] arg0, Bundle arg1) { + // pass } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java new file mode 100644 index 0000000..6071a6b --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.layoutlib.bridge.android; + +import android.os.IBinder; +import android.os.IPowerManager; +import android.os.RemoteException; +import android.os.WorkSource; + +/** + * Fake implementation of IPowerManager. + * + */ +public class BridgePowerManager implements IPowerManager { + + @Override + public boolean isScreenOn() throws RemoteException { + return true; + } + + @Override + public IBinder asBinder() { + // pass for now. + return null; + } + + @Override + public void acquireWakeLock(int arg0, IBinder arg1, String arg2, WorkSource arg3) + throws RemoteException { + // pass for now. + } + + @Override + public void clearUserActivityTimeout(long arg0, long arg1) throws RemoteException { + // pass for now. + } + + @Override + public void crash(String arg0) throws RemoteException { + // pass for now. + } + + @Override + public int getSupportedWakeLockFlags() throws RemoteException { + // pass for now. + return 0; + } + + @Override + public void goToSleep(long arg0) throws RemoteException { + // pass for now. + } + + @Override + public void goToSleepWithReason(long arg0, int arg1) throws RemoteException { + // pass for now. + } + + @Override + public void preventScreenOn(boolean arg0) throws RemoteException { + // pass for now. + } + + @Override + public void reboot(String arg0) throws RemoteException { + // pass for now. + } + + @Override + public void releaseWakeLock(IBinder arg0, int arg1) throws RemoteException { + // pass for now. + } + + @Override + public void setAttentionLight(boolean arg0, int arg1) throws RemoteException { + // pass for now. + } + + @Override + public void setAutoBrightnessAdjustment(float arg0) throws RemoteException { + // pass for now. + } + + @Override + public void setBacklightBrightness(int arg0) throws RemoteException { + // pass for now. + } + + @Override + public void setMaximumScreenOffTimeount(int arg0) throws RemoteException { + // pass for now. + } + + @Override + public void setPokeLock(int arg0, IBinder arg1, String arg2) throws RemoteException { + // pass for now. + } + + @Override + public void setStayOnSetting(int arg0) throws RemoteException { + // pass for now. + } + + @Override + public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1) throws RemoteException { + // pass for now. + } + + @Override + public void userActivity(long arg0, boolean arg1) throws RemoteException { + // pass for now. + } + + @Override + public void userActivityWithForce(long arg0, boolean arg1, boolean arg2) throws RemoteException { + // pass for now. + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java index 79606a4..7c683c9 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java @@ -39,6 +39,7 @@ public final class BridgeWindow implements IWindow { public void dispatchGetNewSurface() throws RemoteException { // pass for now. } + @Override public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2) throws RemoteException { @@ -52,6 +53,11 @@ public final class BridgeWindow implements IWindow { } @Override + public void dispatchScreenState(boolean on) throws RemoteException { + // pass for now. + } + + @Override public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException { // pass for now. } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java index bef2c95..e6c9351 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java @@ -88,7 +88,7 @@ public class BridgeWindowManager implements IWindowManager { // ---- unused implementation of IWindowManager ---- @Override - public boolean canStatusBarHide() throws RemoteException { + public boolean hasSystemNavBar() throws RemoteException { // TODO Auto-generated method stub return false; } @@ -161,92 +161,11 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public int getDPadKeycodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getDPadScancodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - - @Override - public InputDevice getInputDevice(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return null; - } - - @Override - public int[] getInputDeviceIds() throws RemoteException { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getKeycodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getKeycodeStateForDevice(int arg0, int arg1) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - - @Override public int getPendingAppTransition() throws RemoteException { // TODO Auto-generated method stub return 0; } - - @Override - public int getScancodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getScancodeStateForDevice(int arg0, int arg1) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getSwitchState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getSwitchStateForDevice(int arg0, int arg1) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getTrackballKeycodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getTrackballScancodeState(int arg0) throws RemoteException { - // TODO Auto-generated method stub - return 0; - } - - @Override - public boolean hasKeys(int[] arg0, boolean[] arg1) throws RemoteException { - // TODO Auto-generated method stub - return false; - } - @Override public boolean inKeyguardRestrictedInputMode() throws RemoteException { // TODO Auto-generated method stub @@ -254,30 +173,6 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public boolean injectInputEventNoWait(InputEvent arg0) throws RemoteException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean injectKeyEvent(KeyEvent arg0, boolean arg1) throws RemoteException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean injectPointerEvent(MotionEvent arg0, boolean arg1) throws RemoteException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean injectTrackballEvent(MotionEvent arg0, boolean arg1) throws RemoteException { - // TODO Auto-generated method stub - return false; - } - - @Override public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException { // TODO Auto-generated method stub return false; @@ -302,12 +197,6 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public InputChannel monitorInput(String arg0) throws RemoteException { - // TODO Auto-generated method stub - return null; - } - - @Override public void moveAppToken(int arg0, IBinder arg1) throws RemoteException { // TODO Auto-generated method stub @@ -340,6 +229,12 @@ public class BridgeWindowManager implements IWindowManager { } @Override + public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY, + IRemoteCallback startedCallback) throws RemoteException { + // TODO Auto-generated method stub + } + + @Override public void pauseKeyDispatching(IBinder arg0) throws RemoteException { // TODO Auto-generated method stub @@ -456,15 +351,8 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public void setPointerSpeed(int arg0) throws RemoteException { + public void updateRotation(boolean arg0, boolean arg1) throws RemoteException { // TODO Auto-generated method stub - - } - - @Override - public void updateRotation(boolean arg0) throws RemoteException { - // TODO Auto-generated method stub - } @Override diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java new file mode 100644 index 0000000..a1fae95 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.layoutlib.bridge.util; + +import com.android.resources.ResourceType; +import com.android.util.Pair; + +import android.util.SparseArray; + +import java.util.HashMap; +import java.util.Map; + +public class DynamicIdMap { + + private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<Pair<ResourceType, String>, Integer>(); + private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<Pair<ResourceType, String>>(); + private int mDynamicSeed; + + public DynamicIdMap(int seed) { + mDynamicSeed = seed; + } + + public void reset(int seed) { + mDynamicIds.clear(); + mRevDynamicIds.clear(); + mDynamicSeed = seed; + } + + /** + * Returns a dynamic integer for the given resource type/name, creating it if it doesn't + * already exist. + * + * @param type the type of the resource + * @param name the name of the resource + * @return an integer. + */ + public Integer getId(ResourceType type, String name) { + return getId(Pair.of(type, name)); + } + + /** + * Returns a dynamic integer for the given resource type/name, creating it if it doesn't + * already exist. + * + * @param resource the type/name of the resource + * @return an integer. + */ + public Integer getId(Pair<ResourceType, String> resource) { + Integer value = mDynamicIds.get(resource); + if (value == null) { + value = Integer.valueOf(++mDynamicSeed); + mDynamicIds.put(resource, value); + mRevDynamicIds.put(value, resource); + } + + return value; + } + + public Pair<ResourceType, String> resolveId(int id) { + return mRevDynamicIds.get(id); + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index 4b33474..79e02c8 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -114,6 +114,7 @@ public final class CreateInfo implements ICreateInfo { "android.view.LayoutInflater#rInflate", "android.view.LayoutInflater#parseInclude", "android.view.View#isInEditMode", + "android.view.ViewRootImpl#isInTouchMode", "android.view.inputmethod.InputMethodManager#getInstance", "android.util.Log#println_native", "com.android.internal.util.XmlUtils#convertValueToInt", @@ -183,10 +184,11 @@ public final class CreateInfo implements ICreateInfo { */ private final static String[] RENAMED_CLASSES = new String[] { - "android.os.ServiceManager", "android.os._Original_ServiceManager", - "android.view.SurfaceView", "android.view._Original_SurfaceView", + "android.os.ServiceManager", "android.os._Original_ServiceManager", + "android.view.SurfaceView", "android.view._Original_SurfaceView", "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager", - "android.webkit.WebView", "android.webkit._Original_WebView", + "android.webkit.WebView", "android.webkit._Original_WebView", + "com.android.internal.policy.PolicyManager", "com.android.internal.policy._Original_PolicyManager", }; /** |
