• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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