Create C API for accessing android.graphics.Bitmap in native code.

Restrict access to SkBitmap for libandroid_runtime.so to be only within
the boundaries of the graphics module.

Test: CtsUiRenderingTestCases
Bug: 137655431
Change-Id: I4d0ea227e91d22068966513c4e3a55021b9e924f
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 16f2917..6bb896fd 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -20,11 +20,11 @@
     ],
 
     shared_libs: [
+        "libandroid_runtime",
         "libbinder",
         "libcutils",
         "liblog",
         "libutils",
-        "libhwui",
         "libgui",
         "libui",
         "libinput",
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index abf0837..e4348f2 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -24,12 +24,6 @@
 
 #include <log/log.h>
 
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-#include <SkBlendMode.h>
-
 namespace android {
 
 // --- WeakLooperCallback ---
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index fd386e9..804644c 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -23,11 +23,9 @@
 #include <utils/String8.h>
 #include <gui/Surface.h>
 
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-
+#include <android/graphics/bitmap.h>
+#include <android/graphics/canvas.h>
+#include <android/graphics/paint.h>
 #include <android/native_window.h>
 
 namespace android {
@@ -132,8 +130,8 @@
         SpriteUpdate& update = updates.editItemAt(i);
 
         if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) {
-            update.state.surfaceWidth = update.state.icon.bitmap.width();
-            update.state.surfaceHeight = update.state.icon.bitmap.height();
+            update.state.surfaceWidth = update.state.icon.bitmap.getInfo().width;
+            update.state.surfaceHeight = update.state.icon.bitmap.getInfo().height;
             update.state.surfaceDrawn = false;
             update.state.surfaceVisible = false;
             update.state.surfaceControl = obtainSurface(
@@ -154,8 +152,8 @@
         }
 
         if (update.state.wantSurfaceVisible()) {
-            int32_t desiredWidth = update.state.icon.bitmap.width();
-            int32_t desiredHeight = update.state.icon.bitmap.height();
+            int32_t desiredWidth = update.state.icon.bitmap.getInfo().width;
+            int32_t desiredHeight = update.state.icon.bitmap.getInfo().height;
             if (update.state.surfaceWidth < desiredWidth
                     || update.state.surfaceHeight < desiredHeight) {
                 needApplyTransaction = true;
@@ -201,26 +199,22 @@
             if (status) {
                 ALOGE("Error %d locking sprite surface before drawing.", status);
             } else {
-                SkBitmap surfaceBitmap;
-                ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
-                surfaceBitmap.installPixels(SkImageInfo::MakeN32Premul(outBuffer.width, outBuffer.height),
-                                            outBuffer.bits, bpr);
+                graphics::Paint paint;
+                paint.setBlendMode(ABLEND_MODE_SRC);
 
-                SkCanvas surfaceCanvas(surfaceBitmap);
+                graphics::Canvas canvas(outBuffer, (int32_t) surface->getBuffersDataSpace());
+                canvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
 
-                SkPaint paint;
-                paint.setBlendMode(SkBlendMode::kSrc);
-                surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
+                const int iconWidth = update.state.icon.bitmap.getInfo().width;
+                const int iconHeight = update.state.icon.bitmap.getInfo().height;
 
-                if (outBuffer.width > update.state.icon.bitmap.width()) {
-                    paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRect(SkRect::MakeLTRB(update.state.icon.bitmap.width(), 0,
-                            outBuffer.width, update.state.icon.bitmap.height()), paint);
+                if (outBuffer.width > iconWidth) {
+                    paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent
+                    canvas.drawRect({iconWidth, 0, outBuffer.width, iconHeight}, paint);
                 }
-                if (outBuffer.height > update.state.icon.bitmap.height()) {
-                    paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRect(SkRect::MakeLTRB(0, update.state.icon.bitmap.height(),
-                            outBuffer.width, outBuffer.height), paint);
+                if (outBuffer.height > iconHeight) {
+                    paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent
+                    canvas.drawRect({0, iconHeight, outBuffer.width, outBuffer.height}, paint);
                 }
 
                 status = surface->unlockAndPost();
@@ -398,12 +392,7 @@
 
     uint32_t dirty;
     if (icon.isValid()) {
-        SkBitmap* bitmapCopy = &mLocked.state.icon.bitmap;
-        if (bitmapCopy->tryAllocPixels(icon.bitmap.info().makeColorType(kN32_SkColorType))) {
-            icon.bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
-                    bitmapCopy->rowBytes(), 0, 0);
-        }
-
+        mLocked.state.icon.bitmap = icon.bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888);
         if (!mLocked.state.icon.isValid()
                 || mLocked.state.icon.hotSpotX != icon.hotSpotX
                 || mLocked.state.icon.hotSpotY != icon.hotSpotY) {
diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h
index 79a904f..2513544 100644
--- a/libs/input/SpriteController.h
+++ b/libs/input/SpriteController.h
@@ -20,10 +20,9 @@
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
 
+#include <android/graphics/bitmap.h>
 #include <gui/SurfaceComposerClient.h>
 
-#include <SkBitmap.h>
-
 namespace android {
 
 /*
@@ -56,21 +55,16 @@
  */
 struct SpriteIcon {
     inline SpriteIcon() : style(0), hotSpotX(0), hotSpotY(0) { }
-    inline SpriteIcon(const SkBitmap& bitmap, int32_t style, float hotSpotX, float hotSpotY) :
+    inline SpriteIcon(const graphics::Bitmap& bitmap, int32_t style, float hotSpotX, float hotSpotY) :
             bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
 
-    SkBitmap bitmap;
+    graphics::Bitmap bitmap;
     int32_t style;
     float hotSpotX;
     float hotSpotY;
 
     inline SpriteIcon copy() const {
-        SkBitmap bitmapCopy;
-        if (bitmapCopy.tryAllocPixels(bitmap.info().makeColorType(kN32_SkColorType))) {
-            bitmap.readPixels(bitmapCopy.info(), bitmapCopy.getPixels(), bitmapCopy.rowBytes(),
-                    0, 0);
-        }
-        return SpriteIcon(bitmapCopy, style, hotSpotX, hotSpotY);
+        return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY);
     }
 
     inline void reset() {
@@ -81,7 +75,7 @@
     }
 
     inline bool isValid() const {
-        return !bitmap.isNull() && !bitmap.empty();
+        return bitmap.isValid() && !bitmap.isEmpty();
     }
 };
 
@@ -183,7 +177,7 @@
      * This structure is designed so that it can be copied during updates so that
      * surfaces can be resized and redrawn without blocking the client by holding a lock
      * on the sprites for a long time.
-     * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
+     * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */
     struct SpriteState {
         inline SpriteState() :
                 dirty(0), visible(false),
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index e83b2a7..b1e3d6f 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -18,9 +18,9 @@
         "PointerController_test.cpp",
     ],
     shared_libs: [
+        "libandroid_runtime",
         "libinputservice",
         "libgui",
-        "libhwui",
         "libutils",
     ],
     static_libs: [