diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/androidfw/Asset.cpp | 92 | ||||
| -rw-r--r-- | libs/androidfw/AssetManager.cpp | 2 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/Asset.h | 15 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/AssetManager.h | 6 | ||||
| -rw-r--r-- | libs/androidfw/tests/Android.mk | 1 | ||||
| -rw-r--r-- | libs/androidfw/tests/Asset_test.cpp | 37 | ||||
| -rw-r--r-- | libs/hwui/FrameBuilder.cpp | 2 | ||||
| -rw-r--r-- | libs/hwui/tests/unit/FrameBuilderTests.cpp | 29 |
8 files changed, 142 insertions, 42 deletions
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp index 2cfa6666e9ab..8e8c6a2e25a2 100644 --- a/libs/androidfw/Asset.cpp +++ b/libs/androidfw/Asset.cpp @@ -52,6 +52,47 @@ static int32_t gCount = 0; static Asset* gHead = NULL; static Asset* gTail = NULL; +void Asset::registerAsset(Asset* asset) +{ + AutoMutex _l(gAssetLock); + gCount++; + asset->mNext = asset->mPrev = NULL; + if (gTail == NULL) { + gHead = gTail = asset; + } else { + asset->mPrev = gTail; + gTail->mNext = asset; + gTail = asset; + } + + if (kIsDebug) { + ALOGI("Creating Asset %p #%d\n", asset, gCount); + } +} + +void Asset::unregisterAsset(Asset* asset) +{ + AutoMutex _l(gAssetLock); + gCount--; + if (gHead == asset) { + gHead = asset->mNext; + } + if (gTail == asset) { + gTail = asset->mPrev; + } + if (asset->mNext != NULL) { + asset->mNext->mPrev = asset->mPrev; + } + if (asset->mPrev != NULL) { + asset->mPrev->mNext = asset->mNext; + } + asset->mNext = asset->mPrev = NULL; + + if (kIsDebug) { + ALOGI("Destroying Asset in %p #%d\n", asset, gCount); + } +} + int32_t Asset::getGlobalCount() { AutoMutex _l(gAssetLock); @@ -79,43 +120,8 @@ String8 Asset::getAssetAllocations() } Asset::Asset(void) - : mAccessMode(ACCESS_UNKNOWN) + : mAccessMode(ACCESS_UNKNOWN), mNext(NULL), mPrev(NULL) { - AutoMutex _l(gAssetLock); - gCount++; - mNext = mPrev = NULL; - if (gTail == NULL) { - gHead = gTail = this; - } else { - mPrev = gTail; - gTail->mNext = this; - gTail = this; - } - if (kIsDebug) { - ALOGI("Creating Asset %p #%d\n", this, gCount); - } -} - -Asset::~Asset(void) -{ - AutoMutex _l(gAssetLock); - gCount--; - if (gHead == this) { - gHead = mNext; - } - if (gTail == this) { - gTail = mPrev; - } - if (mNext != NULL) { - mNext->mPrev = mPrev; - } - if (mPrev != NULL) { - mPrev->mNext = mNext; - } - mNext = mPrev = NULL; - if (kIsDebug) { - ALOGI("Destroying Asset in %p #%d\n", this, gCount); - } } /* @@ -361,6 +367,9 @@ off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t m _FileAsset::_FileAsset(void) : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL) { + // Register the Asset with the global list here after it is fully constructed and its + // vtable pointer points to this concrete type. b/31113965 + registerAsset(this); } /* @@ -369,6 +378,10 @@ _FileAsset::_FileAsset(void) _FileAsset::~_FileAsset(void) { close(); + + // Unregister the Asset from the global list here before it is destructed and while its vtable + // pointer still points to this concrete type. b/31113965 + unregisterAsset(this); } /* @@ -685,6 +698,9 @@ _CompressedAsset::_CompressedAsset(void) : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0), mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL) { + // Register the Asset with the global list here after it is fully constructed and its + // vtable pointer points to this concrete type. b/31113965 + registerAsset(this); } /* @@ -693,6 +709,10 @@ _CompressedAsset::_CompressedAsset(void) _CompressedAsset::~_CompressedAsset(void) { close(); + + // Unregister the Asset from the global list here before it is destructed and while its vtable + // pointer still points to this concrete type. b/31113965 + unregisterAsset(this); } /* diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 81e91a80783b..80968e51d48c 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -79,7 +79,7 @@ static volatile int32_t gCount = 0; const char* AssetManager::RESOURCES_FILENAME = "resources.arsc"; const char* AssetManager::IDMAP_BIN = "/system/bin/idmap"; const char* AssetManager::OVERLAY_DIR = "/vendor/overlay"; -const char* AssetManager::OVERLAY_SKU_DIR_PROPERTY = "ro.boot.vendor.overlay.sku"; +const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme"; const char* AssetManager::TARGET_PACKAGE_NAME = "android"; const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk"; const char* AssetManager::IDMAP_DIR = "/data/resource-cache"; diff --git a/libs/androidfw/include/androidfw/Asset.h b/libs/androidfw/include/androidfw/Asset.h index 36efbe5a48e9..2cd8c0bf3c78 100644 --- a/libs/androidfw/include/androidfw/Asset.h +++ b/libs/androidfw/include/androidfw/Asset.h @@ -44,7 +44,7 @@ namespace android { */ class Asset { public: - virtual ~Asset(void); + virtual ~Asset(void) = default; static int32_t getGlobalCount(); static String8 getAssetAllocations(); @@ -119,6 +119,19 @@ public: const char* getAssetSource(void) const { return mAssetSource.string(); } protected: + /* + * Adds this Asset to the global Asset list for debugging and + * accounting. + * Concrete subclasses must call this in their constructor. + */ + static void registerAsset(Asset* asset); + + /* + * Removes this Asset from the global Asset list. + * Concrete subclasses must call this in their destructor. + */ + static void unregisterAsset(Asset* asset); + Asset(void); // constructor; only invoked indirectly /* handle common seek() housekeeping */ diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h index b39dccf44a8b..594dba5049dd 100644 --- a/libs/androidfw/include/androidfw/AssetManager.h +++ b/libs/androidfw/include/androidfw/AssetManager.h @@ -64,11 +64,11 @@ public: static const char* IDMAP_BIN; static const char* OVERLAY_DIR; /* - * If OVERLAY_SKU_DIR_PROPERTY is set, search for runtime resource overlay - * APKs in OVERLAY_DIR/<value of OVERLAY_SKU_DIR_PROPERTY> rather than in + * If OVERLAY_THEME_DIR_PROPERTY is set, search for runtime resource overlay + * APKs in OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to * OVERLAY_DIR. */ - static const char* OVERLAY_SKU_DIR_PROPERTY; + static const char* OVERLAY_THEME_DIR_PROPERTY; static const char* TARGET_PACKAGE_NAME; static const char* TARGET_APK_PATH; static const char* IDMAP_DIR; diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk index 2bc026b79ca2..1fe1773578fa 100644 --- a/libs/androidfw/tests/Android.mk +++ b/libs/androidfw/tests/Android.mk @@ -22,6 +22,7 @@ LOCAL_PATH:= $(call my-dir) testFiles := \ AppAsLib_test.cpp \ + Asset_test.cpp \ AttributeFinder_test.cpp \ ByteBucketArray_test.cpp \ Config_test.cpp \ diff --git a/libs/androidfw/tests/Asset_test.cpp b/libs/androidfw/tests/Asset_test.cpp new file mode 100644 index 000000000000..45c8cef92918 --- /dev/null +++ b/libs/androidfw/tests/Asset_test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 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. + */ + +#include <androidfw/Asset.h> + +#include <gtest/gtest.h> + +using namespace android; + +TEST(AssetTest, FileAssetRegistersItself) { + const int32_t count = Asset::getGlobalCount(); + Asset* asset = new _FileAsset(); + EXPECT_EQ(count + 1, Asset::getGlobalCount()); + delete asset; + EXPECT_EQ(count, Asset::getGlobalCount()); +} + +TEST(AssetTest, CompressedAssetRegistersItself) { + const int32_t count = Asset::getGlobalCount(); + Asset* asset = new _CompressedAsset(); + EXPECT_EQ(count + 1, Asset::getGlobalCount()); + delete asset; + EXPECT_EQ(count, Asset::getGlobalCount()); +} diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index 37d9d0e749e6..7524ba0dcea6 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -591,7 +591,7 @@ void FrameBuilder::deferArcOp(const ArcOp& op) { } static bool hasMergeableClip(const BakedOpState& state) { - return state.computedState.clipState + return !state.computedState.clipState || state.computedState.clipState->mode == ClipMode::Rectangle; } diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp index 53dbede2f8e1..e2dc3a0a2c66 100644 --- a/libs/hwui/tests/unit/FrameBuilderTests.cpp +++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp @@ -477,6 +477,35 @@ RENDERTHREAD_TEST(FrameBuilder, clippedMerging) { EXPECT_EQ(4, renderer.getIndex()); } +RENDERTHREAD_TEST(FrameBuilder, regionClipStopsMerge) { + class RegionClipStopsMergeTestRenderer : public TestRendererBase { + public: + void onTextOp(const TextOp& op, const BakedOpState& state) override { mIndex++; } + }; + auto node = TestUtils::createNode(0, 0, 400, 400, + [](RenderProperties& props, TestCanvas& canvas) { + SkPath path; + path.addCircle(200, 200, 200, SkPath::kCW_Direction); + canvas.save(SaveFlags::MatrixClip); + canvas.clipPath(&path, SkRegion::kIntersect_Op); + SkPaint paint; + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + paint.setAntiAlias(true); + paint.setTextSize(50); + TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100); + TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 200); + canvas.restore(); + }); + + FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, + sLightGeometry, Caches::getInstance()); + frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node)); + + RegionClipStopsMergeTestRenderer renderer; + frameBuilder.replayBakedOps<TestDispatcher>(renderer); + EXPECT_EQ(2, renderer.getIndex()); +} + RENDERTHREAD_TEST(FrameBuilder, textMerging) { class TextMergingTestRenderer : public TestRendererBase { public: |