1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <assert.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <string.h>
9 
10 #include <vector>
11 
12 #include "ppapi/c/dev/ppb_video_capture_dev.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/cpp/completion_callback.h"
15 #include "ppapi/cpp/dev/device_ref_dev.h"
16 #include "ppapi/cpp/dev/video_capture_client_dev.h"
17 #include "ppapi/cpp/dev/video_capture_dev.h"
18 #include "ppapi/cpp/instance.h"
19 #include "ppapi/cpp/module.h"
20 #include "ppapi/cpp/private/flash.h"
21 #include "ppapi/cpp/var.h"
22 #include "ppapi/utility/completion_callback_factory.h"
23 
24 // When compiling natively on Windows, PostMessage can be #define-d to
25 // something else.
26 #ifdef PostMessage
27 #undef PostMessage
28 #endif
29 
30 namespace {
31 
32 // This object is the global object representing this plugin library as long
33 // as it is loaded.
34 class EnumerateDevicesDemoModule : public pp::Module {
35  public:
EnumerateDevicesDemoModule()36   EnumerateDevicesDemoModule() : pp::Module() {}
~EnumerateDevicesDemoModule()37   virtual ~EnumerateDevicesDemoModule() {}
38   virtual pp::Instance* CreateInstance(PP_Instance instance);
39 };
40 
41 class EnumerateDevicesDemoInstance : public pp::Instance,
42                                      public pp::VideoCaptureClient_Dev {
43  public:
44   EnumerateDevicesDemoInstance(PP_Instance instance, pp::Module* module);
45   virtual ~EnumerateDevicesDemoInstance();
46 
47   // pp::Instance implementation (see PPP_Instance).
48   virtual void HandleMessage(const pp::Var& message_data);
49 
50   // pp::VideoCaptureClient_Dev implementation.
OnDeviceInfo(PP_Resource resource,const PP_VideoCaptureDeviceInfo_Dev & info,const std::vector<pp::Buffer_Dev> & buffers)51   virtual void OnDeviceInfo(PP_Resource resource,
52                             const PP_VideoCaptureDeviceInfo_Dev& info,
53                             const std::vector<pp::Buffer_Dev>& buffers) {}
OnStatus(PP_Resource resource,uint32_t status)54   virtual void OnStatus(PP_Resource resource, uint32_t status) {}
OnError(PP_Resource resource,uint32_t error)55   virtual void OnError(PP_Resource resource, uint32_t error) {}
OnBufferReady(PP_Resource resource,uint32_t buffer)56   virtual void OnBufferReady(PP_Resource resource, uint32_t buffer) {}
57 
58  private:
59   void EnumerateDevicesFinished(int32_t result,
60                                 std::vector<pp::DeviceRef_Dev>& devices);
61 
62   pp::VideoCapture_Dev video_capture_;
63   pp::CompletionCallbackFactory<EnumerateDevicesDemoInstance> callback_factory_;
64 
65   std::vector<pp::DeviceRef_Dev> devices_;
66 };
67 
EnumerateDevicesDemoInstance(PP_Instance instance,pp::Module * module)68 EnumerateDevicesDemoInstance::EnumerateDevicesDemoInstance(PP_Instance instance,
69                                                            pp::Module* module)
70     : pp::Instance(instance),
71       pp::VideoCaptureClient_Dev(this),
72       video_capture_(this),
73       callback_factory_(this) {
74 }
75 
~EnumerateDevicesDemoInstance()76 EnumerateDevicesDemoInstance::~EnumerateDevicesDemoInstance() {
77 }
78 
HandleMessage(const pp::Var & message_data)79 void EnumerateDevicesDemoInstance::HandleMessage(const pp::Var& message_data) {
80   if (message_data.is_string()) {
81     std::string event = message_data.AsString();
82     if (event == "EnumerateDevicesAsync") {
83       pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> >
84           callback = callback_factory_.NewCallbackWithOutput(
85               &EnumerateDevicesDemoInstance::EnumerateDevicesFinished);
86       video_capture_.EnumerateDevices(callback);
87     } else if (event == "EnumerateDevicesSync") {
88       std::vector<pp::DeviceRef_Dev> devices;
89       int32_t result = pp::flash::Flash::EnumerateVideoCaptureDevices(
90           this, video_capture_, &devices);
91       EnumerateDevicesFinished(result, devices);
92     }
93   }
94 }
95 
EnumerateDevicesFinished(int32_t result,std::vector<pp::DeviceRef_Dev> & devices)96 void EnumerateDevicesDemoInstance::EnumerateDevicesFinished(
97     int32_t result,
98     std::vector<pp::DeviceRef_Dev>& devices) {
99   static const char* const kDelimiter = "#__#";
100 
101   if (result == PP_OK) {
102     devices_.swap(devices);
103     std::string device_names;
104     for (size_t index = 0; index < devices_.size(); ++index) {
105       pp::Var name = devices_[index].GetName();
106       assert(name.is_string());
107 
108       if (index != 0)
109         device_names += kDelimiter;
110       device_names += name.AsString();
111     }
112     PostMessage(pp::Var("EnumerationSuccess" + device_names));
113   } else {
114     PostMessage(pp::Var("EnumerationFailed"));
115   }
116 }
117 
CreateInstance(PP_Instance instance)118 pp::Instance* EnumerateDevicesDemoModule::CreateInstance(PP_Instance instance) {
119   return new EnumerateDevicesDemoInstance(instance, this);
120 }
121 
122 }  // anonymous namespace
123 
124 namespace pp {
125 // Factory function for your specialization of the Module object.
CreateModule()126 Module* CreateModule() {
127   return new EnumerateDevicesDemoModule();
128 }
129 }  // namespace pp
130