• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 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 "deferred_photo_controller.h"
17 
18 #include "basic_definitions.h"
19 #include "dp_timer.h"
20 #include "dp_utils.h"
21 #include "dp_log.h"
22 #include "events_monitor.h"
23 #include "dps_event_report.h"
24 
25 namespace OHOS {
26 namespace CameraStandard {
27 
28 namespace {
29     constexpr int32_t DURATIONMS_500 = 500;
30 }
31 
32 namespace DeferredProcessing {
33 
34 class DeferredPhotoController::EventsListener : public IEventsListener {
35 public:
EventsListener(const std::weak_ptr<DeferredPhotoController> & controller)36     explicit EventsListener(const std::weak_ptr<DeferredPhotoController>& controller)
37         : controller_(controller)
38     {
39         DP_DEBUG_LOG("entered");
40     }
41     ~EventsListener() = default;
42 
OnEventChange(EventType event,int32_t value)43     void OnEventChange(EventType event, int32_t value) override
44     {
45         DP_INFO_LOG("entered, event: %{public}d", event);
46         auto controller = controller_.lock();
47         DP_CHECK_ERROR_RETURN_LOG(controller == nullptr, "photo controller is nullptr.");
48         switch (event) {
49             case EventType::CAMERA_SESSION_STATUS_EVENT:
50                 controller->NotifyCameraStatusChanged(static_cast<CameraSessionStatus>(value));
51                 break;
52             case EventType::PHOTO_HDI_STATUS_EVENT:
53                 controller->NotifyHdiStatusChanged(static_cast<HdiStatus>(value));
54                 break;
55             case EventType::MEDIA_LIBRARY_STATUS_EVENT:
56                 controller->NotifyMediaLibStatusChanged(static_cast<MediaLibraryStatus>(value));
57                 break;
58             case EventType::THERMAL_LEVEL_STATUS_EVENT:
59                 controller->NotifyPressureLevelChanged(ConvertPressureLevel(value));
60                 break;
61             default:
62                 break;
63         }
64         DPSEventReport::GetInstance().SetEventType(event);
65     }
66 
67 private:
68     std::weak_ptr<DeferredPhotoController> controller_;
69 
ConvertPressureLevel(int32_t level)70     SystemPressureLevel ConvertPressureLevel(int32_t level)
71     {
72         if (level < LEVEL_0 || level > LEVEL_5) {
73             return SystemPressureLevel::SEVERE;
74         }
75         SystemPressureLevel eventLevel = SystemPressureLevel::SEVERE;
76         switch (level) {
77             case LEVEL_0:
78             case LEVEL_1:
79                 eventLevel = SystemPressureLevel::NOMINAL;
80                 break;
81             case LEVEL_2:
82             case LEVEL_3:
83             case LEVEL_4:
84                 eventLevel = SystemPressureLevel::FAIR;
85                 break;
86             default:
87                 eventLevel = SystemPressureLevel::SEVERE;
88                 break;
89         }
90         return eventLevel;
91     }
92 };
93 
94 class DeferredPhotoController::PhotoJobRepositoryListener : public IPhotoJobRepositoryListener {
95 public:
PhotoJobRepositoryListener(const std::weak_ptr<DeferredPhotoController> & controller)96     explicit PhotoJobRepositoryListener(const std::weak_ptr<DeferredPhotoController>& controller)
97         : controller_(controller)
98     {
99         DP_DEBUG_LOG("entered");
100     }
101     ~PhotoJobRepositoryListener() = default;
102 
OnPhotoJobChanged(bool priorityChanged,bool statusChanged,DeferredPhotoJobPtr jobPtr)103     void OnPhotoJobChanged(bool priorityChanged, bool statusChanged, DeferredPhotoJobPtr jobPtr) override
104     {
105         auto controller = controller_.lock();
106         DP_CHECK_ERROR_RETURN_LOG(controller == nullptr, "photo controller is nullptr.");
107         controller->OnPhotoJobChanged(priorityChanged, statusChanged, jobPtr);
108     }
109 
110 private:
111     std::weak_ptr<DeferredPhotoController> controller_;
112 };
113 
DeferredPhotoController(const int32_t userId,const std::shared_ptr<PhotoJobRepository> & repository,const std::shared_ptr<DeferredPhotoProcessor> & processor)114 DeferredPhotoController::DeferredPhotoController(const int32_t userId,
115     const std::shared_ptr<PhotoJobRepository>& repository, const std::shared_ptr<DeferredPhotoProcessor>& processor)
116     : userId_(userId),
117       scheduleState_(DpsStatus::DPS_SESSION_STATE_IDLE),
118       photoJobRepository_(repository),
119       photoProcessor_(processor)
120 {
121     DP_DEBUG_LOG("entered, userid: %{public}d", userId_);
122 }
123 
~DeferredPhotoController()124 DeferredPhotoController::~DeferredPhotoController()
125 {
126     DP_DEBUG_LOG("entered, userid: %{public}d", userId_);
127 }
128 
Initialize()129 void DeferredPhotoController::Initialize()
130 {
131     DP_DEBUG_LOG("entered, userid: %{public}d", userId_);
132     //创建策略
133     userInitiatedStrategy_ = std::make_unique<UserInitiatedStrategy>(photoJobRepository_);
134     backgroundStrategy_ = std::make_unique<BackgroundStrategy>(photoJobRepository_);
135     //注册事件监听
136     eventsListener_ = std::make_shared<EventsListener>(weak_from_this());
137     EventsMonitor::GetInstance().RegisterEventsListener(userId_, {
138         EventType::CAMERA_SESSION_STATUS_EVENT,
139         EventType::PHOTO_HDI_STATUS_EVENT,
140         EventType::MEDIA_LIBRARY_STATUS_EVENT,
141         EventType::THERMAL_LEVEL_STATUS_EVENT},
142         eventsListener_);
143     //注册任务监听
144     photoJobRepositoryListener_ = std::make_shared<PhotoJobRepositoryListener>(weak_from_this());
145     photoJobRepository_->RegisterJobListener(photoJobRepositoryListener_);
146     photoProcessor_->Initialize();
147 }
148 
TryDoSchedule()149 void DeferredPhotoController::TryDoSchedule()
150 {
151     auto work = userInitiatedStrategy_->GetWork();
152     DP_INFO_LOG("DPS_PHOTO: UserInitiated get work: %{public}d", work != nullptr);
153     if (work != nullptr) {
154         StopWaitForUser();
155     }
156 
157     if (work == nullptr && timeId_ == INVALID_TIMEID) {
158         work = backgroundStrategy_->GetWork();
159         DP_INFO_LOG("DPS_PHOTO: Background get work: %{public}d", work != nullptr);
160     }
161 
162     DP_INFO_LOG("all strategy get work: %{public}d", work != nullptr);
163     NotifyScheduleState(work != nullptr);
164     if (work == nullptr) {
165         if (photoJobRepository_->GetRunningJobCounts() == 0) {
166             // 重置底层性能模式,避免功耗增加
167             SetDefaultExecutionMode();
168         }
169         return;
170     }
171 
172     if ((photoJobRepository_->GetRunningJobCounts()) < (photoProcessor_->GetConcurrency(work->GetExecutionMode()))) {
173         PostProcess(work);
174     }
175 }
176 
PostProcess(std::shared_ptr<DeferredPhotoWork> work)177 void DeferredPhotoController::PostProcess(std::shared_ptr<DeferredPhotoWork> work)
178 {
179     DP_DEBUG_LOG("entered");
180     photoProcessor_->PostProcess(work);
181 }
182 
SetDefaultExecutionMode()183 void DeferredPhotoController::SetDefaultExecutionMode()
184 {
185     DP_DEBUG_LOG("entered");
186     photoProcessor_->SetDefaultExecutionMode();
187 }
188 
NotifyPressureLevelChanged(SystemPressureLevel level)189 void DeferredPhotoController::NotifyPressureLevelChanged(SystemPressureLevel level)
190 {
191     backgroundStrategy_->NotifyPressureLevelChanged(level);
192     TryDoSchedule();
193 }
194 
NotifyHdiStatusChanged(HdiStatus status)195 void DeferredPhotoController::NotifyHdiStatusChanged(HdiStatus status)
196 {
197     userInitiatedStrategy_->NotifyHdiStatusChanged(status);
198     backgroundStrategy_->NotifyHdiStatusChanged(status);
199     TryDoSchedule();
200 }
201 
NotifyMediaLibStatusChanged(MediaLibraryStatus status)202 void DeferredPhotoController::NotifyMediaLibStatusChanged(MediaLibraryStatus status)
203 {
204     userInitiatedStrategy_->NotifyMediaLibStatusChanged(status);
205     backgroundStrategy_->NotifyMediaLibStatusChanged(status);
206     if (status == MediaLibraryStatus::MEDIA_LIBRARY_AVAILABLE) {
207         TryDoSchedule();
208     }
209 }
210 
NotifyCameraStatusChanged(CameraSessionStatus status)211 void DeferredPhotoController::NotifyCameraStatusChanged(CameraSessionStatus status)
212 {
213     userInitiatedStrategy_->NotifyCameraStatusChanged(status);
214     backgroundStrategy_->NotifyCameraStatusChanged(status);
215     if (status == CameraSessionStatus::SYSTEM_CAMERA_OPEN || status == CameraSessionStatus::NORMAL_CAMERA_OPEN) {
216         photoProcessor_->Interrupt();
217         scheduleState_ = DpsStatus::DPS_SESSION_STATE_PREEMPTED;
218         photoProcessor_->NotifyScheduleState(scheduleState_);
219     }
220     if (status == CameraSessionStatus::SYSTEM_CAMERA_CLOSED || status == CameraSessionStatus::NORMAL_CAMERA_CLOSED) {
221         TryDoSchedule();
222     }
223 }
224 
225 //来自任务仓库的事件
OnPhotoJobChanged(bool priorityChanged,bool statusChanged,DeferredPhotoJobPtr jobPtr)226 void DeferredPhotoController::OnPhotoJobChanged(bool priorityChanged, bool statusChanged, DeferredPhotoJobPtr jobPtr)
227 {
228     DP_INFO_LOG("DPS_PHOTO: priorityChanged: %{public}d, statusChanged: %{public}d, imageId: %{public}s",
229         priorityChanged, statusChanged, jobPtr->GetImageId().c_str());
230     if (priorityChanged && statusChanged) {
231         if (jobPtr->GetPrePriority() == PhotoJobPriority::HIGH && jobPtr->GetPreStatus() == PhotoJobStatus::RUNNING) {
232             StartWaitForUser();
233         }
234     }
235     TryDoSchedule();
236 }
237 
StartWaitForUser()238 void DeferredPhotoController::StartWaitForUser()
239 {
240     timeId_ = DpsTimer::GetInstance().StartTimer([&]() {
241         DP_INFO_LOG("DPS_TIMER: WaitForUser try do schedule, timeId: %{public}u", timeId_);
242         timeId_ = INVALID_TIMEID;
243         TryDoSchedule();
244     }, DURATIONMS_500);
245     DP_INFO_LOG("DPS_TIMER: StartWaitForUser timeId: %{public}u", timeId_);
246 }
247 
StopWaitForUser()248 void DeferredPhotoController::StopWaitForUser()
249 {
250     DP_INFO_LOG("DPS_TIMER: StopWaitForUser timeId: %{public}u", timeId_);
251     DpsTimer::GetInstance().StopTimer(timeId_);
252 }
253 
NotifyScheduleState(bool workAvailable)254 void DeferredPhotoController::NotifyScheduleState(bool workAvailable)
255 {
256     DP_INFO_LOG("entered, workAvailable: %{public}d", workAvailable);
257     DpsStatus scheduleState = DpsStatus::DPS_SESSION_STATE_IDLE;
258     if (workAvailable || photoJobRepository_->GetRunningJobCounts() > 0) {
259         scheduleState = DpsStatus::DPS_SESSION_STATE_RUNNING;
260     } else {
261         if (photoJobRepository_->GetOfflineIdleJobSize() == 0) {
262             scheduleState = DpsStatus::DPS_SESSION_STATE_IDLE;
263         } else {
264             if (backgroundStrategy_->GetHdiStatus() != HdiStatus::HDI_READY) {
265                 scheduleState = DpsStatus::DPS_SESSION_STATE_SUSPENDED;
266             } else {
267                 scheduleState = DpsStatus::DPS_SESSION_STATE_RUNNALBE;
268             }
269         }
270     }
271     DP_INFO_LOG("entered, scheduleState_: %{public}d, scheduleState: %{public}d", scheduleState_, scheduleState);
272     if (scheduleState != scheduleState_) {
273         scheduleState_ = scheduleState;
274         photoProcessor_->NotifyScheduleState(scheduleState_);
275     }
276 }
277 } // namespace DeferredProcessing
278 } // namespace CameraStandard
279 } // namespace OHOS