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 <stdint.h>
17 #include <stdlib.h>
18
19 #include <ohos_errno.h>
20 #include <pthread.h>
21 #include <registry.h>
22 #include <samgr_lite.h>
23 #include <securec.h>
24 #include <unistd.h>
25
26 #include "hilog_wrapper.h"
27 #include "power_mgr.h"
28 #include "screen_saver_interface.h"
29
30 #define MAX_DATA_LEN 1024
31
32 typedef struct {
33 INHERIT_IUNKNOWNENTRY(ScreenSaverProxyInterface);
34 } ScreenSaverProxyEntry;
35
36 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
37 static ScreenSaverProxyInterface *g_intf = NULL;
38
39 static int32_t SetScreenSaverStateProxy(IUnknown *iUnknown, BOOL enable);
40
CreatClient(const char * service,const char * feature,uint32_t size)41 static void *CreatClient(const char *service, const char *feature, uint32_t size)
42 {
43 (void)service;
44 (void)feature;
45 uint32_t len = size + sizeof(ScreenSaverProxyEntry);
46 uint8_t *client = (uint8_t *)malloc(len);
47 if (client == NULL) {
48 POWER_HILOGE("Failed to allocate memory for screen saver proxy entry");
49 return NULL;
50 }
51 (void)memset_s(client, len, 0, len);
52 ScreenSaverProxyEntry *entry = (ScreenSaverProxyEntry *)&client[size];
53 entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
54 entry->ref = 1;
55 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
56 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
57 entry->iUnknown.Release = IUNKNOWN_Release;
58 entry->iUnknown.Invoke = NULL;
59 entry->iUnknown.SetScreenSaverStateFunc = SetScreenSaverStateProxy;
60 return client;
61 }
62
DestroyClient(const char * service,const char * feature,void * iproxy)63 static void DestroyClient(const char *service, const char *feature, void *iproxy)
64 {
65 free(iproxy);
66 }
67
GetScreenSaverProxyInterface(void)68 static ScreenSaverProxyInterface *GetScreenSaverProxyInterface(void)
69 {
70 if (g_intf != NULL) {
71 return g_intf;
72 }
73 pthread_mutex_lock(&g_mutex);
74 if (g_intf != NULL) {
75 pthread_mutex_unlock(&g_mutex);
76 return g_intf;
77 }
78
79 SAMGR_RegisterFactory(POWER_MANAGE_SERVICE, POWER_SCREEN_SAVER_FEATURE, CreatClient, DestroyClient);
80
81 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(POWER_MANAGE_SERVICE, POWER_SCREEN_SAVER_FEATURE);
82 if (iUnknown == NULL) {
83 POWER_HILOGE("Failed to get screen saver iUnknown");
84 pthread_mutex_unlock(&g_mutex);
85 return NULL;
86 }
87
88 int ret = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&g_intf);
89 if ((ret != EC_SUCCESS) || (g_intf == NULL)) {
90 POWER_HILOGE("Failed to query screen saver interface");
91 pthread_mutex_unlock(&g_mutex);
92 return NULL;
93 }
94 pthread_mutex_unlock(&g_mutex);
95 POWER_HILOGI("Succeed to get screen saver proxy interface");
96 return g_intf;
97 }
98
Callback(IOwner owner,int32_t code,IpcIo * reply)99 static int32_t Callback(IOwner owner, int32_t code, IpcIo *reply)
100 {
101 if ((reply == NULL) || (owner == NULL)) {
102 POWER_HILOGE("Invalid parameter");
103 return EC_INVALID;
104 }
105
106 int32_t *ret = (int32_t *)owner;
107 ReadInt32(reply, ret);
108 POWER_HILOGD("Power screen saver callback: %d, code: %d", *ret, code);
109 return EC_SUCCESS;
110 }
111
SetScreenSaverStateProxy(IUnknown * iUnknown,BOOL enable)112 static int32_t SetScreenSaverStateProxy(IUnknown *iUnknown, BOOL enable)
113 {
114 IpcIo request;
115 char buffer[MAX_DATA_LEN];
116 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
117 WriteBool(&request, enable == TRUE);
118
119 int32_t ret;
120 ScreenSaverProxyInterface *proxy = (ScreenSaverProxyInterface *)iUnknown;
121 proxy->Invoke((IClientProxy *)proxy, SCREENSAVER_FUNCID_SETSTATE, &request, &ret, Callback);
122 POWER_HILOGD("Set screen saver state done, enable: %d", (int32_t)enable);
123
124 return ret;
125 }
126
SetScreenSaverState(BOOL enable)127 BOOL SetScreenSaverState(BOOL enable)
128 {
129 int32_t ret = EC_FAILURE;
130 ScreenSaverProxyInterface *intf = GetScreenSaverProxyInterface();
131 if ((intf != NULL) && (intf->SetScreenSaverStateFunc != NULL)) {
132 ret = intf->SetScreenSaverStateFunc((IUnknown *)intf, enable);
133 }
134 return (ret == EC_SUCCESS) ? TRUE : FALSE;
135 }
136