1 /*
2  * Copyright (c) 2020-2021 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 #include "camera_manager.h"
16 #include "camera_impl.h"
17 #include "camera_service_client.h"
18 #include "camera_service_callback.h"
19 #include "media_log.h"
20 
21 #include <cstdio>
22 #include <map>
23 
24 using namespace std;
25 namespace OHOS {
26 namespace Media {
27 class CameraManagerImpl : public CameraManager, public CameraServiceCallback {
28 public:
CameraManagerImpl()29     CameraManagerImpl()
30     {
31         cameraServiceClient_ = CameraServiceClient::GetInstance();
32         cameraServiceClient_->InitCameraServiceClient(this);
33     }
~CameraManagerImpl()34     ~CameraManagerImpl()
35     {
36         for (const auto &i : cameraMapCache_) {
37             delete i.second;
38         }
39     }
40 
OnCameraServiceInitialized(list<string> & availCameraIdList)41     void OnCameraServiceInitialized(list<string> &availCameraIdList) override
42     {
43         /* cameraService_ cannot be nullptr as OnCameraServiceInitialized is a callback of cameraService_ */
44         for (auto &cameraId : availCameraIdList) {
45             InitCameraAbility(cameraId);
46         }
47     }
48 
OnCameraStatusChange(string & cameraId,CameraStatus status)49     void OnCameraStatusChange(string &cameraId, CameraStatus status) override
50     {
51         auto p = cameraMapCache_.find(cameraId);
52         switch (status) {
53             case CAMERA_STATUS_UNAVAIL:
54                 if (p != cameraMapCache_.end()) {
55                     for (auto &i : deviceCbList_) {
56                         i.second->Post(
57                             [i, cameraId]() { i.first->OnCameraStatus(cameraId, CAMERA_DEVICE_STATE_UNAVAILABLE); });
58                     }
59                     // User may still using icamera now
60                     delete p->second;
61                     cameraMapCache_.erase(p);
62                 }
63                 break;
64             case CAMERA_STATUS_AVAIL:
65                 InitCameraAbility(cameraId);
66                 if (p == cameraMapCache_.end()) {
67                     for (auto &i : deviceCbList_) {
68                         i.second->Post(
69                             [i, cameraId]() { i.first->OnCameraStatus(cameraId, CAMERA_DEVICE_STATE_AVAILABLE); });
70                     }
71                 }
72                 break;
73             case CAMERA_STATUS_CREATED:
74                 if (p != cameraMapCache_.end()) {
75                     p->second->OnCreate(cameraId);
76                 }
77                 break;
78             case CAMERA_STATUS_CREATE_FAILED:
79                 if (p != cameraMapCache_.end()) {
80                     p->second->OnCreateFailed();
81                 }
82                 break;
83             default:
84                 break;
85         }
86     }
87 
RegisterCameraDeviceCallback(CameraDeviceCallback & callback,EventHandler & handler)88     void RegisterCameraDeviceCallback(CameraDeviceCallback &callback, EventHandler &handler) override
89     {
90         deviceCbList_.emplace_back(make_pair(&callback, &handler));
91         for (const auto &i : cameraMapCache_) {
92             string cameraId = i.first;
93             handler.Post([&callback, cameraId]() { callback.OnCameraStatus(cameraId, CAMERA_DEVICE_STATE_AVAILABLE); });
94         }
95     }
96 
UnregisterCameraDeviceCallback(CameraDeviceCallback & callback)97     void UnregisterCameraDeviceCallback(CameraDeviceCallback &callback) override
98     {
99         for (auto p = deviceCbList_.begin(); p != deviceCbList_.end(); p++) {
100             if (p->first == &callback) {
101                 deviceCbList_.erase(p);
102                 break;
103             }
104         }
105     }
106 
GetCameraModeNum()107     uint8_t GetCameraModeNum() override
108     {
109         return cameraServiceClient_->GetCameraModeNum();
110     }
111 
SetCameraMode(uint8_t modeIndex)112     int32_t SetCameraMode(uint8_t modeIndex) override
113     {
114         return cameraServiceClient_->SetCameraMode(modeIndex);
115     }
116 
GetCameraIds()117     list<string> GetCameraIds() override
118     {
119         list<string> cameraList;
120         for (auto &i : cameraMapCache_) {
121             MEDIA_DEBUG_LOG("%s", i.first.c_str());
122             cameraList.emplace_back(i.first);
123         }
124         return cameraList;
125     }
126 
GetCameraAbility(const string & cameraId)127     const CameraAbility *GetCameraAbility(const string &cameraId) override
128     {
129         auto camera = cameraMapCache_.find(cameraId);
130         if (camera == cameraMapCache_.end()) {
131             return nullptr;
132         }
133         return camera->second->GetAbility();
134     }
135 
GetCameraInfo(const string & cameraId)136     const CameraInfo *GetCameraInfo(const string &cameraId) override
137     {
138         auto camera = cameraMapCache_.find(cameraId);
139         if (camera == cameraMapCache_.end()) {
140             return nullptr;
141         }
142         return camera->second->GetInfo();
143     }
144 
CreateCamera(const string & cameraId,CameraStateCallback & callback,EventHandler & handler)145     void CreateCamera(const string &cameraId, CameraStateCallback &callback, EventHandler &handler) override
146     {
147         auto p = cameraMapCache_.find(cameraId);
148         if (p == cameraMapCache_.end()) {
149             MEDIA_ERR_LOG("The cameraId %s is not available", cameraId.c_str());
150             handler.Post([&callback, &cameraId] { callback.OnCreateFailed(cameraId, MEDIA_ERR); });
151             return;
152         }
153         p->second->RegistCb(callback, handler);
154         cameraServiceClient_->CreateCamera(cameraId);
155     }
156 private:
157     CameraServiceClient *cameraServiceClient_;
158     map<string, CameraImpl *> cameraMapCache_;
159     list<pair<CameraDeviceCallback *, EventHandler *>> deviceCbList_;
160 
InitCameraAbility(string & cameraId)161     void InitCameraAbility(string &cameraId)
162     {
163         auto ability = cameraServiceClient_->GetCameraAbility(cameraId);
164         auto info = cameraServiceClient_->GetCameraInfo(cameraId);
165         CameraImpl *cam = new (nothrow) CameraImpl(cameraId, ability, info);
166         if (cam == nullptr) {
167             MEDIA_FATAL_LOG("New object failed.");
168             return;
169         }
170         cameraMapCache_[cameraId] = cam;
171     }
172 };
173 
GetInstance()174 CameraManager *CameraManager::GetInstance()
175 {
176     static CameraManagerImpl cameraManagerImpl;
177     return &cameraManagerImpl;
178 }
179 } // namespace Media
180 } // namespace OHOS
181