• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "idle_time.h"
17 
18 #include "hilog_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             HILOG_ERROR("Create VSync receiver failed.");
51             return;
52         }
53         receiver_->Init();
54     }
55 }
56 
EventTask()57 void IdleTime::EventTask()
58 {
59     if (receiver_ == nullptr) {
60         HILOG_ERROR("no VSyncReceiver.");
61         return;
62     }
63 
64     if (callback_ == nullptr) {
65         HILOG_ERROR("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     HILOG_DEBUG("EventTask period %{public}" PRId64 ", lastVSyncTime is %{public}" PRId64, period, lastVSyncTime);
73     int64_t occurTimestamp = GetSysTimeNs();
74     if (GSERROR_OK == err && period > 0 && lastVSyncTime > 0 && occurTimestamp > lastVSyncTime) {
75         int64_t elapsedTime = occurTimestamp - lastVSyncTime;
76         int64_t idleTime = period - (elapsedTime % period) ;
77         int64_t cycle = elapsedTime / period ;
78         HILOG_DEBUG("EventTask idleTime %{public}" PRId64 ", cycle is %{public}" PRId64, idleTime, cycle);
79         if (idleTime > 0 && cycle < MAX_PERIOD_COUNT) {
80             HILOG_DEBUG("callback_");
81             callback_(idleTime / MS_PER_NS);
82         }
83     }
84     PostTask();
85 }
86 
PostTask()87 void IdleTime::PostTask()
88 {
89     if (needStop_) {
90         return;
91     }
92 
93     if (eventHandler_ == nullptr) {
94         HILOG_ERROR("eventHandler_ is nullptr.");
95         return;
96     }
97     std::weak_ptr<IdleTime> weak(shared_from_this());
98     auto task = [weak]() {
99         auto idleTime = weak.lock();
100         if (idleTime == nullptr) {
101             HILOG_ERROR("idleTime is nullptr.");
102             return;
103         }
104         idleTime->EventTask();
105     };
106     eventHandler_->PostTask(task, "IdleTime:PostTask", 0, EventQueue::Priority::IDLE);
107 }
108 
Start()109 void IdleTime::Start()
110 {
111     InitVSyncReceiver();
112     PostTask();
113 }
114 
SetNeedStop(bool needStop)115 void IdleTime::SetNeedStop(bool needStop)
116 {
117     needStop_ = needStop;
118 }
119 
GetNeedStop()120 bool IdleTime::GetNeedStop()
121 {
122     return needStop_;
123 }
124 
GetIdleNotifyFunc()125 IdleNotifyStatusCallback IdleTime::GetIdleNotifyFunc()
126 {
127     IdleNotifyStatusCallback cb = [this](bool needStop) {
128         if (this->GetNeedStop() == needStop) {
129             return;
130         }
131 
132         this->SetNeedStop(needStop);
133         if (needStop == false) {
134             this->Start();
135         }
136     };
137     return cb;
138 }
139 } // AppExecFwk
140 } // namespace OHOS