1 /*
2 * Copyright (C) 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 #include <android/choreographer.h>
18 #include <android/surface_control_input_receiver.h>
19 #include <binder/Binder.h>
20 #include <gui/Choreographer.h>
21 #include <gui/InputTransferToken.h>
22 #include <input/Input.h>
23 #include <input/InputConsumerNoResampling.h>
24
25 #include "android_view_WindowManagerGlobal.h"
26
27 using namespace android;
28
29 extern void InputTransferToken_acquire(InputTransferToken* inputTransferToken);
30
31 struct AInputReceiverCallbacks {
AInputReceiverCallbacksAInputReceiverCallbacks32 AInputReceiverCallbacks(void* context) : context(context) {}
33 void* context;
34 AInputReceiver_onMotionEvent onMotionEvent = nullptr;
35 AInputReceiver_onKeyEvent onKeyEvent = nullptr;
36 };
37
38 class InputReceiver : public InputConsumerCallbacks {
39 public:
InputReceiver(const sp<Looper> & looper,const std::shared_ptr<InputChannel> & inputChannel,const sp<IBinder> & clientToken,const sp<InputTransferToken> & inputTransferToken,AInputReceiverCallbacks * callbacks)40 InputReceiver(const sp<Looper>& looper, const std::shared_ptr<InputChannel>& inputChannel,
41 const sp<IBinder>& clientToken, const sp<InputTransferToken>& inputTransferToken,
42 AInputReceiverCallbacks* callbacks)
43 : mCallbacks(callbacks),
44 mInputConsumer(inputChannel, looper, *this),
45 mClientToken(clientToken),
46 mInputTransferToken(inputTransferToken) {}
47
48 // The InputConsumer does not keep the InputReceiver alive so the receiver is cleared once the
49 // owner releases it.
~InputReceiver()50 ~InputReceiver() {
51 remove();
52 }
53
onKeyEvent(std::unique_ptr<KeyEvent> event,uint32_t seq)54 void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) override {
55 if (mCallbacks->onKeyEvent != nullptr) {
56 const bool handled = mCallbacks->onKeyEvent(mCallbacks->context,
57 static_cast<AInputEvent*>(event.release()));
58 mInputConsumer.finishInputEvent(seq, handled);
59 }
60 }
61
onMotionEvent(std::unique_ptr<MotionEvent> event,uint32_t seq)62 void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) override {
63 if (mCallbacks->onMotionEvent != nullptr) {
64 const bool handled =
65 mCallbacks->onMotionEvent(mCallbacks->context,
66 static_cast<AInputEvent*>(event.release()));
67 mInputConsumer.finishInputEvent(seq, handled);
68 }
69 }
70
onFocusEvent(std::unique_ptr<FocusEvent>,uint32_t seq)71 void onFocusEvent(std::unique_ptr<FocusEvent>, uint32_t seq) override {
72 mInputConsumer.finishInputEvent(seq, false);
73 }
onCaptureEvent(std::unique_ptr<CaptureEvent>,uint32_t seq)74 void onCaptureEvent(std::unique_ptr<CaptureEvent>, uint32_t seq) override {
75 mInputConsumer.finishInputEvent(seq, false);
76 }
onDragEvent(std::unique_ptr<DragEvent>,uint32_t seq)77 void onDragEvent(std::unique_ptr<DragEvent>, uint32_t seq) override {
78 mInputConsumer.finishInputEvent(seq, false);
79 }
onTouchModeEvent(std::unique_ptr<TouchModeEvent>,uint32_t seq)80 void onTouchModeEvent(std::unique_ptr<TouchModeEvent>, uint32_t seq) override {
81 mInputConsumer.finishInputEvent(seq, false);
82 }
83
onBatchedInputEventPending(int32_t)84 virtual void onBatchedInputEventPending(int32_t) override {
85 mInputConsumer.consumeBatchedInputEvents(std::nullopt);
86 }
87
getInputTransferToken()88 const AInputTransferToken* getInputTransferToken() {
89 InputTransferToken_acquire(mInputTransferToken.get());
90 return reinterpret_cast<const AInputTransferToken*>(mInputTransferToken.get());
91 }
92
remove()93 void remove() {
94 removeInputChannel(mClientToken);
95 }
96
97 AInputReceiverCallbacks* mCallbacks;
98
99 protected:
100 InputConsumerNoResampling mInputConsumer;
101
102 private:
103 const sp<IBinder> mClientToken;
104 const sp<InputTransferToken> mInputTransferToken;
105 };
106
107 class BatchedInputReceiver : public InputReceiver {
108 public:
BatchedInputReceiver(Choreographer & choreographer,const std::shared_ptr<InputChannel> & inputChannel,const sp<IBinder> & clientToken,const sp<InputTransferToken> & inputTransferToken,AInputReceiverCallbacks * callbacks)109 BatchedInputReceiver(Choreographer& choreographer,
110 const std::shared_ptr<InputChannel>& inputChannel,
111 const sp<IBinder>& clientToken,
112 const sp<InputTransferToken>& inputTransferToken,
113 AInputReceiverCallbacks* callbacks)
114 : InputReceiver(choreographer.getLooper(), inputChannel, clientToken, inputTransferToken,
115 callbacks),
116 mChoreographer(choreographer) {}
117
vsyncCallback(const AChoreographerFrameCallbackData * callbackData,void * data)118 static void vsyncCallback(const AChoreographerFrameCallbackData* callbackData, void* data) {
119 BatchedInputReceiver* receiver = static_cast<BatchedInputReceiver*>(data);
120 receiver->onVsyncCallback(callbackData);
121 }
122
onVsyncCallback(const AChoreographerFrameCallbackData * callbackData)123 void onVsyncCallback(const AChoreographerFrameCallbackData* callbackData) {
124 int64_t frameTimeNanos = AChoreographerFrameCallbackData_getFrameTimeNanos(callbackData);
125 mInputConsumer.consumeBatchedInputEvents(frameTimeNanos);
126 mBatchedInputScheduled = false;
127 }
128
onBatchedInputEventPending(int32_t)129 void onBatchedInputEventPending(int32_t) override {
130 scheduleBatchedInput();
131 }
132
133 private:
134 Choreographer& mChoreographer;
135 bool mBatchedInputScheduled = false;
136
scheduleBatchedInput()137 void scheduleBatchedInput() {
138 if (!mBatchedInputScheduled) {
139 mBatchedInputScheduled = true;
140 mChoreographer.postFrameCallbackDelayed(nullptr, nullptr, vsyncCallback, this, 0,
141 CallbackType::CALLBACK_INPUT);
142 }
143 }
144 };
145
InputReceiver_to_AInputReceiver(InputReceiver * inputReceiver)146 static inline AInputReceiver* InputReceiver_to_AInputReceiver(InputReceiver* inputReceiver) {
147 return reinterpret_cast<AInputReceiver*>(inputReceiver);
148 }
149
AInputReceiver_to_InputReceiver(AInputReceiver * aInputReceiver)150 static inline InputReceiver* AInputReceiver_to_InputReceiver(AInputReceiver* aInputReceiver) {
151 return reinterpret_cast<InputReceiver*>(aInputReceiver);
152 }
153
AInputReceiver_createBatchedInputReceiver(AChoreographer * aChoreographer,const AInputTransferToken * hostToken,const ASurfaceControl * aSurfaceControl,AInputReceiverCallbacks * callbacks)154 AInputReceiver* AInputReceiver_createBatchedInputReceiver(AChoreographer* aChoreographer,
155 const AInputTransferToken* hostToken,
156 const ASurfaceControl* aSurfaceControl,
157 AInputReceiverCallbacks* callbacks) {
158 // create input channel here through WMS
159 sp<IBinder> clientToken = sp<BBinder>::make();
160 sp<InputTransferToken> clientInputTransferToken = sp<InputTransferToken>::make();
161
162 std::shared_ptr<InputChannel> inputChannel =
163 createInputChannel(clientToken, reinterpret_cast<const InputTransferToken&>(*hostToken),
164 reinterpret_cast<const SurfaceControl&>(*aSurfaceControl),
165 *clientInputTransferToken);
166 return InputReceiver_to_AInputReceiver(
167 new BatchedInputReceiver(reinterpret_cast<Choreographer&>(*aChoreographer),
168 inputChannel, clientToken, clientInputTransferToken,
169 callbacks));
170 }
171
AInputReceiver_createUnbatchedInputReceiver(ALooper * aLooper,const AInputTransferToken * hostToken,const ASurfaceControl * aSurfaceControl,AInputReceiverCallbacks * callbacks)172 AInputReceiver* AInputReceiver_createUnbatchedInputReceiver(ALooper* aLooper,
173 const AInputTransferToken* hostToken,
174 const ASurfaceControl* aSurfaceControl,
175 AInputReceiverCallbacks* callbacks) {
176 // create input channel here through WMS
177 sp<IBinder> clientToken = sp<BBinder>::make();
178 sp<InputTransferToken> clientInputTransferToken = sp<InputTransferToken>::make();
179
180 std::shared_ptr<InputChannel> inputChannel =
181 createInputChannel(clientToken, reinterpret_cast<const InputTransferToken&>(*hostToken),
182 reinterpret_cast<const SurfaceControl&>(*aSurfaceControl),
183 *clientInputTransferToken);
184 return InputReceiver_to_AInputReceiver(new InputReceiver(reinterpret_cast<Looper*>(aLooper),
185 inputChannel, clientToken,
186 clientInputTransferToken, callbacks));
187 }
188
AInputReceiver_getInputTransferToken(AInputReceiver * aInputReceiver)189 const AInputTransferToken* AInputReceiver_getInputTransferToken(AInputReceiver* aInputReceiver) {
190 return AInputReceiver_to_InputReceiver(aInputReceiver)->getInputTransferToken();
191 }
192
AInputReceiver_release(AInputReceiver * aInputReceiver)193 void AInputReceiver_release(AInputReceiver* aInputReceiver) {
194 InputReceiver* inputReceiver = AInputReceiver_to_InputReceiver(aInputReceiver);
195 if (inputReceiver != nullptr) {
196 inputReceiver->remove();
197 }
198 delete inputReceiver;
199 }
200
AInputReceiverCallbacks_setMotionEventCallback(AInputReceiverCallbacks * callbacks,AInputReceiver_onMotionEvent onMotionEvent)201 void AInputReceiverCallbacks_setMotionEventCallback(AInputReceiverCallbacks* callbacks,
202 AInputReceiver_onMotionEvent onMotionEvent) {
203 callbacks->onMotionEvent = onMotionEvent;
204 }
205
AInputReceiverCallbacks_setKeyEventCallback(AInputReceiverCallbacks * callbacks,AInputReceiver_onKeyEvent onKeyEvent)206 void AInputReceiverCallbacks_setKeyEventCallback(AInputReceiverCallbacks* callbacks,
207 AInputReceiver_onKeyEvent onKeyEvent) {
208 callbacks->onKeyEvent = onKeyEvent;
209 }
210
AInputReceiverCallbacks_create(void * context)211 AInputReceiverCallbacks* AInputReceiverCallbacks_create(void* context) {
212 return new AInputReceiverCallbacks(context);
213 }
214
AInputReceiverCallbacks_release(AInputReceiverCallbacks * callbacks)215 void AInputReceiverCallbacks_release(AInputReceiverCallbacks* callbacks) {
216 delete callbacks;
217 }