Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3e9eecf authored by Derek Sollenberger's avatar Derek Sollenberger
Browse files

Don't update the genID for an immutable bitmap

AndroidBitmap_unlockPixels is the only way to release the ref on
pixels acquired using AndroidBitmap_lockPixels.  Apps that lock an
immutable bitmap therefore are forced to call unlock pixels. Prior
to this CL the unlock would update the GenID of the bitmap and also
print a warning that the app was modifying an immutable bitmap. After
this CL the bitmap's GenID will not be updated and no warning will be
printed.

As a result, apps that were using the NDK to allow them to mutate
immutable bitmaps will break without getting a warning message.

Test: hwui_unit_tests
Bug: 150823341
Change-Id: Ie5e5cf86a7a83d53c179c9b3cf9be1a0566cfd93
parent 0e22967d
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -171,7 +171,6 @@ cc_library_headers {

cc_defaults {
    name: "android_graphics_apex",
    host_supported: true,
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-non-virtual-dtor",
@@ -231,7 +230,6 @@ cc_library_headers {

cc_defaults {
    name: "android_graphics_jni",
    host_supported: true,
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-non-virtual-dtor",
@@ -537,7 +535,11 @@ cc_defaults {

cc_test {
    name: "hwui_unit_tests",
    defaults: ["hwui_test_defaults"],
    defaults: [
        "hwui_test_defaults",
        "android_graphics_apex",
        "android_graphics_jni",
    ],

    static_libs: [
        "libgmock",
@@ -549,6 +551,7 @@ cc_test {

    srcs: [
        "tests/unit/main.cpp",
        "tests/unit/ABitmapTests.cpp",
        "tests/unit/CacheManagerTests.cpp",
        "tests/unit/CanvasContextTests.cpp",
        "tests/unit/CommonPoolTests.cpp",
+2 −3
Original line number Diff line number Diff line
@@ -163,10 +163,9 @@ jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat forma

void ABitmap_notifyPixelsChanged(ABitmap* bitmapHandle) {
    Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
    if (bitmap->isImmutable()) {
        ALOGE("Attempting to modify an immutable Bitmap!");
    if (!bitmap->isImmutable()) {
        bitmap->notifyPixelsChanged();
    }
    return bitmap->notifyPixelsChanged();
}

namespace {
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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 <gtest/gtest.h>

#include "android/graphics/bitmap.h"
#include "apex/TypeCast.h"
#include "hwui/Bitmap.h"
#include "tests/common/TestUtils.h"

using namespace android;
using namespace android::uirenderer;

TEST(ABitmap, notifyPixelsChanged) {
    // generate a bitmap and its public API handle
    sk_sp<Bitmap> bitmap(TestUtils::createBitmap(1, 1));
    ABitmap* abmp = android::TypeCast::toABitmap(bitmap.get());

    // verify that notification changes the genID
    uint32_t genID = bitmap->getGenerationID();
    ABitmap_notifyPixelsChanged(abmp);
    ASSERT_TRUE(bitmap->getGenerationID() != genID);

    // mark the bitmap as immutable
    ASSERT_FALSE(bitmap->isImmutable());
    bitmap->setImmutable();
    ASSERT_TRUE(bitmap->isImmutable());

    // attempt to notify that the pixels have changed
    genID = bitmap->getGenerationID();
    ABitmap_notifyPixelsChanged(abmp);
    ASSERT_TRUE(bitmap->getGenerationID() == genID);
}