14#include <unordered_map>
16#include <android/asset_manager.h>
17#include <android/asset_manager_jni.h>
18#include <android/input.h>
19#include <android/keycodes.h>
20#include <android/looper.h>
21#include <android/native_window_jni.h>
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);
49 (void)AAsset_read(asset,
data->writable_data(),
size);
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),
222 while (ident == ALOOPER_POLL_CALLBACK) {
223 ident = ALooper_pollOnce(0,
nullptr,
nullptr,
nullptr);
227 SkDebugf(
"Unhandled ALooper_pollOnce ident=%d !", ident);
229 skiaAndroidApp->fApp->onIdle();
235 JNIEXPORT jlong JNICALL
238 jobject assetManager) {
241 return (jlong)((size_t)skiaAndroidApp);
245 JNIEnv*
env, jobject application, jlong handle) {
251 JNIEnv*
env, jobject activity, jlong handle, jobject
surface) {
255 skiaAndroidApp->postMessage(
message);
259 JNIEnv*
env, jobject activity, jlong handle, jobject
surface) {
263 skiaAndroidApp->postMessage(
message);
267 JNIEnv*
env, jobject activity, jlong handle) {
279 skiaAndroidApp->postMessage(
message);
283 JNIEnv*
env, jobject activity, jlong handle, jint owner, jint
state, jfloat
x, jfloat
y) {
290 skiaAndroidApp->postMessage(
message);
294 JNIEnv*
env, jobject activity, jlong handle, jstring stateName, jstring stateValue) {
297 const char* nameChars =
env->GetStringUTFChars(stateName,
nullptr);
298 const char* valueChars =
env->GetStringUTFChars(stateValue,
nullptr);
301 skiaAndroidApp->postMessage(
message);
302 env->ReleaseStringUTFChars(stateName, nameChars);
303 env->ReleaseStringUTFChars(stateValue, valueChars);
sk_sp< SkData >(* gResourceFactory)(const char *)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool read(SkStream *stream, void *buffer, size_t amount)
static SkString resource(SkPDFResourceType type, int index)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr size_t SkToSizeT(S x)
static sk_sp< SkData > MakeUninitialized(size_t length)
static Application * Create(int argc, char **argv, void *platformData)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceChanged(JNIEnv *env, jobject activity, jlong handle, jobject surface)
static const int LOOPER_ID_MESSAGEPIPE
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onKeyPressed(JNIEnv *env, jobject activity, jlong handle, jint keycode)
static void config_resource_mgr(JNIEnv *env, jobject assetManager)
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 }, })
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerApplication_destroyNativeApp(JNIEnv *env, jobject application, jlong handle)
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onUIStateChanged(JNIEnv *env, jobject activity, jlong handle, jstring stateName, jstring stateValue)
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceCreated(JNIEnv *env, jobject activity, jlong handle, jobject surface)
JNIEXPORT jlong JNICALL Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv *env, jobject application, jobject assetManager)
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onTouched(JNIEnv *env, jobject activity, jlong handle, jint owner, jint state, jfloat x, jfloat y)
JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceDestroyed(JNIEnv *env, jobject activity, jlong handle)
static const std::unordered_map< int, skui::Key > ANDROID_TO_WINDOW_KEYMAP({ {AKEYCODE_SOFT_LEFT, skui::Key::kLeft }, {AKEYCODE_SOFT_RIGHT, skui::Key::kRight} })
void write(SkWStream *wStream, const T &text)
void setUIState(const char *state) const
SkiaAndroidApp(JNIEnv *env, jobject androidApp)
void setTitle(const char *title) const
void readMessage(Message *message) const
void postMessage(const Message &message) const
std::shared_ptr< const fml::Mapping > data