aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java7
-rw-r--r--platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerApplication.java17
-rw-r--r--tools/viewer/sk_app/android/Window_android.cpp3
-rw-r--r--tools/viewer/sk_app/android/surface_glue_android.cpp32
-rw-r--r--tools/viewer/sk_app/android/surface_glue_android.h24
5 files changed, 65 insertions, 18 deletions
diff --git a/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java b/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java
index e3260c25f7..d6fe710aeb 100644
--- a/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java
+++ b/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java
@@ -60,6 +60,7 @@ public class ViewerActivity
setContentView(R.layout.activity_main);
mApplication = (ViewerApplication) getApplication();
+ mApplication.setViewerActivity(this);
mView = (SurfaceView) findViewById(R.id.surfaceView);
mView.getHolder().addCallback(this);
@@ -67,6 +68,12 @@ public class ViewerActivity
}
@Override
+ protected void onDestroy() {
+ mApplication.setViewerActivity(null);
+ super.onDestroy();
+ }
+
+ @Override
public void surfaceCreated(SurfaceHolder holder) {
if (mApplication.getNativeHandle() != 0) {
onSurfaceCreated(mApplication.getNativeHandle(), holder.getSurface());
diff --git a/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerApplication.java b/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerApplication.java
index 9389f72208..4b890bd5e1 100644
--- a/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerApplication.java
+++ b/platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerApplication.java
@@ -11,6 +11,7 @@ import android.app.Application;
public class ViewerApplication extends Application {
private long mNativeHandle = 0;
+ private ViewerActivity mViewerActivity;
static {
System.loadLibrary("skia_android");
@@ -38,4 +39,20 @@ public class ViewerApplication extends Application {
public long getNativeHandle() {
return mNativeHandle;
}
+
+ public void setViewerActivity(ViewerActivity viewerActivity) {
+ this.mViewerActivity = viewerActivity;
+ }
+
+ public void setTitle(String title) {
+ final String finalTitle = title;
+ if (mViewerActivity != null) {
+ mViewerActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mViewerActivity.setTitle(finalTitle);
+ }
+ });
+ }
+ }
}
diff --git a/tools/viewer/sk_app/android/Window_android.cpp b/tools/viewer/sk_app/android/Window_android.cpp
index 0156ea123e..f16e56753f 100644
--- a/tools/viewer/sk_app/android/Window_android.cpp
+++ b/tools/viewer/sk_app/android/Window_android.cpp
@@ -38,8 +38,7 @@ const DisplayParams& Window_android::getDisplayParams() {
}
void Window_android::setTitle(const char* title) {
- //todo
- SkDebugf("Title: %s", title);
+ fSkiaAndroidApp->setTitle(title);
}
bool Window_android::attach(BackEndType attachType, const DisplayParams& params) {
diff --git a/tools/viewer/sk_app/android/surface_glue_android.cpp b/tools/viewer/sk_app/android/surface_glue_android.cpp
index acee839a30..3d8617f0aa 100644
--- a/tools/viewer/sk_app/android/surface_glue_android.cpp
+++ b/tools/viewer/sk_app/android/surface_glue_android.cpp
@@ -31,14 +31,17 @@ static const std::unordered_map<int, Window::Key> ANDROID_TO_WINDOW_KEYMAP({
{AKEYCODE_SOFT_RIGHT, Window::Key::kRight}
});
-void* pthread_main(void* arg);
-
-SkiaAndroidApp::SkiaAndroidApp() {
+SkiaAndroidApp::SkiaAndroidApp(JNIEnv* env, jobject androidApp) {
+ env->GetJavaVM(&fJavaVM);
+ fAndroidApp = env->NewGlobalRef(androidApp);
+ jclass cls = env->GetObjectClass(fAndroidApp);
+ fSetTitleMethodID = env->GetMethodID(cls, "setTitle", "(Ljava/lang/String;)V");
fNativeWindow = nullptr;
pthread_create(&fThread, nullptr, pthread_main, this);
}
SkiaAndroidApp::~SkiaAndroidApp() {
+ fPThreadEnv->DeleteGlobalRef(fAndroidApp);
if (fWindow) {
fWindow->detach();
}
@@ -51,23 +54,29 @@ SkiaAndroidApp::~SkiaAndroidApp() {
}
}
+void SkiaAndroidApp::setTitle(const char* title) const {
+ jstring titleString = fPThreadEnv->NewStringUTF(title);
+ fPThreadEnv->CallVoidMethod(fAndroidApp, fSetTitleMethodID, titleString);
+ fPThreadEnv->DeleteLocalRef(titleString);
+}
+
void SkiaAndroidApp::paintIfNeeded() {
if (fNativeWindow && fWindow) {
fWindow->onPaint();
}
}
-void SkiaAndroidApp::postMessage(const Message& message) {
+void SkiaAndroidApp::postMessage(const Message& message) const {
auto writeSize = write(fPipes[1], &message, sizeof(message));
SkASSERT(writeSize == sizeof(message));
}
-void SkiaAndroidApp::readMessage(Message* message) {
+void SkiaAndroidApp::readMessage(Message* message) const {
auto readSize = read(fPipes[0], message, sizeof(Message));
SkASSERT(readSize == sizeof(Message));
}
-static int message_callback(int fd, int events, void* data) {
+int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
auto skiaAndroidApp = (SkiaAndroidApp*)data;
Message message;
skiaAndroidApp->readMessage(&message);
@@ -127,11 +136,14 @@ static int message_callback(int fd, int events, void* data) {
return 1; // continue receiving callbacks
}
-void* pthread_main(void* arg) {
+void* SkiaAndroidApp::pthread_main(void* arg) {
SkDebugf("pthread_main begins");
auto skiaAndroidApp = (SkiaAndroidApp*)arg;
+ // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv
+ skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr);
+
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
pipe(skiaAndroidApp->fPipes);
ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
@@ -152,13 +164,13 @@ void* pthread_main(void* arg) {
extern "C" // extern "C" is needed for JNI (although the method itself is in C++)
JNIEXPORT jlong JNICALL
- Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv* env, jobject activity) {
- SkiaAndroidApp* skiaAndroidApp = new SkiaAndroidApp;
+ Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv* env, jobject application) {
+ SkiaAndroidApp* skiaAndroidApp = new SkiaAndroidApp(env, application);
return (jlong)((size_t)skiaAndroidApp);
}
extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerApplication_destroyNativeApp(
- JNIEnv* env, jobject activity, jlong handle) {
+ JNIEnv* env, jobject application, jlong handle) {
auto skiaAndroidApp = (SkiaAndroidApp*)handle;
skiaAndroidApp->postMessage(Message(kDestroyApp));
}
diff --git a/tools/viewer/sk_app/android/surface_glue_android.h b/tools/viewer/sk_app/android/surface_glue_android.h
index 296112258e..1ce06674b9 100644
--- a/tools/viewer/sk_app/android/surface_glue_android.h
+++ b/tools/viewer/sk_app/android/surface_glue_android.h
@@ -37,19 +37,31 @@ struct Message {
};
struct SkiaAndroidApp {
- int fPipes[2]; // 0 is the read message pipe, 1 is the write message pipe
Application* fApp;
Window* fWindow;
- ANativeWindow* fNativeWindow;
+ jobject fAndroidApp;
- SkiaAndroidApp();
- ~SkiaAndroidApp();
- void postMessage(const Message& message);
- void readMessage(Message* message);
+ SkiaAndroidApp(JNIEnv* env, jobject androidApp);
+
+ void postMessage(const Message& message) const;
+ void readMessage(Message* message) const;
void paintIfNeeded();
+ // This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive
+ void setTitle(const char* title) const;
private:
pthread_t fThread;
+ ANativeWindow* fNativeWindow;
+ int fPipes[2]; // 0 is the read message pipe, 1 is the write message pipe
+ JavaVM* fJavaVM;
+ JNIEnv* fPThreadEnv;
+ jmethodID fSetTitleMethodID;
+
+ // This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive
+ ~SkiaAndroidApp();
+
+ static int message_callback(int fd, int events, void* data);
+ static void* pthread_main(void*);
};
} // namespace sk_app