1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18 // This is for off_t and similar.
19 // They are also used in asset_manager.h without an include.
20 #include <sys/types.h>
21
22 #include <android/asset_manager.h>
23 #include <android/asset_manager_jni.h>
24 #include <android/choreographer.h>
25 #include <android/hardware_buffer_jni.h>
26 #include <android/input.h>
27 #include <android/looper.h>
28 #include <android/native_activity.h>
29 #include <android/native_window_jni.h>
30 #include <android/sensor.h>
31 #include <android/sharedmem_jni.h>
32 #include <android/storage_manager.h>
33 #include <android/surface_texture_jni.h>
34 #include <jni.h>
35
36 #include "berberis/guest_abi/function_wrappers.h"
37 #include "berberis/guest_abi/guest_params.h"
38 #include "berberis/guest_state/guest_addr.h"
39 #include "berberis/guest_state/guest_state.h"
40 #include "berberis/native_activity/native_activity.h"
41 #include "berberis/proxy_loader/proxy_library_builder.h"
42
43 namespace berberis {
44
45 template <>
46 struct GuestAbi::GuestArgumentInfo<ANativeActivity*> : GuestAbi::GuestArgumentInfo<void*> {
47 using GuestType = berberis::Guest_ANativeActivity*;
48 using HostType = ANativeActivity*;
49 };
50
51 } // namespace berberis
52
53 namespace berberis {
54
55 namespace {
56
57 // Note: on host (glibc-based systems) in some cases we have 64-bit off_t while 32-bit Android
58 // always uses 32-bit off_t. We no don't support use of these libraries with GlibC thus we could
59 // just assert that size of long and off_t are the same.
60 //
61 // The following functions are potentially affected: AAsset_getLength, AAsset_getRemainingLength,
62 // AAsset_seek, and AAsset_openFileDescriptor.
63 static_assert(sizeof(long) == sizeof(off_t));
64
65 typedef int (*ALooper_callbackFunc)(int fd, int events, void* data);
66
67 template <typename ResultType, typename... ArgumentType>
WrapLooperCallback(GuestType<ResultType (*)(ArgumentType...)> callback)68 ALooper_callbackFunc WrapLooperCallback(GuestType<ResultType (*)(ArgumentType...)> callback) {
69 if (ToGuestAddr(callback) == 0) {
70 return nullptr;
71 }
72 return WrapGuestFunction(callback, "ALooper_callbackFunc");
73 }
74
DoCustomTrampoline_ALooper_addFd(HostCode,ProcessState * state)75 void DoCustomTrampoline_ALooper_addFd(HostCode /* callee */, ProcessState* state) {
76 auto [looper, fd, ident, events, guest_callback, data] =
77 GuestParamsValues<decltype(ALooper_addFd)>(state);
78 ALooper_callbackFunc host_callback = WrapLooperCallback(guest_callback);
79 auto&& [ret] = GuestReturnReference<decltype(ALooper_addFd)>(state);
80 ret = ALooper_addFd(looper, fd, ident, events, host_callback, data);
81 }
82
DoCustomTrampoline_ASensorManager_createEventQueue(HostCode,ProcessState * state)83 void DoCustomTrampoline_ASensorManager_createEventQueue(HostCode /* callee */,
84 ProcessState* state) {
85 auto [manager, looper, ident, guest_callback, data] =
86 GuestParamsValues<decltype(ASensorManager_createEventQueue)>(state);
87 ALooper_callbackFunc host_callback = WrapLooperCallback(guest_callback);
88 auto&& [ret] = GuestReturnReference<decltype(ASensorManager_createEventQueue)>(state);
89 ret = ASensorManager_createEventQueue(manager, looper, ident, host_callback, data);
90 }
91
DoCustomTrampoline_AInputQueue_attachLooper(HostCode,ProcessState * state)92 void DoCustomTrampoline_AInputQueue_attachLooper(HostCode /* callee */, ProcessState* state) {
93 auto [queue, looper, ident, guest_callback, data] =
94 GuestParamsValues<decltype(AInputQueue_attachLooper)>(state);
95 ALooper_callbackFunc host_callback = WrapLooperCallback(guest_callback);
96 AInputQueue_attachLooper(queue, looper, ident, host_callback, data);
97 }
98
DoCustomTrampoline_ANativeActivity_finish(HostCode,ProcessState * state)99 void DoCustomTrampoline_ANativeActivity_finish(HostCode /* callee */, ProcessState* state) {
100 auto [guest_activity] = GuestParamsValues<decltype(ANativeActivity_finish)>(state);
101 ANativeActivity_finish(guest_activity->host_native_activity);
102 }
103
DoCustomTrampoline_ANativeActivity_setWindowFormat(HostCode,ProcessState * state)104 void DoCustomTrampoline_ANativeActivity_setWindowFormat(HostCode /* callee */,
105 ProcessState* state) {
106 auto [guest_activity, format] =
107 GuestParamsValues<decltype(ANativeActivity_setWindowFormat)>(state);
108 ANativeActivity_setWindowFormat(guest_activity->host_native_activity, format);
109 }
110
DoCustomTrampoline_ANativeActivity_setWindowFlags(HostCode,ProcessState * state)111 void DoCustomTrampoline_ANativeActivity_setWindowFlags(HostCode /* callee */, ProcessState* state) {
112 auto [guest_activity, addFlags, removeFlags] =
113 GuestParamsValues<decltype(ANativeActivity_setWindowFlags)>(state);
114 ANativeActivity_setWindowFlags(guest_activity->host_native_activity, addFlags, removeFlags);
115 }
116
DoCustomTrampoline_ANativeActivity_showSoftInput(HostCode,ProcessState * state)117 void DoCustomTrampoline_ANativeActivity_showSoftInput(HostCode /* callee */, ProcessState* state) {
118 auto [guest_activity, flags] = GuestParamsValues<decltype(ANativeActivity_showSoftInput)>(state);
119 ANativeActivity_showSoftInput(guest_activity->host_native_activity, flags);
120 }
121
DoCustomTrampoline_ANativeActivity_hideSoftInput(HostCode,ProcessState * state)122 void DoCustomTrampoline_ANativeActivity_hideSoftInput(HostCode /* callee */, ProcessState* state) {
123 auto [guest_activity, flags] = GuestParamsValues<decltype(ANativeActivity_hideSoftInput)>(state);
124 ANativeActivity_hideSoftInput(guest_activity->host_native_activity, flags);
125 }
126
127 // Note, AChoreographer is opaque (from frameworks/native/include/android/choreographer.h):
128 //
129 // struct AChoreographer;
130 // typedef struct AChoreographer AChoreographer;
131 //
132 // typedef void (*AChoreographer_frameCallback)(long frameTimeNanos, void* data);
133 //
134 // void AChoreographer_postFrameCallback(AChoreographer* choreographer,
135 // AChoreographer_frameCallback callback, void* data);
136 //
137 // void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer,
138 // AChoreographer_frameCallback callback, void* data, long
139 // delayMillis);
140
DoCustomTrampoline_AChoreographer_postFrameCallback(HostCode,ProcessState * state)141 void DoCustomTrampoline_AChoreographer_postFrameCallback(HostCode /* callee */,
142 ProcessState* state) {
143 #pragma clang diagnostic push
144 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
145 auto [choreographer, guest_callback, data] =
146 GuestParamsValues<decltype(AChoreographer_postFrameCallback)>(state);
147 AChoreographer_frameCallback host_callback =
148 WrapGuestFunction(guest_callback, "AChoreographer_frameCallback");
149 AChoreographer_postFrameCallback(choreographer, host_callback, data);
150 #pragma clang diagnostic pop
151 }
152
DoCustomTrampoline_AChoreographer_postFrameCallbackDelayed(HostCode,ProcessState * state)153 void DoCustomTrampoline_AChoreographer_postFrameCallbackDelayed(HostCode /* callee */,
154 ProcessState* state) {
155 #pragma clang diagnostic push
156 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
157 auto [choreographer, guest_callback, data, delay] =
158 GuestParamsValues<decltype(AChoreographer_postFrameCallbackDelayed)>(state);
159 AChoreographer_frameCallback host_callback =
160 WrapGuestFunction(guest_callback, "AChoreographer_frameCallback");
161 AChoreographer_postFrameCallbackDelayed(choreographer, host_callback, data, delay);
162 #pragma clang diagnostic pop
163 }
164
DoCustomTrampoline_AStorageManager_mountObb(HostCode,ProcessState * state)165 void DoCustomTrampoline_AStorageManager_mountObb(HostCode /* callee */, ProcessState* state) {
166 auto [mgr, filename, key, guest_callback, data] =
167 GuestParamsValues<decltype(AStorageManager_mountObb)>(state);
168 AStorageManager_obbCallbackFunc host_callback =
169 WrapGuestFunction(guest_callback, "AStorageManager_obbCallbackFunc");
170 AStorageManager_mountObb(mgr, filename, key, host_callback, data);
171 }
172
DoCustomTrampoline_AStorageManager_unmountObb(HostCode,ProcessState * state)173 void DoCustomTrampoline_AStorageManager_unmountObb(HostCode /* callee */, ProcessState* state) {
174 auto [mgr, filename, force, guest_callback, data] =
175 GuestParamsValues<decltype(AStorageManager_unmountObb)>(state);
176 AStorageManager_obbCallbackFunc host_callback =
177 WrapGuestFunction(guest_callback, "AStorageManager_obbCallbackFunc");
178 AStorageManager_unmountObb(mgr, filename, force, host_callback, data);
179 }
180
181 #if defined(NATIVE_BRIDGE_GUEST_ARCH_ARM) && defined(__i386__)
182
183 #include "trampolines_arm_to_x86-inl.h" // generated file NOLINT [build/include]
184
185 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_ARM64) && defined(__x86_64__)
186
187 #include "trampolines_arm64_to_x86_64-inl.h" // generated file NOLINT [build/include]
188
189 #elif defined(NATIVE_BRIDGE_GUEST_ARCH_RISCV64) && defined(__x86_64__)
190
191 #include "trampolines_riscv64_to_x86_64-inl.h" // generated file NOLINT [build/include]
192
193 #else
194
195 #error "Unknown guest/host arch combination"
196
197 #endif
198
199 DEFINE_INIT_PROXY_LIBRARY("libandroid.so")
200
201 } // namespace
202
203 } // namespace berberis
204