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 }