[androidkit] Register native methods explicitly

Use RegisterNatives() to bind native methods, instead of relying on
dynamic linker naming conventions.

Change-Id: I602f2efe73e3b9c3c7dfaf7af2307dcfb4cd935e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/396016
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index b6848a9..bfec322 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2456,6 +2456,7 @@
       is_shared_library = true
 
       sources = [
+        "modules/androidkit/src/AndroidKit.cpp",
         "modules/androidkit/src/Canvas.cpp",
         "modules/androidkit/src/Surface.cpp",
       ]
diff --git a/modules/androidkit/src/AndroidKit.cpp b/modules/androidkit/src/AndroidKit.cpp
new file mode 100644
index 0000000..d99ab55
--- /dev/null
+++ b/modules/androidkit/src/AndroidKit.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <android/log.h>
+#include <jni.h>
+
+#define REGISTER_NATIVES(class_name)                     \
+extern int register_androidkit_##class_name(JNIEnv*);    \
+if (auto rc = register_androidkit_##class_name(env)) {   \
+    __android_log_print(ANDROID_LOG_ERROR, "AndroidKit", \
+        "Failed to load natives: " #class_name);         \
+    return rc;                                           \
+}
+
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return JNI_ERR;
+    }
+
+    REGISTER_NATIVES(Canvas)
+    REGISTER_NATIVES(Surface)
+
+    return JNI_VERSION_1_6;
+}
diff --git a/modules/androidkit/src/Canvas.cpp b/modules/androidkit/src/Canvas.cpp
index a1174f4..8433e6f 100644
--- a/modules/androidkit/src/Canvas.cpp
+++ b/modules/androidkit/src/Canvas.cpp
@@ -21,14 +21,22 @@
     return paint;
 }
 
-}  // namespace
-
-extern "C" JNIEXPORT void
-JNICALL
-Java_org_skia_androidkit_Canvas_nDrawRect(JNIEnv* env, jobject, jlong native_instance,
-                                          jfloat left, jfloat top, jfloat right, jfloat bottom,
-                                          jobject paint) {
+void Canvas_DrawRect(JNIEnv* env, jobject, jlong native_instance,
+                     jfloat left, jfloat top, jfloat right, jfloat bottom, jobject paint) {
     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
         canvas->drawRect(SkRect::MakeLTRB(left, top, right, bottom), skpaint(env, paint));
     }
 }
+
+}  // namespace
+
+int register_androidkit_Canvas(JNIEnv* env) {
+    static const JNINativeMethod methods[] = {
+        {"nDrawRect", "(JFFFFLandroid/graphics/Paint;)V", reinterpret_cast<void*>(Canvas_DrawRect)},
+    };
+
+    const auto clazz = env->FindClass("org/skia/androidkit/Canvas");
+    return clazz
+        ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
+        : JNI_ERR;
+}
diff --git a/modules/androidkit/src/Surface.cpp b/modules/androidkit/src/Surface.cpp
index 7aa3b0e..98e4883 100644
--- a/modules/androidkit/src/Surface.cpp
+++ b/modules/androidkit/src/Surface.cpp
@@ -11,6 +11,7 @@
 
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkSurface.h"
+#include "include/core/SkTypes.h"
 
 namespace {
 
@@ -85,31 +86,36 @@
     jobject fBitmap;
 };
 
-}  // namespace
-
-/*
- * Takes in a native instance of Bitmap and returns a pointer to the raster surface.
- */
-extern "C" JNIEXPORT jlong
-JNICALL
-Java_org_skia_androidkit_Surface_nCreateBitmap(JNIEnv* env, jobject, jobject bitmap) {
+static jlong Surface_CreateBitmap(JNIEnv* env, jobject, jobject bitmap) {
     return reinterpret_cast<jlong>(new BitmapSurface(env, bitmap));
 }
 
-extern "C" JNIEXPORT void
-JNICALL
-Java_org_skia_androidkit_Surface_nRelease(JNIEnv* env, jobject, jlong native_surface) {
+static void Surface_Release(JNIEnv* env, jobject, jlong native_surface) {
     if (auto* surface = reinterpret_cast<Surface*>(native_surface)) {
         surface->release(env);
         delete surface;
     }
 }
 
-extern "C" JNIEXPORT jlong
-JNICALL
-Java_org_skia_androidkit_Surface_nGetNativeCanvas(JNIEnv* env, jobject, jlong native_surface) {
+static jlong Surface_GetNativeCanvas(JNIEnv* env, jobject, jlong native_surface) {
     const auto* surface = reinterpret_cast<Surface*>(native_surface);
     return surface
         ? reinterpret_cast<jlong>(surface->getCanvas())
         : 0;
 }
+
+}  // namespace
+
+int register_androidkit_Surface(JNIEnv* env) {
+    static const JNINativeMethod methods[] = {
+        {"nCreateBitmap"   , "(Landroid/graphics/Bitmap;)J",
+            reinterpret_cast<void*>(Surface_CreateBitmap)},
+        {"nRelease"        , "(J)V", reinterpret_cast<void*>(Surface_Release)},
+        {"nGetNativeCanvas", "(J)J", reinterpret_cast<void*>(Surface_GetNativeCanvas)},
+    };
+
+    const auto clazz = env->FindClass("org/skia/androidkit/Surface");
+    return clazz
+        ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
+        : JNI_ERR;
+}