1cb69b360Sopenharmony_ci/* 2cb69b360Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3cb69b360Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cb69b360Sopenharmony_ci * you may not use this file except in compliance with the License. 5cb69b360Sopenharmony_ci * You may obtain a copy of the License at 6cb69b360Sopenharmony_ci * 7cb69b360Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cb69b360Sopenharmony_ci * 9cb69b360Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cb69b360Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cb69b360Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cb69b360Sopenharmony_ci * See the License for the specific language governing permissions and 13cb69b360Sopenharmony_ci * limitations under the License. 14cb69b360Sopenharmony_ci */ 15cb69b360Sopenharmony_ci 16cb69b360Sopenharmony_ci#include <stdlib.h> 17cb69b360Sopenharmony_ci 18cb69b360Sopenharmony_ci#include <common.h> 19cb69b360Sopenharmony_ci#include <ohos_errno.h> 20cb69b360Sopenharmony_ci#include <pthread.h> 21cb69b360Sopenharmony_ci#include <securec.h> 22cb69b360Sopenharmony_ci 23cb69b360Sopenharmony_ci#include "hilog_wrapper.h" 24cb69b360Sopenharmony_ci#include "power/suspend_controller.h" 25cb69b360Sopenharmony_ci#include "running_lock_entry.h" 26cb69b360Sopenharmony_ci 27cb69b360Sopenharmony_cistatic pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 28cb69b360Sopenharmony_cistatic Vector g_runningLocks[RUNNINGLOCK_BUTT]; 29cb69b360Sopenharmony_cistatic const char * const g_runningLockNames[RUNNINGLOCK_BUTT] = { 30cb69b360Sopenharmony_ci "OHOSPowerMgr.Screen", 31cb69b360Sopenharmony_ci "OHOSPowerMgr.Background", 32cb69b360Sopenharmony_ci "OHOSPowerMgr.Proximity", 33cb69b360Sopenharmony_ci}; 34cb69b360Sopenharmony_ci 35cb69b360Sopenharmony_cistatic RunningLockEntry *DupRunningLockEntry(RunningLockEntry *entry) 36cb69b360Sopenharmony_ci{ 37cb69b360Sopenharmony_ci RunningLockEntry *e = (RunningLockEntry *)malloc(sizeof(RunningLockEntry)); 38cb69b360Sopenharmony_ci if (e == NULL) { 39cb69b360Sopenharmony_ci POWER_HILOGE("Failed allocate running lock entry"); 40cb69b360Sopenharmony_ci return NULL; 41cb69b360Sopenharmony_ci } 42cb69b360Sopenharmony_ci if (memcpy_s(e, sizeof(RunningLockEntry), entry, sizeof(RunningLockEntry)) != EOK) { 43cb69b360Sopenharmony_ci POWER_HILOGE("Failed copy running lock entry"); 44cb69b360Sopenharmony_ci free(e); 45cb69b360Sopenharmony_ci return NULL; 46cb69b360Sopenharmony_ci } 47cb69b360Sopenharmony_ci return e; 48cb69b360Sopenharmony_ci} 49cb69b360Sopenharmony_ci 50cb69b360Sopenharmony_cistatic BOOL AddRunningLockEntryLocked(Vector *vec, RunningLockEntry *entry) 51cb69b360Sopenharmony_ci{ 52cb69b360Sopenharmony_ci int16_t pos = VECTOR_FindByKey(vec, (void *)&entry->identity); 53cb69b360Sopenharmony_ci if (pos >= 0) { 54cb69b360Sopenharmony_ci POWER_HILOGD("Already acquired: %s", entry->lock.name); 55cb69b360Sopenharmony_ci return TRUE; 56cb69b360Sopenharmony_ci } 57cb69b360Sopenharmony_ci RunningLockEntry *e = DupRunningLockEntry(entry); 58cb69b360Sopenharmony_ci if (e == NULL) { 59cb69b360Sopenharmony_ci POWER_HILOGE("Failed duplicate running lock entry"); 60cb69b360Sopenharmony_ci return FALSE; 61cb69b360Sopenharmony_ci } 62cb69b360Sopenharmony_ci pos = VECTOR_Add(vec, (void *)e); 63cb69b360Sopenharmony_ci if (pos == INVALID_INDEX) { 64cb69b360Sopenharmony_ci POWER_HILOGE("Failed to add entry to vector"); 65cb69b360Sopenharmony_ci free(e); 66cb69b360Sopenharmony_ci return FALSE; 67cb69b360Sopenharmony_ci } 68cb69b360Sopenharmony_ci POWER_HILOGD("Add running lock entry, name: %s, type: %d", e->lock.name, e->lock.type); 69cb69b360Sopenharmony_ci if (VECTOR_Num(vec) == 1) { 70cb69b360Sopenharmony_ci ScAcquireRunningLock(g_runningLockNames[entry->lock.type]); 71cb69b360Sopenharmony_ci } 72cb69b360Sopenharmony_ci return TRUE; 73cb69b360Sopenharmony_ci} 74cb69b360Sopenharmony_ci 75cb69b360Sopenharmony_cistatic BOOL RemoveRunningLockEntryLocked(Vector *vec, RunningLockEntry *entry) 76cb69b360Sopenharmony_ci{ 77cb69b360Sopenharmony_ci int16_t pos = VECTOR_FindByKey(vec, (void *)&entry->identity); 78cb69b360Sopenharmony_ci if (pos < 0) { 79cb69b360Sopenharmony_ci POWER_HILOGE("Non-existent running lock"); 80cb69b360Sopenharmony_ci return TRUE; 81cb69b360Sopenharmony_ci } 82cb69b360Sopenharmony_ci RunningLockEntry *e = (RunningLockEntry *)VECTOR_Swap(vec, pos, NULL); 83cb69b360Sopenharmony_ci free(e); 84cb69b360Sopenharmony_ci POWER_HILOGD("Remove running lock entry, name: %s, type: %d", entry->lock.name, entry->lock.type); 85cb69b360Sopenharmony_ci if (VECTOR_Num(vec) == 0) { 86cb69b360Sopenharmony_ci ScReleaseRunningLock(g_runningLockNames[entry->lock.type]); 87cb69b360Sopenharmony_ci } 88cb69b360Sopenharmony_ci return TRUE; 89cb69b360Sopenharmony_ci} 90cb69b360Sopenharmony_ci 91cb69b360Sopenharmony_cistatic void ShowLocks() 92cb69b360Sopenharmony_ci{ 93cb69b360Sopenharmony_ci#ifdef OHOS_DEBUG 94cb69b360Sopenharmony_ci for (int32_t t = RUNNINGLOCK_SCREEN; t < RUNNINGLOCK_BUTT; t++) { 95cb69b360Sopenharmony_ci Vector *vec = &g_runningLocks[t]; 96cb69b360Sopenharmony_ci int32_t size = VECTOR_Size(vec); 97cb69b360Sopenharmony_ci POWER_HILOGD("type: %d, lock num: %d", t, VECTOR_Num(vec)); 98cb69b360Sopenharmony_ci for (int32_t i = 0; i < size; i++) { 99cb69b360Sopenharmony_ci RunningLockEntry* e = VECTOR_At(vec, i); 100cb69b360Sopenharmony_ci if (e != NULL) { 101cb69b360Sopenharmony_ci POWER_HILOGD("No.%d, name: %s, pid: %u, token: %llu", 102cb69b360Sopenharmony_ci i, e->lock.name, e->identity.pid, (long long)e->identity.token); 103cb69b360Sopenharmony_ci } 104cb69b360Sopenharmony_ci } 105cb69b360Sopenharmony_ci } 106cb69b360Sopenharmony_ci#endif 107cb69b360Sopenharmony_ci} 108cb69b360Sopenharmony_ci 109cb69b360Sopenharmony_ciint32_t RunningLockMgrAcquireEntry(RunningLockEntry *entry, int32_t timeoutMs) 110cb69b360Sopenharmony_ci{ 111cb69b360Sopenharmony_ci if (IsValidRunningLockEntry(entry) == FALSE) { 112cb69b360Sopenharmony_ci POWER_HILOGE("Invalid running lock entry"); 113cb69b360Sopenharmony_ci return EC_INVALID; 114cb69b360Sopenharmony_ci } 115cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 116cb69b360Sopenharmony_ci Vector *vec = &g_runningLocks[entry->lock.type]; 117cb69b360Sopenharmony_ci BOOL ret = AddRunningLockEntryLocked(vec, entry); 118cb69b360Sopenharmony_ci ShowLocks(); 119cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 120cb69b360Sopenharmony_ci return (ret == TRUE) ? EC_SUCCESS : EC_FAILURE; 121cb69b360Sopenharmony_ci} 122cb69b360Sopenharmony_ci 123cb69b360Sopenharmony_ciint32_t RunningLockMgrReleaseEntry(RunningLockEntry *entry) 124cb69b360Sopenharmony_ci{ 125cb69b360Sopenharmony_ci if (IsValidRunningLockEntry(entry) == FALSE) { 126cb69b360Sopenharmony_ci POWER_HILOGE("Invalid running lock entry"); 127cb69b360Sopenharmony_ci return EC_INVALID; 128cb69b360Sopenharmony_ci } 129cb69b360Sopenharmony_ci 130cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 131cb69b360Sopenharmony_ci Vector *vec = &g_runningLocks[entry->lock.type]; 132cb69b360Sopenharmony_ci BOOL ret = RemoveRunningLockEntryLocked(vec, entry); 133cb69b360Sopenharmony_ci ShowLocks(); 134cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 135cb69b360Sopenharmony_ci return (ret == TRUE) ? EC_SUCCESS : EC_FAILURE; 136cb69b360Sopenharmony_ci} 137cb69b360Sopenharmony_ci 138cb69b360Sopenharmony_ciuint32_t RunningLockMgrGetLockCount(RunningLockType type) 139cb69b360Sopenharmony_ci{ 140cb69b360Sopenharmony_ci uint32_t cnt = 0; 141cb69b360Sopenharmony_ci if ((type >= 0) && (type < RUNNINGLOCK_BUTT)) { 142cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 143cb69b360Sopenharmony_ci cnt = VECTOR_Num(&g_runningLocks[type]); 144cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 145cb69b360Sopenharmony_ci } 146cb69b360Sopenharmony_ci return cnt; 147cb69b360Sopenharmony_ci} 148cb69b360Sopenharmony_ci 149cb69b360Sopenharmony_ciuint32_t RunningLockMgrGetTotalLockCount() 150cb69b360Sopenharmony_ci{ 151cb69b360Sopenharmony_ci uint32_t cnt = 0; 152cb69b360Sopenharmony_ci pthread_mutex_lock(&g_mutex); 153cb69b360Sopenharmony_ci for (int32_t t = RUNNINGLOCK_SCREEN; t < RUNNINGLOCK_BUTT; t++) { 154cb69b360Sopenharmony_ci cnt += VECTOR_Num(&g_runningLocks[t]); 155cb69b360Sopenharmony_ci } 156cb69b360Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 157cb69b360Sopenharmony_ci POWER_HILOGD("Total lock count: %u", cnt); 158cb69b360Sopenharmony_ci return cnt; 159cb69b360Sopenharmony_ci} 160cb69b360Sopenharmony_ci 161cb69b360Sopenharmony_cistatic const RunningLockIdentity *GetRunningLockIdentity(const RunningLockEntry *entry) 162cb69b360Sopenharmony_ci{ 163cb69b360Sopenharmony_ci return &entry->identity; 164cb69b360Sopenharmony_ci} 165cb69b360Sopenharmony_ci 166cb69b360Sopenharmony_cistatic int32_t RunningLockIdentityCmp(const RunningLockIdentity *a, const RunningLockIdentity *b) 167cb69b360Sopenharmony_ci{ 168cb69b360Sopenharmony_ci return (IsSameRunningLockIdentity(a, b) == TRUE) ? 0 : -1; 169cb69b360Sopenharmony_ci} 170cb69b360Sopenharmony_ci 171cb69b360Sopenharmony_civoid RunningLockMgrInit(void) 172cb69b360Sopenharmony_ci{ 173cb69b360Sopenharmony_ci for (int32_t i = 0; i < RUNNINGLOCK_BUTT; i++) { 174cb69b360Sopenharmony_ci g_runningLocks[i] = VECTOR_Make((VECTOR_Key)GetRunningLockIdentity, (VECTOR_Compare)RunningLockIdentityCmp); 175cb69b360Sopenharmony_ci } 176cb69b360Sopenharmony_ci} 177