Change Android activity title from JNI call
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1978843002 Review-Url: https://codereview.chromium.org/1978843002
This commit is contained in:
parent
9fb420393e
commit
36632f46a6
@ -60,12 +60,19 @@ public class ViewerActivity
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mApplication = (ViewerApplication) getApplication();
|
||||
mApplication.setViewerActivity(this);
|
||||
mView = (SurfaceView) findViewById(R.id.surfaceView);
|
||||
mView.getHolder().addCallback(this);
|
||||
|
||||
mView.setOnTouchListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
mApplication.setViewerActivity(null);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (mApplication.getNativeHandle() != 0) {
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user