1 /*
2  * Copyright (C) 2016 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 #include "static_properties.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <hardware/camera3.h>
22 #include <system/camera.h>
23 
24 #include "metadata/metadata_reader_mock.h"
25 
26 using testing::AtMost;
27 using testing::Expectation;
28 using testing::Return;
29 using testing::SetArgPointee;
30 using testing::Test;
31 using testing::_;
32 
33 namespace default_camera_hal {
34 
35 class StaticPropertiesTest : public Test {
36  protected:
SetUp()37   virtual void SetUp() {
38     // Ensure tests will probably fail if PrepareDUT isn't called.
39     dut_.reset();
40     mock_reader_ = std::make_unique<MetadataReaderMock>();
41   }
42 
PrepareDUT()43   void PrepareDUT() {
44     dut_.reset(StaticProperties::NewStaticProperties(std::move(mock_reader_)));
45   }
46 
PrepareDefaultDUT()47   void PrepareDefaultDUT() {
48     SetDefaultExpectations();
49     PrepareDUT();
50     ASSERT_NE(dut_, nullptr);
51   }
52 
SetDefaultExpectations()53   void SetDefaultExpectations() {
54     EXPECT_CALL(*mock_reader_, Facing(_))
55         .Times(AtMost(1))
56         .WillOnce(DoAll(SetArgPointee<0>(test_facing_), Return(0)));
57     EXPECT_CALL(*mock_reader_, Orientation(_))
58         .Times(AtMost(1))
59         .WillOnce(DoAll(SetArgPointee<0>(test_orientation_), Return(0)));
60     EXPECT_CALL(*mock_reader_, MaxInputStreams(_))
61         .Times(AtMost(1))
62         .WillOnce(DoAll(SetArgPointee<0>(test_max_inputs_), Return(0)));
63     EXPECT_CALL(*mock_reader_, MaxOutputStreams(_, _, _))
64         .Times(AtMost(1))
65         .WillOnce(DoAll(SetArgPointee<0>(test_max_raw_outputs_),
66                         SetArgPointee<1>(test_max_non_stalling_outputs_),
67                         SetArgPointee<2>(test_max_stalling_outputs_),
68                         Return(0)));
69     EXPECT_CALL(*mock_reader_, RequestCapabilities(_))
70         .Times(AtMost(1))
71         .WillOnce(
72             DoAll(SetArgPointee<0>(test_request_capabilities_), Return(0)));
73     EXPECT_CALL(*mock_reader_, StreamConfigurations(_))
74         .Times(AtMost(1))
75         .WillOnce(DoAll(SetArgPointee<0>(test_configs_), Return(0)));
76     EXPECT_CALL(*mock_reader_, StreamStallDurations(_))
77         .Times(AtMost(1))
78         .WillOnce(DoAll(SetArgPointee<0>(test_stalls_), Return(0)));
79     EXPECT_CALL(*mock_reader_, ReprocessFormats(_))
80         .Times(AtMost(1))
81         .WillOnce(DoAll(SetArgPointee<0>(test_reprocess_map_), Return(0)));
82   }
83 
MakeStream(int32_t format,bool output=true,bool input=false,int32_t width=kWidth,int32_t height=kHeight)84   camera3_stream_t MakeStream(int32_t format,
85                               bool output = true,
86                               bool input = false,
87                               int32_t width = kWidth,
88                               int32_t height = kHeight) {
89     int type = -1;
90     if (output && input) {
91       type = CAMERA3_STREAM_BIDIRECTIONAL;
92     } else if (output) {
93       type = CAMERA3_STREAM_OUTPUT;
94     } else if (input) {
95       type = CAMERA3_STREAM_INPUT;
96     }
97     camera3_stream_t stream;
98     stream.stream_type = type;
99     stream.width = width;
100     stream.height = height;
101     stream.format = format;
102     return stream;
103   }
104 
ExpectConfigurationSupported(std::vector<camera3_stream_t> & streams,bool expected)105   void ExpectConfigurationSupported(std::vector<camera3_stream_t>& streams,
106                                     bool expected) {
107     std::vector<camera3_stream_t*> stream_addresses;
108     for (size_t i = 0; i < streams.size(); ++i) {
109       stream_addresses.push_back(&streams[i]);
110     }
111     camera3_stream_configuration_t config = {
112         static_cast<uint32_t>(stream_addresses.size()),
113         stream_addresses.data(),
114         CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE,
115         nullptr};
116     PrepareDefaultDUT();
117     EXPECT_EQ(dut_->StreamConfigurationSupported(&config), expected);
118   }
119 
120   std::unique_ptr<StaticProperties> dut_;
121   std::unique_ptr<MetadataReaderMock> mock_reader_;
122 
123   // Some helper values used for stream testing.
124   static constexpr int32_t kWidth = 320;
125   static constexpr int32_t kHeight = 240;
126   static constexpr int32_t kAlternateWidth = 640;
127   static constexpr int32_t kAlternateHeight = 480;
128 
129   const int test_facing_ = CAMERA_FACING_FRONT;
130   const int test_orientation_ = 90;
131   const int32_t test_max_inputs_ = 3;
132   const int32_t test_max_raw_outputs_ = 1;
133   const int32_t test_max_non_stalling_outputs_ = 2;
134   const int32_t test_max_stalling_outputs_ = 3;
135   const std::set<uint8_t> test_request_capabilities_ = {
136       ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
137       ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
138       ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING};
139 
140   // Some formats for various purposes (in various combinations,
141   // these types should be capable of testing all failure conditions).
142   const int32_t output_multisize_non_stalling_ = 1;
143   const int32_t bidirectional_self_supporting_stalling_ = 2;
144   const int32_t bidirectional_raw_ = HAL_PIXEL_FORMAT_RAW10;
145   const int32_t input_ = 3;
146   const int32_t other = input_;
147 
148   const std::vector<StreamConfiguration> test_configs_ = {
149       {{{output_multisize_non_stalling_,
150          kWidth,
151          kHeight,
152          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
153       {{{output_multisize_non_stalling_,
154          kAlternateWidth,
155          kAlternateHeight,
156          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
157       {{{bidirectional_self_supporting_stalling_,
158          kWidth,
159          kHeight,
160          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT}}},
161       {{{bidirectional_self_supporting_stalling_,
162          kWidth,
163          kHeight,
164          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
165       {{{bidirectional_raw_,
166          kWidth,
167          kHeight,
168          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT}}},
169       {{{bidirectional_raw_,
170          kWidth,
171          kHeight,
172          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
173       {{{input_,
174          kWidth,
175          kHeight,
176          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT}}}};
177   // Raw having a stall duration shouldn't matter,
178   // it should still be counted as the raw type.
179   const std::vector<StreamStallDuration> test_stalls_ = {
180       {{{output_multisize_non_stalling_, kWidth, kHeight, 0}}},
181       {{{output_multisize_non_stalling_,
182          kAlternateWidth,
183          kAlternateHeight,
184          0}}},
185       {{{bidirectional_self_supporting_stalling_, kWidth, kHeight, 10}}},
186       {{{bidirectional_raw_, kWidth, kHeight, 15}}}};
187   // Format 2 can go to itself or 1. 3 and RAW can only go to 1.
188   const ReprocessFormatMap test_reprocess_map_ = {
189       {bidirectional_self_supporting_stalling_,
190        {output_multisize_non_stalling_,
191         bidirectional_self_supporting_stalling_}},
192       {bidirectional_raw_, {output_multisize_non_stalling_}},
193       {input_, {output_multisize_non_stalling_}}};
194   // Codify the above information about format capabilities in some helpful
195   // vectors.
196   int32_t multi_size_format_ = 1;
197   const std::vector<int32_t> input_formats_ = {2, 3, HAL_PIXEL_FORMAT_RAW10};
198   const std::vector<int32_t> output_formats_ = {1, 2, HAL_PIXEL_FORMAT_RAW10};
199 };
200 
TEST_F(StaticPropertiesTest,FactorySuccess)201 TEST_F(StaticPropertiesTest, FactorySuccess) {
202   PrepareDefaultDUT();
203   EXPECT_EQ(dut_->facing(), test_facing_);
204   EXPECT_EQ(dut_->orientation(), test_orientation_);
205 
206   // Stream configurations tested seperately.
207 }
208 
TEST_F(StaticPropertiesTest,FactoryFailedFacing)209 TEST_F(StaticPropertiesTest, FactoryFailedFacing) {
210   SetDefaultExpectations();
211   // Override with a failure expectation.
212   EXPECT_CALL(*mock_reader_, Facing(_)).WillOnce(Return(99));
213   PrepareDUT();
214   EXPECT_EQ(dut_, nullptr);
215 }
216 
TEST_F(StaticPropertiesTest,FactoryFailedOrientation)217 TEST_F(StaticPropertiesTest, FactoryFailedOrientation) {
218   SetDefaultExpectations();
219   // Override with a failure expectation.
220   EXPECT_CALL(*mock_reader_, Orientation(_)).WillOnce(Return(99));
221   PrepareDUT();
222   EXPECT_EQ(dut_, nullptr);
223 }
224 
TEST_F(StaticPropertiesTest,FactoryFailedMaxInputs)225 TEST_F(StaticPropertiesTest, FactoryFailedMaxInputs) {
226   SetDefaultExpectations();
227   // Override with a failure expectation.
228   EXPECT_CALL(*mock_reader_, MaxInputStreams(_)).WillOnce(Return(99));
229   PrepareDUT();
230   EXPECT_EQ(dut_, nullptr);
231 }
232 
TEST_F(StaticPropertiesTest,FactoryFailedMaxOutputs)233 TEST_F(StaticPropertiesTest, FactoryFailedMaxOutputs) {
234   SetDefaultExpectations();
235   // Override with a failure expectation.
236   EXPECT_CALL(*mock_reader_, MaxOutputStreams(_, _, _)).WillOnce(Return(99));
237   PrepareDUT();
238   EXPECT_EQ(dut_, nullptr);
239 }
240 
TEST_F(StaticPropertiesTest,FactoryFailedRequestCapabilities)241 TEST_F(StaticPropertiesTest, FactoryFailedRequestCapabilities) {
242   SetDefaultExpectations();
243   // Override with a failure expectation.
244   EXPECT_CALL(*mock_reader_, RequestCapabilities(_)).WillOnce(Return(99));
245   PrepareDUT();
246   EXPECT_EQ(dut_, nullptr);
247 }
248 
TEST_F(StaticPropertiesTest,FactoryFailedStreamConfigs)249 TEST_F(StaticPropertiesTest, FactoryFailedStreamConfigs) {
250   SetDefaultExpectations();
251   // Override with a failure expectation.
252   EXPECT_CALL(*mock_reader_, StreamConfigurations(_)).WillOnce(Return(99));
253   PrepareDUT();
254   EXPECT_EQ(dut_, nullptr);
255 }
256 
TEST_F(StaticPropertiesTest,FactoryFailedStallDurations)257 TEST_F(StaticPropertiesTest, FactoryFailedStallDurations) {
258   SetDefaultExpectations();
259   // Override with a failure expectation.
260   EXPECT_CALL(*mock_reader_, StreamStallDurations(_)).WillOnce(Return(99));
261   PrepareDUT();
262   EXPECT_EQ(dut_, nullptr);
263 }
264 
TEST_F(StaticPropertiesTest,FactoryFailedReprocessFormats)265 TEST_F(StaticPropertiesTest, FactoryFailedReprocessFormats) {
266   SetDefaultExpectations();
267   // Override with a failure expectation.
268   EXPECT_CALL(*mock_reader_, ReprocessFormats(_)).WillOnce(Return(99));
269   PrepareDUT();
270   EXPECT_EQ(dut_, nullptr);
271 }
272 
TEST_F(StaticPropertiesTest,FactoryNoReprocessFormats)273 TEST_F(StaticPropertiesTest, FactoryNoReprocessFormats) {
274   // If there are no inputs allowed, the reprocess formats shouldn't matter.
275   SetDefaultExpectations();
276   // Override max inputs.
277   EXPECT_CALL(*mock_reader_, MaxInputStreams(_))
278       .WillOnce(DoAll(SetArgPointee<0>(0), Return(0)));
279   // Override reprocess formats with a failure expectation.
280   EXPECT_CALL(*mock_reader_, ReprocessFormats(_))
281       .Times(AtMost(1))
282       .WillOnce(Return(99));
283   PrepareDUT();
284   // Should be ok.
285   EXPECT_NE(dut_, nullptr);
286 }
287 
TEST_F(StaticPropertiesTest,FactoryInvalidCapabilities)288 TEST_F(StaticPropertiesTest, FactoryInvalidCapabilities) {
289   SetDefaultExpectations();
290   // Override configs with an extra output format.
291   std::vector<StreamConfiguration> configs = test_configs_;
292   configs.push_back(
293       {{{5,
294          kWidth,
295          kHeight,
296          ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}});
297   EXPECT_CALL(*mock_reader_, StreamConfigurations(_))
298       .WillOnce(DoAll(SetArgPointee<0>(configs), Return(0)));
299   PrepareDUT();
300   // Should fail because not every output has a stall.
301   EXPECT_EQ(dut_, nullptr);
302 }
303 
TEST_F(StaticPropertiesTest,InvalidReprocessNoInputs)304 TEST_F(StaticPropertiesTest, InvalidReprocessNoInputs) {
305   SetDefaultExpectations();
306   // Override configs by removing all inputs.
307   std::vector<StreamConfiguration> configs = test_configs_;
308   for (auto it = configs.begin(); it != configs.end();) {
309     if ((*it).direction ==
310         ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
311       it = configs.erase(it);
312     } else {
313       ++it;
314     }
315   }
316   EXPECT_CALL(*mock_reader_, StreamConfigurations(_))
317       .WillOnce(DoAll(SetArgPointee<0>(configs), Return(0)));
318   PrepareDUT();
319   // Should fail because inputs are supported but there are no input formats.
320   EXPECT_EQ(dut_, nullptr);
321 }
322 
TEST_F(StaticPropertiesTest,InvalidReprocessExtraInput)323 TEST_F(StaticPropertiesTest, InvalidReprocessExtraInput) {
324   SetDefaultExpectations();
325   // Override configs with an extra input format.
326   std::vector<StreamConfiguration> configs = test_configs_;
327   configs.push_back({{{5,
328                        kWidth,
329                        kHeight,
330                        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT}}});
331   EXPECT_CALL(*mock_reader_, StreamConfigurations(_))
332       .WillOnce(DoAll(SetArgPointee<0>(configs), Return(0)));
333   PrepareDUT();
334   // Should fail because no reprocess outputs are listed for the extra input.
335   EXPECT_EQ(dut_, nullptr);
336 }
337 
TEST_F(StaticPropertiesTest,InvalidReprocessExtraMapEntry)338 TEST_F(StaticPropertiesTest, InvalidReprocessExtraMapEntry) {
339   SetDefaultExpectations();
340   // Override the reprocess map with an extra entry.
341   ReprocessFormatMap reprocess_map = test_reprocess_map_;
342   reprocess_map[5] = {1};
343   EXPECT_CALL(*mock_reader_, ReprocessFormats(_))
344       .WillOnce(DoAll(SetArgPointee<0>(reprocess_map), Return(0)));
345   PrepareDUT();
346   // Should fail because the extra map entry doesn't correspond to an input.
347   EXPECT_EQ(dut_, nullptr);
348 }
349 
TEST_F(StaticPropertiesTest,InvalidReprocessWrongMapEntries)350 TEST_F(StaticPropertiesTest, InvalidReprocessWrongMapEntries) {
351   SetDefaultExpectations();
352   // Override the reprocess map replacing the entry for the
353   // input-only format with the output-only format.
354   ReprocessFormatMap reprocess_map = test_reprocess_map_;
355   reprocess_map.erase(input_);
356   reprocess_map[output_multisize_non_stalling_] = {1};
357   EXPECT_CALL(*mock_reader_, ReprocessFormats(_))
358       .WillOnce(DoAll(SetArgPointee<0>(reprocess_map), Return(0)));
359   PrepareDUT();
360   // Should fail because not all input formats are present/
361   // one of the map "input" formats is output only.
362   EXPECT_EQ(dut_, nullptr);
363 }
364 
TEST_F(StaticPropertiesTest,InvalidReprocessNotAnOutput)365 TEST_F(StaticPropertiesTest, InvalidReprocessNotAnOutput) {
366   SetDefaultExpectations();
367   // Override the reprocess map with a non-output output entry.
368   ReprocessFormatMap reprocess_map = test_reprocess_map_;
369   reprocess_map[input_].insert(input_);
370   EXPECT_CALL(*mock_reader_, ReprocessFormats(_))
371       .WillOnce(DoAll(SetArgPointee<0>(reprocess_map), Return(0)));
372   PrepareDUT();
373   // Should fail because a specified output format doesn't support output.
374   EXPECT_EQ(dut_, nullptr);
375 }
376 
TEST_F(StaticPropertiesTest,TemplatesValid)377 TEST_F(StaticPropertiesTest, TemplatesValid) {
378   PrepareDefaultDUT();
379   for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; ++i) {
380     EXPECT_TRUE(dut_->TemplateSupported(i));
381   }
382 }
383 
TEST_F(StaticPropertiesTest,ConfigureSingleOutput)384 TEST_F(StaticPropertiesTest, ConfigureSingleOutput) {
385   std::vector<camera3_stream_t> streams;
386   streams.push_back(MakeStream(output_multisize_non_stalling_));
387   ExpectConfigurationSupported(streams, true);
388 }
389 
TEST_F(StaticPropertiesTest,ConfigureMultipleOutputs)390 TEST_F(StaticPropertiesTest, ConfigureMultipleOutputs) {
391   std::vector<camera3_stream_t> streams;
392   // 2 outputs, of different sizes.
393   streams.push_back(MakeStream(bidirectional_raw_));
394   // Use the alternate size.
395   streams.push_back(MakeStream(output_multisize_non_stalling_,
396                                true,
397                                false,
398                                kAlternateWidth,
399                                kAlternateHeight));
400   ExpectConfigurationSupported(streams, true);
401 }
402 
TEST_F(StaticPropertiesTest,ConfigureInput)403 TEST_F(StaticPropertiesTest, ConfigureInput) {
404   std::vector<camera3_stream_t> streams;
405   // Single input -> different output.
406   streams.push_back(MakeStream(input_, false, true));
407   // Use the alternate size, it should be ok.
408   streams.push_back(MakeStream(output_multisize_non_stalling_,
409                                true,
410                                false,
411                                kAlternateWidth,
412                                kAlternateHeight));
413   ExpectConfigurationSupported(streams, true);
414 }
415 
TEST_F(StaticPropertiesTest,ConfigureBidirectional)416 TEST_F(StaticPropertiesTest, ConfigureBidirectional) {
417   std::vector<camera3_stream_t> streams;
418   // Single input -> same output.
419   streams.push_back(
420       MakeStream(bidirectional_self_supporting_stalling_, true, true));
421   ExpectConfigurationSupported(streams, true);
422 }
423 
TEST_F(StaticPropertiesTest,ConfigureMultipleReprocess)424 TEST_F(StaticPropertiesTest, ConfigureMultipleReprocess) {
425   std::vector<camera3_stream_t> streams;
426   // Single input -> multiple outputs.
427   streams.push_back(
428       MakeStream(bidirectional_self_supporting_stalling_, true, true));
429   streams.push_back(MakeStream(output_multisize_non_stalling_));
430   ExpectConfigurationSupported(streams, true);
431 }
432 
TEST_F(StaticPropertiesTest,ConfigureNull)433 TEST_F(StaticPropertiesTest, ConfigureNull) {
434   PrepareDefaultDUT();
435   EXPECT_FALSE(dut_->StreamConfigurationSupported(nullptr));
436 }
437 
TEST_F(StaticPropertiesTest,ConfigureEmptyStreams)438 TEST_F(StaticPropertiesTest, ConfigureEmptyStreams) {
439   std::vector<camera3_stream_t*> streams(1);
440   camera3_stream_configuration_t config = {
441       0, streams.data(), CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, nullptr};
442   PrepareDefaultDUT();
443   EXPECT_FALSE(dut_->StreamConfigurationSupported(&config));
444 }
445 
TEST_F(StaticPropertiesTest,ConfigureNullStreams)446 TEST_F(StaticPropertiesTest, ConfigureNullStreams) {
447   std::vector<camera3_stream_t*> streams(2, nullptr);
448   camera3_stream_configuration_t config = {
449       static_cast<uint32_t>(streams.size()),
450       streams.data(),
451       CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE,
452       nullptr};
453   PrepareDefaultDUT();
454   EXPECT_FALSE(dut_->StreamConfigurationSupported(&config));
455 }
456 
TEST_F(StaticPropertiesTest,ConfigureNullStreamVector)457 TEST_F(StaticPropertiesTest, ConfigureNullStreamVector) {
458   // Even if the camera claims to have multiple streams, check for null.
459   camera3_stream_configuration_t config = {
460       3, nullptr, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, nullptr};
461   PrepareDefaultDUT();
462   EXPECT_FALSE(dut_->StreamConfigurationSupported(&config));
463 }
464 
TEST_F(StaticPropertiesTest,ConfigureNoOutput)465 TEST_F(StaticPropertiesTest, ConfigureNoOutput) {
466   std::vector<camera3_stream_t> streams;
467   // Only an input stream, no output.
468   streams.push_back(MakeStream(input_, false, true));
469   ExpectConfigurationSupported(streams, false);
470 }
471 
TEST_F(StaticPropertiesTest,ConfigureInvalidType)472 TEST_F(StaticPropertiesTest, ConfigureInvalidType) {
473   std::vector<camera3_stream_t> streams;
474   // Not input, output, or bidirectional.
475   streams.push_back(MakeStream(output_multisize_non_stalling_, false, false));
476   ExpectConfigurationSupported(streams, false);
477 }
478 
TEST_F(StaticPropertiesTest,ConfigureSpecFormatDoesNotExist)479 TEST_F(StaticPropertiesTest, ConfigureSpecFormatDoesNotExist) {
480   std::vector<camera3_stream_t> streams;
481   // Format 99 is not supported in any form.
482   streams.push_back(MakeStream(99));
483   ExpectConfigurationSupported(streams, false);
484 }
485 
TEST_F(StaticPropertiesTest,ConfigureSpecSizeDoesNotExist)486 TEST_F(StaticPropertiesTest, ConfigureSpecSizeDoesNotExist) {
487   std::vector<camera3_stream_t> streams;
488   // Size 99 x 99 not supported for the output format.
489   streams.push_back(
490       MakeStream(output_multisize_non_stalling_, true, false, 99, 99));
491   ExpectConfigurationSupported(streams, false);
492 }
493 
TEST_F(StaticPropertiesTest,ConfigureNotAnInput)494 TEST_F(StaticPropertiesTest, ConfigureNotAnInput) {
495   std::vector<camera3_stream_t> streams;
496   streams.push_back(MakeStream(output_multisize_non_stalling_));
497   // Can't use output-only format as an input.
498   streams.push_back(MakeStream(output_multisize_non_stalling_, false, true));
499   ExpectConfigurationSupported(streams, false);
500 }
501 
TEST_F(StaticPropertiesTest,ConfigureNotAnOutput)502 TEST_F(StaticPropertiesTest, ConfigureNotAnOutput) {
503   std::vector<camera3_stream_t> streams;
504   // Can't use input-only format as an output.
505   streams.push_back(MakeStream(input_));
506   ExpectConfigurationSupported(streams, false);
507 }
508 
TEST_F(StaticPropertiesTest,ConfigureTooManyInputs)509 TEST_F(StaticPropertiesTest, ConfigureTooManyInputs) {
510   std::vector<camera3_stream_t> streams;
511   // At the threshold is ok.
512   for (int32_t i = 0; i < test_max_inputs_; ++i) {
513     streams.push_back(MakeStream(input_, false, true));
514   }
515   // Have a valid output still.
516   streams.push_back(MakeStream(output_multisize_non_stalling_));
517   ExpectConfigurationSupported(streams, false);
518 
519   // Reset.
520   mock_reader_ = std::make_unique<MetadataReaderMock>();
521   streams.clear();
522 
523   // Try again with too many.
524   for (int32_t i = 0; i <= test_max_inputs_; ++i) {
525     streams.push_back(MakeStream(input_, false, true));
526   }
527   // Have a valid output still.
528   streams.push_back(MakeStream(output_multisize_non_stalling_));
529   ExpectConfigurationSupported(streams, false);
530 }
531 
TEST_F(StaticPropertiesTest,ConfigureTooManyRaw)532 TEST_F(StaticPropertiesTest, ConfigureTooManyRaw) {
533   std::vector<camera3_stream_t> streams;
534   // At the threshold is ok.
535   for (int32_t i = 0; i < test_max_raw_outputs_; ++i) {
536     streams.push_back(MakeStream(bidirectional_raw_));
537   }
538   ExpectConfigurationSupported(streams, true);
539 
540   // Reset.
541   mock_reader_ = std::make_unique<MetadataReaderMock>();
542   streams.clear();
543 
544   // Try again with too many.
545   for (int32_t i = 0; i <= test_max_raw_outputs_; ++i) {
546     streams.push_back(MakeStream(bidirectional_raw_));
547   }
548   ExpectConfigurationSupported(streams, false);
549 }
550 
TEST_F(StaticPropertiesTest,ConfigureTooManyStalling)551 TEST_F(StaticPropertiesTest, ConfigureTooManyStalling) {
552   std::vector<camera3_stream_t> streams;
553   // At the threshold is ok.
554   for (int32_t i = 0; i < test_max_stalling_outputs_; ++i) {
555     streams.push_back(MakeStream(bidirectional_self_supporting_stalling_));
556   }
557   ExpectConfigurationSupported(streams, true);
558 
559   // Reset.
560   mock_reader_ = std::make_unique<MetadataReaderMock>();
561   streams.clear();
562 
563   // Try again with too many.
564   for (int32_t i = 0; i <= test_max_stalling_outputs_; ++i) {
565     streams.push_back(MakeStream(bidirectional_self_supporting_stalling_));
566   }
567   ExpectConfigurationSupported(streams, false);
568 }
569 
TEST_F(StaticPropertiesTest,ConfigureTooManyNonStalling)570 TEST_F(StaticPropertiesTest, ConfigureTooManyNonStalling) {
571   std::vector<camera3_stream_t> streams;
572   // At the threshold is ok.
573   for (int32_t i = 0; i < test_max_non_stalling_outputs_; ++i) {
574     streams.push_back(MakeStream(output_multisize_non_stalling_));
575   }
576   ExpectConfigurationSupported(streams, true);
577 
578   // Reset.
579   mock_reader_ = std::make_unique<MetadataReaderMock>();
580   streams.clear();
581 
582   // Try again with too many.
583   for (int32_t i = 0; i <= test_max_non_stalling_outputs_; ++i) {
584     streams.push_back(MakeStream(output_multisize_non_stalling_));
585   }
586   ExpectConfigurationSupported(streams, false);
587 }
588 
TEST_F(StaticPropertiesTest,ConfigureUnuspportedInput)589 TEST_F(StaticPropertiesTest, ConfigureUnuspportedInput) {
590   std::vector<camera3_stream_t> streams;
591   streams.push_back(MakeStream(input_, false, true));
592   streams.push_back(MakeStream(bidirectional_raw_));
593   // No matching output format for input.
594   ExpectConfigurationSupported(streams, false);
595 }
596 
TEST_F(StaticPropertiesTest,ConfigureUnsupportedOutput)597 TEST_F(StaticPropertiesTest, ConfigureUnsupportedOutput) {
598   std::vector<camera3_stream_t> streams;
599   streams.push_back(MakeStream(input_, false, true));
600   // The universal output does match input.
601   streams.push_back(MakeStream(output_multisize_non_stalling_));
602   // Raw does not match input.
603   streams.push_back(MakeStream(bidirectional_raw_));
604   // Input is matched; it's ok that raw doesn't match (only the actual
605   // requests care).
606   ExpectConfigurationSupported(streams, true);
607 }
608 
TEST_F(StaticPropertiesTest,ConfigureUnsupportedBidirectional)609 TEST_F(StaticPropertiesTest, ConfigureUnsupportedBidirectional) {
610   std::vector<camera3_stream_t> streams;
611   // The test raw format, while supporting both input and output,
612   // does not actually support itself.
613   streams.push_back(MakeStream(bidirectional_raw_, true, true));
614   ExpectConfigurationSupported(streams, false);
615 }
616 
TEST_F(StaticPropertiesTest,ConfigureBadOperationMode)617 TEST_F(StaticPropertiesTest, ConfigureBadOperationMode) {
618   // A valid stream set.
619   camera3_stream_t stream = MakeStream(output_multisize_non_stalling_);
620   camera3_stream_t* stream_address = &stream;
621   // But not a valid config.
622   camera3_stream_configuration_t config = {
623       1,
624       &stream_address,
625       99, // Not a valid operation mode.
626       nullptr
627   };
628   PrepareDefaultDUT();
629   EXPECT_FALSE(dut_->StreamConfigurationSupported(&config));
630 }
631 
TEST_F(StaticPropertiesTest,ReprocessingSingleOutput)632 TEST_F(StaticPropertiesTest, ReprocessingSingleOutput) {
633   camera3_stream_t input_stream = MakeStream(input_);
634   camera3_stream_t output_stream = MakeStream(output_multisize_non_stalling_);
635   PrepareDefaultDUT();
636   EXPECT_TRUE(dut_->ReprocessingSupported(&input_stream, {&output_stream}));
637 }
638 
TEST_F(StaticPropertiesTest,ReprocessingMultipleOutputs)639 TEST_F(StaticPropertiesTest, ReprocessingMultipleOutputs) {
640   camera3_stream_t input_stream =
641       MakeStream(bidirectional_self_supporting_stalling_, false, true);
642   // Bi-directional self-supporting supports the universal output and itself.
643   camera3_stream_t output_stream1 = MakeStream(output_multisize_non_stalling_);
644   camera3_stream_t output_stream2 =
645       MakeStream(bidirectional_self_supporting_stalling_);
646   PrepareDefaultDUT();
647   EXPECT_TRUE(dut_->ReprocessingSupported(&input_stream,
648                                           {&output_stream1, &output_stream2}));
649 }
650 
TEST_F(StaticPropertiesTest,ReprocessingNoInput)651 TEST_F(StaticPropertiesTest, ReprocessingNoInput) {
652   camera3_stream_t output_stream = MakeStream(output_multisize_non_stalling_);
653   PrepareDefaultDUT();
654   EXPECT_FALSE(dut_->ReprocessingSupported(nullptr, {&output_stream}));
655 }
656 
TEST_F(StaticPropertiesTest,ReprocessingNoOutput)657 TEST_F(StaticPropertiesTest, ReprocessingNoOutput) {
658   camera3_stream_t input_stream = MakeStream(input_);
659   PrepareDefaultDUT();
660   EXPECT_FALSE(dut_->ReprocessingSupported(&input_stream, {}));
661 }
662 
TEST_F(StaticPropertiesTest,ReprocessingInvalidOutput)663 TEST_F(StaticPropertiesTest, ReprocessingInvalidOutput) {
664   camera3_stream_t input_stream = MakeStream(input_, false, true);
665   // The universal output does match input.
666   camera3_stream_t output_stream1 = MakeStream(output_multisize_non_stalling_);
667   // Raw does not match input.
668   camera3_stream_t output_stream2 = MakeStream(bidirectional_raw_);
669   PrepareDefaultDUT();
670   EXPECT_FALSE(dut_->ReprocessingSupported(&input_stream,
671                                            {&output_stream1, &output_stream2}));
672 }
673 
674 }  // namespace default_camera_hal
675