1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 */
15
16 #include "wayland_drm_auth_client.h"
17 #include <errno.h>
18 #include <stdlib.h>
19 #include "xf86drm.h"
20 #include "wayland-client.h"
21 #include "drm-auth-client-protocol.h"
22 #include "display_common.h"
23
24 typedef struct {
25 struct wl_display *display;
26 struct wl_registry *registry;
27 struct wl_drm_auth *drmAuth;
28 enum wl_drm_auth_status authStatus;
29 } WaylandDisplay;
30
31 const char *AUTH_INTERFACE_NAME = "wl_drm_auth";
32
AuthenticationStatus(void * data,struct wl_drm_auth * wlDrmAuth,uint32_t status)33 static void AuthenticationStatus(void *data, struct wl_drm_auth *wlDrmAuth, uint32_t status)
34 {
35 (void)wlDrmAuth;
36 DISPLAY_DEBUGLOG("AuthenticationStatus the status %{public}d", status);
37 WaylandDisplay *display = data;
38 display->authStatus = status;
39 }
40
41 static const struct wl_drm_auth_listener g_drmAuthListener = { AuthenticationStatus };
42
RegistryHandleGlobal(void * data,struct wl_registry * registry,uint32_t id,const char * interface,uint32_t version)43 static void RegistryHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
44 uint32_t version)
45 {
46 WaylandDisplay *display = data;
47 DISPLAY_DEBUGLOG("interface global : %{public}s", interface);
48 if (strcmp(interface, wl_drm_auth_interface.name) == 0) {
49 display->drmAuth = wl_registry_bind(registry, id, &wl_drm_auth_interface, 1);
50 wl_drm_auth_add_listener(display->drmAuth, &g_drmAuthListener, display);
51 }
52 }
53
RegistryHandleGlobalRemove(void * data,struct wl_registry * registry,uint32_t name)54 static void RegistryHandleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name)
55 {
56 DISPLAY_DEBUGLOG("RegistryHandleGlobalRemove %{publuc}d name ", name);
57 }
58
59 static const struct wl_registry_listener g_registrListener = { RegistryHandleGlobal, RegistryHandleGlobalRemove };
60
DeInitWaylandClient(WaylandDisplay * display)61 void DeInitWaylandClient(WaylandDisplay *display)
62 {
63 DISPLAY_DEBUGLOG("DeInitWaylandClient");
64 DISPLAY_CHK_RETURN_NOT_VALUE((display == NULL), DISPLAY_DEBUGLOG("display is NULL"));
65 if (display->registry != NULL) {
66 wl_registry_destroy(display->registry);
67 }
68
69 if (display->display != NULL) {
70 wl_display_flush(display->display);
71 wl_display_disconnect(display->display);
72 }
73 free(display);
74 }
75
InitWaylandClient(void)76 WaylandDisplay *InitWaylandClient(void)
77 {
78 WaylandDisplay *dsp;
79 int ret;
80 dsp = calloc(1, sizeof(WaylandDisplay));
81 DISPLAY_CHK_RETURN((dsp == NULL), NULL, DISPLAY_LOGE("can not alloc memory errno : %{public}d", errno));
82 dsp->display = wl_display_connect(NULL);
83 DISPLAY_CHK_RETURN((dsp->display == NULL), NULL, DISPLAY_LOGE("display connect failed, errno: %{public}d", errno);
84 DeInitWaylandClient(dsp));
85 dsp->registry = wl_display_get_registry(dsp->display);
86 DISPLAY_CHK_RETURN((dsp->registry == NULL), NULL, DISPLAY_LOGE("can not get registry");
87 DeInitWaylandClient(dsp));
88 ret = wl_registry_add_listener(dsp->registry, &g_registrListener, dsp);
89 DISPLAY_CHK_RETURN((ret < 0), NULL, DISPLAY_LOGE("add listener failed"));
90 wl_display_roundtrip(dsp->display); // for get registry
91 wl_display_roundtrip(dsp->display); // for the listener will bind the service
92 return dsp;
93 }
94
WaylandDrmAuth(int drmFd)95 int32_t WaylandDrmAuth(int drmFd)
96 {
97 WaylandDisplay *dsp;
98 drm_magic_t magic;
99 int ret;
100 dsp = InitWaylandClient();
101 DISPLAY_CHK_RETURN((dsp == NULL), AUTH_FAILED, DISPLAY_LOGE("init wayland client failed"));
102 ret = drmGetMagic(drmFd, &magic);
103 DISPLAY_CHK_RETURN((ret != 0), AUTH_FAILED, DISPLAY_LOGE("can not get magic"));
104 DISPLAY_CHK_RETURN((dsp->drmAuth == NULL), AUTH_FAILED, DISPLAY_LOGE("drm auth service no find"));
105 wl_drm_auth_authenticate(dsp->drmAuth, magic);
106 wl_display_roundtrip(dsp->display); // wait for authenticate status return
107 DISPLAY_DEBUGLOG("the status of authenticate is %{public}d", dsp->authStatus);
108 if (dsp->authStatus == WL_DRM_AUTH_STATUS_SUCCESS) {
109 ret = AUTH_SCUCCESS;
110 }
111 DeInitWaylandClient(dsp);
112 return ret;
113 }
114