• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "GfxStreamAgents.h"
15 
16 #include <stdint.h>  // for uint32_t
17 #include <stdio.h>   // for fprintf
18 
19 #include <map>      // for map, __ma...
20 #include <utility>  // for pair
21 
22 #include "host-common/HostmemIdMapping.h"             // for android_e...
23 #include "host-common/MultiDisplay.h"                 // for MultiDisp...
24 #include "host-common/multi_display_agent.h"  // for QAndroidM...
25 #include "host-common/vm_operations.h"        // for SnapshotC...
26 #include "host-common/window_agent.h"         // for WindowMes...
27 #include "host-common/misc.h"
28 
29 #ifdef _DEBUG
30 #define DEBUG_LOG(fd, fmt, ...) fprintf(fd, fmt, __VA_ARGS__);
31 #else
32 #define DEBUG_LOG(fd, fmt, ...)
33 #endif
34 
35 std::map<uint32_t, android::MultiDisplayInfo> mMultiDisplay;
36 
37 using namespace android;
38 
39 static const QAndroidMultiDisplayAgent sMultiDisplayAgent = {
40         .setMultiDisplay = [](uint32_t id,
41                               int32_t x,
42                               int32_t y,
43                               uint32_t w,
44                               uint32_t h,
45                               uint32_t dpi,
46                               uint32_t flag,
__anon119e3d800102() 47                               bool add) -> int {
48             DEBUG_LOG(stderr,
49                     "setMultiDisplay (mock): %d, x: %d, y: %d, w: %d, h: %d, "
50                     "dpi: %d, flag: %d\n",
51                     id, x, y, w, h, dpi, flag);
52             return 0;
53         },
54         .getMultiDisplay = [](uint32_t id,
55                               int32_t* x,
56                               int32_t* y,
57                               uint32_t* w,
58                               uint32_t* h,
59                               uint32_t* dpi,
60                               uint32_t* flag,
__anon119e3d800202() 61                               bool* enabled) -> bool {
62             DEBUG_LOG(stderr, "getMultiDisplay (mock) id %u\n", id);
63             if (mMultiDisplay.find(id) == mMultiDisplay.end()) {
64                 if (enabled) {
65                     *enabled = false;
66                 }
67                 return false;
68             }
69             if (x) {
70                 *x = mMultiDisplay[id].pos_x;
71             }
72             if (y) {
73                 *y = mMultiDisplay[id].pos_y;
74             }
75             if (w) {
76                 *w = mMultiDisplay[id].width;
77             }
78             if (h) {
79                 *h = mMultiDisplay[id].height;
80             }
81             if (dpi) {
82                 *dpi = mMultiDisplay[id].dpi;
83             }
84             if (flag) {
85                 *flag = mMultiDisplay[id].flag;
86             }
87             if (enabled) {
88                 *enabled = mMultiDisplay[id].enabled;
89             }
90             return true;
91         },
92         .getNextMultiDisplay = [](int32_t start_id,
93                                   uint32_t* id,
94                                   int32_t* x,
95                                   int32_t* y,
96                                   uint32_t* w,
97                                   uint32_t* h,
98                                   uint32_t* dpi,
99                                   uint32_t* flag,
__anon119e3d800302() 100                                   uint32_t* cb) -> bool {
101             DEBUG_LOG(stderr, "getNextMultiDisplay (mock) start_id %u\n",
102                     start_id);
103             uint32_t key;
104             std::map<uint32_t, android::MultiDisplayInfo>::iterator i;
105             if (start_id < 0) {
106                 key = 0;
107             } else {
108                 key = start_id + 1;
109             }
110             i = mMultiDisplay.lower_bound(key);
111             if (i == mMultiDisplay.end()) {
112                 return false;
113             } else {
114                 if (id) {
115                     *id = i->first;
116                 }
117                 if (x) {
118                     *x = i->second.pos_x;
119                 }
120                 if (y) {
121                     *y = i->second.pos_y;
122                 }
123                 if (w) {
124                     *w = i->second.width;
125                 }
126                 if (h) {
127                     *h = i->second.height;
128                 }
129                 if (dpi) {
130                     *dpi = i->second.dpi;
131                 }
132                 if (flag) {
133                     *flag = i->second.flag;
134                 }
135                 if (cb) {
136                     *cb = i->second.cb;
137                 }
138                 return true;
139             }
140         },
__anon119e3d800402() 141         .isMultiDisplayEnabled = [](void) -> bool {
142             return mMultiDisplay.size() > 1;
143         },
__anon119e3d800502() 144         .getCombinedDisplaySize = [](uint32_t* width, uint32_t* height) {},
145         .multiDisplayParamValidate = [](uint32_t id,
146                                         uint32_t w,
147                                         uint32_t h,
148                                         uint32_t dpi,
__anon119e3d800602() 149                                         uint32_t flag) -> bool { return true; },
150         .translateCoordination =
__anon119e3d800702() 151                 [](uint32_t* x, uint32_t* y, uint32_t* displayId) -> bool {
152             return true;
153         },
__anon119e3d800802() 154         .setGpuMode = [](bool isGuestMode, uint32_t w, uint32_t h) {},
__anon119e3d800902() 155         .createDisplay = [](uint32_t* displayId) -> int {
156             if (displayId == nullptr) {
157                 fprintf(stderr, "null displayId pointer\n");
158                 return -1;
159             }
160             if (mMultiDisplay.size() >= MultiDisplay::s_maxNumMultiDisplay) {
161                 fprintf(stderr, "cannot create more displays, exceeding limits %d\n",
162                         MultiDisplay::s_maxNumMultiDisplay);
163                 return -1;
164             }
165             if (mMultiDisplay.find(*displayId) != mMultiDisplay.end()) {
166                 return 0;
167             }
168             // displays created by internal rcCommands
169             if (*displayId == MultiDisplay::s_invalidIdMultiDisplay) {
170                 for (int i = MultiDisplay::s_displayIdInternalBegin; i < MultiDisplay::s_maxNumMultiDisplay; i++) {
171                     if (mMultiDisplay.find(i) == mMultiDisplay.end()) {
172                         *displayId = i;
173                         break;
174                     }
175                 }
176             }
177             if (*displayId == MultiDisplay::s_invalidIdMultiDisplay) {
178                 fprintf(stderr, "cannot create more internaldisplays, exceeding limits %d\n",
179                         MultiDisplay::s_maxNumMultiDisplay - MultiDisplay::s_displayIdInternalBegin);
180                 return -1;
181             }
182 
183             mMultiDisplay.emplace(*displayId, android::MultiDisplayInfo());
184             return 0;
185         },
__anon119e3d800a02() 186         .destroyDisplay = [](uint32_t displayId) -> int {
187             mMultiDisplay.erase(displayId);
188             return 0;
189         },
190         .setDisplayPose = [](uint32_t displayId,
191                              int32_t x,
192                              int32_t y,
193                              uint32_t w,
194                              uint32_t h,
__anon119e3d800b02() 195                              uint32_t dpi) -> int {
196             if (mMultiDisplay.find(displayId) == mMultiDisplay.end()) {
197                 fprintf(stderr, "cannot find display %d\n", displayId);
198                 return -1;
199             }
200             mMultiDisplay[displayId].pos_x = x;
201             mMultiDisplay[displayId].pos_y = y;
202             mMultiDisplay[displayId].width = w;
203             mMultiDisplay[displayId].height = h;
204             mMultiDisplay[displayId].dpi = dpi;
205             return 0;
206         },
207         .getDisplayPose = [](uint32_t displayId,
208                              int32_t* x,
209                              int32_t* y,
210                              uint32_t* w,
__anon119e3d800c02() 211                              uint32_t* h) -> int {
212             if (mMultiDisplay.find(displayId) == mMultiDisplay.end()) {
213                 fprintf(stderr, "cannot find display %d\n", displayId);
214                 return -1;
215             }
216             if (x)
217                 *x = mMultiDisplay[displayId].pos_x;
218             if (y)
219                 *y = mMultiDisplay[displayId].pos_y;
220             if (w)
221                 *w = mMultiDisplay[displayId].width;
222             if (h)
223                 *h = mMultiDisplay[displayId].height;
224             return 0;
225         },
226         .getDisplayColorBuffer = [](uint32_t displayId,
__anon119e3d800d02() 227                                     uint32_t* colorBuffer) -> int {
228             if (mMultiDisplay.find(displayId) == mMultiDisplay.end()) {
229                 fprintf(stderr, "cannot find display %d\n", displayId);
230                 return -1;
231             }
232             *colorBuffer = mMultiDisplay[displayId].cb;
233             return 0;
234         },
235         .getColorBufferDisplay = [](uint32_t colorBuffer,
__anon119e3d800e02() 236                                     uint32_t* displayId) -> int {
237             for (const auto& iter : mMultiDisplay) {
238                 if (iter.second.cb == colorBuffer) {
239                     *displayId = iter.first;
240                     return 0;
241                 }
242             }
243             return -1;
244         },
245         .setDisplayColorBuffer = [](uint32_t displayId,
__anon119e3d800f02() 246                                     uint32_t colorBuffer) -> int {
247             if (mMultiDisplay.find(displayId) == mMultiDisplay.end()) {
248                 fprintf(stderr, "cannot find display %d\n", displayId);
249                 return -1;
250             }
251             mMultiDisplay[displayId].cb = colorBuffer;
252             return 0;
253         }};
254 
255 static bool sIsFolded = false;
256 
257 static const QAndroidEmulatorWindowAgent sQAndroidEmulatorWindowAgent = {
258         .getEmulatorWindow =
__anon119e3d801002() 259                 [](void) {
260                     DEBUG_LOG(stderr,
261                             "window-agent-GfxStream-impl: "
262                             ".getEmulatorWindow\n");
263                     return (EmulatorWindow*)nullptr;
264                 },
265         .rotate90Clockwise =
__anon119e3d801102() 266                 [](void) {
267                     DEBUG_LOG(stderr,
268                             "window-agent-GfxStream-impl: "
269                             ".rotate90Clockwise\n");
270                     return true;
271                 },
272         .rotate =
__anon119e3d801202() 273                 [](int rotation) {
274                     DEBUG_LOG(stderr,
275                             "window-agent-GfxStream-impl: "
276                             ".rotate90Clockwise\n");
277                     return true;
278                 },
279         .getRotation =
__anon119e3d801302() 280                 [](void) {
281                     DEBUG_LOG(stderr,
282                             "window-agent-GfxStream-impl: .getRotation\n");
283                     return (int)SKIN_ROTATION_0;
284                 },
285         .showMessage =
__anon119e3d801402() 286                 [](const char* message, WindowMessageType type, int timeoutMs) {
287                     DEBUG_LOG(stderr,
288                             "window-agent-GfxStream-impl: .showMessage %s\n",
289                             message);
290                 },
291         .showMessageWithDismissCallback =
292                 [](const char* message,
293                    WindowMessageType type,
294                    const char* dismissText,
295                    void* context,
296                    void (*func)(void*),
__anon119e3d801502() 297                    int timeoutMs) {
298                     DEBUG_LOG(stderr,
299                             "window-agent-GfxStream-impl: "
300                             ".showMessageWithDismissCallback %s\n",
301                             message);
302                 },
303         .fold =
__anon119e3d801602() 304                 [](bool is_fold) -> bool {
305                     DEBUG_LOG(stderr, "window-agent-GfxStream-impl: .fold %d\n",
306                             is_fold);
307                     sIsFolded = is_fold;
308                     return true;
309                 },
__anon119e3d801702() 310         .isFolded = [](void) -> bool { return sIsFolded; },
__anon119e3d801802() 311         .getFoldedArea = [](int* x, int* y, int* w, int* h) -> bool {
312             DEBUG_LOG(stderr, "window-agent-GfxStream-impl: .getFoldedArea\n");
313             return true;
314         },
__anon119e3d801902() 315         .updateFoldablePostureIndicator = [](bool) {
316             DEBUG_LOG(stderr, "window-agent-GfxStream-impl: updateFoldablePostureIndicator\n");
317         },
318         .setUIDisplayRegion =
__anon119e3d801a02() 319                 [](int x_offset, int y_offset, int w, int h) {
320                     DEBUG_LOG(stderr,
321                             "window-agent-GfxStream-impl: .setUIDisplayRegion "
322                             "%d %d %dx%d\n",
323                             x_offset, y_offset, w, h);
324                 },
325         .getMultiDisplay = 0,
__anon119e3d801b02() 326         .setNoSkin = [](void) {},
__anon119e3d801c02() 327         .restoreSkin = [](void) {},
328         .updateUIMultiDisplayPage =
__anon119e3d801d02() 329                 [](uint32_t id) {
330                     DEBUG_LOG(stderr, "updateMultiDisplayPage\n");
331                 },
332         .getMonitorRect =
__anon119e3d801e02() 333                 [](uint32_t* w, uint32_t* h) -> bool {
334                     if (w)
335                         *w = 2500;
336                     if (h)
337                         *h = 1600;
338                     return true;
339                 },
340 };
341 
342 static const QAndroidVmOperations sQAndroidVmOperations = {
__anon119e3d801f02() 343         .vmStop = []() -> bool {
344             DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm stop\n");
345             return true;
346         },
__anon119e3d802002() 347         .vmStart = []() -> bool {
348             DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm start\n");
349             return true;
350         },
351         .vmReset =
__anon119e3d802102() 352                 []() { DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm reset\n"); },
353         .vmShutdown =
__anon119e3d802202() 354                 []() { DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm reset\n"); },
__anon119e3d802302() 355         .vmPause = []() -> bool {
356             DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm pause\n");
357             return true;
358         },
__anon119e3d802402() 359         .vmResume = []() -> bool {
360             DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm resume\n");
361             return true;
362         },
__anon119e3d802502() 363         .vmIsRunning = []() -> bool {
364             DEBUG_LOG(stderr, "goldfish-opengl vm ops: vm is running\n");
365             return true;
366         },
367         .snapshotList =
__anon119e3d802602() 368                 [](void*, LineConsumerCallback, LineConsumerCallback) -> bool {
369             DEBUG_LOG(stderr, "goldfish-opengl vm ops: snapshot list\n");
370             return true;
371         },
372         .snapshotSave = [](const char* name,
373                            void* opaque,
__anon119e3d802702() 374                            LineConsumerCallback) -> bool {
375             DEBUG_LOG(stderr, "gfxstream vm ops: snapshot save\n");
376             return true;
377         },
378         .snapshotLoad = [](const char* name,
379                            void* opaque,
__anon119e3d802802() 380                            LineConsumerCallback) -> bool {
381             DEBUG_LOG(stderr, "gfxstream vm ops: snapshot load\n");
382             return true;
383         },
384         .snapshotDelete = [](const char* name,
385                              void* opaque,
__anon119e3d802902() 386                              LineConsumerCallback errConsumer) -> bool {
387             DEBUG_LOG(stderr, "goldfish-opengl vm ops: snapshot delete\n");
388             return true;
389         },
390         .snapshotRemap = [](bool shared,
391                             void* opaque,
__anon119e3d802a02() 392                             LineConsumerCallback errConsumer) -> bool {
393             DEBUG_LOG(stderr, "goldfish-opengl vm ops: snapshot remap\n");
394             return true;
395         },
396         .snapshotExport = [](const char* snapshot,
397                              const char* dest,
398                              void* opaque,
__anon119e3d802b02() 399                              LineConsumerCallback errConsumer) -> bool {
400             DEBUG_LOG(stderr, "goldfish-opengl vm ops: snapshot export image\n");
401             return true;
402         },
403         .setSnapshotCallbacks =
__anon119e3d802c02() 404                 [](void* opaque, const SnapshotCallbacks* callbacks) {
405                     DEBUG_LOG(stderr,
406                             "goldfish-opengl vm ops: set snapshot callbacks\n");
407                 },
408         .mapUserBackedRam =
__anon119e3d802d02() 409                 [](uint64_t gpa, void* hva, uint64_t size) {
410                     DEBUG_LOG(stderr, "%s: map user backed ram\n", __func__);
411                 },
412         .unmapUserBackedRam =
__anon119e3d802e02() 413                 [](uint64_t gpa, uint64_t size) {
414                     DEBUG_LOG(stderr, "%s: unmap user backed ram\n", __func__);
415                 },
416         .getVmConfiguration =
__anon119e3d802f02() 417                 [](VmConfiguration* out) {
418                     DEBUG_LOG(stderr,
419                             "goldfish-opengl vm ops: get vm configuration\n");
420                 },
421         .setFailureReason =
__anon119e3d803002() 422                 [](const char* name, int failureReason) {
423                     DEBUG_LOG(stderr,
424                             "goldfish-opengl vm ops: set failure reason\n");
425                 },
426         .setExiting =
__anon119e3d803102() 427                 []() {
428                     DEBUG_LOG(stderr, "goldfish-opengl vm ops: set exiting\n");
429                 },
430         .allowRealAudio =
__anon119e3d803202() 431                 [](bool allow) {
432                     DEBUG_LOG(stderr,
433                             "goldfish-opengl vm ops: allow real audio\n");
434                 },
435         .physicalMemoryGetAddr =
__anon119e3d803302() 436                 [](uint64_t gpa) {
437                     DEBUG_LOG(stderr, "%s: physmemGetAddr\n", __func__);
438                     return (void*)nullptr;
439                 },
440         .isRealAudioAllowed =
__anon119e3d803402() 441                 [](void) {
442                     DEBUG_LOG(stderr,
443                             "goldfish-opengl vm ops: is real audiop allowed\n");
444                     return true;
445                 },
446         .setSkipSnapshotSave =
__anon119e3d803502() 447                 [](bool used) {
448                     DEBUG_LOG(stderr,
449                             "goldfish-opengl vm ops: set skip snapshot save\n");
450                 },
451         .isSnapshotSaveSkipped =
__anon119e3d803602() 452                 []() {
453                     DEBUG_LOG(stderr,
454                             "goldfish-opengl vm ops: is snapshot save "
455                             "skipped\n");
456                     return false;
457                 },
458         .hostmemRegister = android_emulation_hostmem_register,
459         .hostmemUnregister = android_emulation_hostmem_unregister,
460         .hostmemGetInfo = android_emulation_hostmem_get_info,
461 };
462 
463 namespace android {
464 namespace emulation {
465 
466 const QAndroidVmOperations* const
android_get_QAndroidVmOperations() const467 GfxStreamAndroidConsoleFactory::android_get_QAndroidVmOperations() const {
468     return &sQAndroidVmOperations;
469 }
470 
471 const QAndroidMultiDisplayAgent* const
android_get_QAndroidMultiDisplayAgent() const472 GfxStreamAndroidConsoleFactory::android_get_QAndroidMultiDisplayAgent() const {
473     return &sMultiDisplayAgent;
474 }
475 
476 const QAndroidEmulatorWindowAgent* const
android_get_QAndroidEmulatorWindowAgent() const477 GfxStreamAndroidConsoleFactory::android_get_QAndroidEmulatorWindowAgent()
478         const {
479     return &sQAndroidEmulatorWindowAgent;
480 }
481 }  // namespace emulation
482 }  // namespace android
483