1 /*
2 * Copyright (c) 2022-2024 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 "idle_time.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "transaction/rs_interfaces.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 constexpr int64_t MS_PER_NS = 1000000;
25 constexpr int32_t MAX_PERIOD_COUNT = 10;
26 }
27
IdleTime(const std::shared_ptr<EventHandler> & eventHandler,IdleTimeCallback idleTimeCallback)28 IdleTime::IdleTime(const std::shared_ptr<EventHandler> &eventHandler, IdleTimeCallback idleTimeCallback)
29 {
30 eventHandler_ = eventHandler;
31 callback_ = idleTimeCallback;
32 }
33
GetSysTimeNs()34 int64_t IdleTime::GetSysTimeNs()
35 {
36 auto now = std::chrono::steady_clock::now().time_since_epoch();
37 return std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
38 }
39
InitVSyncReceiver()40 void IdleTime::InitVSyncReceiver()
41 {
42 if (needStop_) {
43 return;
44 }
45
46 if (receiver_ == nullptr) {
47 auto& rsClient = Rosen::RSInterfaces::GetInstance();
48 receiver_ = rsClient.CreateVSyncReceiver("ABILITY", eventHandler_);
49 if (receiver_ == nullptr) {
50 TAG_LOGE(AAFwkTag::APPKIT, "Create VSync receiver failed");
51 return;
52 }
53 receiver_->Init();
54 }
55 }
56
EventTask()57 void IdleTime::EventTask()
58 {
59 if (receiver_ == nullptr) {
60 TAG_LOGE(AAFwkTag::APPKIT, "no VSyncReceiver");
61 return;
62 }
63
64 if (callback_ == nullptr) {
65 TAG_LOGE(AAFwkTag::APPKIT, "no callback_");
66 return;
67 }
68
69 int64_t period = 0;
70 int64_t lastVSyncTime = 0;
71 VsyncError err = receiver_->GetVSyncPeriodAndLastTimeStamp(period, lastVSyncTime, true);
72 TAG_LOGD(AAFwkTag::APPKIT, "EventTask period %{public}" PRId64 ", lastVSyncTime is %{public}" PRId64, period,
73 lastVSyncTime);
74 int64_t occurTimestamp = GetSysTimeNs();
75 if (GSERROR_OK == err && period > 0 && lastVSyncTime > 0 && occurTimestamp > lastVSyncTime) {
76 int64_t elapsedTime = occurTimestamp - lastVSyncTime;
77 int64_t idleTime = period - (elapsedTime % period) ;
78 int64_t cycle = elapsedTime / period ;
79 TAG_LOGD(
80 AAFwkTag::APPKIT, "EventTask idleTime %{public}" PRId64 ", cycle is %{public}" PRId64, idleTime, cycle);
81 if (idleTime > 0 && cycle < MAX_PERIOD_COUNT) {
82 TAG_LOGD(AAFwkTag::APPKIT, "callback_");
83 callback_(idleTime / MS_PER_NS);
84 }
85 }
86 PostTask();
87 }
88
PostTask()89 void IdleTime::PostTask()
90 {
91 if (needStop_) {
92 return;
93 }
94
95 if (eventHandler_ == nullptr) {
96 TAG_LOGE(AAFwkTag::APPKIT, "eventHandler_ is nullptr");
97 return;
98 }
99 std::weak_ptr<IdleTime> weak(shared_from_this());
100 auto task = [weak]() {
101 auto idleTime = weak.lock();
102 if (idleTime == nullptr) {
103 TAG_LOGE(AAFwkTag::APPKIT, "idleTime is nullptr");
104 return;
105 }
106 idleTime->EventTask();
107 };
108 eventHandler_->PostTask(task, "IdleTime:PostTask", 0, EventQueue::Priority::IDLE);
109 }
110
Start()111 void IdleTime::Start()
112 {
113 InitVSyncReceiver();
114 PostTask();
115 }
116
SetNeedStop(bool needStop)117 void IdleTime::SetNeedStop(bool needStop)
118 {
119 needStop_ = needStop;
120 }
121
GetNeedStop()122 bool IdleTime::GetNeedStop()
123 {
124 return needStop_;
125 }
126
GetIdleNotifyFunc()127 IdleNotifyStatusCallback IdleTime::GetIdleNotifyFunc()
128 {
129 IdleNotifyStatusCallback cb = [this](bool needStop) {
130 if (this->GetNeedStop() == needStop) {
131 return;
132 }
133
134 this->SetNeedStop(needStop);
135 if (needStop == false) {
136 this->Start();
137 }
138 };
139 return cb;
140 }
141 } // AppExecFwk
142 } // namespace OHOS