blob: d79f93eac100ae143991d80a11168af4f020456c [file] [log] [blame]
Haoxiang Li3993d002019-09-17 14:42:02 -07001/*
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#include <hidl/HidlTransportSupport.h>
17#include <log/log.h>
18#include <utils/SystemClock.h>
19
20#include "AnalyzeUseCase.h"
21#include "ConfigManager.h"
22
23using android::hardware::configureRpcThreadpool;
24using android::hardware::joinRpcThreadpool;
25
26namespace android {
27namespace automotive {
28namespace evs {
29namespace support {
30
31AnalyzeUseCase::AnalyzeUseCase(string cameraId, BaseAnalyzeCallback* callback)
32 : BaseUseCase(vector<string>(1, cameraId)),
33 mAnalyzeCallback(callback) {}
34
35AnalyzeUseCase::~AnalyzeUseCase() {}
36
37bool AnalyzeUseCase::initialize() {
38 // TODO(b/130246434): Move the following ConfigManager and thread pool
39 // logic into ResourceManager, for both display and analyze use case.
40
41 ConfigManager config;
Changyeon Jo039c2902020-02-24 16:37:16 -080042 if (!config.initialize("/system/etc/automotive/evs_support_lib/camera_config.json")) {
Haoxiang Li3993d002019-09-17 14:42:02 -070043 ALOGE("Missing or improper configuration for the EVS application. Exiting.");
44 return false;
45 }
46
47 // Set thread pool size to one to avoid concurrent events from the HAL.
48 // This pool will handle the EvsCameraStream callbacks.
49 // Note: This _will_ run in parallel with the EvsListener run() loop below which
50 // runs the application logic that reacts to the async events.
51 configureRpcThreadpool(1, false /* callerWillJoin */);
52
53 mResourceManager = ResourceManager::getInstance();
54
55 ALOGD("Requesting camera list");
56 for (auto&& info : config.getCameras()) {
57 // This use case is currently a single camera use case.
58 // Only one element is available in the camera id list.
59 string cameraId = mCameraIds[0];
60 if (cameraId == info.cameraId) {
61 mStreamHandler =
62 mResourceManager->obtainStreamHandler(cameraId);
63 if (mStreamHandler.get() == nullptr) {
64 ALOGE("Failed to get a valid StreamHandler for %s",
65 cameraId.c_str());
66 return false;
67 }
68
69 mIsInitialized = true;
70 return true;
71 }
72 }
73
74 ALOGE("Cannot find a match camera. Exiting");
75 return false;
76}
77
78bool AnalyzeUseCase::startVideoStream() {
79 ALOGD("AnalyzeUseCase::startVideoStream");
80
81 // Initialize the use case.
82 if (!mIsInitialized && !initialize()) {
83 ALOGE("There is an error while initializing the use case. Exiting");
84 return false;
85 }
86
87 ALOGD("Attach callback to StreamHandler");
88 if (mAnalyzeCallback != nullptr) {
89 mStreamHandler->attachAnalyzeCallback(mAnalyzeCallback);
90 }
91
92 mStreamHandler->startStream();
93
94 return true;
95}
96
97void AnalyzeUseCase::stopVideoStream() {
98 ALOGD("AnalyzeUseCase::stopVideoStream");
99
100 if (mStreamHandler == nullptr) {
101 ALOGE("Failed to detach render callback since stream handler is null");
102
103 // Something may go wrong. Instead of to return this method right away,
104 // we want to finish the remaining logic of this method to try to
105 // release other resources.
106 } else {
107 mStreamHandler->detachAnalyzeCallback();
108 }
109
110 if (mResourceManager == nullptr) {
111 ALOGE("Failed to release resources since resource manager is null");
112 } else {
113 mResourceManager->releaseStreamHandler(mCameraIds[0]);
114 }
115
116 mStreamHandler = nullptr;
117
118 // TODO(b/130246434): with the current logic, the initialize method will
119 // be triggered every time when a pair of
120 // stopVideoStream/startVideoStream is called. We might want to move
121 // some heavy work away from initialize method so increase the
122 // performance.
123
124 // Sets mIsInitialzed to false so the initialize method will be
125 // triggered when startVideoStream is called again.
126 mIsInitialized = false;
127}
128
129// TODO(b/130246434): For both Analyze use case and Display use case, return a
130// pointer instead of an object.
131AnalyzeUseCase AnalyzeUseCase::createDefaultUseCase(
132 string cameraId, BaseAnalyzeCallback* callback) {
133 return AnalyzeUseCase(cameraId, callback);
134}
135
136} // namespace support
137} // namespace evs
138} // namespace automotive
139} // namespace android
140