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 "video_strategy_center.h"
17
18 #include "battery_level_strategy.h"
19 #include "dp_log.h"
20 #include "dps_event_report.h"
21 #include "events_info.h"
22 #include "events_monitor.h"
23 #include "ivideo_state_change_listener.h"
24 #include "video_battery_level_state.h"
25 #include "video_battery_state.h"
26 #include "video_camera_state.h"
27 #include "video_charging_state.h"
28 #include "video_hal_state.h"
29 #include "video_media_library_state.h"
30 #include "video_photo_process_state.h"
31 #include "video_screen_state.h"
32 #include "video_temperature_state.h"
33
34 namespace OHOS {
35 namespace CameraStandard {
36 namespace DeferredProcessing {
37 namespace {
38 constexpr uint32_t SINGLE_TIME_LIMIT = 0b1;
39 constexpr uint32_t TOTAL_TIME_LIMIT = 0b10;
40 constexpr int32_t DEFAULT_TIME = 0;
41 }
42
43 class VideoStrategyCenter::EventsListener : public IEventsListener {
44 public:
EventsListener(const std::weak_ptr<VideoStrategyCenter> & strategyCenter)45 explicit EventsListener(const std::weak_ptr<VideoStrategyCenter>& strategyCenter)
46 : strategyCenter_(strategyCenter)
47 {
48 DP_DEBUG_LOG("entered");
49 }
50
~EventsListener()51 ~EventsListener()
52 {
53 DP_DEBUG_LOG("entered");
54 }
55
OnEventChange(EventType event,int32_t value)56 void OnEventChange(EventType event, int32_t value) override
57 {
58 DP_DEBUG_LOG("entered, event: %{public}d", event);
59 auto strategy = strategyCenter_.lock();
60 DP_CHECK_ERROR_RETURN_LOG(strategy == nullptr, "VideoStrategyCenter is nullptr.");
61 strategy->HandleEventChanged(event, value);
62 DPSEventReport::GetInstance().SetEventType(event);
63 }
64
65 private:
66 std::weak_ptr<VideoStrategyCenter> strategyCenter_;
67 };
68
VideoStrategyCenter(const int32_t userId,const std::shared_ptr<VideoJobRepository> & repository)69 VideoStrategyCenter::VideoStrategyCenter(const int32_t userId, const std::shared_ptr<VideoJobRepository>& repository)
70 : userId_(userId), videoJobRepository_(repository)
71 {
72 DP_INFO_LOG("entered");
73 }
74
~VideoStrategyCenter()75 VideoStrategyCenter::~VideoStrategyCenter()
76 {
77 DP_INFO_LOG("entered");
78 eventsListener_ = nullptr;
79 eventHandlerList_.clear();
80 scheduleStateList_.clear();
81 videoJobRepository_ = nullptr;
82 }
83
Initialize()84 void VideoStrategyCenter::Initialize()
85 {
86 DP_INFO_LOG("entered");
87 InitHandleEvent();
88 InitScheduleState();
89 eventsListener_ = std::make_shared<EventsListener>(weak_from_this());
90 EventsMonitor::GetInstance().RegisterEventsListener(userId_, {
91 EventType::CAMERA_SESSION_STATUS_EVENT,
92 EventType::HDI_STATUS_EVENT,
93 EventType::MEDIA_LIBRARY_STATUS_EVENT,
94 EventType::THERMAL_LEVEL_STATUS_EVENT,
95 EventType::SCREEN_STATUS_EVENT,
96 EventType::BATTERY_STATUS_EVENT,
97 EventType::BATTERY_LEVEL_STATUS_EVENT,
98 EventType::CHARGING_STATUS_EVENT,
99 EventType::PHOTO_PROCESS_STATUS_EVENT},
100 eventsListener_);
101 }
102
InitHandleEvent()103 void VideoStrategyCenter::InitHandleEvent()
104 {
105 DP_INFO_LOG("entered");
106 eventHandlerList_.insert({CAMERA_SESSION_STATUS_EVENT, [this](int32_t value){HandleCameraEvent(value);}});
107 eventHandlerList_.insert({HDI_STATUS_EVENT, [this](int32_t value){HandleHalEvent(value);}});
108 eventHandlerList_.insert({MEDIA_LIBRARY_STATUS_EVENT, [this](int32_t value){HandleMedialLibraryEvent(value);}});
109 eventHandlerList_.insert({SCREEN_STATUS_EVENT, [this](int32_t value){HandleScreenEvent(value);}});
110 eventHandlerList_.insert({CHARGING_STATUS_EVENT, [this](int32_t value){HandleChargingEvent(value);}});
111 eventHandlerList_.insert({BATTERY_STATUS_EVENT, [this](int32_t value){HandleBatteryEvent(value);}});
112 eventHandlerList_.insert({BATTERY_LEVEL_STATUS_EVENT, [this](int32_t value){HandleBatteryLevelEvent(value);}});
113 eventHandlerList_.insert({THERMAL_LEVEL_STATUS_EVENT, [this](int32_t value){HandleTemperatureEvent(value);}});
114 eventHandlerList_.insert({PHOTO_PROCESS_STATUS_EVENT, [this](int32_t value){HandlePhotoProcessEvent(value);}});
115 }
116
InitScheduleState()117 void VideoStrategyCenter::InitScheduleState()
118 {
119 DP_INFO_LOG("entered");
120 auto state = EventsInfo::GetInstance().GetChargingState();
121 isCharging_ = state == ChargingStatus::CHARGING;
122 scheduleStateList_.insert({CAMERA_STATE,
123 std::make_shared<VideoCameraState>(CameraSessionStatus::SYSTEM_CAMERA_CLOSED)});
124 scheduleStateList_.insert({HDI_STATE,
125 std::make_shared<VideoHalState>(HdiStatus::HDI_READY)});
126 scheduleStateList_.insert({MEDIA_LIBRARY_STATE,
127 std::make_shared<VideoMediaLibraryState>(MediaLibraryStatus::MEDIA_LIBRARY_AVAILABLE)});
128 scheduleStateList_.insert({SCREEN_STATE,
129 std::make_shared<VideoScreenState>(EventsInfo::GetInstance().GetScreenState())});
130 scheduleStateList_.insert({CHARGING_STATE,
131 std::make_shared<VideoChargingState>(state)});
132 scheduleStateList_.insert({BATTERY_STATE,
133 std::make_shared<VideoBatteryState>(EventsInfo::GetInstance().GetBatteryState())});
134 scheduleStateList_.insert({BATTERY_LEVEL_STATE,
135 std::make_shared<VideoBatteryLevelState>(EventsInfo::GetInstance().GetBatteryLevel())});
136 scheduleStateList_.insert({THERMAL_LEVEL_STATE,
137 std::make_shared<VideoTemperatureState>(ConvertThermalLevel(EventsInfo::GetInstance().GetThermalLevel()))});
138 scheduleStateList_.insert({PHOTO_PROCESS_STATE,
139 std::make_shared<VideoPhotoProcessState>(PhotoProcessStatus::IDLE)});
140 for (const auto& item : scheduleStateList_) {
141 if (item.second == nullptr) {
142 DP_ERR_LOG("schedule state init failed, type: %{public}d", item.first);
143 continue;
144 }
145 item.second->Initialize();
146 }
147 }
148
HandleEventChanged(EventType event,int32_t value)149 void VideoStrategyCenter::HandleEventChanged(EventType event, int32_t value)
150 {
151 DP_INFO_LOG("entered, eventType: %{public}d, value: %{public}d", event, value);
152 auto item = eventHandlerList_.find(event);
153 if (item != eventHandlerList_.end()) {
154 item->second(value);
155 } else {
156 DP_WARNING_LOG("not support handle event: %{public}d", event);
157 }
158 }
159
RegisterStateChangeListener(const std::weak_ptr<IVideoStateChangeListener> & listener)160 void VideoStrategyCenter::RegisterStateChangeListener(const std::weak_ptr<IVideoStateChangeListener>& listener)
161 {
162 videoStateChangeListener_ = listener;
163 }
164
GetWork()165 DeferredVideoWorkPtr VideoStrategyCenter::GetWork()
166 {
167 auto jobPtr = GetJob();
168 ExecutionMode mode = GetExecutionMode();
169 if ((jobPtr != nullptr) && (mode != ExecutionMode::DUMMY)) {
170 return std::make_shared<DeferredVideoWork>(jobPtr, mode, isCharging_);
171 }
172 return nullptr;
173 }
174
GetJob()175 DeferredVideoJobPtr VideoStrategyCenter::GetJob()
176 {
177 return videoJobRepository_->GetJob();
178 }
179
GetExecutionMode()180 ExecutionMode VideoStrategyCenter::GetExecutionMode()
181 {
182 if (isCharging_) {
183 DP_CHECK_RETURN_RET(IsReady(), ExecutionMode::LOAD_BALANCE);
184 } else {
185 DP_CHECK_RETURN_RET(IsReady() && IsTimeReady(), ExecutionMode::LOAD_BALANCE);
186 }
187 return ExecutionMode::DUMMY;
188 }
189
HandleCameraEvent(int32_t value)190 void VideoStrategyCenter::HandleCameraEvent(int32_t value)
191 {
192 DP_DEBUG_LOG("CameraEvent value: %{public}d", value);
193 UpdateValue(ScheduleType::CAMERA_STATE, value);
194 }
195
HandleHalEvent(int32_t value)196 void VideoStrategyCenter::HandleHalEvent(int32_t value)
197 {
198 DP_DEBUG_LOG("HalEvent value: %{public}d", value);
199 UpdateValue(ScheduleType::HDI_STATE, value);
200 }
201
HandleMedialLibraryEvent(int32_t value)202 void VideoStrategyCenter::HandleMedialLibraryEvent(int32_t value)
203 {
204 DP_DEBUG_LOG("MedialLibraryEvent value: %{public}d", value);
205 UpdateValue(ScheduleType::MEDIA_LIBRARY_STATE, value);
206 }
207
HandleScreenEvent(int32_t value)208 void VideoStrategyCenter::HandleScreenEvent(int32_t value)
209 {
210 DP_DEBUG_LOG("ScreenEvent value: %{public}d", value);
211 DP_CHECK_EXECUTE(value == ScreenStatus::SCREEN_ON, UpdateSingleTime(true));
212 UpdateValue(ScheduleType::SCREEN_STATE, value);
213 }
214
HandleChargingEvent(int32_t value)215 void VideoStrategyCenter::HandleChargingEvent(int32_t value)
216 {
217 DP_DEBUG_LOG("ChargingEvent value: %{public}d", value);
218 isCharging_ = value == ChargingStatus::CHARGING;
219 DP_CHECK_EXECUTE(isCharging_, UpdateAvailableTime(true, DEFAULT_TIME));
220 UpdateValue(ScheduleType::CHARGING_STATE, value);
221 }
HandleBatteryEvent(int32_t value)222 void VideoStrategyCenter::HandleBatteryEvent(int32_t value)
223 {
224 DP_DEBUG_LOG("BatteryEvent value: %{public}d", value);
225 UpdateValue(ScheduleType::BATTERY_STATE, value);
226 }
227
HandleBatteryLevelEvent(int32_t value)228 void VideoStrategyCenter::HandleBatteryLevelEvent(int32_t value)
229 {
230 DP_DEBUG_LOG("BatteryLevelEvent value: %{public}d", value);
231 UpdateValue(ScheduleType::BATTERY_LEVEL_STATE, value);
232 }
233
HandleTemperatureEvent(int32_t value)234 void VideoStrategyCenter::HandleTemperatureEvent(int32_t value)
235 {
236 DP_DEBUG_LOG("TemperatureEvent value: %{public}d", value);
237 auto level = ConvertThermalLevel(value);
238 UpdateValue(ScheduleType::THERMAL_LEVEL_STATE, level);
239 }
240
HandlePhotoProcessEvent(int32_t value)241 void VideoStrategyCenter::HandlePhotoProcessEvent(int32_t value)
242 {
243 DP_DEBUG_LOG("PhotoProcessEvent value: %{public}d", value);
244 auto state = ConvertProcessState(value);
245 UpdateValue(ScheduleType::PHOTO_PROCESS_STATE, state);
246 }
247
UpdateValue(ScheduleType type,int32_t value)248 void VideoStrategyCenter::UpdateValue(ScheduleType type, int32_t value)
249 {
250 auto scheduleState = GetScheduleState(type);
251 DP_CHECK_ERROR_RETURN_LOG(scheduleState == nullptr, "UpdateValue failed.");
252 if (scheduleState->UpdateSchedulerInfo(type, value)) {
253 auto info = ReevaluateSchedulerInfo();
254 isNeedStop_ = info.isNeedStop;
255 auto listener = videoStateChangeListener_.lock();
256 DP_CHECK_ERROR_RETURN_LOG(listener == nullptr, "VideoStateChangeListener is nullptr.");
257 listener->OnSchedulerChanged(type, info);
258 }
259 }
260
UpdateSingleTime(bool isOk)261 void VideoStrategyCenter::UpdateSingleTime(bool isOk)
262 {
263 if (isOk) {
264 isTimeOk_ &= ~SINGLE_TIME_LIMIT;
265 } else {
266 isTimeOk_ |= SINGLE_TIME_LIMIT;
267 }
268 DP_INFO_LOG("process time type: 0x%{public}x", isTimeOk_);
269 }
270
UpdateAvailableTime(bool isNeedReset,int32_t useTime)271 void VideoStrategyCenter::UpdateAvailableTime(bool isNeedReset, int32_t useTime)
272 {
273 if (isNeedReset) {
274 availableTime_ = TOTAL_PROCESS_TIME;
275 } else {
276 availableTime_ -= useTime;
277 }
278
279 if (availableTime_ > 0) {
280 isTimeOk_ &= ~TOTAL_TIME_LIMIT;
281 } else {
282 availableTime_ = 0;
283 isTimeOk_ |= TOTAL_TIME_LIMIT;
284 }
285 DP_INFO_LOG("available process time: %{public}d, type: 0x%{public}x", availableTime_, isTimeOk_);
286 }
287
ReevaluateSchedulerInfo()288 ScheduleInfo VideoStrategyCenter::ReevaluateSchedulerInfo()
289 {
290 ScheduleInfo cameraInfo = GetScheduleInfo(ScheduleType::CAMERA_STATE);
291 ScheduleInfo halInfo = GetScheduleInfo(ScheduleType::HDI_STATE);
292 ScheduleInfo mediaLibraryInfo = GetScheduleInfo(ScheduleType::MEDIA_LIBRARY_STATE);
293 ScheduleInfo screenInfo = GetScheduleInfo(ScheduleType::SCREEN_STATE);
294 ScheduleInfo temperatureInfo = GetScheduleInfo(ScheduleType::THERMAL_LEVEL_STATE);
295 ScheduleInfo photoProcessInfo = GetScheduleInfo(ScheduleType::PHOTO_PROCESS_STATE);
296 ScheduleInfo chargingInfo = GetScheduleInfo(ScheduleType::CHARGING_STATE);
297 if (cameraInfo.isNeedStop || halInfo.isNeedStop || mediaLibraryInfo.isNeedStop ||
298 screenInfo.isNeedStop || temperatureInfo.isNeedStop || photoProcessInfo.isNeedStop) {
299 DP_INFO_LOG("video stop schedule, hdi : %{public}d, mediaLibrary: %{public}d, camear: %{public}d, "
300 "screen: %{public}d, temperatureInfo: %{public}d, photoProcessInfo: %{public}d",
301 halInfo.isNeedStop, mediaLibraryInfo.isNeedStop, cameraInfo.isNeedStop,
302 screenInfo.isNeedStop, temperatureInfo.isNeedStop, photoProcessInfo.isNeedStop);
303 return {true, chargingInfo.isCharging};
304 }
305
306 if (chargingInfo.isCharging) {
307 DP_CHECK_RETURN_RET_LOG(videoJobRepository_->GetRunningJobCounts() > 0,
308 chargingInfo, "has video job running.");
309
310 DP_INFO_LOG("video try schedule in charging.");
311 return GetScheduleInfo(ScheduleType::BATTERY_LEVEL_STATE);
312 }
313
314 DP_INFO_LOG("video try schedule in normal.");
315 return GetScheduleInfo(ScheduleType::BATTERY_STATE);
316 }
317
GetScheduleInfo(ScheduleType type)318 ScheduleInfo VideoStrategyCenter::GetScheduleInfo(ScheduleType type)
319 {
320 ScheduleInfo defaultInfo = {true, false};
321 auto scheduleState = GetScheduleState(type);
322 DP_CHECK_ERROR_RETURN_RET_LOG(scheduleState == nullptr, defaultInfo, "not find schedule type: %{public}d", type);
323 return scheduleState->GetScheduleInfo(type);
324 }
325
GetScheduleState(ScheduleType type)326 std::shared_ptr<ISchedulerVideoState> VideoStrategyCenter::GetScheduleState(ScheduleType type)
327 {
328 auto item = scheduleStateList_.find(type);
329 DP_CHECK_ERROR_RETURN_RET_LOG(item == scheduleStateList_.end(), nullptr,
330 "can not find ScheduleState by ScheduleType: %{public}d", type);
331
332 auto scheduleState = item->second;
333 DP_CHECK_ERROR_PRINT_LOG(scheduleState == nullptr, "ScheduleState get by EventType: %{public}d is nullptr", type);
334 return scheduleState;
335 }
336
337 } // namespace DeferredProcessing
338 } // namespace CameraStandard
339 } // namespace OHOS