• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <android_native_app_glue.h>
19 #include <cpu-features.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <cerrno>
23 #include <unistd.h>
24 #include <dlfcn.h>
25 #include <deque>
26 #include <memory>
27 #include <string>
28 #include <vector>
29 
30 #include <GLES/gl.h>
31 #include <EGL/egl.h>
32 
33 #include <uv.h>
34 #include <node.h>
35 
36 #include "skoala-interop.h"
37 #include "node-interop.h"
38 #include "jni-bridge.h"
39 
40 struct SavedState {
41     int index;
42 };
43 
44 struct InputTextEventState {
45     int type;
46     std::string characters;
47     int cursorPosition;
InputTextEventStateInputTextEventState48     InputTextEventState(int type, int cursorPosition, std::string characters) {
49         this->type = type;
50         this->cursorPosition = cursorPosition;
51         this->characters = characters;
52     }
53 };
54 
55 struct InputKeyEventState {
56     int key;
57     int modifiers;
58     int action;
InputKeyEventStateInputKeyEventState59     InputKeyEventState(int key, int modifiers, int action) {
60         this->key = key;
61         this->modifiers = modifiers;
62         this->action = action;
63     }
64 };
65 
66 struct PermissionGrantedEventState {
67     int requestCode;
68     std::vector<std::string> permissions;
69     std::vector<int> grantResults;
PermissionGrantedEventStatePermissionGrantedEventState70     PermissionGrantedEventState(
71         int requestCode,
72         std::vector<std::string>& permissions,
73         std::vector<int>& grantResults) {
74         this->requestCode = requestCode;
75         this->permissions = permissions;
76         this->grantResults = grantResults;
77     }
78 };
79 
80 class Engine {
81     enum Kind {
82         INIT,
83         DEINIT,
84         RESIZE,
85         REDRAW,
86         FOCUS,
87         UNFOCUS,
88         PAUSE,
89         RESUME,
90         TAP,
91         MOVE,
92         KEY
93     };
94     struct Event {
95         Kind kind;
96         int count;
97         int args1[10];
98         int args2[10];
99         int arg3;
100         int target;
EventEvent101         Event(Kind kind, int arg1, int arg2, int arg3) : kind(kind), count(1), arg3(arg3), target(0) {
102             args1[0] = arg1;
103             args2[0] = arg2;
104         }
EventEvent105         Event(Kind kind, int arg1, int arg2) : kind(kind), count(1), arg3(0), target(0) {
106             args1[0] = arg1;
107             args2[0] = arg2;
108         }
EventEvent109         Event(Kind kind, int count) : kind(kind), count(count), arg3(0), target(0) {
110             args1[0] = 0;
111             args2[0] = 0;
112         }
EventEvent113         Event(Kind kind) : Event(kind, 1) {}
114     };
115     std::deque<std::unique_ptr<Event>> _pendingEvents;
116 
117     typedef void (*engine_callback_t)(Engine*, void* ctx);
118     android_app *app;
119 
120     // Node runtime state.
121     std::unique_ptr<NodeRuntime> nodeRuntime;
122     std::unique_ptr<NodeScopedState> nodeScopedState;
123 
124     // Graphics state.
125     EGLDisplay display;
126     EGLSurface surface;
127     EGLContext context;
128     float density;
129 
130     int canDraw;
131 
132     AndroidCpuFamily androidCpuFamily;
133 
134     // Saved state.
135     SavedState savedState;
136 
137     int initDisplay();
138     void deinitDisplay();
139     void resizeDisplay();
140 
141     std::shared_ptr<JNIBridge> jniBridge;
checkJniBridge()142     bool checkJniBridge() {
143         if (!jniBridge) {
144             jniBridge = std::make_shared<JNIBridge>(this->app->activity->vm);
145             if (!jniBridge->init()) {
146                 jniBridge.reset();
147                 return false;
148             }
149         }
150         return true;
151     }
152 
153     // We may need  to scale to display coordinates on some platforms.
maybeScale(int * xpos,int * ypos)154     void maybeScale(int* xpos, int* ypos) {
155         float density = getContentScale();
156         *xpos = (int)(*xpos / density);
157         *ypos = (int)(*ypos / density);
158     }
159 
maybeScaleVector(Event * pointerEvent)160     void maybeScaleVector(Event* pointerEvent) {
161         float density = getContentScale();
162         for (int i = 0; i < pointerEvent->count; i++) {
163             pointerEvent->args1[i] = (int)(pointerEvent->args1[i] / density);
164             pointerEvent->args2[i] = (int)(pointerEvent->args2[i] / density);
165         }
166     }
167 
getPointersCount(const AInputEvent * event)168     int getPointersCount(const AInputEvent* event) {
169         return AMotionEvent_getPointerCount(event);
170     }
171 
getCurrentAction(const AInputEvent * event)172     int getCurrentAction(const AInputEvent* event) {
173         return AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
174     }
175 
getCurrentPointerIndex(const AInputEvent * event)176     int getCurrentPointerIndex(const AInputEvent* event) {
177         int pointerMask = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK;
178         return pointerMask >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
179     }
180 
181     jclass vibrationEffectClass;
182 
183     jobject vibratorInstance;
184 
185     jmethodID vibrateWithDurationMethod;
186     jmethodID vibrateWithEffectMethod;
187     jmethodID createPredefinedEffectMethod;
188 
189     static RedrawerPeer* peer_factory(void* ctx, v8::Local<v8::Object> redrawer);
190 
191     std::mutex locker;
192     std::deque<std::pair<engine_callback_t, void*>> cb_queue;
193     void processQueue();
194 
195     int physicalWidth;
196     int physicalHeight;
197 
198  public:
199     Engine(android_app *app);
200     RedrawerPeer* peer;
201 
202     int prepareNode(std::vector<std::string> &errors, const std::string& startScript);
203 
204     bool initNode();
205     void runNode();
206     void deinitNode();
207 
208     void drawFrame();
209 
deinit()210     void deinit() {
211         deinitNode();
212         deinitDisplay();
213     }
214 
215     int handleInput(AInputEvent* event);
216     void handleCommand(int command);
217 
218     bool makeCurrent(bool attach);
219     void swapBuffers();
220     bool checkEvents();
221 
222     float getContentScale();
223     KNativePointer getFrame(KNativePointer peerPtr, int width, int height);
224     int32_t getFrameWidth();
225     int32_t getFrameHeight();
226     int32_t getPhysicalWidth();
227     int32_t getPhysicalHeight();
228     void requestHaptic(int32_t p1, int32_t p2);
229     int32_t getOrientation();
230     void softKeyboard(bool show);
231     void commitInput();
232     SkString* getClipboard();
233     void setClipboard(const SkString&);
234     int getUnicodeChar(AInputEvent *event);
235     void globalPointer(int32_t &x, int32_t &y);
236 
237     jstring androidPermissionName(const char* perm_name);
238     bool androidHasPermission(const char* perm_name);
239     bool androidExistPermission(const char* perm_name);
240     void askPermissions(std::vector<std::string> &perms);
241 
242     void callOnUIThread(engine_callback_t cb, void* state);
243 };
244