34 static AAssetManager* gAAssetManager =
nullptr;
36 gAAssetManager = AAssetManager_fromJava(
env, assetManager);
39 if (!gAAssetManager) {
43 AAsset* asset = AAssetManager_open(gAAssetManager, path.c_str(), AASSET_MODE_STREAMING);
47 size_t size =
SkToSizeT(AAsset_getLength(asset));
49 (void)AAsset_read(asset, data->writable_data(), size);
58 {AKEYCODE_SOFT_LEFT, skui::Key::kLeft },
59 {AKEYCODE_SOFT_RIGHT, skui::Key::kRight}
72 env->GetJavaVM(&fJavaVM);
75 fSetTitleMethodID =
env->GetMethodID(cls,
"setTitle",
"(Ljava/lang/String;)V");
76 fSetStateMethodID =
env->GetMethodID(cls,
"setState",
"(Ljava/lang/String;)V");
77 fNativeWindow =
nullptr;
78 pthread_create(&fThread,
nullptr, pthread_main,
this);
81SkiaAndroidApp::~SkiaAndroidApp() {
87 ANativeWindow_release(fNativeWindow);
88 fNativeWindow =
nullptr;
96 jstring titleString = fPThreadEnv->NewStringUTF(title);
97 fPThreadEnv->CallVoidMethod(
fAndroidApp, fSetTitleMethodID, titleString);
98 fPThreadEnv->DeleteLocalRef(titleString);
102 jstring jstr = fPThreadEnv->NewStringUTF(
state);
103 fPThreadEnv->CallVoidMethod(
fAndroidApp, fSetStateMethodID, jstr);
104 fPThreadEnv->DeleteLocalRef(jstr);
117int SkiaAndroidApp::message_callback(
int fd,
int events,
void* data) {
120 skiaAndroidApp->readMessage(&
message);
125 delete skiaAndroidApp;
126 pthread_exit(
nullptr);
129 ((Window_android*)skiaAndroidApp->fWindow)->paintIfNeeded();
134 skiaAndroidApp->fNativeWindow =
message.fNativeWindow;
135 auto window_android = (Window_android*)skiaAndroidApp->fWindow;
136 window_android->initDisplay(skiaAndroidApp->fNativeWindow);
137 ((Window_android*)skiaAndroidApp->fWindow)->paintIfNeeded();
142 int width = ANativeWindow_getWidth(skiaAndroidApp->fNativeWindow);
143 int height = ANativeWindow_getHeight(skiaAndroidApp->fNativeWindow);
144 auto window_android = (Window_android*)skiaAndroidApp->fWindow;
145 if (
message.fNativeWindow != skiaAndroidApp->fNativeWindow) {
146 window_android->onDisplayDestroyed();
147 ANativeWindow_release(skiaAndroidApp->fNativeWindow);
148 skiaAndroidApp->fNativeWindow =
message.fNativeWindow;
149 window_android->initDisplay(skiaAndroidApp->fNativeWindow);
152 window_android->paintIfNeeded();
156 if (skiaAndroidApp->fNativeWindow) {
157 auto window_android = (Window_android*)skiaAndroidApp->fWindow;
158 window_android->onDisplayDestroyed();
159 ANativeWindow_release(skiaAndroidApp->fNativeWindow);
160 skiaAndroidApp->fNativeWindow =
nullptr;
175 skiaAndroidApp->fWindow->onTouch(
message.fTouchOwner, it->second,
message.fTouchX,
183 skiaAndroidApp->fWindow->onUIStateChanged(*
message.stateName, *
message.stateValue);
196void* SkiaAndroidApp::pthread_main(
void* arg) {
202 skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv),
nullptr);
204 ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
205 pipe(skiaAndroidApp->fPipes);
207 message_callback, skiaAndroidApp);
209 static const char* gCmdLine[] = {
217 const_cast<char**
>(gCmdLine),
221 const int ident = ALooper_pollAll(0,
nullptr,
nullptr,
nullptr);
224 SkDebugf(
"Unhandled ALooper_pollAll ident=%d !", ident);
226 skiaAndroidApp->fApp->onIdle();
232 JNIEXPORT jlong JNICALL
235 jobject assetManager) {
238 return (jlong)((size_t)skiaAndroidApp);
242 JNIEnv*
env, jobject application, jlong handle) {
248 JNIEnv*
env, jobject activity, jlong handle, jobject
surface) {
252 skiaAndroidApp->postMessage(
message);
256 JNIEnv*
env, jobject activity, jlong handle, jobject
surface) {
260 skiaAndroidApp->postMessage(
message);
264 JNIEnv*
env, jobject activity, jlong handle) {
276 skiaAndroidApp->postMessage(
message);
280 JNIEnv*
env, jobject activity, jlong handle, jint owner, jint
state, jfloat
x, jfloat
y) {
287 skiaAndroidApp->postMessage(
message);
291 JNIEnv*
env, jobject activity, jlong handle, jstring stateName, jstring stateValue) {
294 const char* nameChars =
env->GetStringUTFChars(stateName,
nullptr);
295 const char* valueChars =
env->GetStringUTFChars(stateValue,
nullptr);
298 skiaAndroidApp->postMessage(
message);
299 env->ReleaseStringUTFChars(stateName, nameChars);
300 env->ReleaseStringUTFChars(stateValue, valueChars);
static const std::unordered_map< int, skui::InputState > ANDROID_TO_WINDOW_STATEMAP({ {AMOTION_EVENT_ACTION_DOWN, skui::InputState::kDown }, {AMOTION_EVENT_ACTION_POINTER_DOWN, skui::InputState::kDown }, {AMOTION_EVENT_ACTION_UP, skui::InputState::kUp }, {AMOTION_EVENT_ACTION_POINTER_UP, skui::InputState::kUp }, {AMOTION_EVENT_ACTION_MOVE, skui::InputState::kMove }, {AMOTION_EVENT_ACTION_CANCEL, skui::InputState::kUp }, })