• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <ohos_types.h>
21 #include <pthread.h>
22 #include <registry.h>
23 #include <samgr_lite.h>
24 #include <securec.h>
25 #include <unistd.h>
26 
27 #include "hilog_wrapper.h"
28 #include "power_manage_interface.h"
29 #include "power_mgr.h"
30 
31 #define MAX_DATA_LEN    1024
32 
33 typedef struct {
34     INHERIT_IUNKNOWNENTRY(PowerManageProxyInterface);
35 } PowerManageProxyEntry;
36 
37 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
38 static PowerManageProxyInterface *g_intf = NULL;
39 
40 static int32_t AcquireRunningLockEntryProxy(IUnknown *iUnknown, RunningLockEntry *entry, int32_t timeoutMs);
41 static int32_t ReleaseRunningLockEntryProxy(IUnknown *iUnknown, RunningLockEntry *entry);
42 static BOOL IsAnyRunningLockHoldingProxy(IUnknown *iUnknown);
43 static void SuspendDeviceProxy(IUnknown *iUnknown, SuspendDeviceType reason, BOOL suspendImmed);
44 static void WakeupDeviceProxy(IUnknown *iUnknown, WakeupDeviceType reason, const char* details);
45 
CreatClient(const char * service,const char * feature,uint32_t size)46 static void *CreatClient(const char *service, const char *feature, uint32_t size)
47 {
48     (void)service;
49     (void)feature;
50     uint32_t len = size + sizeof(PowerManageProxyEntry);
51     uint8_t *client = (uint8_t *)malloc(len);
52     if (client == NULL) {
53         POWER_HILOGE("Failed to allocate memory for power manage proxy entry");
54         return NULL;
55     }
56     (void)memset_s(client, len, 0, len);
57     PowerManageProxyEntry *entry = (PowerManageProxyEntry *)&client[size];
58     entry->ver =  ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
59     entry->ref = 1;
60     entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
61     entry->iUnknown.AddRef = IUNKNOWN_AddRef;
62     entry->iUnknown.Release = IUNKNOWN_Release;
63     entry->iUnknown.Invoke = NULL;
64     entry->iUnknown.AcquireRunningLockEntryFunc = AcquireRunningLockEntryProxy;
65     entry->iUnknown.ReleaseRunningLockEntryFunc = ReleaseRunningLockEntryProxy;
66     entry->iUnknown.IsAnyRunningLockHoldingFunc = IsAnyRunningLockHoldingProxy;
67     entry->iUnknown.SuspendDeviceFunc = SuspendDeviceProxy;
68     entry->iUnknown.WakeupDeviceFunc = WakeupDeviceProxy;
69     return client;
70 }
71 
DestroyClient(const char * service,const char * feature,void * iproxy)72 static void DestroyClient(const char *service, const char *feature, void *iproxy)
73 {
74     (void)service;
75     (void)feature;
76     free(iproxy);
77 }
78 
GetPowerManageProxyInterface(void)79 static PowerManageProxyInterface *GetPowerManageProxyInterface(void)
80 {
81     if (g_intf != NULL) {
82         return g_intf;
83     }
84     pthread_mutex_lock(&g_mutex);
85     if (g_intf != NULL) {
86         pthread_mutex_unlock(&g_mutex);
87         return g_intf;
88     }
89 
90     SAMGR_RegisterFactory(POWER_MANAGE_SERVICE, POWER_MANAGE_FEATURE, CreatClient, DestroyClient);
91 
92     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(POWER_MANAGE_SERVICE, POWER_MANAGE_FEATURE);
93     if (iUnknown == NULL) {
94         POWER_HILOGE("Failed to get power manage iUnknown");
95         pthread_mutex_unlock(&g_mutex);
96         return NULL;
97     }
98 
99     int ret = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&g_intf);
100     if ((ret != EC_SUCCESS) || (g_intf == NULL)) {
101         POWER_HILOGE("Failed to query power manage interface");
102         pthread_mutex_unlock(&g_mutex);
103         return NULL;
104     }
105     pthread_mutex_unlock(&g_mutex);
106     POWER_HILOGI("Succeed to get power manage proxy interface");
107     return g_intf;
108 }
109 
AcquireReleaseCallback(IOwner owner,int32_t code,IpcIo * reply)110 static int32_t AcquireReleaseCallback(IOwner owner, int32_t code, IpcIo *reply)
111 {
112     if ((reply == NULL) || (owner == NULL)) {
113         POWER_HILOGE("Invalid parameter");
114         return EC_INVALID;
115     }
116 
117     int32_t *ret = (int32_t *)owner;
118     ReadInt32(reply, ret);
119     POWER_HILOGD("Running lock callback: %d, code: %d", *ret, code);
120     return EC_SUCCESS;
121 }
122 
AcquireRunningLockEntryProxy(IUnknown * iUnknown,RunningLockEntry * entry,int32_t timeoutMs)123 static int32_t AcquireRunningLockEntryProxy(IUnknown *iUnknown, RunningLockEntry *entry, int32_t timeoutMs)
124 {
125     if (IsValidRunningLockEntry(entry) == FALSE) {
126         POWER_HILOGE("Invalid running lock entry");
127         return EC_INVALID;
128     }
129 
130     IpcIo request;
131     char buffer[MAX_DATA_LEN];
132     IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
133     bool value = WriteRawData(&request, entry, sizeof(RunningLockEntry));
134     if (!value) {
135         POWER_HILOGE("WriteRawData faild");
136         return EC_INVALID;
137     }
138     WriteInt32(&request, timeoutMs);
139 
140     int32_t ret;
141     PowerManageProxyInterface *proxy = (PowerManageProxyInterface *)iUnknown;
142     proxy->Invoke((IClientProxy *)proxy, POWERMANAGE_FUNCID_ACQUIRERUNNINGLOCK,
143         &request, &ret, AcquireReleaseCallback);
144     POWER_HILOGD("Acquire running lock done, name: %s, type: %d", entry->lock.name, entry->lock.type);
145 
146     return ret;
147 }
148 
ReleaseRunningLockEntryProxy(IUnknown * iUnknown,RunningLockEntry * entry)149 static int32_t ReleaseRunningLockEntryProxy(IUnknown *iUnknown, RunningLockEntry *entry)
150 {
151     if (IsValidRunningLockEntry(entry) == FALSE) {
152         POWER_HILOGE("Invalid running lock entry");
153         return EC_INVALID;
154     }
155 
156     IpcIo request;
157     char buffer[MAX_DATA_LEN];
158     IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
159     bool value = WriteRawData(&request, entry, sizeof(RunningLockEntry));
160     if (!value) {
161         POWER_HILOGE("WriteRawData faild");
162         return EC_INVALID;
163     }
164 
165     int32_t ret;
166     PowerManageProxyInterface *proxy = (PowerManageProxyInterface *)iUnknown;
167     proxy->Invoke((IClientProxy *)proxy, POWERMANAGE_FUNCID_RELEASERUNNINGLOCK,
168         &request, &ret, AcquireReleaseCallback);
169     POWER_HILOGD("Release running lock done, name: %s, type: %d", entry->lock.name, entry->lock.type);
170 
171     return ret;
172 }
173 
IsAnyHoldingCallback(IOwner owner,int32_t code,IpcIo * reply)174 static int32_t IsAnyHoldingCallback(IOwner owner, int32_t code, IpcIo *reply)
175 {
176     if ((reply == NULL) || (owner == NULL)) {
177         POWER_HILOGE("Invalid parameter");
178         return EC_INVALID;
179     }
180 
181     BOOL *ret = (BOOL *)owner;
182     bool readRet;
183     ReadBool(reply, &readRet);
184     *ret = readRet ? TRUE : FALSE;
185     POWER_HILOGD("Any running lock holding: %d, code: %d", *ret, code);
186     return EC_SUCCESS;
187 }
188 
IsAnyRunningLockHoldingProxy(IUnknown * iUnknown)189 static BOOL IsAnyRunningLockHoldingProxy(IUnknown *iUnknown)
190 {
191     BOOL ret;
192     PowerManageProxyInterface *proxy = (PowerManageProxyInterface *)iUnknown;
193     IpcIo request;
194     char buffer[MAX_DATA_LEN];
195     IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
196     proxy->Invoke((IClientProxy *)proxy, POWERMANAGE_FUNCID_ISANYRUNNINGLOCKHOLDING,
197         &request, &ret, IsAnyHoldingCallback);
198     return ret;
199 }
200 
InitIdentity(RunningLockEntry * entry)201 void InitIdentity(RunningLockEntry *entry)
202 {
203     if (entry == NULL) {
204         return;
205     }
206     entry->identity.pid = getpid();
207     entry->identity.token = (uint64_t)(uintptr_t)entry;
208 }
209 
AcquireRunningLockEntry(RunningLockEntry * entry,int32_t timeoutMs)210 BOOL AcquireRunningLockEntry(RunningLockEntry *entry, int32_t timeoutMs)
211 {
212     int32_t ret = EC_FAILURE;
213     PowerManageProxyInterface *intf = GetPowerManageProxyInterface();
214     if ((intf != NULL) && (intf->AcquireRunningLockEntryFunc != NULL)) {
215         ret = intf->AcquireRunningLockEntryFunc((IUnknown *)intf, entry, timeoutMs);
216     }
217     return (ret == EC_SUCCESS) ? TRUE : FALSE;
218 }
219 
ReleaseRunningLockEntry(RunningLockEntry * entry)220 BOOL ReleaseRunningLockEntry(RunningLockEntry *entry)
221 {
222     int32_t ret = EC_FAILURE;
223     PowerManageProxyInterface *intf = GetPowerManageProxyInterface();
224     if ((intf != NULL) && (intf->ReleaseRunningLockEntryFunc != NULL)) {
225         ret = intf->ReleaseRunningLockEntryFunc((IUnknown *)intf, entry);
226     }
227     return (ret == EC_SUCCESS) ? TRUE : FALSE;
228 }
229 
IsAnyRunningLockHolding()230 BOOL IsAnyRunningLockHolding()
231 {
232     BOOL ret = FALSE;
233     PowerManageProxyInterface *intf = GetPowerManageProxyInterface();
234     if ((intf != NULL) && (intf->IsAnyRunningLockHoldingFunc != NULL)) {
235         ret = intf->IsAnyRunningLockHoldingFunc((IUnknown *)intf);
236     }
237     return ret;
238 }
239 
SuspendDeviceProxy(IUnknown * iUnknown,SuspendDeviceType reason,BOOL suspendImmed)240 static void SuspendDeviceProxy(IUnknown *iUnknown, SuspendDeviceType reason, BOOL suspendImmed)
241 {
242     IpcIo request;
243     char buffer[MAX_DATA_LEN];
244     IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
245     WriteInt32(&request, (int32_t)reason);
246     WriteBool(&request, (suspendImmed == TRUE));
247 
248     PowerManageProxyInterface *proxy = (PowerManageProxyInterface *)iUnknown;
249     proxy->Invoke((IClientProxy *)proxy, POWERMANAGE_FUNCID_SUSPEND, &request, NULL, NULL);
250     POWER_HILOGD("Suspend device done, reason: %{public}d", reason);
251 }
252 
WakeupDeviceProxy(IUnknown * iUnknown,WakeupDeviceType reason,const char * details)253 static void WakeupDeviceProxy(IUnknown *iUnknown, WakeupDeviceType reason, const char* details)
254 {
255     IpcIo request;
256     char buffer[MAX_DATA_LEN];
257     IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
258     WriteInt32(&request, (int32_t)reason);
259     WriteString(&request, details);
260 
261     PowerManageProxyInterface *proxy = (PowerManageProxyInterface *)iUnknown;
262     proxy->Invoke((IClientProxy *)proxy, POWERMANAGE_FUNCID_WAKEUP, &request, NULL, NULL);
263     POWER_HILOGD("Wakeup device done, reason: %{public}d", reason);
264 }
265 
SuspendDevice(SuspendDeviceType reason,BOOL suspendImmed)266 void SuspendDevice(SuspendDeviceType reason, BOOL suspendImmed)
267 {
268     PowerManageProxyInterface *intf = GetPowerManageProxyInterface();
269     if ((intf != NULL) && (intf->SuspendDeviceFunc != NULL)) {
270         intf->SuspendDeviceFunc((IUnknown *)intf, reason, suspendImmed);
271     }
272 }
273 
WakeupDevice(WakeupDeviceType reason,const char * details)274 void WakeupDevice(WakeupDeviceType reason, const char* details)
275 {
276     const char* detailReason = (details != NULL) ? details : "No details";
277     PowerManageProxyInterface *intf = GetPowerManageProxyInterface();
278     if ((intf != NULL) && (intf->WakeupDeviceFunc != NULL)) {
279         intf->WakeupDeviceFunc((IUnknown *)intf, reason, detailReason);
280     }
281 }
282