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