summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/androidfw/ResourceTypes.cpp74
-rw-r--r--libs/androidfw/tests/Android.mk30
-rw-r--r--libs/androidfw/tests/ResTable_test.cpp81
-rw-r--r--libs/hwui/AssetAtlas.cpp22
-rw-r--r--libs/hwui/AssetAtlas.h62
-rw-r--r--libs/hwui/Canvas.h7
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--libs/hwui/SkiaCanvas.cpp28
-rw-r--r--libs/hwui/SkiaCanvasProxy.cpp1
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp4
-rw-r--r--libs/hwui/renderthread/RenderProxy.h2
11 files changed, 213 insertions, 100 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index e247150..04ebe70 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -17,6 +17,16 @@
#define LOG_TAG "ResourceType"
//#define LOG_NDEBUG 0
+#include <ctype.h>
+#include <memory.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <limits>
+#include <type_traits>
+
#include <androidfw/ByteBucketArray.h>
#include <androidfw/ResourceTypes.h>
#include <androidfw/TypeWrappers.h>
@@ -27,17 +37,10 @@
#include <utils/String16.h>
#include <utils/String8.h>
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
#include <binder/TextOutput.h>
#endif
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <ctype.h>
-#include <stdint.h>
-#include <stddef.h>
-
#ifndef INT32_MAX
#define INT32_MAX ((int32_t)(2147483647))
#endif
@@ -4615,8 +4618,7 @@ static bool parse_unit(const char* str, Res_value* outValue,
return false;
}
-
-bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
+bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue)
{
while (len > 0 && isspace16(*s)) {
s++;
@@ -4628,7 +4630,7 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
}
size_t i = 0;
- int32_t val = 0;
+ int64_t val = 0;
bool neg = false;
if (*s == '-') {
@@ -4640,28 +4642,50 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
return false;
}
+ static_assert(std::is_same<uint32_t, Res_value::data_type>::value,
+ "Res_value::data_type has changed. The range checks in this "
+ "function are no longer correct.");
+
// Decimal or hex?
- if (s[i] == '0' && s[i+1] == 'x') {
- if (outValue)
- outValue->dataType = outValue->TYPE_INT_HEX;
+ bool isHex;
+ if (len > 1 && s[i] == '0' && s[i+1] == 'x') {
+ isHex = true;
i += 2;
+
+ if (neg) {
+ return false;
+ }
+
+ if (i == len) {
+ // Just u"0x"
+ return false;
+ }
+
bool error = false;
while (i < len && !error) {
val = (val*16) + get_hex(s[i], &error);
i++;
+
+ if (val > std::numeric_limits<uint32_t>::max()) {
+ return false;
+ }
}
if (error) {
return false;
}
} else {
- if (outValue)
- outValue->dataType = outValue->TYPE_INT_DEC;
+ isHex = false;
while (i < len) {
if (s[i] < '0' || s[i] > '9') {
return false;
}
val = (val*10) + s[i]-'0';
i++;
+
+ if ((neg && -val < std::numeric_limits<int32_t>::min()) ||
+ (!neg && val > std::numeric_limits<int32_t>::max())) {
+ return false;
+ }
}
}
@@ -4671,13 +4695,21 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
i++;
}
- if (i == len) {
- if (outValue)
- outValue->data = val;
- return true;
+ if (i != len) {
+ return false;
}
- return false;
+ if (outValue) {
+ outValue->dataType =
+ isHex ? outValue->TYPE_INT_HEX : outValue->TYPE_INT_DEC;
+ outValue->data = static_cast<Res_value::data_type>(val);
+ }
+ return true;
+}
+
+bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
+{
+ return U16StringToInt(s, len, outValue);
}
bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 58b78b5..a353575 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -19,6 +19,7 @@
# targets here.
# ==========================================================
LOCAL_PATH:= $(call my-dir)
+
testFiles := \
AttributeFinder_test.cpp \
ByteBucketArray_test.cpp \
@@ -32,27 +33,33 @@ testFiles := \
TypeWrappers_test.cpp \
ZipUtils_test.cpp
+androidfw_test_cflags := \
+ -Wall \
+ -Werror \
+ -Wunused \
+ -Wunreachable-code \
+ -Wno-missing-field-initializers \
+
+# gtest is broken.
+androidfw_test_cflags += -Wno-unnamed-type-template-args
+
# ==========================================================
# Build the host tests: libandroidfw_tests
# ==========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-# gtest is broken.
-LOCAL_CFLAGS += -Wno-unnamed-type-template-args
-
+LOCAL_CFLAGS := $(androidfw_test_cflags)
LOCAL_SRC_FILES := $(testFiles)
LOCAL_STATIC_LIBRARIES := \
libandroidfw \
libutils \
libcutils \
- liblog
+ liblog \
+ libz \
include $(BUILD_HOST_NATIVE_TEST)
-
# ==========================================================
# Build the device tests: libandroidfw_tests
# ==========================================================
@@ -60,14 +67,11 @@ ifneq ($(SDK_ONLY),true)
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-# gtest is broken.
-LOCAL_CFLAGS += -Wno-unnamed-type-template-args
-
+LOCAL_CFLAGS := $(androidfw_test_cflags)
LOCAL_SRC_FILES := $(testFiles) \
BackupData_test.cpp \
- ObbFile_test.cpp
+ ObbFile_test.cpp \
+
LOCAL_SHARED_LIBRARIES := \
libandroidfw \
libcutils \
diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp
index 6a9314e..dcfe91e 100644
--- a/libs/androidfw/tests/ResTable_test.cpp
+++ b/libs/androidfw/tests/ResTable_test.cpp
@@ -16,6 +16,10 @@
#include <androidfw/ResourceTypes.h>
+#include <codecvt>
+#include <locale>
+#include <string>
+
#include <utils/String8.h>
#include <utils/String16.h>
#include "TestHelpers.h"
@@ -201,4 +205,81 @@ TEST(ResTableTest, emptyTableHasSensibleDefaults) {
ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);
}
+void testU16StringToInt(const char16_t* str, uint32_t expectedValue,
+ bool expectSuccess, bool expectHex) {
+ size_t len = std::char_traits<char16_t>::length(str);
+
+ // Gtest can't print UTF-16 strings, so we have to convert to UTF-8 :(
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ std::string s = convert.to_bytes(std::u16string(str, len));
+
+ Res_value out = {};
+ ASSERT_EQ(expectSuccess, U16StringToInt(str, len, &out))
+ << "Failed with " << s;
+
+ if (!expectSuccess) {
+ ASSERT_EQ(out.TYPE_NULL, out.dataType) << "Failed with " << s;
+ return;
+ }
+
+ if (expectHex) {
+ ASSERT_EQ(out.TYPE_INT_HEX, out.dataType) << "Failed with " << s;
+ } else {
+ ASSERT_EQ(out.TYPE_INT_DEC, out.dataType) << "Failed with " << s;
+ }
+
+ ASSERT_EQ(expectedValue, out.data) << "Failed with " << s;
+}
+
+TEST(ResTableTest, U16StringToInt) {
+ testU16StringToInt(u"", 0U, false, false);
+ testU16StringToInt(u" ", 0U, false, false);
+ testU16StringToInt(u"\t\n", 0U, false, false);
+
+ testU16StringToInt(u"abcd", 0U, false, false);
+ testU16StringToInt(u"10abcd", 0U, false, false);
+ testU16StringToInt(u"42 42", 0U, false, false);
+ testU16StringToInt(u"- 42", 0U, false, false);
+ testU16StringToInt(u"-", 0U, false, false);
+
+ testU16StringToInt(u"0x", 0U, false, true);
+ testU16StringToInt(u"0xnope", 0U, false, true);
+ testU16StringToInt(u"0X42", 0U, false, true);
+ testU16StringToInt(u"0x42 0x42", 0U, false, true);
+ testU16StringToInt(u"-0x0", 0U, false, true);
+ testU16StringToInt(u"-0x42", 0U, false, true);
+ testU16StringToInt(u"- 0x42", 0U, false, true);
+
+ // Note that u" 42" would pass. This preserves the old behavior, but it may
+ // not be desired.
+ testU16StringToInt(u"42 ", 0U, false, false);
+ testU16StringToInt(u"0x42 ", 0U, false, true);
+
+ // Decimal cases.
+ testU16StringToInt(u"0", 0U, true, false);
+ testU16StringToInt(u"-0", 0U, true, false);
+ testU16StringToInt(u"42", 42U, true, false);
+ testU16StringToInt(u" 42", 42U, true, false);
+ testU16StringToInt(u"-42", static_cast<uint32_t>(-42), true, false);
+ testU16StringToInt(u" -42", static_cast<uint32_t>(-42), true, false);
+ testU16StringToInt(u"042", 42U, true, false);
+ testU16StringToInt(u"-042", static_cast<uint32_t>(-42), true, false);
+
+ // Hex cases.
+ testU16StringToInt(u"0x0", 0x0, true, true);
+ testU16StringToInt(u"0x42", 0x42, true, true);
+ testU16StringToInt(u" 0x42", 0x42, true, true);
+
+ // Just before overflow cases:
+ testU16StringToInt(u"2147483647", INT_MAX, true, false);
+ testU16StringToInt(u"-2147483648", static_cast<uint32_t>(INT_MIN), true,
+ false);
+ testU16StringToInt(u"0xffffffff", UINT_MAX, true, true);
+
+ // Overflow cases:
+ testU16StringToInt(u"2147483648", 0U, false, false);
+ testU16StringToInt(u"-2147483649", 0U, false, false);
+ testU16StringToInt(u"0x1ffffffff", 0U, false, true);
+}
+
}
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 4d2e3a0..882826e 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -82,12 +82,12 @@ void AssetAtlas::updateTextureId() {
///////////////////////////////////////////////////////////////////////////////
AssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const {
- ssize_t index = mEntries.indexOfKey(bitmap);
+ ssize_t index = mEntries.indexOfKey(bitmap->pixelRef());
return index >= 0 ? mEntries.valueAt(index) : nullptr;
}
Texture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const {
- ssize_t index = mEntries.indexOfKey(bitmap);
+ ssize_t index = mEntries.indexOfKey(bitmap->pixelRef());
return index >= 0 ? mEntries.valueAt(index)->texture : nullptr;
}
@@ -120,7 +120,7 @@ void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
const float height = float(mTexture->height);
for (int i = 0; i < count; ) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(map[i++]);
+ SkPixelRef* pixelRef = reinterpret_cast<SkPixelRef*>(map[i++]);
// NOTE: We're converting from 64 bit signed values to 32 bit
// signed values. This is guaranteed to be safe because the "x"
// and "y" coordinate values are guaranteed to be representable
@@ -131,21 +131,21 @@ void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
bool rotated = map[i++] > 0;
// Bitmaps should never be null, we're just extra paranoid
- if (!bitmap) continue;
+ if (!pixelRef) continue;
const UvMapper mapper(
- x / width, (x + bitmap->width()) / width,
- y / height, (y + bitmap->height()) / height);
+ x / width, (x + pixelRef->info().width()) / width,
+ y / height, (y + pixelRef->info().height()) / height);
Texture* texture = new DelegateTexture(caches, mTexture);
- texture->blend = !bitmap->isOpaque();
- texture->width = bitmap->width();
- texture->height = bitmap->height();
+ texture->blend = !SkAlphaTypeIsOpaque(pixelRef->info().alphaType());
+ texture->width = pixelRef->info().width();
+ texture->height = pixelRef->info().height();
- Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
+ Entry* entry = new Entry(pixelRef, x, y, rotated, texture, mapper, *this);
texture->uvMapper = &entry->uvMapper;
- mEntries.add(entry->bitmap, entry);
+ mEntries.add(entry->pixelRef, entry);
}
}
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 1772eff..17c5281 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -48,24 +48,8 @@ public:
* Entry representing the position and rotation of a
* bitmap inside the atlas.
*/
- struct Entry {
- /**
- * The bitmap that generated this atlas entry.
- */
- SkBitmap* bitmap;
-
- /**
- * Location of the bitmap inside the atlas, in pixels.
- */
- int x;
- int y;
-
- /**
- * If set, the bitmap is rotated 90 degrees (clockwise)
- * inside the atlas.
- */
- bool rotated;
-
+ class Entry {
+ public:
/*
* A "virtual texture" object that represents the texture
* this entry belongs to. This texture should never be
@@ -80,11 +64,6 @@ public:
const UvMapper uvMapper;
/**
- * Atlas this entry belongs to.
- */
- const AssetAtlas& atlas;
-
- /**
* Unique identifier used to merge bitmaps and 9-patches stored
* in the atlas.
*/
@@ -93,10 +72,37 @@ public:
}
private:
- Entry(SkBitmap* bitmap, int x, int y, bool rotated,
- Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
- bitmap(bitmap), x(x), y(y), rotated(rotated),
- texture(texture), uvMapper(mapper), atlas(atlas) {
+ /**
+ * The pixel ref that generated this atlas entry.
+ */
+ SkPixelRef* pixelRef;
+
+ /**
+ * Location of the bitmap inside the atlas, in pixels.
+ */
+ int x;
+ int y;
+
+ /**
+ * If set, the bitmap is rotated 90 degrees (clockwise)
+ * inside the atlas.
+ */
+ bool rotated;
+
+ /**
+ * Atlas this entry belongs to.
+ */
+ const AssetAtlas& atlas;
+
+ Entry(SkPixelRef* pixelRef, int x, int y, bool rotated,
+ Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas)
+ : texture(texture)
+ , uvMapper(mapper)
+ , pixelRef(pixelRef)
+ , x(x)
+ , y(y)
+ , rotated(rotated)
+ , atlas(atlas) {
}
~Entry() {
@@ -178,7 +184,7 @@ private:
const bool mBlendKey;
const bool mOpaqueKey;
- KeyedVector<const SkBitmap*, Entry*> mEntries;
+ KeyedVector<const SkPixelRef*, Entry*> mEntries;
}; // class AssetAtlas
}; // namespace uirenderer
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 7ad0683..aa24673 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -29,7 +29,7 @@ class ANDROID_API Canvas {
public:
virtual ~Canvas() {};
- static Canvas* create_canvas(SkBitmap* bitmap);
+ static Canvas* create_canvas(const SkBitmap& bitmap);
/**
* Create a new Canvas object which delegates to an SkCanvas.
@@ -52,7 +52,7 @@ public:
*/
virtual SkCanvas* asSkCanvas() = 0;
- virtual void setBitmap(SkBitmap* bitmap, bool copyState) = 0;
+ virtual void setBitmap(const SkBitmap& bitmap) = 0;
virtual bool isOpaque() = 0;
virtual int width() = 0;
@@ -87,7 +87,8 @@ public:
virtual bool quickRejectRect(float left, float top, float right, float bottom) const = 0;
virtual bool quickRejectPath(const SkPath& path) const = 0;
- virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
+ virtual bool clipRect(float left, float top, float right, float bottom,
+ SkRegion::Op op = SkRegion::kIntersect_Op) = 0;
virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 53fd1ad..ff698f5 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -138,7 +138,7 @@ public:
// ----------------------------------------------------------------------------
virtual SkCanvas* asSkCanvas() override;
- virtual void setBitmap(SkBitmap* bitmap, bool copyState) override {
+ virtual void setBitmap(const SkBitmap& bitmap) override {
LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
}
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 8b11757..a323065 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -31,7 +31,7 @@ namespace android {
// Holds an SkCanvas reference plus additional native data.
class SkiaCanvas : public Canvas {
public:
- explicit SkiaCanvas(SkBitmap* bitmap);
+ explicit SkiaCanvas(const SkBitmap& bitmap);
/**
* Create a new SkiaCanvas.
@@ -49,7 +49,7 @@ public:
return mCanvas.get();
}
- virtual void setBitmap(SkBitmap* bitmap, bool copyState) override;
+ virtual void setBitmap(const SkBitmap& bitmap) override;
virtual bool isOpaque() override;
virtual int width() override;
@@ -145,19 +145,7 @@ private:
SkAutoTDelete<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
};
-// Construct an SkCanvas from the bitmap.
-static SkCanvas* createCanvas(SkBitmap* bitmap) {
- if (bitmap) {
- return SkNEW_ARGS(SkCanvas, (*bitmap));
- }
-
- // Create an empty bitmap device to prevent callers from crashing
- // if they attempt to draw into this canvas.
- SkBitmap emptyBitmap;
- return new SkCanvas(emptyBitmap);
-}
-
-Canvas* Canvas::create_canvas(SkBitmap* bitmap) {
+Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
return new SkiaCanvas(bitmap);
}
@@ -165,8 +153,8 @@ Canvas* Canvas::create_canvas(SkCanvas* skiaCanvas) {
return new SkiaCanvas(skiaCanvas);
}
-SkiaCanvas::SkiaCanvas(SkBitmap* bitmap) {
- mCanvas.reset(createCanvas(bitmap));
+SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
+ mCanvas.reset(new SkCanvas(bitmap));
}
// ----------------------------------------------------------------------------
@@ -191,11 +179,11 @@ private:
SkCanvas* m_dstCanvas;
};
-void SkiaCanvas::setBitmap(SkBitmap* bitmap, bool copyState) {
- SkCanvas* newCanvas = createCanvas(bitmap);
+void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
+ SkCanvas* newCanvas = new SkCanvas(bitmap);
SkASSERT(newCanvas);
- if (copyState) {
+ if (!bitmap.isNull()) {
// Copy the canvas matrix & clip state.
newCanvas->setMatrix(mCanvas->getTotalMatrix());
if (NULL != mCanvas->getDevice() && NULL != newCanvas->getDevice()) {
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index ec1bb90..8a6c8c5 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -289,6 +289,7 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S
// but even more conservative bounds if this is too slow.
SkRect bounds;
glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
+ bounds.offset(x, y);
SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index cc87241..d15fa39 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -293,11 +293,11 @@ CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* laye
return (void*) success;
}
-bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
SETUP_TASK(copyLayerInto);
args->context = mContext;
args->layer = layer;
- args->bitmap = bitmap;
+ args->bitmap = &bitmap;
return (bool) postAndWait(task);
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 29c6f08..cc475fa 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -83,7 +83,7 @@ public:
ANDROID_API DeferredLayerUpdater* createTextureLayer();
ANDROID_API void buildLayer(RenderNode* node);
- ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
+ ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);