summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/androidfw/Asset.cpp92
-rw-r--r--libs/androidfw/AssetManager.cpp2
-rw-r--r--libs/androidfw/include/androidfw/Asset.h15
-rw-r--r--libs/androidfw/include/androidfw/AssetManager.h6
-rw-r--r--libs/androidfw/tests/Android.mk1
-rw-r--r--libs/androidfw/tests/Asset_test.cpp37
-rw-r--r--libs/hwui/FrameBuilder.cpp2
-rw-r--r--libs/hwui/tests/unit/FrameBuilderTests.cpp29
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: