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 #define LOG_TAG "EmulatedCameraDevSession"
17 #define ATRACE_TAG ATRACE_TAG_CAMERA
18 
19 #include "EmulatedCameraDeviceSessionHWLImpl.h"
20 
21 #include <android/hardware/graphics/common/1.2/types.h>
22 #include <hardware/gralloc.h>
23 #include <inttypes.h>
24 #include <log/log.h>
25 #include <utils/Trace.h>
26 
27 #include <memory>
28 
29 #include "EmulatedSensor.h"
30 #include "utils.h"
31 #include "utils/HWLUtils.h"
32 
33 namespace android {
34 
35 using google_camera_hal::utils::GetSensorActiveArraySize;
36 using google_camera_hal::utils::HasCapability;
37 
38 using android::hardware::graphics::common::V1_2::Dataspace;
39 std::unique_ptr<EmulatedCameraZoomRatioMapperHwlImpl>
Create(const std::unordered_map<uint32_t,std::pair<Dimension,Dimension>> & dims)40 EmulatedCameraZoomRatioMapperHwlImpl::Create(
41     const std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>& dims) {
42   auto zoom_ratio_mapper_hwl_impl =
43       std::make_unique<EmulatedCameraZoomRatioMapperHwlImpl>(dims);
44   return zoom_ratio_mapper_hwl_impl;
45 }
46 
EmulatedCameraZoomRatioMapperHwlImpl(const std::unordered_map<uint32_t,std::pair<Dimension,Dimension>> & dims)47 EmulatedCameraZoomRatioMapperHwlImpl::EmulatedCameraZoomRatioMapperHwlImpl(
48     const std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>& dims)
49     : camera_ids_to_dimensions_(dims) {
50 }
51 
GetActiveArrayDimensionToBeUsed(uint32_t camera_id,const HalCameraMetadata * settings,Dimension * active_array_dimension) const52 bool EmulatedCameraZoomRatioMapperHwlImpl::GetActiveArrayDimensionToBeUsed(
53     uint32_t camera_id, const HalCameraMetadata* settings,
54     Dimension* active_array_dimension) const {
55   auto dim_it = camera_ids_to_dimensions_.find(camera_id);
56   if (settings == nullptr || active_array_dimension == nullptr ||
57       dim_it == camera_ids_to_dimensions_.end()) {
58     // default request / camera id not found
59     return false;
60   }
61   camera_metadata_ro_entry entry = {};
62   status_t res = settings->Get(ANDROID_SENSOR_PIXEL_MODE, &entry);
63   if (res != OK) {
64     // return default res dimension
65     *active_array_dimension = dim_it->second.second;
66     return true;
67   }
68   if (entry.data.u8[0] == ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
69     // return max res mode dimension
70     *active_array_dimension = dim_it->second.first;
71   } else {
72     *active_array_dimension = dim_it->second.second;
73   }
74   return true;
75 }
76 
77 std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>
Create(uint32_t camera_id,std::unique_ptr<EmulatedCameraDeviceInfo> device_info,PhysicalDeviceMapPtr physical_devices,std::shared_ptr<EmulatedTorchState> torch_state)78 EmulatedCameraDeviceSessionHwlImpl::Create(
79     uint32_t camera_id, std::unique_ptr<EmulatedCameraDeviceInfo> device_info,
80     PhysicalDeviceMapPtr physical_devices,
81     std::shared_ptr<EmulatedTorchState> torch_state) {
82   ATRACE_CALL();
83   if (device_info.get() == nullptr) {
84     return nullptr;
85   }
86 
87   auto session = std::unique_ptr<EmulatedCameraDeviceSessionHwlImpl>(
88       new EmulatedCameraDeviceSessionHwlImpl(std::move(physical_devices),
89                                              torch_state));
90   if (session == nullptr) {
91     ALOGE("%s: Creating EmulatedCameraDeviceSessionHwlImpl failed",
92           __FUNCTION__);
93     return nullptr;
94   }
95 
96   status_t res = session->Initialize(camera_id, std::move(device_info));
97   if (res != OK) {
98     ALOGE("%s: Initializing EmulatedCameraDeviceSessionHwlImpl failed: %s(%d)",
99           __FUNCTION__, strerror(-res), res);
100     return nullptr;
101   }
102 
103   return session;
104 }
105 
GetArrayDimensions(uint32_t camera_id,const HalCameraMetadata * metadata)106 static std::pair<Dimension, Dimension> GetArrayDimensions(
107     uint32_t camera_id, const HalCameraMetadata* metadata) {
108   google_camera_hal::Rect active_array_size;
109   Dimension active_array_size_dimension;
110   Dimension active_array_size_dimension_maximum_resolution;
111   status_t ret = GetSensorActiveArraySize(metadata, &active_array_size);
112   if (ret != OK) {
113     ALOGE("%s: Failed to get sensor active array size for camera id %d",
114           __FUNCTION__, (int)camera_id);
115     return std::pair<Dimension, Dimension>();
116   }
117   active_array_size_dimension = {
118       active_array_size.right - active_array_size.left + 1,
119       active_array_size.bottom - active_array_size.top + 1};
120 
121   active_array_size_dimension_maximum_resolution = active_array_size_dimension;
122   if (HasCapability(
123           metadata,
124           ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) {
125     status_t ret = GetSensorActiveArraySize(metadata, &active_array_size,
126                                             /*maximum_resolution=*/true);
127     if (ret != OK) {
128       ALOGE(
129           "%s: Failed to get max resolution sensor active array size for "
130           "camera id %d",
131           __FUNCTION__, (int)camera_id);
132       return std::pair<Dimension, Dimension>();
133     }
134     active_array_size_dimension_maximum_resolution = {
135         active_array_size.right - active_array_size.left + 1,
136         active_array_size.bottom - active_array_size.top + 1};
137   }
138   return std::make_pair(active_array_size_dimension_maximum_resolution,
139                         active_array_size_dimension);
140 }
141 
Initialize(uint32_t camera_id,std::unique_ptr<EmulatedCameraDeviceInfo> device_info)142 status_t EmulatedCameraDeviceSessionHwlImpl::Initialize(
143     uint32_t camera_id, std::unique_ptr<EmulatedCameraDeviceInfo> device_info) {
144   camera_id_ = camera_id;
145   device_info_ = std::move(device_info);
146   stream_configuration_map_ = std::make_unique<StreamConfigurationMap>(
147       *(device_info_->static_metadata_));
148   stream_configuration_map_max_resolution_ =
149       std::make_unique<StreamConfigurationMap>(
150           *(device_info_->static_metadata_), true);
151   camera_metadata_ro_entry_t entry;
152   auto ret = device_info_->static_metadata_->Get(
153       ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &entry);
154   if (ret != OK) {
155     ALOGE("%s: Unable to extract ANDROID_REQUEST_PIPELINE_MAX_DEPTH, %s (%d)",
156           __FUNCTION__, strerror(-ret), ret);
157     return ret;
158   }
159 
160   max_pipeline_depth_ = entry.data.u8[0];
161 
162   std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>
163       camera_ids_to_dimensions;
164   camera_ids_to_dimensions[camera_id] =
165       GetArrayDimensions(camera_id, device_info_->static_metadata_.get());
166 
167   ret = GetSensorCharacteristics(device_info_->static_metadata_.get(),
168                                  &sensor_chars_);
169   if (ret != OK) {
170     ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
171           strerror(-ret), ret);
172     return ret;
173   }
174 
175   ret = SupportsSessionHalBufManager(device_info_->static_metadata_.get(),
176                                      &supports_session_hal_buf_manager_);
177   if (ret != OK) {
178     ALOGE("%s: Unable to get sensor hal buffer manager support %s (%d)",
179           __FUNCTION__, strerror(-ret), ret);
180     return ret;
181   }
182 
183   logical_chars_.emplace(camera_id_, sensor_chars_);
184   for (const auto& it : *physical_device_map_) {
185     SensorCharacteristics physical_chars;
186     auto stat = GetSensorCharacteristics(it.second.second.get(), &physical_chars);
187     if (stat == OK) {
188       logical_chars_.emplace(it.first, physical_chars);
189     } else {
190       ALOGE("%s: Unable to extract physical device: %u characteristics %s (%d)",
191             __FUNCTION__, it.first, strerror(-ret), ret);
192       return ret;
193     }
194     camera_ids_to_dimensions[it.first] =
195         GetArrayDimensions(it.first, it.second.second.get());
196     physical_stream_configuration_map_.emplace(
197         it.first,
198         std::make_unique<StreamConfigurationMap>(*it.second.second.get()));
199     physical_stream_configuration_map_max_resolution_.emplace(
200         it.first, std::make_unique<StreamConfigurationMap>(
201                       *it.second.second.get(), true));
202   }
203 
204   zoom_ratio_mapper_hwl_impl_ = std::move(
205       EmulatedCameraZoomRatioMapperHwlImpl::Create(camera_ids_to_dimensions));
206   return InitializeRequestProcessor();
207 }
208 
InitializeRequestProcessor()209 status_t EmulatedCameraDeviceSessionHwlImpl::InitializeRequestProcessor() {
210   sp<EmulatedSensor> emulated_sensor = new EmulatedSensor();
211   auto logical_chars = std::make_unique<LogicalCharacteristics>(logical_chars_);
212   auto ret = emulated_sensor->StartUp(camera_id_, std::move(logical_chars));
213   if (ret != OK) {
214     ALOGE("%s: Failed on sensor start up %s (%d)", __FUNCTION__, strerror(-ret),
215           ret);
216     return ret;
217   }
218 
219   request_processor_ = std::make_shared<EmulatedRequestProcessor>(
220       camera_id_, emulated_sensor, session_callback_);
221 
222   request_processor_->InitializeSensorQueue(request_processor_);
223 
224   return request_processor_->Initialize(
225       EmulatedCameraDeviceInfo::Clone(*device_info_),
226       ClonePhysicalDeviceMap(physical_device_map_));
227 }
228 
~EmulatedCameraDeviceSessionHwlImpl()229 EmulatedCameraDeviceSessionHwlImpl::~EmulatedCameraDeviceSessionHwlImpl() {
230   if (torch_state_.get() != nullptr) {
231     torch_state_->ReleaseFlashHw();
232   }
233 }
234 
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)235 status_t EmulatedCameraDeviceSessionHwlImpl::ConstructDefaultRequestSettings(
236     RequestTemplate type, std::unique_ptr<HalCameraMetadata>* default_settings) {
237   ATRACE_CALL();
238   std::lock_guard<std::mutex> lock(api_mutex_);
239 
240   return request_processor_->GetDefaultRequest(type, default_settings);
241 }
242 
ConfigurePipeline(uint32_t physical_camera_id,HwlPipelineCallback hwl_pipeline_callback,const StreamConfiguration & request_config,const StreamConfiguration &,uint32_t * pipeline_id)243 status_t EmulatedCameraDeviceSessionHwlImpl::ConfigurePipeline(
244     uint32_t physical_camera_id, HwlPipelineCallback hwl_pipeline_callback,
245     const StreamConfiguration& request_config,
246     const StreamConfiguration& /*overall_config*/, uint32_t* pipeline_id) {
247   ATRACE_CALL();
248   std::lock_guard<std::mutex> lock(api_mutex_);
249   if (pipeline_id == nullptr) {
250     ALOGE("%s pipeline_id is nullptr", __FUNCTION__);
251     return BAD_VALUE;
252   }
253 
254   if (pipelines_built_) {
255     ALOGE("%s Cannot configure pipelines after calling BuildPipelines()",
256           __FUNCTION__);
257     return ALREADY_EXISTS;
258   }
259 
260   if (!EmulatedSensor::IsStreamCombinationSupported(
261           physical_camera_id, request_config, *stream_configuration_map_,
262           *stream_configuration_map_max_resolution_,
263           physical_stream_configuration_map_,
264           physical_stream_configuration_map_max_resolution_, logical_chars_)) {
265     ALOGE("%s: Stream combination not supported!", __FUNCTION__);
266     return BAD_VALUE;
267   }
268 
269   if ((physical_camera_id != camera_id_) &&
270       (physical_device_map_.get() != nullptr)) {
271     if (physical_device_map_->find(physical_camera_id) ==
272         physical_device_map_->end()) {
273       ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
274             __FUNCTION__, camera_id_, physical_camera_id);
275       return BAD_VALUE;
276     }
277   }
278 
279   *pipeline_id = pipelines_.size();
280   EmulatedPipeline emulated_pipeline{.cb = hwl_pipeline_callback,
281                                      .physical_camera_id = physical_camera_id,
282                                      .pipeline_id = *pipeline_id,};
283 
284   emulated_pipeline.streams.reserve(request_config.streams.size());
285   for (const auto& stream : request_config.streams) {
286     bool is_input = stream.stream_type == google_camera_hal::StreamType::kInput;
287     emulated_pipeline.streams.emplace(
288         stream.id,
289         EmulatedStream(
290             {{.id = stream.id,
291               .override_format =
292                   is_input ? stream.format
293                            : EmulatedSensor::OverrideFormat(
294                                  stream.format, stream.dynamic_profile),
295               .producer_usage = is_input ? 0
296                                          : GRALLOC_USAGE_SW_WRITE_OFTEN |
297                                                GRALLOC_USAGE_HW_CAMERA_WRITE |
298                                                GRALLOC_USAGE_HW_CAMERA_READ,
299               .consumer_usage = 0,
300               .max_buffers = max_pipeline_depth_,
301               .override_data_space =
302                   (stream.dynamic_profile ==
303                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10) &&
304                           (stream.format ==
305                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
306                       ? static_cast<android_dataspace_t>(
307                             Dataspace::BT2020_ITU_HLG)
308                       : stream.data_space,
309               .is_physical_camera_stream = stream.is_physical_camera_stream,
310               .physical_camera_id = stream.physical_camera_id},
311              .width = stream.width,
312              .height = stream.height,
313              .buffer_size = stream.buffer_size,
314              .is_input = is_input,
315              .group_id = stream.group_id,
316              .use_case = stream.use_case,
317              .color_space = stream.color_space}));
318 
319     if (stream.group_id != -1 && stream.is_physical_camera_stream) {
320       // TODO: For quad bayer camera, the logical camera id should be used if
321       // this is not a physical camera.
322       dynamic_stream_id_map_[stream.physical_camera_id][stream.group_id] =
323           stream.id;
324     }
325     if (!stream.is_physical_camera_stream &&
326         (stream.format == HAL_PIXEL_FORMAT_RAW16)) {
327       has_raw_stream_ = true;
328     }
329   }
330 
331   pipelines_.push_back(emulated_pipeline);
332 
333   return OK;
334 }
335 
GetConfiguredHalStream(uint32_t pipeline_id,std::vector<HalStream> * hal_streams) const336 status_t EmulatedCameraDeviceSessionHwlImpl::GetConfiguredHalStream(
337     uint32_t pipeline_id, std::vector<HalStream>* hal_streams) const {
338   ATRACE_CALL();
339   std::lock_guard<std::mutex> lock(api_mutex_);
340   if (hal_streams == nullptr) {
341     ALOGE("%s hal_streams is nullptr", __FUNCTION__);
342     return BAD_VALUE;
343   }
344 
345   if (!pipelines_built_) {
346     ALOGE("%s No pipeline was built.", __FUNCTION__);
347     return NO_INIT;
348   }
349 
350   if (pipeline_id >= pipelines_.size()) {
351     ALOGE("%s: Unknown pipeline ID: %u", __FUNCTION__, pipeline_id);
352     return NAME_NOT_FOUND;
353   }
354 
355   const auto& streams = pipelines_[pipeline_id].streams;
356   hal_streams->reserve(streams.size());
357   for (const auto& it : streams) {
358     hal_streams->push_back(it.second);
359   }
360 
361   return OK;
362 }
363 
BuildPipelines()364 status_t EmulatedCameraDeviceSessionHwlImpl::BuildPipelines() {
365   ATRACE_CALL();
366   std::lock_guard<std::mutex> lock(api_mutex_);
367   if (pipelines_built_) {
368     ALOGE("%s Pipelines have already been built!", __FUNCTION__);
369     return ALREADY_EXISTS;
370   } else if (pipelines_.size() == 0) {
371     ALOGE("%s No pipelines have been configured yet!", __FUNCTION__);
372     return NO_INIT;
373   }
374 
375   status_t ret = OK;
376   if (request_processor_ == nullptr) {
377     ret = InitializeRequestProcessor();
378   }
379 
380   if (ret == OK) {
381     pipelines_built_ = true;
382   }
383 
384   return OK;
385 }
386 
GetHalBufferManagedStreams(const StreamConfiguration & config)387 std::set<int32_t> EmulatedCameraDeviceSessionHwlImpl::GetHalBufferManagedStreams(
388     const StreamConfiguration& config) {
389   std::set<int32_t> ret;
390   for (const auto& stream : config.streams) {
391     if (stream.stream_type == google_camera_hal::StreamType::kInput) {
392       continue;
393     }
394     // Just a heuristic - odd numbered stream ids are hal buffer managed.
395     if ((stream.group_id != -1) || (stream.id % 2)) {
396       ret.insert(stream.id);
397     }
398   }
399   return ret;
400 }
401 
DestroyPipelines()402 void EmulatedCameraDeviceSessionHwlImpl::DestroyPipelines() {
403   ATRACE_CALL();
404   std::lock_guard<std::mutex> lock(api_mutex_);
405   if (!pipelines_built_) {
406     // Not an error - nothing to destroy
407     ALOGV("%s nothing to destroy", __FUNCTION__);
408     return;
409   }
410 
411   pipelines_built_ = false;
412   has_raw_stream_ = false;
413   pipelines_.clear();
414   request_processor_ = nullptr;
415 }
416 
CheckOutputFormatsForInput(const HwlPipelineRequest & request,const std::unordered_map<uint32_t,EmulatedStream> & streams,const std::unique_ptr<StreamConfigurationMap> & stream_configuration_map,android_pixel_format_t input_format)417 status_t EmulatedCameraDeviceSessionHwlImpl::CheckOutputFormatsForInput(
418     const HwlPipelineRequest& request,
419     const std::unordered_map<uint32_t, EmulatedStream>& streams,
420     const std::unique_ptr<StreamConfigurationMap>& stream_configuration_map,
421     android_pixel_format_t input_format) {
422   auto output_formats =
423       stream_configuration_map->GetValidOutputFormatsForInput(input_format);
424   for (const auto& output_buffer : request.output_buffers) {
425     auto output_stream = streams.at(output_buffer.stream_id);
426     if (output_formats.find(output_stream.override_format) ==
427         output_formats.end()) {
428       ALOGE(
429           "%s: Reprocess request with input format: 0x%x to output "
430           "format: 0x%x"
431           " not supported!",
432           __FUNCTION__, input_format, output_stream.override_format);
433       return BAD_VALUE;
434     }
435   }
436   return OK;
437 }
438 
SubmitRequests(uint32_t frame_number,std::vector<HwlPipelineRequest> & requests)439 status_t EmulatedCameraDeviceSessionHwlImpl::SubmitRequests(
440     uint32_t frame_number, std::vector<HwlPipelineRequest>& requests) {
441   ATRACE_CALL();
442   std::lock_guard<std::mutex> lock(api_mutex_);
443 
444   // Check whether reprocess request has valid/supported outputs.
445   for (const auto& request : requests) {
446     if (!request.input_buffers.empty()) {
447       for (const auto& input_buffer : request.input_buffers) {
448         const auto& streams = pipelines_[request.pipeline_id].streams;
449         auto input_stream = streams.at(input_buffer.stream_id);
450         if ((CheckOutputFormatsForInput(request, streams,
451                                         stream_configuration_map_,
452                                         input_stream.override_format) != OK) &&
453             (CheckOutputFormatsForInput(
454                  request, streams, stream_configuration_map_max_resolution_,
455                  input_stream.override_format) != OK)) {
456           return BAD_VALUE;
457         }
458       }
459     }
460   }
461 
462   if (error_state_) {
463     ALOGE("%s session is in error state and cannot process further requests",
464           __FUNCTION__);
465     return INVALID_OPERATION;
466   }
467 
468   return request_processor_->ProcessPipelineRequests(
469       frame_number, requests, pipelines_, dynamic_stream_id_map_,
470       has_raw_stream_);
471 }
472 
Flush()473 status_t EmulatedCameraDeviceSessionHwlImpl::Flush() {
474   ATRACE_CALL();
475   std::lock_guard<std::mutex> lock(api_mutex_);
476   return request_processor_->Flush();
477 }
478 
GetCameraId() const479 uint32_t EmulatedCameraDeviceSessionHwlImpl::GetCameraId() const {
480   return camera_id_;
481 }
482 
GetPhysicalCameraIds() const483 std::vector<uint32_t> EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraIds()
484     const {
485   if ((physical_device_map_.get() == nullptr) ||
486       (physical_device_map_->empty())) {
487     return std::vector<uint32_t>{};
488   }
489 
490   std::vector<uint32_t> ret;
491   ret.reserve(physical_device_map_->size());
492   for (const auto& it : *physical_device_map_) {
493     ret.push_back(it.first);
494   }
495 
496   return ret;
497 }
498 
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics) const499 status_t EmulatedCameraDeviceSessionHwlImpl::GetCameraCharacteristics(
500     std::unique_ptr<HalCameraMetadata>* characteristics) const {
501   ATRACE_CALL();
502   if (characteristics == nullptr) {
503     return BAD_VALUE;
504   }
505 
506   (*characteristics) =
507       HalCameraMetadata::Clone(device_info_->static_metadata_.get());
508 
509   if (*characteristics == nullptr) {
510     ALOGE("%s metadata clone failed", __FUNCTION__);
511     return NO_MEMORY;
512   }
513 
514   return OK;
515 }
516 
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics) const517 status_t EmulatedCameraDeviceSessionHwlImpl::GetPhysicalCameraCharacteristics(
518     uint32_t physical_camera_id,
519     std::unique_ptr<HalCameraMetadata>* characteristics) const {
520   ATRACE_CALL();
521   if (characteristics == nullptr) {
522     return BAD_VALUE;
523   }
524 
525   if (physical_device_map_.get() == nullptr) {
526     ALOGE("%s: Camera: %d doesn't have physical device support!", __FUNCTION__,
527           camera_id_);
528     return BAD_VALUE;
529   }
530 
531   if (physical_device_map_->find(physical_camera_id) ==
532       physical_device_map_->end()) {
533     ALOGE("%s: Camera: %d doesn't include physical device with id: %u",
534           __FUNCTION__, camera_id_, physical_camera_id);
535     return BAD_VALUE;
536   }
537 
538   (*characteristics) = HalCameraMetadata::Clone(
539       physical_device_map_->at(physical_camera_id).second.get());
540 
541   return OK;
542 }
543 
SetSessionCallback(const HwlSessionCallback & hwl_session_callback)544 void EmulatedCameraDeviceSessionHwlImpl::SetSessionCallback(
545     const HwlSessionCallback& hwl_session_callback) {
546   ATRACE_CALL();
547   std::lock_guard<std::mutex> lock(api_mutex_);
548   session_callback_ = hwl_session_callback;
549   if (request_processor_ != nullptr) {
550     request_processor_->SetSessionCallback(hwl_session_callback);
551   }
552 }
553 
554 }  // namespace android
555