1 /*
2 * Copyright 2024 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 #define LOG_TAG "NativeMonkey"
18
19 #include <aidl/com/android/commands/monkey/BnMonkey.h>
20 #include <android-base/logging.h>
21 #include <android/binder_ibinder_jni.h>
22 #include <input/VirtualInputDevice.h>
23
24 namespace {
25
26 constexpr int32_t GOOGLE_VENDOR_ID = 0x18d1;
27 constexpr int32_t PRODUCT_ID = 0x0001;
28
openUinputTouchscreen(int width,int height)29 android::base::unique_fd openUinputTouchscreen(int width, int height) {
30 return openUinput("Monkey touch", GOOGLE_VENDOR_ID, PRODUCT_ID,
31 /*phys=*/"monkeydevice", android::DeviceType::TOUCHSCREEN,
32 height, width);
33 }
34 } // namespace
35
36 class MonkeyService : public aidl::com::android::commands::monkey::BnMonkey {
37 public:
MonkeyService(int width,int height)38 MonkeyService(int width, int height)
39 : mTouchScreen(openUinputTouchscreen(width, height)) {}
40
41 private:
writeTouchEvent(int32_t pointerId,int32_t toolType,int32_t action,float x,float y,float pressure,float majorAxisSize,int64_t eventTime,bool * _aidl_return)42 ::ndk::ScopedAStatus writeTouchEvent(int32_t pointerId, int32_t toolType,
43 int32_t action, float x, float y,
44 float pressure, float majorAxisSize,
45 int64_t eventTime,
46 bool *_aidl_return) override {
47 *_aidl_return = mTouchScreen.writeTouchEvent(
48 pointerId, toolType, action, x, y, pressure, majorAxisSize,
49 std::chrono::nanoseconds(eventTime));
50 return ndk::ScopedAStatus::ok();
51 }
52
53 android::VirtualTouchscreen mTouchScreen;
54 };
55
createNativeService(JNIEnv * env,jclass,jint width,jint height)56 static jobject createNativeService(JNIEnv *env, jclass, jint width,
57 jint height) {
58 std::shared_ptr<MonkeyService> service =
59 ndk::SharedRefBase::make<MonkeyService>(width, height);
60 // The call `AIBinder_toJavaBinder` increments the refcount, so this will
61 // prevent "service" from getting destructed. The ownership will now be
62 // transferred to Java.
63 return AIBinder_toJavaBinder(env, service->asBinder().get());
64 }
65
66 extern "C" JNIEXPORT jobject JNICALL
Java_com_android_commands_monkey_Monkey_createNativeService(JNIEnv * env,jclass clazz,jint width,jint height)67 Java_com_android_commands_monkey_Monkey_createNativeService(JNIEnv *env,
68 jclass clazz,
69 jint width,
70 jint height) {
71 return createNativeService(env, clazz, width, height);
72 }
73