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 <stdlib.h>
17
18 #include <common.h>
19 #include <ohos_errno.h>
20 #include <pthread.h>
21 #include <securec.h>
22
23 #include "hilog_wrapper.h"
24 #include "power/suspend_controller.h"
25 #include "running_lock_entry.h"
26
27 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static Vector g_runningLocks[RUNNINGLOCK_BUTT];
29 static const char * const g_runningLockNames[RUNNINGLOCK_BUTT] = {
30 "OHOSPowerMgr.Screen",
31 "OHOSPowerMgr.Background",
32 "OHOSPowerMgr.Proximity",
33 };
34
DupRunningLockEntry(RunningLockEntry * entry)35 static RunningLockEntry *DupRunningLockEntry(RunningLockEntry *entry)
36 {
37 RunningLockEntry *e = (RunningLockEntry *)malloc(sizeof(RunningLockEntry));
38 if (e == NULL) {
39 POWER_HILOGE("Failed allocate running lock entry");
40 return NULL;
41 }
42 if (memcpy_s(e, sizeof(RunningLockEntry), entry, sizeof(RunningLockEntry)) != EOK) {
43 POWER_HILOGE("Failed copy running lock entry");
44 free(e);
45 return NULL;
46 }
47 return e;
48 }
49
AddRunningLockEntryLocked(Vector * vec,RunningLockEntry * entry)50 static BOOL AddRunningLockEntryLocked(Vector *vec, RunningLockEntry *entry)
51 {
52 int16_t pos = VECTOR_FindByKey(vec, (void *)&entry->identity);
53 if (pos >= 0) {
54 POWER_HILOGD("Already acquired: %s", entry->lock.name);
55 return TRUE;
56 }
57 RunningLockEntry *e = DupRunningLockEntry(entry);
58 if (e == NULL) {
59 POWER_HILOGE("Failed duplicate running lock entry");
60 return FALSE;
61 }
62 pos = VECTOR_Add(vec, (void *)e);
63 if (pos == INVALID_INDEX) {
64 POWER_HILOGE("Failed to add entry to vector");
65 free(e);
66 return FALSE;
67 }
68 POWER_HILOGD("Add running lock entry, name: %s, type: %d", e->lock.name, e->lock.type);
69 if (VECTOR_Num(vec) == 1) {
70 ScAcquireRunningLock(g_runningLockNames[entry->lock.type]);
71 }
72 return TRUE;
73 }
74
RemoveRunningLockEntryLocked(Vector * vec,RunningLockEntry * entry)75 static BOOL RemoveRunningLockEntryLocked(Vector *vec, RunningLockEntry *entry)
76 {
77 int16_t pos = VECTOR_FindByKey(vec, (void *)&entry->identity);
78 if (pos < 0) {
79 POWER_HILOGE("Non-existent running lock");
80 return TRUE;
81 }
82 RunningLockEntry *e = (RunningLockEntry *)VECTOR_Swap(vec, pos, NULL);
83 free(e);
84 POWER_HILOGD("Remove running lock entry, name: %s, type: %d", entry->lock.name, entry->lock.type);
85 if (VECTOR_Num(vec) == 0) {
86 ScReleaseRunningLock(g_runningLockNames[entry->lock.type]);
87 }
88 return TRUE;
89 }
90
ShowLocks()91 static void ShowLocks()
92 {
93 #ifdef OHOS_DEBUG
94 for (int32_t t = RUNNINGLOCK_SCREEN; t < RUNNINGLOCK_BUTT; t++) {
95 Vector *vec = &g_runningLocks[t];
96 int32_t size = VECTOR_Size(vec);
97 POWER_HILOGD("type: %d, lock num: %d", t, VECTOR_Num(vec));
98 for (int32_t i = 0; i < size; i++) {
99 RunningLockEntry* e = VECTOR_At(vec, i);
100 if (e != NULL) {
101 POWER_HILOGD("No.%d, name: %s, pid: %u, token: %llu",
102 i, e->lock.name, e->identity.pid, (long long)e->identity.token);
103 }
104 }
105 }
106 #endif
107 }
108
RunningLockMgrAcquireEntry(RunningLockEntry * entry,int32_t timeoutMs)109 int32_t RunningLockMgrAcquireEntry(RunningLockEntry *entry, int32_t timeoutMs)
110 {
111 if (IsValidRunningLockEntry(entry) == FALSE) {
112 POWER_HILOGE("Invalid running lock entry");
113 return EC_INVALID;
114 }
115 pthread_mutex_lock(&g_mutex);
116 Vector *vec = &g_runningLocks[entry->lock.type];
117 BOOL ret = AddRunningLockEntryLocked(vec, entry);
118 ShowLocks();
119 pthread_mutex_unlock(&g_mutex);
120 return (ret == TRUE) ? EC_SUCCESS : EC_FAILURE;
121 }
122
RunningLockMgrReleaseEntry(RunningLockEntry * entry)123 int32_t RunningLockMgrReleaseEntry(RunningLockEntry *entry)
124 {
125 if (IsValidRunningLockEntry(entry) == FALSE) {
126 POWER_HILOGE("Invalid running lock entry");
127 return EC_INVALID;
128 }
129
130 pthread_mutex_lock(&g_mutex);
131 Vector *vec = &g_runningLocks[entry->lock.type];
132 BOOL ret = RemoveRunningLockEntryLocked(vec, entry);
133 ShowLocks();
134 pthread_mutex_unlock(&g_mutex);
135 return (ret == TRUE) ? EC_SUCCESS : EC_FAILURE;
136 }
137
RunningLockMgrGetLockCount(RunningLockType type)138 uint32_t RunningLockMgrGetLockCount(RunningLockType type)
139 {
140 uint32_t cnt = 0;
141 if ((type >= 0) && (type < RUNNINGLOCK_BUTT)) {
142 pthread_mutex_lock(&g_mutex);
143 cnt = VECTOR_Num(&g_runningLocks[type]);
144 pthread_mutex_unlock(&g_mutex);
145 }
146 return cnt;
147 }
148
RunningLockMgrGetTotalLockCount()149 uint32_t RunningLockMgrGetTotalLockCount()
150 {
151 uint32_t cnt = 0;
152 pthread_mutex_lock(&g_mutex);
153 for (int32_t t = RUNNINGLOCK_SCREEN; t < RUNNINGLOCK_BUTT; t++) {
154 cnt += VECTOR_Num(&g_runningLocks[t]);
155 }
156 pthread_mutex_unlock(&g_mutex);
157 POWER_HILOGD("Total lock count: %u", cnt);
158 return cnt;
159 }
160
GetRunningLockIdentity(const RunningLockEntry * entry)161 static const RunningLockIdentity *GetRunningLockIdentity(const RunningLockEntry *entry)
162 {
163 return &entry->identity;
164 }
165
RunningLockIdentityCmp(const RunningLockIdentity * a,const RunningLockIdentity * b)166 static int32_t RunningLockIdentityCmp(const RunningLockIdentity *a, const RunningLockIdentity *b)
167 {
168 return (IsSameRunningLockIdentity(a, b) == TRUE) ? 0 : -1;
169 }
170
RunningLockMgrInit(void)171 void RunningLockMgrInit(void)
172 {
173 for (int32_t i = 0; i < RUNNINGLOCK_BUTT; i++) {
174 g_runningLocks[i] = VECTOR_Make((VECTOR_Key)GetRunningLockIdentity, (VECTOR_Compare)RunningLockIdentityCmp);
175 }
176 }
177