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 "screen_saver_handler.h"
17 
18 #include <thread>
19 
20 #include <element_name.h>
21 #include <samgr_lite.h>
22 #include <securec.h>
23 #include <want.h>
24 
25 #include "hilog_wrapper.h"
26 #include "running_lock_mgr.h"
27 
28 static const int32_t DELAY_TIME = 20;
29 
30 namespace OHOS {
~ScreenSaverHandler()31 ScreenSaverHandler::~ScreenSaverHandler()
32 {
33     if (timer_ != nullptr) {
34         PowerMgrDestroyTimer(timer_);
35         timer_ = nullptr;
36     }
37 }
38 
GetAmsInterface()39 AmsInterface *ScreenSaverHandler::GetAmsInterface()
40 {
41     static struct AmsInterface *ams = nullptr;
42     if (ams != nullptr) {
43         return ams;
44     }
45 
46     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_FEATURE);
47     if (iUnknown == nullptr) {
48         POWER_HILOGE("Failed to get ams iUnknown");
49         return nullptr;
50     }
51 
52     int ret = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&ams);
53     if ((ret != EC_SUCCESS) || (ams == nullptr)) {
54         POWER_HILOGE("Failed to query ams interface");
55         return nullptr;
56     }
57     POWER_HILOGI("Succeed to get ams interface");
58     return ams;
59 }
60 
StartScreenSaverLocked()61 bool ScreenSaverHandler::StartScreenSaverLocked()
62 {
63     AmsInterface *ams = GetAmsInterface();
64     if (ams == nullptr) {
65         POWER_HILOGE("Failed to get ams interface");
66         return false;
67     }
68 
69     Want want = { nullptr };
70     ElementName element = { nullptr };
71     SetElementBundleName(&element, "com.huawei.screensaver");
72     SetElementAbilityName(&element, "ScreensaverAbility");
73     SetWantElement(&want, element);
74     SetWantData(&want, "WantData", strlen("WantData") + 1);
75     int32_t ret = ams->StartAbility(&want);
76     ClearElement(&element);
77     ClearWant(&want);
78     return ret == EC_SUCCESS;
79 }
80 
StartScreenSaver()81 void ScreenSaverHandler::StartScreenSaver()
82 {
83     POWER_HILOGI("Time to start screen saver");
84     std::lock_guard<std::mutex> lock(mutex_);
85     if (!enabled_ || screenSaverStarted_ || (RunningLockMgrIsLockHolding(RUNNINGLOCK_SCREEN) == TRUE)) {
86         return;
87     }
88     screenSaverStarted_ = StartScreenSaverLocked();
89     POWER_HILOGI("Start screen saver: %d", static_cast<int32_t>(screenSaverStarted_));
90 }
91 
PowerTimerCallback(void * data)92 void PowerTimerCallback(void *data)
93 {
94     if (data == nullptr) {
95         POWER_HILOGE("Invalid timer data");
96         return;
97     }
98     ScreenSaverHandler *handler = static_cast<ScreenSaverHandler *>(data);
99     handler->StartScreenSaver();
100 }
101 
Init()102 void ScreenSaverHandler::Init()
103 {
104     if (timer_ == nullptr) {
105         timer_ = PowerMgrCreateTimer(intervalMsec_, intervalMsec_, PowerTimerCallback);
106     }
107     std::thread lateInit([this] {
108         sleep(DELAY_TIME); // set delay to avoid registing input evnet listener failure
109         SetState(true);
110     });
111     lateInit.detach();
112 }
113 
SetInterval(int64_t intervalMsec)114 void ScreenSaverHandler::SetInterval(int64_t intervalMsec)
115 {
116     std::lock_guard<std::mutex> lock(mutex_);
117     if (intervalMsec_ == intervalMsec) {
118         return;
119     }
120     if (timer_ != nullptr) {
121         PowerMgrResetTimer(timer_, intervalMsec, intervalMsec);
122         if (enabled_) {
123             SetEnableLocked();
124         }
125     }
126     intervalMsec_ = intervalMsec;
127 }
128 
SetEnableLocked()129 bool ScreenSaverHandler::SetEnableLocked()
130 {
131     if (PowerMgrStartTimer(timer_, (void *)this) == FALSE) {
132         POWER_HILOGE("Failed to start timer");
133         return false;
134     }
135 
136     if (!InputEventListenerProxy::GetInstance()->RegisterInputEventListener(this)) {
137         PowerMgrStopTimer(timer_);
138         POWER_HILOGE("Failed to register input event listener");
139         return false;
140     }
141 
142     POWER_HILOGI("Succeed to enable screen saver");
143     return true;
144 }
145 
SetDisableLocked()146 bool ScreenSaverHandler::SetDisableLocked()
147 {
148     InputEventListenerProxy::GetInstance()->UnregisterInputEventListener();
149 
150     PowerMgrStopTimer(timer_);
151     POWER_HILOGI("Succeed to disable screen saver");
152     return true;
153 }
154 
SetState(bool enable)155 int32_t ScreenSaverHandler::SetState(bool enable)
156 {
157     std::lock_guard<std::mutex> lock(mutex_);
158     if (timer_ == nullptr) {
159         return EC_FAILURE;
160     }
161     if (enabled_ == enable) {
162         return EC_SUCCESS;
163     }
164     bool ret = enable ? SetEnableLocked() : SetDisableLocked();
165     if (!ret) {
166         POWER_HILOGE("Failed to set state: %d", static_cast<int32_t>(enable));
167         return EC_FAILURE;
168     }
169     enabled_ = enable;
170     return EC_SUCCESS;
171 }
172 
OnRawEvent(const RawEvent & event)173 void ScreenSaverHandler::OnRawEvent(const RawEvent &event)
174 {
175     static int64_t lastUpdateTime = 0;
176     std::lock_guard<std::mutex> lock(mutex_);
177     screenSaverStarted_ = false;
178     int64_t currentTime = GetCurrentTimeMsec(CLOCK_MONOTONIC);
179     if ((currentTime - lastUpdateTime) > MSEC_PER_SEC) {
180         PowerMgrRestartTimer(timer_, (void *)this);
181         lastUpdateTime = currentTime;
182     }
183 }
184 } // namespace OHOS
185