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 "background_strategy.h"
17 #include "steady_clock.h"
18 #include "dp_log.h"
19 
20 namespace OHOS {
21 namespace CameraStandard {
22 
23 namespace {
24     constexpr int32_t DURATIONMS_25_SEC = 25 * 1000;
25 }
26 
27 namespace DeferredProcessing {
BackgroundStrategy(std::shared_ptr<PhotoJobRepository> repository)28 BackgroundStrategy::BackgroundStrategy(std::shared_ptr<PhotoJobRepository> repository)
29     : trailingStartTimeStamp_(0),
30       remainingTrailingTime_(0),
31       isInTrailing_(false),
32       cameraSessionStatus_(CameraSessionStatus::NORMAL_CAMERA_CLOSED),
33       hdiStatus_(HdiStatus::HDI_READY),
34       mediaLibraryStatus_(MediaLibraryStatus::MEDIA_LIBRARY_AVAILABLE),
35       systemPressureLevel_(SystemPressureLevel::NOMINAL),
36       jobRepository_(repository)
37 {
38     DP_DEBUG_LOG("entered");
39 }
40 
~BackgroundStrategy()41 BackgroundStrategy::~BackgroundStrategy()
42 {
43     DP_DEBUG_LOG("entered");
44     jobRepository_ = nullptr;
45 }
46 
GetWork()47 DeferredPhotoWorkPtr BackgroundStrategy::GetWork()
48 {
49     DP_INFO_LOG("entered");
50     ExecutionMode mode = GetExecutionMode();
51     if (mode == ExecutionMode::DUMMY) {
52         return nullptr;
53     }
54     DeferredPhotoJobPtr jobPtr = GetJob();
55     if (jobPtr == nullptr) {
56         return nullptr;
57     }
58     return std::make_shared<DeferredPhotoWork>(jobPtr, mode);
59 }
60 
GetJob()61 DeferredPhotoJobPtr BackgroundStrategy::GetJob()
62 {
63     DP_INFO_LOG("entered");
64     DeferredPhotoJobPtr jobPtr = nullptr;
65     jobPtr = jobRepository_->GetNormalPriorityJob();
66     if (jobPtr == nullptr) {
67         jobPtr = jobRepository_->GetLowPriorityJob();
68     }
69     return jobPtr;
70 }
71 
GetExecutionMode()72 ExecutionMode BackgroundStrategy::GetExecutionMode()
73 {
74     DP_INFO_LOG("entered");
75     if (cameraSessionStatus_ == CameraSessionStatus::SYSTEM_CAMERA_OPEN
76         || cameraSessionStatus_ == CameraSessionStatus::NORMAL_CAMERA_OPEN
77         || !(hdiStatus_ == HdiStatus::HDI_READY || hdiStatus_ == HdiStatus::HDI_READY_SPACE_LIMIT_REACHED)
78         || mediaLibraryStatus_ != MediaLibraryStatus::MEDIA_LIBRARY_AVAILABLE) {
79         DP_INFO_LOG("cameraSessionStatus_: %{public}d, hdiStatus_: %{public}d, mediaLibraryStatus_: %{public}d, ",
80             cameraSessionStatus_, hdiStatus_, mediaLibraryStatus_);
81         return ExecutionMode::DUMMY;
82     }
83     FlashTrailingState();
84     DP_INFO_LOG("isInTrailing_: %{public}d", isInTrailing_);
85     if (isInTrailing_) {
86         return ExecutionMode::LOAD_BALANCE;
87     }
88     DP_INFO_LOG("systemPressureLevel_: %{public}d", systemPressureLevel_);
89     if (systemPressureLevel_ == SystemPressureLevel::NOMINAL) {
90         return ExecutionMode::LOAD_BALANCE;
91     }
92     return ExecutionMode::DUMMY;
93 }
94 
GetHdiStatus()95 HdiStatus BackgroundStrategy::GetHdiStatus()
96 {
97     DP_INFO_LOG("hdiStatus_: %{public}d", hdiStatus_);
98     return hdiStatus_;
99 }
100 
NotifyPressureLevelChanged(SystemPressureLevel level)101 void BackgroundStrategy::NotifyPressureLevelChanged(SystemPressureLevel level)
102 {
103     DP_INFO_LOG("previous system pressure level: %{public}d, new level: %{public}d", systemPressureLevel_, level);
104     systemPressureLevel_ = level;
105     return;
106 }
107 
NotifyHdiStatusChanged(HdiStatus status)108 void BackgroundStrategy::NotifyHdiStatusChanged(HdiStatus status)
109 {
110     DP_INFO_LOG("previous hdi status %{public}d, new status: %{public}d", hdiStatus_, status);
111     hdiStatus_ = status;
112     return;
113 }
114 
NotifyMediaLibStatusChanged(MediaLibraryStatus status)115 void BackgroundStrategy::NotifyMediaLibStatusChanged(MediaLibraryStatus status)
116 {
117     DP_INFO_LOG("previous media lib status %{public}d, new status: %{public}d", mediaLibraryStatus_, status);
118     mediaLibraryStatus_ = status;
119     return;
120 }
121 
NotifyCameraStatusChanged(CameraSessionStatus status)122 void BackgroundStrategy::NotifyCameraStatusChanged(CameraSessionStatus status)
123 {
124     DP_INFO_LOG("previous camera session status %{public}d, new status: %{public}d", cameraSessionStatus_, status);
125     cameraSessionStatus_ = status;
126     switch (status) {
127         case CameraSessionStatus::SYSTEM_CAMERA_CLOSED:
128             StartTrailing(DURATIONMS_25_SEC);
129             break;
130         case CameraSessionStatus::NORMAL_CAMERA_CLOSED:
131             StartTrailing(0);
132             break;
133         case CameraSessionStatus::SYSTEM_CAMERA_OPEN:
134         case CameraSessionStatus::NORMAL_CAMERA_OPEN:
135             StopTrailing();
136             break;
137         default:
138             break;
139     }
140     return;
141 }
142 
StartTrailing(uint64_t duration)143 void BackgroundStrategy::StartTrailing(uint64_t duration)
144 {
145     DP_INFO_LOG("entered, is in trailing: %{public}d", isInTrailing_);
146     if (duration <= 0) {
147         return;
148     }
149     if (isInTrailing_) {
150         auto passedTime = SteadyClock::GetTimestampMilli() - trailingStartTimeStamp_;
151         if (passedTime >= remainingTrailingTime_) {
152             remainingTrailingTime_ = 0;
153         } else {
154             remainingTrailingTime_ = remainingTrailingTime_ - passedTime;
155         }
156     }
157     remainingTrailingTime_ = duration > remainingTrailingTime_ ? duration : remainingTrailingTime_;
158     trailingStartTimeStamp_ = SteadyClock::GetTimestampMilli();
159     isInTrailing_ = true;
160     return;
161 }
162 
StopTrailing()163 void BackgroundStrategy::StopTrailing()
164 {
165     DP_INFO_LOG("entered, is in trailing: %{public}d", isInTrailing_);
166     if (isInTrailing_) {
167         auto passedTime = SteadyClock::GetTimestampMilli() - trailingStartTimeStamp_;
168         if (passedTime >= remainingTrailingTime_) {
169             remainingTrailingTime_ = 0;
170         } else {
171             remainingTrailingTime_ = remainingTrailingTime_ - passedTime;
172         }
173         isInTrailing_ = false;
174     }
175     return;
176 }
177 
FlashTrailingState()178 void BackgroundStrategy::FlashTrailingState()
179 {
180     DP_INFO_LOG("entered, is in trailing: %{public}d", isInTrailing_);
181     if (isInTrailing_) {
182         auto passedTime = SteadyClock::GetTimestampMilli() - trailingStartTimeStamp_;
183         if (passedTime >= remainingTrailingTime_) {
184             remainingTrailingTime_ = 0;
185             isInTrailing_ = false;
186         }
187     }
188     return;
189 }
190 } // namespace DeferredProcessing
191 } // namespace CameraStandard
192 } // namespace OHOS