• 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 "running_lock_mgr.h"
17 
18 #include <cinttypes>
19 #include <datetime_ex.h>
20 #include <hisysevent.h>
21 #include <ipc_skeleton.h>
22 #include <securec.h>
23 
24 #ifdef HAS_DISPLAY_MANAGER_PART
25 #include "dm_common.h"
26 #endif
27 #include "hitrace_meter.h"
28 #include "power_log.h"
29 #include "power_mgr_factory.h"
30 #include "power_mgr_service.h"
31 #ifdef HAS_DISPLAY_MANAGER_PART
32 #include "screen_manager.h"
33 #endif
34 
35 using namespace std;
36 
37 namespace OHOS {
38 namespace PowerMgr {
39 namespace {
40 const string TASK_RUNNINGLOCK_FORCEUNLOCK = "RunningLock_ForceUnLock";
41 }
42 
~RunningLockMgr()43 RunningLockMgr::~RunningLockMgr() {}
44 
Init()45 bool RunningLockMgr::Init()
46 {
47     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Init start");
48     std::lock_guard<std::mutex> lock(mutex_);
49     if (runningLockDeathRecipient_ == nullptr) {
50         runningLockDeathRecipient_ = new RunningLockDeathRecipient();
51     }
52     if (runningLockAction_ == nullptr) {
53         runningLockAction_ = PowerMgrFactory::GetRunningLockAction();
54         if (!runningLockAction_) {
55             POWER_HILOGE(FEATURE_RUNNING_LOCK, "Get running lock action fail");
56             return false;
57         }
58     }
59     auto pmsptr = pms_.promote();
60     if (pmsptr == nullptr) {
61         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Power manager service is null");
62         return false;
63     }
64     handler_ = pmsptr->GetHandler();
65 
66     systemLocks_.emplace(SystemLockType::SYSTEM_LOCK_APP,
67         std::make_shared<SystemLock>(runningLockAction_, LOCK_TAG_APP));
68     systemLocks_.emplace(SystemLockType::SYSTEM_LOCK_DISPLAY,
69         std::make_shared<SystemLock>(runningLockAction_, LOCK_TAG_DISPLAY));
70 
71     bool ret = InitLocks();
72 
73     POWER_HILOGI(FEATURE_RUNNING_LOCK, "Init success");
74     return ret;
75 }
76 
InitLocks()77 bool RunningLockMgr::InitLocks()
78 {
79     InitLocksTypeScreen();
80     InitLocksTypeBackground();
81     InitLocksTypeProximity();
82     return true;
83 }
84 
InitLocksTypeScreen()85 void RunningLockMgr::InitLocksTypeScreen()
86 {
87     lockCounters_.emplace(RunningLockType::RUNNINGLOCK_SCREEN,
88         std::make_shared<LockCounter>(
89         RunningLockType::RUNNINGLOCK_SCREEN, [this](bool active) {
90             POWER_HILOGD(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_SCREEN action start");
91             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
92             if (pms == nullptr) {
93                 return;
94             }
95             auto stateMachine = pms->GetPowerStateMachine();
96             if (stateMachine == nullptr) {
97                 return;
98             }
99             if (active) {
100                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_SCREEN active");
101                 stateMachine->SetState(PowerState::AWAKE,
102                     StateChangeReason::STATE_CHANGE_REASON_RUNNING_LOCK);
103                 stateMachine->CancelDelayTimer(
104                     PowermsEventHandler::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
105                 stateMachine->CancelDelayTimer(
106                     PowermsEventHandler::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
107             } else {
108                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_SCREEN inactive");
109                 if (stateMachine->GetState() == PowerState::AWAKE) {
110                     stateMachine->ResetInactiveTimer();
111                 } else {
112                     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Screen unlock in state: %{public}d",
113                         stateMachine->GetState());
114                 }
115             }
116         })
117     );
118 }
119 
InitLocksTypeBackground()120 void RunningLockMgr::InitLocksTypeBackground()
121 {
122     lockCounters_.emplace(RunningLockType::RUNNINGLOCK_BACKGROUND,
123         std::make_shared<LockCounter>(
124         RunningLockType::RUNNINGLOCK_BACKGROUND, [this](bool active) {
125             POWER_HILOGD(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_BACKGROUND action start");
126             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
127             if (pms == nullptr) {
128                 return;
129             }
130             auto stateMachine = pms->GetPowerStateMachine();
131             if (stateMachine == nullptr) {
132                 return;
133             }
134             auto iterator = systemLocks_.find(SystemLockType::SYSTEM_LOCK_APP);
135             if (iterator == systemLocks_.end()) {
136                 return;
137             }
138             std::shared_ptr<SystemLock> pSysLock = iterator->second;
139             if (active) {
140                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_BACKGROUND active");
141                 stateMachine->CancelDelayTimer(
142                     PowermsEventHandler::CHECK_USER_ACTIVITY_SLEEP_TIMEOUT_MSG);
143                 pSysLock->Lock();
144             } else {
145                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_BACKGROUND inactive");
146                 if (stateMachine->GetState() == PowerState::INACTIVE) {
147                     stateMachine->ResetSleepTimer();
148                 } else {
149                     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Background unlock in state: %{public}d",
150                         stateMachine->GetState());
151                 }
152                 pSysLock->Unlock();
153             }
154         })
155     );
156 }
157 
InitLocksTypeProximity()158 void RunningLockMgr::InitLocksTypeProximity()
159 {
160     lockCounters_.emplace(RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL,
161         std::make_shared<LockCounter>(
162         RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL, [this](bool active) {
163             POWER_HILOGD(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL action start");
164             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
165             if (pms == nullptr) {
166                 return;
167             }
168             auto stateMachine = pms->GetPowerStateMachine();
169             if (stateMachine == nullptr) {
170                 return;
171             }
172             auto iterator = systemLocks_.find(SystemLockType::SYSTEM_LOCK_APP);
173             if (iterator == systemLocks_.end()) {
174                 return;
175             }
176             std::shared_ptr<SystemLock> pSysLock = iterator->second;
177             if (active) {
178                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL active");
179                 proximityController_.Enable();
180                 if (proximityController_.IsClose()) {
181                     POWER_HILOGI(FEATURE_RUNNING_LOCK, "INACTIVE when proximity is closed");
182                     stateMachine->SetState(PowerState::INACTIVE,
183                         StateChangeReason::STATE_CHANGE_REASON_RUNNING_LOCK, true);
184                 } else {
185                     POWER_HILOGI(FEATURE_RUNNING_LOCK, "AWAKE when proximity is away");
186                     stateMachine->SetState(PowerState::AWAKE,
187                         StateChangeReason::STATE_CHANGE_REASON_RUNNING_LOCK, true);
188                 }
189                 stateMachine->CancelDelayTimer(
190                     PowermsEventHandler::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
191                 stateMachine->CancelDelayTimer(
192                     PowermsEventHandler::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
193                 pSysLock->Lock();
194             } else {
195                 POWER_HILOGI(FEATURE_RUNNING_LOCK, "RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL inactive");
196                 stateMachine->SetState(PowerState::AWAKE,
197                     StateChangeReason::STATE_CHANGE_REASON_RUNNING_LOCK);
198                 stateMachine->ResetInactiveTimer();
199                 pSysLock->Unlock();
200                 proximityController_.Disable();
201             }
202         })
203     );
204 }
205 
GetRunningLockInner(const sptr<IRemoteObject> & remoteObj)206 std::shared_ptr<RunningLockInner> RunningLockMgr::GetRunningLockInner(
207     const sptr<IRemoteObject>& remoteObj)
208 {
209     std::lock_guard<std::mutex> lock(mutex_);
210     auto iterator = runningLocks_.find(remoteObj);
211     if (iterator != runningLocks_.end()) {
212         return iterator->second;
213     }
214     return nullptr;
215 }
216 
CreateRunningLock(const sptr<IRemoteObject> & remoteObj,const RunningLockInfo & runningLockInfo,const UserIPCInfo & userIPCinfo)217 std::shared_ptr<RunningLockInner> RunningLockMgr::CreateRunningLock(
218     const sptr<IRemoteObject>& remoteObj,
219     const RunningLockInfo& runningLockInfo,
220     const UserIPCInfo& userIPCinfo)
221 {
222     auto lockInner = RunningLockInner::CreateRunningLockInner(runningLockInfo, userIPCinfo);
223     if (lockInner == nullptr) {
224         return nullptr;
225     }
226     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Create lock success, name=%{public}s, type=%{public}d",
227         runningLockInfo.name.c_str(), runningLockInfo.type);
228 
229     mutex_.lock();
230     runningLocks_.emplace(remoteObj, lockInner);
231     mutex_.unlock();
232     remoteObj->AddDeathRecipient(runningLockDeathRecipient_);
233     return lockInner;
234 }
235 
ReleaseLock(const sptr<IRemoteObject> remoteObj)236 bool RunningLockMgr::ReleaseLock(const sptr<IRemoteObject> remoteObj)
237 {
238     bool result = false;
239     auto lockInner = GetRunningLockInner(remoteObj);
240     if (lockInner == nullptr) {
241         return result;
242     }
243     if (!lockInner->GetDisabled()) {
244         UnLock(remoteObj);
245     }
246     mutex_.lock();
247     runningLocks_.erase(remoteObj);
248     mutex_.unlock();
249     result = remoteObj->RemoveDeathRecipient(runningLockDeathRecipient_);
250     return result;
251 }
252 
RemoveAndPostUnlockTask(const sptr<IRemoteObject> & remoteObj,uint32_t timeOutMS)253 void RunningLockMgr::RemoveAndPostUnlockTask(
254     const sptr<IRemoteObject>& remoteObj, uint32_t timeOutMS)
255 {
256     auto handler = handler_.lock();
257     if (handler == nullptr) {
258         POWER_HILOGI(FEATURE_RUNNING_LOCK, "Handler is nullptr");
259         return;
260     }
261     const string& remoteObjStr = to_string(reinterpret_cast<uintptr_t>(remoteObj.GetRefPtr()));
262     POWER_HILOGD(FEATURE_RUNNING_LOCK, "timeOutMS=%{public}d", timeOutMS);
263     handler->RemoveTask(remoteObjStr);
264     if (timeOutMS != 0) {
265         std::function<void()> unLockFunc = std::bind(&RunningLockMgr::UnLock, this,  remoteObj);
266         handler->PostTask(unLockFunc, remoteObjStr, timeOutMS);
267     }
268 }
269 
Lock(const sptr<IRemoteObject> & remoteObj,const RunningLockInfo & runningLockInfo,const UserIPCInfo & userIPCinfo,uint32_t timeOutMS)270 void RunningLockMgr::Lock(const sptr<IRemoteObject>& remoteObj,
271     const RunningLockInfo& runningLockInfo,
272     const UserIPCInfo& userIPCinfo, uint32_t timeOutMS)
273 {
274     StartTrace(HITRACE_TAG_POWER, "RunningLock_Lock");
275     POWER_HILOGD(FEATURE_RUNNING_LOCK, "name=%{public}s, type=%{public}d",
276         runningLockInfo.name.c_str(), runningLockInfo.type);
277 
278     auto lockInner = GetRunningLockInner(remoteObj);
279     if (lockInner == nullptr) {
280         POWER_HILOGE(FEATURE_RUNNING_LOCK, "LockInner is nullptr");
281         return;
282     }
283     if (!lockInner->GetDisabled()) {
284         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Lock is already enabled");
285         return;
286     }
287 
288     auto iterator = lockCounters_.find(lockInner->GetRunningLockType());
289     if (iterator == lockCounters_.end()) {
290         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Lock failed unsupported type, type=%{public}d",
291             lockInner->GetRunningLockType());
292         return;
293     }
294     std::shared_ptr<LockCounter> counter = iterator->second;
295     counter->Increase(remoteObj, lockInner);
296     lockInner->SetDisabled(false);
297     POWER_HILOGD(FEATURE_RUNNING_LOCK, "LockCounter type=%{public}d, count=%{public}d", lockInner->GetRunningLockType(),
298         counter->GetCount());
299     if (timeOutMS > 0) {
300         RemoveAndPostUnlockTask(remoteObj, timeOutMS);
301     }
302     FinishTrace(HITRACE_TAG_POWER);
303 }
304 
UnLock(const sptr<IRemoteObject> remoteObj)305 void RunningLockMgr::UnLock(const sptr<IRemoteObject> remoteObj)
306 {
307     StartTrace(HITRACE_TAG_POWER, "RunningLock_Unlock");
308 
309     auto lockInner = GetRunningLockInner(remoteObj);
310     if (lockInner == nullptr) {
311         return;
312     }
313     POWER_HILOGI(FEATURE_RUNNING_LOCK, "LockInner name=%{public}s, type=%{public}d",
314         lockInner->GetRunningLockName().c_str(), lockInner->GetRunningLockType());
315     if (lockInner->GetDisabled()) {
316         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Lock is already disabled name=%{public}s",
317             lockInner->GetRunningLockName().c_str());
318         return;
319     }
320     RemoveAndPostUnlockTask(remoteObj);
321 
322     auto iterator = lockCounters_.find(lockInner->GetRunningLockType());
323     if (iterator == lockCounters_.end()) {
324         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Unlock failed unsupported type, type=%{public}d",
325             lockInner->GetRunningLockType());
326         return;
327     }
328     std::shared_ptr<LockCounter> counter = iterator->second;
329     counter->Decrease(remoteObj, lockInner);
330     lockInner->SetDisabled(true);
331     POWER_HILOGD(FEATURE_RUNNING_LOCK, "LockCounter type=%{public}d, count=%{public}d", lockInner->GetRunningLockType(),
332         counter->GetCount());
333     FinishTrace(HITRACE_TAG_POWER);
334 }
335 
IsUsed(const sptr<IRemoteObject> & remoteObj)336 bool RunningLockMgr::IsUsed(const sptr<IRemoteObject>& remoteObj)
337 {
338     auto lockInner = GetRunningLockInner(remoteObj);
339     if (lockInner == nullptr || lockInner->GetDisabled()) {
340         return false;
341     }
342     return true;
343 }
344 
GetRunningLockNum(RunningLockType type)345 uint32_t RunningLockMgr::GetRunningLockNum(RunningLockType type)
346 {
347     std::lock_guard<std::mutex> lock(mutex_);
348     if (type == RunningLockType::RUNNINGLOCK_BUTT) {
349         return runningLocks_.size();
350     }
351     return std::count_if(runningLocks_.begin(), runningLocks_.end(),
352         [&type](const auto& pair) {
353             return pair.second->GetRunningLockType() == type;
354         });
355 }
356 
GetValidRunningLockNum(RunningLockType type)357 uint32_t RunningLockMgr::GetValidRunningLockNum(RunningLockType type)
358 {
359     auto iterator = lockCounters_.find(type);
360     if (iterator == lockCounters_.end()) {
361         POWER_HILOGD(FEATURE_RUNNING_LOCK, "No specific lock, type=%{public}d", type);
362         return 0;
363     }
364     std::shared_ptr<LockCounter> counter = iterator->second;
365 
366     return counter->GetCount();
367 }
368 
ExistValidRunningLock()369 bool RunningLockMgr::ExistValidRunningLock()
370 {
371     std::lock_guard<std::mutex> lock(mutex_);
372     for (auto it = runningLocks_.begin(); it != runningLocks_.end(); it++) {
373         auto& lockinner = it->second;
374         if (lockinner->GetDisabled() == false) {
375             return true;
376         }
377     }
378     return false;
379 }
380 
SetWorkTriggerList(const sptr<IRemoteObject> & remoteObj,const WorkTriggerList & workTriggerList)381 void RunningLockMgr::SetWorkTriggerList(const sptr<IRemoteObject>& remoteObj,
382     const WorkTriggerList& workTriggerList)
383 {
384     auto lockInner = GetRunningLockInner(remoteObj);
385     if (lockInner == nullptr) {
386         return;
387     }
388     lockInner->SetWorkTriggerList(workTriggerList);
389     NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_WORKTRIGGER_CHANGED);
390     // After update triggerlist, maybe need disabled the lock or enable the lock.
391     SetRunningLockDisableFlag(lockInner);
392     // If enabled, we really lock here.
393     LockReally(remoteObj, lockInner);
394     // If disabled, we really unlock here.
395     UnLockReally(remoteObj, lockInner);
396 }
397 
NotifyHiViewRunningLockInfo(const RunningLockInner & lockInner,RunningLockChangedType changeType) const398 void RunningLockMgr::NotifyHiViewRunningLockInfo(const RunningLockInner& lockInner,
399     RunningLockChangedType changeType) const
400 {
401     NotifyHiView(changeType, lockInner);
402 }
403 
CheckOverTime()404 void RunningLockMgr::CheckOverTime()
405 {
406     auto handler = handler_.lock();
407     if (handler == nullptr) {
408         return;
409     }
410     handler->RemoveEvent(PowermsEventHandler::CHECK_RUNNINGLOCK_OVERTIME_MSG);
411     if (runningLocks_.empty()) {
412         return;
413     }
414     int64_t curTime = GetTickCount();
415     int64_t detectTime = curTime - CHECK_TIMEOUT_INTERVAL_MS;
416     POWER_HILOGI(FEATURE_RUNNING_LOCK, "curTime=%{public}" PRId64 " detectTime=%{public}" PRId64 "", curTime,
417         detectTime);
418     if (detectTime < 0) {
419         return;
420     }
421     int64_t nextDetectTime = INT_MAX;
422     for (auto& it : runningLocks_) {
423         auto lockInner = it.second;
424         if (!lockInner->GetDisabled() && (!lockInner->GetOverTimeFlag())) {
425             if (lockInner->GetLockTimeMs() < detectTime) {
426                 lockInner->SetOverTimeFlag(true);
427                 NotifyRunningLockChanged(it.first, lockInner, NOTIFY_RUNNINGLOCK_OVERTIME);
428             } else {
429                 if (lockInner->GetLockTimeMs() < nextDetectTime) {
430                     nextDetectTime = lockInner->GetLockTimeMs();
431                 }
432             }
433         }
434     }
435     if (nextDetectTime != INT_MAX) {
436         detectTime = nextDetectTime - curTime + CHECK_TIMEOUT_INTERVAL_MS;
437         SendCheckOverTimeMsg(detectTime);
438     }
439 }
440 
SendCheckOverTimeMsg(int64_t delayTime)441 void RunningLockMgr::SendCheckOverTimeMsg(int64_t delayTime)
442 {
443     auto handler = handler_.lock();
444     if (handler == nullptr) {
445         return;
446     }
447     POWER_HILOGD(FEATURE_RUNNING_LOCK, "delayTime=%{public}" PRId64 "", delayTime);
448     handler->SendEvent(PowermsEventHandler::CHECK_RUNNINGLOCK_OVERTIME_MSG, 0, delayTime);
449 }
450 
NotifyRunningLockChanged(const sptr<IRemoteObject> & remoteObj,std::shared_ptr<RunningLockInner> & lockInner,RunningLockChangedType changeType)451 void RunningLockMgr::NotifyRunningLockChanged(const sptr<IRemoteObject>& remoteObj,
452     std::shared_ptr<RunningLockInner>& lockInner, RunningLockChangedType changeType)
453 {
454     if (changeType >= RUNNINGLOCK_CHANGED_BUTT) {
455         return;
456     }
457     switch (changeType) {
458         case NOTIFY_RUNNINGLOCK_ADD: {
459             NotifyHiViewRunningLockInfo(*lockInner, changeType);
460             SendCheckOverTimeMsg(CHECK_TIMEOUT_INTERVAL_MS);
461             break;
462         }
463         case NOTIFY_RUNNINGLOCK_REMOVE: {
464             NotifyHiView(changeType, *lockInner);
465             break;
466         }
467         case NOTIFY_RUNNINGLOCK_WORKTRIGGER_CHANGED: {
468             NotifyHiViewRunningLockInfo(*lockInner, changeType);
469             break;
470         }
471         case NOTIFY_RUNNINGLOCK_OVERTIME: {
472             break;
473         }
474         default: {
475             break;
476         }
477     }
478 }
MatchProxyMap(const UserIPCInfo & userIPCinfo)479 bool RunningLockMgr::MatchProxyMap(const UserIPCInfo& userIPCinfo)
480 {
481     if (proxyMap_.empty()) {
482         POWER_HILOGW(FEATURE_RUNNING_LOCK, "ProxyMap_ is empty, uid = %{public}d, pid = %{public}d",
483             userIPCinfo.uid, userIPCinfo.pid);
484         return false;
485     }
486     auto it = proxyMap_.find(userIPCinfo.uid);
487     // 1. Find pidset by uid.
488     if (it == proxyMap_.end()) {
489         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Pid set not match, uid = %{public}d, pid = %{public}d",
490             userIPCinfo.uid, userIPCinfo.pid);
491         return false;
492     }
493     auto& pidset = it->second;
494     // 2. Count by owner pid.
495     if (pidset.count(userIPCinfo.pid) > 0) {
496         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Pid set match and count > 0, uid = %{public}d, pid = %{public}d",
497             userIPCinfo.uid, userIPCinfo.pid);
498         return true;
499     }
500     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Pid set match and count(-1) = %{public}d, uid = %{public}d, pid = %{public}d",
501         static_cast<unsigned int>(pidset.count(INVALID_PID)), userIPCinfo.uid, userIPCinfo.pid);
502     // 3. Count by INVALID_PID, return true when proxy (uid, -1).
503     return (pidset.count(INVALID_PID) > 0);
504 }
505 
SetRunningLockDisableFlag(std::shared_ptr<RunningLockInner> & lockInner,bool forceRefresh)506 void RunningLockMgr::SetRunningLockDisableFlag(
507     std::shared_ptr<RunningLockInner>& lockInner,
508     bool forceRefresh)
509 {
510     if (proxyMap_.empty() && (!forceRefresh)) {
511         /**
512          * Generally when proxymap empty keep the default value false.
513          * When PGManager cancel proxy uid and pid,
514          * because we update the proxy map before, so we should refresh
515          * all of the runninglock disable flag always.
516          */
517         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Set lock enable, proxyMap_ is empty and forceRefresh is false");
518         lockInner->SetDisabled(false);
519         return;
520     }
521     const UserIPCInfo& userIPCinfo = lockInner->GetUserIPCInfo();
522     bool matched = MatchProxyMap(userIPCinfo);
523     if (matched) {
524         // Matched the lock owner useripcinfo, set disabled directly.
525         lockInner->SetDisabled(true);
526         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Lock and ipc matched, uid = %{public}d, pid = %{public}d",
527             userIPCinfo.uid, userIPCinfo.pid);
528         return;
529     }
530     const RunningLockInfo& runningLockInfo = lockInner->GetRunningLockInfo();
531     const WorkTriggerList& list = runningLockInfo.workTriggerlist;
532     if (list.empty()) {
533         // Not matched, and no trigger list.
534         lockInner->SetDisabled(false);
535         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Work trigger list is empty");
536         return;
537     }
538     bool triggerMatched = true;
539     // Have trigger list, need to judge whether or not all of the list matched,
540     // otherwise we should hold the lock.
541     for (auto& workTrigger : list) {
542         UserIPCInfo triggerIPCInfo {workTrigger->GetUid(), workTrigger->GetPid()};
543         if (!MatchProxyMap(triggerIPCInfo)) {
544             triggerMatched = false;
545             POWER_HILOGD(FEATURE_RUNNING_LOCK, "WorkTrigger not matched uid = %{public}d, pid = %{public}d",
546                 triggerIPCInfo.uid, triggerIPCInfo.pid);
547             break;
548         }
549     }
550     POWER_HILOGD(FEATURE_RUNNING_LOCK, "TriggerMatched = %{public}d, uid = %{public}d, pid = %{public}d",
551         userIPCinfo.uid, userIPCinfo.pid, triggerMatched);
552     lockInner->SetDisabled(triggerMatched);
553 }
554 
LockReally(const sptr<IRemoteObject> & remoteObj,std::shared_ptr<RunningLockInner> & lockInner)555 void RunningLockMgr::LockReally(const sptr<IRemoteObject>& remoteObj,
556     std::shared_ptr<RunningLockInner>& lockInner)
557 {
558     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Start");
559     if (lockInner->GetReallyLocked()) {
560         POWER_HILOGD(FEATURE_RUNNING_LOCK, "lockInner->GetReallyLocked() is true, return");
561         return;
562     }
563     if (lockInner->GetDisabled()) {
564         POWER_HILOGD(FEATURE_RUNNING_LOCK, "lockInner->GetDisabled() is true, return");
565         return;
566     }
567     runningLockAction_->Acquire(lockInner->GetRunningLockType());
568     lockInner->SetReallyLocked(true);
569     NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_ADD);
570     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Finish");
571 }
UnLockReally(const sptr<IRemoteObject> & remoteObj,std::shared_ptr<RunningLockInner> & lockInner)572 void RunningLockMgr::UnLockReally(const sptr<IRemoteObject>& remoteObj,
573     std::shared_ptr<RunningLockInner>& lockInner)
574 {
575     /**
576      * Case 1: Firstly PGManager ProxyRunningLock by uid and pid,
577      * secondly application lock by the same uid and
578      * pid, when call Lock() we matched the proxymap, and no really locked to kernel.
579      * So we don't need to unlocked to kernel.
580      * Case 2: Firstly application create the runninglock and call Lock(),
581      * and then PGManager Proxyed it,
582      * At this time, lock should be unlocked to kernel because we have locked to kernel for it.
583      */
584     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Start");
585     if (!lockInner->GetReallyLocked()) {
586         POWER_HILOGD(FEATURE_RUNNING_LOCK, "lockInner->GetReallyLocked() is false, return");
587         return;
588     }
589     // If disabled, unlock to the kernel.
590     if (!lockInner->GetDisabled()) {
591         POWER_HILOGD(FEATURE_RUNNING_LOCK, "lockInner->GetDisabled() is false, return");
592         return;
593     }
594     runningLockAction_->Release(lockInner->GetRunningLockType());
595     lockInner->SetReallyLocked(false);
596     NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_REMOVE);
597     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Finish");
598 }
599 
ProxyRunningLockInner(bool proxyLock)600 void RunningLockMgr::ProxyRunningLockInner(bool proxyLock)
601 {
602     if (proxyLock) {
603         for (auto& it : runningLocks_) {
604             SetRunningLockDisableFlag(it.second);
605             UnLockReally(it.first, it.second);
606         }
607     } else {
608         for (auto& it : runningLocks_) {
609             SetRunningLockDisableFlag(it.second, true);
610             LockReally(it.first, it.second);
611         }
612     }
613 }
614 
ProxyRunningLock(bool proxyLock,pid_t uid,pid_t pid)615 void RunningLockMgr::ProxyRunningLock(bool proxyLock, pid_t uid, pid_t pid)
616 {
617     POWER_HILOGD(FEATURE_RUNNING_LOCK, "proxyLock = %{public}d, uid = %{public}d, pid = %{public}d",
618         proxyLock, uid, pid);
619     auto it = proxyMap_.find(uid);
620     if (proxyLock) {
621         // PGManager insert proxy info.
622         if (it == proxyMap_.end()) {
623             unordered_set<pid_t> pidset({pid});
624             proxyMap_.emplace(uid, pidset);
625             POWER_HILOGD(FEATURE_RUNNING_LOCK, "Emplace first proxyMap_ {uid = %{public}d, pid = %{public}d}",
626                 uid, pid);
627         } else {
628             if (pid == INVALID_PID) {
629                 // Insert uid, pid = -1,remove other pid
630                 proxyMap_.erase(uid);
631                 unordered_set<pid_t> pidset({pid});
632                 proxyMap_.emplace(uid, pidset);
633                 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Re-emplace proxyMap_ {uid = %{public}d, pid = %{public}d}",
634                     uid, pid);
635             } else {
636                 auto& pidset = it->second;
637                 pidset.insert(pid);
638                 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Insert proxyMap_ {uid = %{public}d, pid = %{public}d}", uid, pid);
639             }
640         }
641         // 1. Set the matched runninglock inner disabled flag.
642     } else {
643         if (it == proxyMap_.end()) {
644             // No insert proxy info, nothing to erase.
645             POWER_HILOGD(FEATURE_RUNNING_LOCK, "No uid in proxyMap_, uid = %{public}d", uid);
646             return;
647         }
648         // 1. Clear the runninglock inner disabled flag 2.removed from proxyMap_
649         if (pid == INVALID_PID) {
650             proxyMap_.erase(uid);
651             POWER_HILOGD(FEATURE_RUNNING_LOCK, "pid = -1, erase from proxyMap_, uid = %{public}d", uid);
652         } else {
653             auto& pidset = it->second;
654             pidset.erase(pid);
655             POWER_HILOGD(FEATURE_RUNNING_LOCK, "Erase from proxyMap_, uid = %{public}d, pid = %{public}d", uid, pid);
656             if (pidset.size() == 0) {
657                 proxyMap_.erase(uid);
658                 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Pidset is empty erase uid from proxyMap_, uid = %{public}d", uid);
659             }
660         }
661     }
662     ProxyRunningLockInner(proxyLock);
663 }
664 
NotifyHiView(RunningLockChangedType changeType,const RunningLockInner & lockInner) const665 void RunningLockMgr::NotifyHiView(RunningLockChangedType changeType, const RunningLockInner& lockInner) const
666 {
667     const UserIPCInfo& ipcInfo = lockInner.GetUserIPCInfo();
668     int32_t pid = ipcInfo.pid;
669     int32_t uid = ipcInfo.uid;
670     bool state = lockInner.GetDisabled();
671     int32_t type = static_cast <int32_t>(lockInner.GetRunningLockType());
672     string name = lockInner.GetRunningLockName();
673     const int logLevel = 2;
674     const string &tag = runninglockNotifyStr_.at(changeType);
675     HiviewDFX::HiSysEvent::Write("POWER", "POWER_RUNNINGLOCK",
676         HiviewDFX::HiSysEvent::EventType::STATISTIC,
677         "PID", pid, "UID", uid, "STATE", state, "TYPE", type, "NAME", name,
678         "LOG_LEVEL", logLevel, "TAG", tag);
679     POWER_HILOGD(FEATURE_RUNNING_LOCK, "pid = %{public}d, uid= %{public}d, tag=%{public}s",
680         pid, uid, tag.c_str());
681 }
682 
EnableMock(IRunningLockAction * mockAction)683 void RunningLockMgr::EnableMock(IRunningLockAction* mockAction)
684 {
685     // reset lock list
686     runningLocks_.clear();
687     for (auto it = lockCounters_.begin(); it != lockCounters_.end(); it++) {
688         it->second->Clear();
689     }
690     proximityController_.Clear();
691 
692     std::shared_ptr<IRunningLockAction> mock(mockAction);
693     for (auto it = systemLocks_.begin(); it != systemLocks_.end(); it++) {
694         it->second->EnableMock(mock);
695     }
696     runningLockAction_ = mock;
697 }
698 
GetRunningLockTypeString(RunningLockType type)699 static const std::string GetRunningLockTypeString(RunningLockType type)
700 {
701     switch (type) {
702         case RunningLockType::RUNNINGLOCK_SCREEN:
703             return "SCREEN";
704         case RunningLockType::RUNNINGLOCK_BACKGROUND:
705             return "BACKGROUND";
706         case RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL:
707             return "PROXIMITY_SCREEN_CONTROL";
708         case RunningLockType::RUNNINGLOCK_BUTT:
709             return "BUTT";
710         default:
711             break;
712     }
713 
714     return "UNKNOWN";
715 }
716 
DumpInfo(std::string & result)717 void RunningLockMgr::DumpInfo(std::string& result)
718 {
719     auto validSize = GetValidRunningLockNum();
720     std::lock_guard<std::mutex> lock(mutex_);
721 
722     result.append("RUNNING LOCK DUMP:\n");
723     result.append("  totalSize=").append(ToString(runningLocks_.size()))
724             .append(" validSize=").append(ToString(validSize)).append("\n");
725     result.append("Summary By Type: \n");
726     for (auto it = lockCounters_.begin(); it != lockCounters_.end(); it++) {
727         result.append("  ")
728             .append(GetRunningLockTypeString(it->first))
729             .append(": ")
730             .append(ToString(it->second->GetCount()))
731             .append("\n");
732     }
733 
734     if (runningLocks_.empty()) {
735         result.append("Lock List is Empty. \n");
736         return;
737     }
738 
739     result.append("Dump Lock List: \n");
740     auto curTick = GetTickCount();
741     int index = 0;
742     for (auto& it : runningLocks_) {
743         index++;
744         auto lockInner = it.second;
745         if (lockInner == nullptr) {
746             return;
747         }
748         auto& lockinfo = lockInner->GetRunningLockInfo();
749         auto& ipcinfo = lockInner->GetUserIPCInfo();
750         result.append("  index=").append(ToString(index))
751             .append(" time=").append(ToString(curTick - lockInner->GetLockTimeMs()))
752             .append(" type=").append(GetRunningLockTypeString(lockinfo.type))
753             .append(" name=").append(lockinfo.name)
754             .append(" uid=").append(ToString(ipcinfo.uid))
755             .append(" pid=").append(ToString(ipcinfo.pid))
756             .append(" disable=").append(ToString(lockInner->GetDisabled()))
757             .append("\n");
758     }
759 
760     result.append("Peripherals Info: \n")
761             .append("  Proximity: ")
762             .append("Enabled=")
763             .append(ToString(proximityController_.IsEnabled()))
764             .append(" Status=")
765             .append(ToString(proximityController_.GetStatus()))
766             .append("\n");
767 }
768 
OnRemoteDied(const wptr<IRemoteObject> & remote)769 void RunningLockMgr::RunningLockDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
770 {
771     if (remote.promote() == nullptr) {
772         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Remote is nullptr");
773         return;
774     }
775     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
776     if (pms == nullptr) {
777         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Power service is nullptr");
778         return;
779     }
780     auto handler = pms->GetHandler();
781     if (handler == nullptr) {
782         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Handler is nullptr");
783         return;
784     }
785     std::function<void()> forceUnLockFunc = std::bind(&PowerMgrService::ForceUnLock, pms,
786         remote.promote());
787     handler->PostTask(forceUnLockFunc, TASK_RUNNINGLOCK_FORCEUNLOCK);
788 }
789 
Lock()790 void RunningLockMgr::SystemLock::Lock()
791 {
792     if (!locking_) {
793         action_->Lock(RunningLockType::RUNNINGLOCK_BUTT, tag_.c_str());
794         locking_ = true;
795     }
796 }
797 
Unlock()798 void RunningLockMgr::SystemLock::Unlock()
799 {
800     if (locking_) {
801         action_->Unlock(RunningLockType::RUNNINGLOCK_BUTT, tag_.c_str());
802         locking_ = false;
803     }
804 }
805 
Increase(const sptr<IRemoteObject> & remoteObj,std::shared_ptr<RunningLockInner> & lockInner)806 uint32_t RunningLockMgr::LockCounter::Increase(const sptr<IRemoteObject>& remoteObj,
807     std::shared_ptr<RunningLockInner>& lockInner)
808 {
809     ++counter_;
810     if (counter_ == 1) {
811         activate_(true);
812     }
813     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
814     if (pms == nullptr) {
815         POWER_HILOGW(FEATURE_RUNNING_LOCK, "No power service instance");
816         return counter_;
817     }
818     pms->GetRunningLockMgr()->NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_ADD);
819     return counter_;
820 }
821 
Decrease(const sptr<IRemoteObject> remoteObj,std::shared_ptr<RunningLockInner> & lockInner)822 uint32_t RunningLockMgr::LockCounter::Decrease(const sptr<IRemoteObject> remoteObj,
823     std::shared_ptr<RunningLockInner>& lockInner)
824 {
825     --counter_;
826     if (counter_ == 0) {
827         activate_(false);
828     }
829     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
830     if (pms == nullptr) {
831         POWER_HILOGW(FEATURE_RUNNING_LOCK, "No power service instance");
832         return counter_;
833     }
834     pms->GetRunningLockMgr()->NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_REMOVE);
835     return counter_;
836 }
837 
Clear()838 void RunningLockMgr::LockCounter::Clear()
839 {
840     counter_ = 0;
841 }
842 
RecordSensorCallback(SensorEvent * event)843 void RunningLockMgr::ProximityController::RecordSensorCallback(SensorEvent *event)
844 {
845     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Sensor Callback come in");
846     if (event == nullptr) {
847         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Sensor event is nullptr");
848         return;
849     }
850     if (event->sensorTypeId != SENSOR_TYPE_ID_PROXIMITY) {
851         POWER_HILOGW(FEATURE_RUNNING_LOCK, "Sensor type is not PROXIMITY");
852         return;
853     }
854     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
855     if (pms == nullptr) {
856         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Power service is nullptr");
857         return;
858     }
859     auto runningLock = pms->GetRunningLockMgr();
860     ProximityData* data = (ProximityData*)event->data;
861     int32_t distance = static_cast<int32_t>(data->distance);
862 
863     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Sensor Callback data->distance=%{public}d", distance);
864     if (distance == PROXIMITY_CLOSE_SCALAR) {
865         runningLock->SetProximity(PROXIMITY_CLOSE);
866     } else if (distance == PROXIMITY_AWAY_SCALAR) {
867         runningLock->SetProximity(PROXIMITY_AWAY);
868     }
869 }
870 
ProximityController()871 RunningLockMgr::ProximityController::ProximityController()
872 {
873     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Instance enter");
874     SensorInfo* sensorInfo = nullptr;
875     int32_t count;
876     int ret = GetAllSensors(&sensorInfo, &count);
877     if (ret != 0 || sensorInfo == nullptr) {
878         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Get sensors fail, ret=%{public}d", ret);
879         return;
880     }
881     for (int32_t i = 0; i < count; i++) {
882         if (sensorInfo[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY) {
883             POWER_HILOGD(FEATURE_RUNNING_LOCK, "Support PROXIMITY sensor");
884             support_ = true;
885             break;
886         }
887     }
888     if (!support_) {
889         POWER_HILOGE(FEATURE_RUNNING_LOCK, "PROXIMITY sensor not support");
890         return;
891     }
892     if (strcpy_s(user_.name, sizeof(user_.name), "RunningLock") != EOK) {
893         POWER_HILOGE(FEATURE_RUNNING_LOCK, "strcpy_s error");
894         return;
895     }
896     user_.userData = nullptr;
897     user_.callback = &RecordSensorCallback;
898 }
899 
~ProximityController()900 RunningLockMgr::ProximityController::~ProximityController()
901 {
902     if (support_) {
903         UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &user_);
904     }
905 }
906 
Enable()907 void RunningLockMgr::ProximityController::Enable()
908 {
909     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Enter");
910     enabled_ = true;
911     if (!support_) {
912         POWER_HILOGE(FEATURE_RUNNING_LOCK, "PROXIMITY sensor not support");
913         return;
914     }
915 
916     int32_t errorCode = SubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &user_);
917     if (errorCode != ERR_OK) {
918         POWER_HILOGW(FEATURE_RUNNING_LOCK, "SubscribeSensor PROXIMITY failed, errorCode=%{public}d", errorCode);
919         return;
920     }
921     SetBatch(SENSOR_TYPE_ID_PROXIMITY, &user_, SAMPLING_RATE, SAMPLING_RATE);
922     errorCode = ActivateSensor(SENSOR_TYPE_ID_PROXIMITY, &user_);
923     if (errorCode != ERR_OK) {
924         POWER_HILOGW(FEATURE_RUNNING_LOCK, "ActivateSensor PROXIMITY failed, errorCode=%{public}d", errorCode);
925         return;
926     }
927     SetMode(SENSOR_TYPE_ID_PROXIMITY, &user_, SENSOR_ON_CHANGE);
928 }
929 
Disable()930 void RunningLockMgr::ProximityController::Disable()
931 {
932     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Enter");
933     enabled_ = false;
934     if (!support_) {
935         POWER_HILOGE(FEATURE_RUNNING_LOCK, "PROXIMITY sensor not support");
936         return;
937     }
938 
939     DeactivateSensor(SENSOR_TYPE_ID_PROXIMITY, &user_);
940     int32_t errorCode = UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &user_);
941     if (errorCode != ERR_OK) {
942         POWER_HILOGW(FEATURE_RUNNING_LOCK, "UnsubscribeSensor PROXIMITY failed, errorCode=%{public}d", errorCode);
943     }
944 }
945 
IsClose()946 bool RunningLockMgr::ProximityController::IsClose()
947 {
948     POWER_HILOGD(FEATURE_RUNNING_LOCK, "PROXIMITY IsClose: %{public}d", isClose);
949     return isClose;
950 }
951 
OnClose()952 void RunningLockMgr::ProximityController::OnClose()
953 {
954     if (!enabled_ || IsClose()) {
955         POWER_HILOGD(FEATURE_RUNNING_LOCK, "PROXIMITY is disabled or closed already");
956         return;
957     }
958     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
959     if (pms == nullptr) {
960         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Power service is nullptr");
961         return;
962     }
963     auto stateMachine = pms->GetPowerStateMachine();
964     if (stateMachine == nullptr) {
965         POWER_HILOGE(FEATURE_RUNNING_LOCK, "state machine is nullptr");
966         return;
967     }
968     isClose = true;
969     POWER_HILOGD(FEATURE_RUNNING_LOCK, "PROXIMITY is closed");
970     auto runningLock = pms->GetRunningLockMgr();
971     if (runningLock->GetValidRunningLockNum(
972         RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL) > 0) {
973         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Change state to INACITVE when holding PROXIMITY LOCK");
974 #ifdef HAS_DISPLAY_MANAGER_PART
975         Rosen::ScreenManager::GetInstance().SetScreenPowerForAll(Rosen::ScreenPowerState::POWER_OFF,
976             Rosen::PowerStateChangeReason::POWER_BUTTON);
977 #endif
978     }
979 }
980 
OnAway()981 void RunningLockMgr::ProximityController::OnAway()
982 {
983     if (!enabled_ || !IsClose()) {
984         POWER_HILOGD(FEATURE_RUNNING_LOCK, "PROXIMITY is disabled or away already");
985         return;
986     }
987     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
988     if (pms == nullptr) {
989         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Power service is nullptr");
990         return;
991     }
992     auto stateMachine = pms->GetPowerStateMachine();
993     if (stateMachine == nullptr) {
994         POWER_HILOGE(FEATURE_RUNNING_LOCK, "state machine is nullptr");
995         return;
996     }
997     isClose = false;
998     POWER_HILOGD(FEATURE_RUNNING_LOCK, "PROXIMITY is away");
999     auto runningLock = pms->GetRunningLockMgr();
1000     if (runningLock->GetValidRunningLockNum(
1001         RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL) > 0) {
1002         POWER_HILOGD(FEATURE_RUNNING_LOCK, "Change state to AWAKE when holding PROXIMITY LOCK");
1003 #ifdef HAS_DISPLAY_MANAGER_PART
1004         Rosen::ScreenManager::GetInstance().SetScreenPowerForAll(Rosen::ScreenPowerState::POWER_ON,
1005             Rosen::PowerStateChangeReason::POWER_BUTTON);
1006 #endif
1007     }
1008 }
1009 
Clear()1010 void RunningLockMgr::ProximityController::Clear()
1011 {
1012     isClose = false;
1013 }
1014 
SetProximity(uint32_t status)1015 void RunningLockMgr::SetProximity(uint32_t status)
1016 {
1017     switch (status) {
1018         case PROXIMITY_CLOSE:
1019             proximityController_.OnClose();
1020             break;
1021         case PROXIMITY_AWAY:
1022             proximityController_.OnAway();
1023             break;
1024         default:
1025             break;
1026     }
1027 }
1028 } // namespace PowerMgr
1029 } // namespace OHOS
1030