1 /*
2  * libjingle
3  * Copyright 2004 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "talk/media/devices/devicemanager.h"
29 
30 #ifdef WIN32
31 #include <objbase.h>
32 #include "webrtc/base/win32.h"
33 #endif
34 #include <string>
35 
36 #include "talk/media/base/fakevideocapturer.h"
37 #include "talk/media/base/screencastid.h"
38 #include "talk/media/base/testutils.h"
39 #include "talk/media/base/videocapturerfactory.h"
40 #include "talk/media/devices/filevideocapturer.h"
41 #include "talk/media/devices/v4llookup.h"
42 #include "webrtc/base/arraysize.h"
43 #include "webrtc/base/fileutils.h"
44 #include "webrtc/base/gunit.h"
45 #include "webrtc/base/logging.h"
46 #include "webrtc/base/pathutils.h"
47 #include "webrtc/base/scoped_ptr.h"
48 #include "webrtc/base/stream.h"
49 #include "webrtc/base/windowpickerfactory.h"
50 
51 #ifdef WEBRTC_LINUX
52 // TODO(juberti): Figure out why this doesn't compile on Windows.
53 #include "webrtc/base/fileutils_mock.h"
54 #endif  // WEBRTC_LINUX
55 
56 using rtc::Pathname;
57 using rtc::FileTimeType;
58 using rtc::scoped_ptr;
59 using cricket::Device;
60 using cricket::DeviceManager;
61 using cricket::DeviceManagerFactory;
62 using cricket::DeviceManagerInterface;
63 
64 const cricket::VideoFormat kVgaFormat(640, 480,
65                                       cricket::VideoFormat::FpsToInterval(30),
66                                       cricket::FOURCC_I420);
67 const cricket::VideoFormat kHdFormat(1280, 720,
68                                      cricket::VideoFormat::FpsToInterval(30),
69                                      cricket::FOURCC_I420);
70 
71 class FakeVideoDeviceCapturerFactory :
72     public cricket::VideoDeviceCapturerFactory {
73  public:
FakeVideoDeviceCapturerFactory()74   FakeVideoDeviceCapturerFactory() {}
~FakeVideoDeviceCapturerFactory()75   virtual ~FakeVideoDeviceCapturerFactory() {}
76 
Create(const cricket::Device & device)77   virtual cricket::VideoCapturer* Create(const cricket::Device& device) {
78     return new cricket::FakeVideoCapturer;
79   }
80 };
81 
82 class FakeScreenCapturerFactory : public cricket::ScreenCapturerFactory {
83  public:
FakeScreenCapturerFactory()84   FakeScreenCapturerFactory() {}
~FakeScreenCapturerFactory()85   virtual ~FakeScreenCapturerFactory() {}
86 
Create(const cricket::ScreencastId & screenid)87   virtual cricket::VideoCapturer* Create(
88       const cricket::ScreencastId& screenid) {
89     return new cricket::FakeVideoCapturer;
90   }
91 };
92 
93 class DeviceManagerTestFake : public testing::Test {
94  public:
SetUp()95   virtual void SetUp() {
96     dm_.reset(DeviceManagerFactory::Create());
97     EXPECT_TRUE(dm_->Init());
98     DeviceManager* device_manager = static_cast<DeviceManager*>(dm_.get());
99     device_manager->SetVideoDeviceCapturerFactory(
100         new FakeVideoDeviceCapturerFactory());
101     device_manager->SetScreenCapturerFactory(
102         new FakeScreenCapturerFactory());
103   }
104 
TearDown()105   virtual void TearDown() {
106     dm_->Terminate();
107   }
108 
109  protected:
110   scoped_ptr<DeviceManagerInterface> dm_;
111 };
112 
113 
114 // Test that we startup/shutdown properly.
TEST(DeviceManagerTest,StartupShutdown)115 TEST(DeviceManagerTest, StartupShutdown) {
116   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
117   EXPECT_TRUE(dm->Init());
118   dm->Terminate();
119 }
120 
121 // Test CoInitEx behavior
122 #ifdef WIN32
TEST(DeviceManagerTest,CoInitialize)123 TEST(DeviceManagerTest, CoInitialize) {
124   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
125   std::vector<Device> devices;
126   // Ensure that calls to video device work if COM is not yet initialized.
127   EXPECT_TRUE(dm->Init());
128   EXPECT_TRUE(dm->GetVideoCaptureDevices(&devices));
129   dm->Terminate();
130   // Ensure that the ref count is correct.
131   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
132   CoUninitialize();
133   // Ensure that Init works in COINIT_APARTMENTTHREADED setting.
134   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
135   EXPECT_TRUE(dm->Init());
136   dm->Terminate();
137   CoUninitialize();
138   // Ensure that the ref count is correct.
139   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
140   CoUninitialize();
141   // Ensure that Init works in COINIT_MULTITHREADED setting.
142   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
143   EXPECT_TRUE(dm->Init());
144   dm->Terminate();
145   CoUninitialize();
146   // Ensure that the ref count is correct.
147   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
148   CoUninitialize();
149 }
150 #endif
151 
152 // Test enumerating devices (although we may not find any).
TEST(DeviceManagerTest,GetDevices)153 TEST(DeviceManagerTest, GetDevices) {
154   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
155   std::vector<Device> audio_ins, audio_outs, video_ins;
156   std::vector<cricket::Device> video_in_devs;
157   cricket::Device def_video;
158   EXPECT_TRUE(dm->Init());
159   EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
160   EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
161   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
162   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_in_devs));
163   EXPECT_EQ(video_ins.size(), video_in_devs.size());
164   // If we have any video devices, we should be able to pick a default.
165   EXPECT_TRUE(dm->GetVideoCaptureDevice(
166       cricket::DeviceManagerInterface::kDefaultDeviceName, &def_video)
167       != video_ins.empty());
168 }
169 
170 // Test that we return correct ids for default and bogus devices.
TEST(DeviceManagerTest,GetAudioDeviceIds)171 TEST(DeviceManagerTest, GetAudioDeviceIds) {
172   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
173   Device device;
174   EXPECT_TRUE(dm->Init());
175   EXPECT_TRUE(dm->GetAudioInputDevice(
176       cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
177   EXPECT_EQ("-1", device.id);
178   EXPECT_TRUE(dm->GetAudioOutputDevice(
179       cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
180   EXPECT_EQ("-1", device.id);
181   EXPECT_FALSE(dm->GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
182   EXPECT_FALSE(dm->GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
183 }
184 
185 // Test that we get the video capture device by name properly.
TEST(DeviceManagerTest,GetVideoDeviceIds)186 TEST(DeviceManagerTest, GetVideoDeviceIds) {
187   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
188   Device device;
189   EXPECT_TRUE(dm->Init());
190   EXPECT_FALSE(dm->GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
191   std::vector<Device> video_ins;
192   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
193   if (!video_ins.empty()) {
194     // Get the default device with the parameter kDefaultDeviceName.
195     EXPECT_TRUE(dm->GetVideoCaptureDevice(
196         cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
197 
198     // Get the first device with the parameter video_ins[0].name.
199     EXPECT_TRUE(dm->GetVideoCaptureDevice(video_ins[0].name, &device));
200     EXPECT_EQ(device.name, video_ins[0].name);
201     EXPECT_EQ(device.id, video_ins[0].id);
202   }
203 }
204 
TEST(DeviceManagerTest,GetVideoDeviceIds_File)205 TEST(DeviceManagerTest, GetVideoDeviceIds_File) {
206   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
207   EXPECT_TRUE(dm->Init());
208   Device device;
209   const std::string test_file =
210       cricket::GetTestFilePath("captured-320x240-2s-48.frames");
211   EXPECT_TRUE(dm->GetVideoCaptureDevice(test_file, &device));
212   EXPECT_TRUE(cricket::FileVideoCapturer::IsFileVideoCapturerDevice(device));
213 }
214 
TEST(DeviceManagerTest,VerifyDevicesListsAreCleared)215 TEST(DeviceManagerTest, VerifyDevicesListsAreCleared) {
216   const std::string imaginary("_NOT A REAL DEVICE_");
217   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
218   std::vector<Device> audio_ins, audio_outs, video_ins;
219   audio_ins.push_back(Device(imaginary, imaginary));
220   audio_outs.push_back(Device(imaginary, imaginary));
221   video_ins.push_back(Device(imaginary, imaginary));
222   EXPECT_TRUE(dm->Init());
223   EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
224   EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
225   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
226   for (size_t i = 0; i < audio_ins.size(); ++i) {
227     EXPECT_NE(imaginary, audio_ins[i].name);
228   }
229   for (size_t i = 0; i < audio_outs.size(); ++i) {
230     EXPECT_NE(imaginary, audio_outs[i].name);
231   }
232   for (size_t i = 0; i < video_ins.size(); ++i) {
233     EXPECT_NE(imaginary, video_ins[i].name);
234   }
235 }
236 
CompareDeviceList(std::vector<Device> & devices,const char * const device_list[],int list_size)237 static bool CompareDeviceList(std::vector<Device>& devices,
238     const char* const device_list[], int list_size) {
239   if (list_size != static_cast<int>(devices.size())) {
240     return false;
241   }
242   for (int i = 0; i < list_size; ++i) {
243     if (devices[i].name.compare(device_list[i]) != 0) {
244       return false;
245     }
246   }
247   return true;
248 }
249 
TEST(DeviceManagerTest,VerifyFilterDevices)250 TEST(DeviceManagerTest, VerifyFilterDevices) {
251   static const char* const kTotalDevicesName[] = {
252       "Google Camera Adapters are tons of fun.",
253       "device1",
254       "device2",
255       "device3",
256       "device4",
257       "device5",
258       "Google Camera Adapter 0",
259       "Google Camera Adapter 1",
260   };
261   static const char* const kFilteredDevicesName[] = {
262       "device2",
263       "device4",
264       "Google Camera Adapter",
265       NULL,
266   };
267   static const char* const kDevicesName[] = {
268       "device1",
269       "device3",
270       "device5",
271   };
272   std::vector<Device> devices;
273   for (int i = 0; i < arraysize(kTotalDevicesName); ++i) {
274     devices.push_back(Device(kTotalDevicesName[i], i));
275   }
276   EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
277                                 arraysize(kTotalDevicesName)));
278   // Return false if given NULL as the exclusion list.
279   EXPECT_TRUE(DeviceManager::FilterDevices(&devices, NULL));
280   // The devices should not change.
281   EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
282                                 arraysize(kTotalDevicesName)));
283   EXPECT_TRUE(DeviceManager::FilterDevices(&devices, kFilteredDevicesName));
284   EXPECT_TRUE(CompareDeviceList(devices, kDevicesName,
285                                 arraysize(kDevicesName)));
286 }
287 
288 #ifdef WEBRTC_LINUX
289 class FakeV4LLookup : public cricket::V4LLookup {
290  public:
FakeV4LLookup(std::vector<std::string> device_paths)291   explicit FakeV4LLookup(std::vector<std::string> device_paths)
292       : device_paths_(device_paths) {}
293 
294  protected:
CheckIsV4L2Device(const std::string & device)295   bool CheckIsV4L2Device(const std::string& device) {
296     return std::find(device_paths_.begin(), device_paths_.end(), device)
297         != device_paths_.end();
298   }
299 
300  private:
301   std::vector<std::string> device_paths_;
302 };
303 
TEST(DeviceManagerTest,GetVideoCaptureDevices_K2_6)304 TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_6) {
305   std::vector<std::string> devices;
306   devices.push_back("/dev/video0");
307   devices.push_back("/dev/video5");
308   cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
309 
310   std::vector<rtc::FakeFileSystem::File> files;
311   files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
312   files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
313   files.push_back(rtc::FakeFileSystem::File(
314       "/sys/class/video4linux/video0/name", "Video Device 1"));
315   files.push_back(rtc::FakeFileSystem::File(
316       "/sys/class/video4linux/video1/model", "Bad Device"));
317   files.push_back(
318       rtc::FakeFileSystem::File("/sys/class/video4linux/video5/model",
319                                       "Video Device 2"));
320   rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
321 
322   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
323   std::vector<Device> video_ins;
324   EXPECT_TRUE(dm->Init());
325   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
326   EXPECT_EQ(2u, video_ins.size());
327   EXPECT_EQ("Video Device 1", video_ins.at(0).name);
328   EXPECT_EQ("Video Device 2", video_ins.at(1).name);
329 }
330 
TEST(DeviceManagerTest,GetVideoCaptureDevices_K2_4)331 TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_4) {
332   std::vector<std::string> devices;
333   devices.push_back("/dev/video0");
334   devices.push_back("/dev/video5");
335   cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
336 
337   std::vector<rtc::FakeFileSystem::File> files;
338   files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
339   files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
340   files.push_back(rtc::FakeFileSystem::File(
341           "/proc/video/dev/video0",
342           "param1: value1\nname: Video Device 1\n param2: value2\n"));
343   files.push_back(rtc::FakeFileSystem::File(
344           "/proc/video/dev/video1",
345           "param1: value1\nname: Bad Device\n param2: value2\n"));
346   files.push_back(rtc::FakeFileSystem::File(
347           "/proc/video/dev/video5",
348           "param1: value1\nname:   Video Device 2\n param2: value2\n"));
349   rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
350 
351   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
352   std::vector<Device> video_ins;
353   EXPECT_TRUE(dm->Init());
354   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
355   EXPECT_EQ(2u, video_ins.size());
356   EXPECT_EQ("Video Device 1", video_ins.at(0).name);
357   EXPECT_EQ("Video Device 2", video_ins.at(1).name);
358 }
359 
TEST(DeviceManagerTest,GetVideoCaptureDevices_KUnknown)360 TEST(DeviceManagerTest, GetVideoCaptureDevices_KUnknown) {
361   std::vector<std::string> devices;
362   devices.push_back("/dev/video0");
363   devices.push_back("/dev/video5");
364   cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
365 
366   std::vector<rtc::FakeFileSystem::File> files;
367   files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
368   files.push_back(rtc::FakeFileSystem::File("/dev/video1", ""));
369   files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
370   rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
371 
372   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
373   std::vector<Device> video_ins;
374   EXPECT_TRUE(dm->Init());
375   EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
376   EXPECT_EQ(2u, video_ins.size());
377   EXPECT_EQ("/dev/video0", video_ins.at(0).name);
378   EXPECT_EQ("/dev/video5", video_ins.at(1).name);
379 }
380 #endif  // WEBRTC_LINUX
381 
382 // TODO(noahric): These are flaky on windows on headless machines.
383 #ifndef WIN32
TEST(DeviceManagerTest,GetWindows)384 TEST(DeviceManagerTest, GetWindows) {
385   if (!rtc::WindowPickerFactory::IsSupported()) {
386     LOG(LS_INFO) << "skipping test: window capturing is not supported with "
387                  << "current configuration.";
388     return;
389   }
390   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
391   dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
392   std::vector<rtc::WindowDescription> descriptions;
393   EXPECT_TRUE(dm->Init());
394   if (!dm->GetWindows(&descriptions) || descriptions.empty()) {
395     LOG(LS_INFO) << "skipping test: window capturing. Does not have any "
396                  << "windows to capture.";
397     return;
398   }
399   scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
400       cricket::ScreencastId(descriptions.front().id())));
401   EXPECT_FALSE(capturer.get() == NULL);
402   // TODO(hellner): creating a window capturer and immediately deleting it
403   // results in "Continuous Build and Test Mainline - Mac opt" failure (crash).
404   // Remove the following line as soon as this has been resolved.
405   rtc::Thread::Current()->ProcessMessages(1);
406 }
407 
TEST(DeviceManagerTest,GetDesktops)408 TEST(DeviceManagerTest, GetDesktops) {
409   if (!rtc::WindowPickerFactory::IsSupported()) {
410     LOG(LS_INFO) << "skipping test: desktop capturing is not supported with "
411                  << "current configuration.";
412     return;
413   }
414   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
415   dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
416   std::vector<rtc::DesktopDescription> descriptions;
417   EXPECT_TRUE(dm->Init());
418   if (!dm->GetDesktops(&descriptions) || descriptions.empty()) {
419     LOG(LS_INFO) << "skipping test: desktop capturing. Does not have any "
420                  << "desktops to capture.";
421     return;
422   }
423   scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
424       cricket::ScreencastId(descriptions.front().id())));
425   EXPECT_FALSE(capturer.get() == NULL);
426 }
427 #endif  // !WIN32
428 
TEST_F(DeviceManagerTestFake,CaptureConstraintsWhitelisted)429 TEST_F(DeviceManagerTestFake, CaptureConstraintsWhitelisted) {
430   const Device device("white", "white_id");
431   dm_->SetVideoCaptureDeviceMaxFormat(device.name, kHdFormat);
432   scoped_ptr<cricket::VideoCapturer> capturer(
433       dm_->CreateVideoCapturer(device));
434   cricket::VideoFormat best_format;
435   capturer->set_enable_camera_list(true);
436   EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
437   EXPECT_EQ(kHdFormat, best_format);
438 }
439 
TEST_F(DeviceManagerTestFake,CaptureConstraintsNotWhitelisted)440 TEST_F(DeviceManagerTestFake, CaptureConstraintsNotWhitelisted) {
441   const Device device("regular", "regular_id");
442   scoped_ptr<cricket::VideoCapturer> capturer(
443       dm_->CreateVideoCapturer(device));
444   cricket::VideoFormat best_format;
445   capturer->set_enable_camera_list(true);
446   EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
447   EXPECT_EQ(kHdFormat, best_format);
448 }
449 
TEST_F(DeviceManagerTestFake,CaptureConstraintsUnWhitelisted)450 TEST_F(DeviceManagerTestFake, CaptureConstraintsUnWhitelisted) {
451   const Device device("un_white", "un_white_id");
452   dm_->SetVideoCaptureDeviceMaxFormat(device.name, kHdFormat);
453   dm_->ClearVideoCaptureDeviceMaxFormat(device.name);
454   scoped_ptr<cricket::VideoCapturer> capturer(
455       dm_->CreateVideoCapturer(device));
456   cricket::VideoFormat best_format;
457   capturer->set_enable_camera_list(true);
458   EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
459   EXPECT_EQ(kHdFormat, best_format);
460 }
461 
TEST_F(DeviceManagerTestFake,CaptureConstraintsWildcard)462 TEST_F(DeviceManagerTestFake, CaptureConstraintsWildcard) {
463   const Device device("any_device", "any_device");
464   dm_->SetVideoCaptureDeviceMaxFormat("*", kHdFormat);
465   scoped_ptr<cricket::VideoCapturer> capturer(
466       dm_->CreateVideoCapturer(device));
467   cricket::VideoFormat best_format;
468   capturer->set_enable_camera_list(true);
469   EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
470   EXPECT_EQ(kHdFormat, best_format);
471 }
472