1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_ZslResultDispatcher"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22 
23 #include <inttypes.h>
24 
25 #include "utils.h"
26 #include "zsl_result_dispatcher.h"
27 
28 namespace android {
29 namespace google_camera_hal {
30 
Create(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)31 std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
32     uint32_t partial_result_count,
33     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
34   ATRACE_CALL();
35   auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
36       new ZslResultDispatcher(process_capture_result, notify));
37   if (dispatcher == nullptr) {
38     ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
39     return nullptr;
40   }
41 
42   status_t res = dispatcher->Initialize(partial_result_count);
43   if (res != OK) {
44     ALOGE("%s: Initialize failed.", __FUNCTION__);
45     return nullptr;
46   }
47 
48   return dispatcher;
49 }
50 
ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)51 ZslResultDispatcher::ZslResultDispatcher(
52     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
53     : device_session_process_capture_result_(process_capture_result),
54       device_session_notify_(notify) {
55 }
56 
Initialize(uint32_t partial_result_count)57 status_t ZslResultDispatcher::Initialize(uint32_t partial_result_count) {
58   ATRACE_CALL();
59   process_capture_result_ =
60       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
61         ProcessCaptureResult(std::move(result));
62       });
63   notify_ = NotifyFunc(
64       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
65 
66   normal_result_dispatcher_ =
67       std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
68           partial_result_count, process_capture_result_, notify_));
69   if (normal_result_dispatcher_ == nullptr) {
70     ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
71     return BAD_VALUE;
72   }
73 
74   zsl_result_dispatcher_ =
75       std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
76           partial_result_count, process_capture_result_, notify_));
77   if (zsl_result_dispatcher_ == nullptr) {
78     ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
79     return BAD_VALUE;
80   }
81 
82   return OK;
83 }
84 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)85 void ZslResultDispatcher::ProcessCaptureResult(
86     std::unique_ptr<CaptureResult> result) {
87   std::lock_guard<std::mutex> lock(process_capture_result_lock_);
88   device_session_process_capture_result_(std::move(result));
89 }
90 
IsZslFrame(uint32_t frame_number)91 bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
92   std::lock_guard<std::mutex> lock(zsl_frames_lock_);
93   if (zsl_frames_.empty()) {
94     return false;
95   }
96   if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
97       zsl_frames_.end()) {
98     return false;
99   }
100   return true;
101 }
102 
NotifyHalMessage(const NotifyMessage & message)103 void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
104   std::lock_guard<std::mutex> lock(result_lock_);
105   device_session_notify_(message);
106 }
107 
AddPendingRequest(const CaptureRequest & pending_request,bool is_zsl_request)108 status_t ZslResultDispatcher::AddPendingRequest(
109     const CaptureRequest& pending_request, bool is_zsl_request) {
110   ATRACE_CALL();
111   if (is_zsl_request) {
112     uint32_t frame_number = pending_request.frame_number;
113     {
114       std::lock_guard<std::mutex> lock(zsl_frames_lock_);
115       zsl_frames_.push_back(frame_number);
116     }
117 
118     status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
119     if (res != OK) {
120       std::lock_guard<std::mutex> lock(zsl_frames_lock_);
121       zsl_frames_.erase(
122           std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
123     }
124     return res;
125   } else {
126     return normal_result_dispatcher_->AddPendingRequest(pending_request);
127   }
128 }
129 
AddResult(std::unique_ptr<CaptureResult> result)130 status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
131   ATRACE_CALL();
132   if (result == nullptr) {
133     ALOGE("%s: result is nullptr", __FUNCTION__);
134     return BAD_VALUE;
135   }
136   uint32_t frame_number = result->frame_number;
137   bool is_zsl_request = IsZslFrame(frame_number);
138   if (is_zsl_request) {
139     return zsl_result_dispatcher_->AddResult(std::move(result));
140   } else {
141     return normal_result_dispatcher_->AddResult(std::move(result));
142   }
143 }
144 
AddShutter(uint32_t frame_number,int64_t timestamp_ns)145 status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
146                                          int64_t timestamp_ns) {
147   ATRACE_CALL();
148   bool is_zsl_request = IsZslFrame(frame_number);
149   if (is_zsl_request) {
150     return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
151   } else {
152     return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
153   }
154 }
155 
AddError(const ErrorMessage & error)156 status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
157   ATRACE_CALL();
158   uint32_t frame_number = error.frame_number;
159   bool is_zsl_request = IsZslFrame(frame_number);
160   if (is_zsl_request) {
161     return zsl_result_dispatcher_->AddError(error);
162   } else {
163     return normal_result_dispatcher_->AddError(error);
164   }
165 }
166 
RemovePendingRequest(uint32_t frame_number)167 void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
168   ATRACE_CALL();
169   bool is_zsl_request = IsZslFrame(frame_number);
170   if (is_zsl_request) {
171     zsl_result_dispatcher_->RemovePendingRequest(frame_number);
172     std::lock_guard<std::mutex> lock(zsl_frames_lock_);
173     zsl_frames_.erase(
174         std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
175   } else {
176     normal_result_dispatcher_->RemovePendingRequest(frame_number);
177   }
178 }
179 
180 }  // namespace google_camera_hal
181 }  // namespace android
182