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