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_TAG "CameraProviderTests"
18 #include <log/log.h>
19 
20 #include <camera_provider.h>
21 #include <gtest/gtest.h>
22 
23 #include "mock_provider_hwl.h"
24 
25 namespace android {
26 namespace google_camera_hal {
27 
28 class CameraProviderTest : public ::testing::Test {
29  protected:
CreateCameraProviderAndCheck(std::unique_ptr<MockProviderHwl> mock_provider_hwl=nullptr)30   void CreateCameraProviderAndCheck(
31       std::unique_ptr<MockProviderHwl> mock_provider_hwl = nullptr) {
32     if (mock_provider_hwl == nullptr) {
33       mock_provider_hwl = MockProviderHwl::Create();
34     }
35 
36     DestroyCameraProvider();
37     provider_ = CameraProvider::Create(std::move(mock_provider_hwl));
38     ASSERT_NE(provider_, nullptr) << "Creating a CameraProvider failed.";
39   }
40 
DestroyCameraProvider()41   void DestroyCameraProvider() {
42     provider_ = nullptr;
43   }
44 
45   std::unique_ptr<CameraProvider> provider_;
46 };
47 
TEST_F(CameraProviderTest,Create)48 TEST_F(CameraProviderTest, Create) {
49   CreateCameraProviderAndCheck();
50 }
51 
TEST_F(CameraProviderTest,SetCallback)52 TEST_F(CameraProviderTest, SetCallback) {
53   CameraDeviceStatus device_status = CameraDeviceStatus::kNotPresent;
54   TorchModeStatus torch_status = TorchModeStatus::kAvailableOff;
55   CameraProviderCallback callback = {
56       .camera_device_status_change =
57           [&device_status](std::string /*camera_id*/,
58                            CameraDeviceStatus new_status) {
59             device_status = new_status;
60           },
61       .torch_mode_status_change =
62           [&torch_status](std::string /*camera_id*/, TorchModeStatus new_status) {
63             torch_status = new_status;
64           },
65   };
66 
67   static const std::vector<CameraDeviceStatus> kMockCameraDeviceStatus = {
68       CameraDeviceStatus::kNotPresent, CameraDeviceStatus::kPresent,
69       CameraDeviceStatus::kEnumerating};
70 
71   // Verify the mock device status is same as set from callback.
72   for (auto mock_device_status : kMockCameraDeviceStatus) {
73     auto mock_provider_hwl = MockProviderHwl::Create();
74     mock_provider_hwl->camera_device_status_ = mock_device_status;
75 
76     CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
77 
78     status_t res = provider_->SetCallback(&callback);
79     ASSERT_EQ(res, OK) << "Setting callback failed: " << strerror(res);
80 
81     EXPECT_EQ(device_status, mock_device_status);
82   }
83 
84   static const std::vector<TorchModeStatus> kMockTorchModeStatus = {
85       TorchModeStatus::kNotAvailable, TorchModeStatus::kAvailableOff,
86       TorchModeStatus::kAvailableOn};
87 
88   // Verify the mock torch mode status is same as set from callback.
89   for (auto mock_torch_status : kMockTorchModeStatus) {
90     auto mock_provider_hwl = MockProviderHwl::Create();
91     mock_provider_hwl->torch_status_ = mock_torch_status;
92 
93     CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
94 
95     status_t res = provider_->SetCallback(&callback);
96     ASSERT_EQ(res, OK) << "Setting callback failed: " << strerror(res);
97 
98     EXPECT_EQ(torch_status, mock_torch_status);
99   }
100 }
101 
102 // Test if camera provider passes all vendor tags specified in HWL.
TEST_F(CameraProviderTest,GetVendorTags)103 TEST_F(CameraProviderTest, GetVendorTags) {
104   static const uint32_t kMockTagIdOffset = 0x80000000;
105   static const std::vector<VendorTagSection> kMockVendorTagSections = {
106       {
107           .section_name = "vendor.section_0",
108           .tags =
109               {
110                   {
111                       .tag_id = kMockTagIdOffset + 0,
112                       .tag_name = "tag0",
113                       .tag_type = CameraMetadataType::kByte,
114                   },
115                   {
116                       .tag_id = kMockTagIdOffset + 1,
117                       .tag_name = "tag1",
118                       .tag_type = CameraMetadataType::kInt32,
119                   },
120               },
121       },
122       {
123           .section_name = "vendor.section_1",
124           .tags =
125               {
126                   {
127                       .tag_id = kMockTagIdOffset + 2,
128                       .tag_name = "tag2",
129                       .tag_type = CameraMetadataType::kFloat,
130                   },
131                   {
132                       .tag_id = kMockTagIdOffset + 3,
133                       .tag_name = "tag3",
134                       .tag_type = CameraMetadataType::kInt64,
135                   },
136                   {
137                       .tag_id = kMockTagIdOffset + 4,
138                       .tag_name = "tag4",
139                       .tag_type = CameraMetadataType::kRational,
140                   },
141               },
142       },
143   };
144 
145   auto mock_provider_hwl = MockProviderHwl::Create();
146   mock_provider_hwl->vendor_tag_sections_ = kMockVendorTagSections;
147 
148   CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
149 
150   // Verify GetVendorTags(nullptr) returns an error.
151   EXPECT_NE(provider_->GetVendorTags(nullptr), OK);
152 
153   std::vector<VendorTagSection> sections;
154   status_t res = provider_->GetVendorTags(&sections);
155   ASSERT_EQ(res, OK) << "Getting vendor tags failed: " << strerror(res);
156 
157   // Verify the mock sections are included in the returned sections.
158   for (auto mock_section : kMockVendorTagSections) {
159     bool found_section = false;
160 
161     for (auto returned_section : sections) {
162       if (returned_section.section_name == mock_section.section_name) {
163         found_section = true;
164 
165         // Verify the mock tags are included in the returned tags.
166         for (auto mock_tag : mock_section.tags) {
167           bool found_tag = false;
168           for (auto returned_tag : returned_section.tags) {
169             if (returned_tag.tag_id == mock_tag.tag_id) {
170               found_tag = true;
171               EXPECT_EQ(returned_tag.tag_name, mock_tag.tag_name);
172               EXPECT_EQ(returned_tag.tag_type, mock_tag.tag_type);
173               break;
174             }
175           }
176           EXPECT_EQ(found_tag, true)
177               << "Mock tag " << std::to_string(mock_tag.tag_id)
178               << " in section " << mock_section.section_name << " is not found";
179         }
180         break;
181       }
182     }
183 
184     EXPECT_EQ(found_section, true)
185         << "Mock section " << mock_section.section_name << " is not found";
186   }
187 }
188 
189 // Test if GetCameraIdList() returns the right number of camera IDs visible
190 // to framework.
TEST_F(CameraProviderTest,GetCameraIdList)191 TEST_F(CameraProviderTest, GetCameraIdList) {
192   static const std::vector<CameraIdMap> id_maps = {
193       {
194           .id = 0,
195           .visible_to_framework = true,
196       },
197       {
198           .id = 1,
199           .visible_to_framework = false,
200       },
201       {
202           .id = 2,
203           .visible_to_framework = true,
204       },
205   };
206 
207   // Calculate the number of public cameras.
208   uint32_t num_public_cameras = 0;
209   for (auto id_map : id_maps) {
210     if (id_map.visible_to_framework) {
211       num_public_cameras++;
212     }
213   }
214 
215   auto mock_provider_hwl = MockProviderHwl::Create();
216   mock_provider_hwl->cameras_ = id_maps;
217 
218   CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
219 
220   // Verify GetCameraIdList(nullptr) returns an error.
221   EXPECT_NE(provider_->GetCameraIdList(nullptr), OK);
222 
223   std::vector<uint32_t> camera_ids;
224   status_t res = provider_->GetCameraIdList(&camera_ids);
225   ASSERT_EQ(res, OK) << "Getting camera IDs failed: " << strerror(res);
226 
227   // Verify the returned number of public cameras.
228   EXPECT_EQ(camera_ids.size(), num_public_cameras);
229 }
230 
231 // Test if IsSetTorchModeSupported() returns the same value that mock HWL
232 // returns.
TEST_F(CameraProviderTest,IsSetTorchModeSupported)233 TEST_F(CameraProviderTest, IsSetTorchModeSupported) {
234   static const bool kIsTorchSupported[] = {true, false};
235 
236   for (auto is_torch_supported : kIsTorchSupported) {
237     auto mock_provider_hwl = MockProviderHwl::Create();
238     mock_provider_hwl->is_torch_supported_ = is_torch_supported;
239     CreateCameraProviderAndCheck(std::move(mock_provider_hwl));
240 
241     EXPECT_EQ(provider_->IsSetTorchModeSupported(), is_torch_supported);
242     DestroyCameraProvider();
243   }
244 }
245 
TEST_F(CameraProviderTest,CreateCameraDevice)246 TEST_F(CameraProviderTest, CreateCameraDevice) {
247   CreateCameraProviderAndCheck();
248 
249   std::vector<uint32_t> camera_ids;
250   status_t res = provider_->GetCameraIdList(&camera_ids);
251   ASSERT_EQ(res, OK) << "Getting camera IDs failed: " << strerror(res);
252 
253   for (auto camera_id : camera_ids) {
254     std::unique_ptr<CameraDevice> device;
255     provider_->CreateCameraDevice(camera_id, &device);
256     EXPECT_NE(device, nullptr)
257         << "Creating a CameraDevice for ID " << camera_id << " failed.";
258   }
259 }
260 
261 }  // namespace google_camera_hal
262 }  // namespace android
263