Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/cpp/dev/audio_input_dev.h" | 5 #include "ppapi/cpp/dev/audio_input_dev.h" |
| 6 | 6 |
| 7 #include "ppapi/c/dev/ppb_audio_input_dev.h" | 7 #include "ppapi/c/dev/ppb_audio_input_dev.h" |
| 8 #include "ppapi/c/pp_bool.h" | |
| 8 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
| 10 #include "ppapi/cpp/completion_callback.h" | |
| 11 #include "ppapi/cpp/dev/device_ref_dev.h" | |
| 12 #include "ppapi/cpp/dev/resource_array_dev.h" | |
| 9 #include "ppapi/cpp/instance_handle.h" | 13 #include "ppapi/cpp/instance_handle.h" |
| 10 #include "ppapi/cpp/module.h" | 14 #include "ppapi/cpp/module.h" |
| 11 #include "ppapi/cpp/module_impl.h" | 15 #include "ppapi/cpp/module_impl.h" |
| 12 | 16 |
| 13 namespace pp { | 17 namespace pp { |
| 14 | 18 |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 template <> const char* interface_name<PPB_AudioInput_Dev>() { | 21 template <> const char* interface_name<PPB_AudioInput_Dev_0_2>() { |
| 18 return PPB_AUDIO_INPUT_DEV_INTERFACE; | 22 return PPB_AUDIO_INPUT_DEV_INTERFACE_0_2; |
| 23 } | |
| 24 | |
| 25 template <> const char* interface_name<PPB_AudioInput_Dev_0_1>() { | |
| 26 return PPB_AUDIO_INPUT_DEV_INTERFACE_0_1; | |
| 19 } | 27 } |
| 20 | 28 |
| 21 } // namespace | 29 } // namespace |
| 22 | 30 |
| 31 struct AudioInput_Dev::EnumerateDevicesState { | |
| 32 EnumerateDevicesState(std::vector<DeviceRef_Dev>* in_devices, | |
| 33 const CompletionCallback& in_callback, | |
| 34 AudioInput_Dev* in_audio_input) | |
| 35 : devices_resource(0), | |
| 36 devices(in_devices), | |
| 37 callback(in_callback), | |
| 38 audio_input(in_audio_input) { | |
| 39 } | |
| 40 | |
| 41 PP_Resource devices_resource; | |
| 42 std::vector<DeviceRef_Dev>* devices; | |
| 43 CompletionCallback callback; | |
| 44 AudioInput_Dev* audio_input; | |
| 45 }; | |
| 46 | |
| 47 AudioInput_Dev::AudioInput_Dev() : enum_state_(NULL), | |
| 48 audio_input_callback_(NULL), | |
| 49 user_data_(NULL) { | |
| 50 } | |
| 51 | |
| 23 AudioInput_Dev::AudioInput_Dev(const InstanceHandle& instance, | 52 AudioInput_Dev::AudioInput_Dev(const InstanceHandle& instance, |
| 24 const AudioConfig& config, | 53 const AudioConfig& config, |
| 25 PPB_AudioInput_Callback callback, | 54 PPB_AudioInput_Callback callback, |
| 26 void* user_data) | 55 void* user_data) |
| 27 : config_(config) { | 56 : config_(config), |
| 28 if (has_interface<PPB_AudioInput_Dev>()) { | 57 enum_state_(NULL), |
| 29 PassRefFromConstructor(get_interface<PPB_AudioInput_Dev>()->Create( | 58 audio_input_callback_(callback), |
| 59 user_data_(user_data) { | |
| 60 if (has_interface<PPB_AudioInput_Dev_0_2>()) { | |
| 61 PassRefFromConstructor(get_interface<PPB_AudioInput_Dev_0_2>()->Create( | |
| 62 instance.pp_instance())); | |
| 63 } else if (has_interface<PPB_AudioInput_Dev_0_1>()) { | |
| 64 PassRefFromConstructor(get_interface<PPB_AudioInput_Dev_0_1>()->Create( | |
| 30 instance.pp_instance(), config.pp_resource(), callback, user_data)); | 65 instance.pp_instance(), config.pp_resource(), callback, user_data)); |
| 31 } | 66 } |
| 32 } | 67 } |
| 33 | 68 |
| 69 AudioInput_Dev::AudioInput_Dev(const AudioInput_Dev& other) | |
| 70 : Resource(other), | |
| 71 config_(other.config_), | |
| 72 enum_state_(NULL), | |
| 73 audio_input_callback_(other.audio_input_callback_), | |
| 74 user_data_(other.user_data_) { | |
| 75 } | |
| 76 | |
| 77 AudioInput_Dev::~AudioInput_Dev() { | |
| 78 AbortEnumerateDevices(); | |
| 79 } | |
| 80 | |
| 81 AudioInput_Dev& AudioInput_Dev::operator=(const AudioInput_Dev& other) { | |
| 82 AbortEnumerateDevices(); | |
| 83 | |
| 84 Resource::operator=(other); | |
| 85 config_ = other.config_; | |
| 86 audio_input_callback_ = other.audio_input_callback_; | |
| 87 user_data_ = other.user_data_; | |
| 88 return *this; | |
| 89 } | |
| 90 | |
| 34 // static | 91 // static |
| 35 bool AudioInput_Dev::IsAvailable() { | 92 bool AudioInput_Dev::IsAvailable() { |
| 36 return has_interface<PPB_AudioInput_Dev>(); | 93 return has_interface<PPB_AudioInput_Dev_0_2>() || |
| 94 has_interface<PPB_AudioInput_Dev_0_1>(); | |
| 95 } | |
| 96 | |
| 97 int32_t AudioInput_Dev::EnumerateDevices(std::vector<DeviceRef_Dev>* devices, | |
| 98 const CompletionCallback& callback) { | |
| 99 if (!has_interface<PPB_AudioInput_Dev_0_2>()) | |
| 100 return callback.MayForce(PP_ERROR_NOINTERFACE); | |
| 101 if (!devices) | |
| 102 return callback.MayForce(PP_ERROR_BADARGUMENT); | |
| 103 if (!callback.pp_completion_callback().func) | |
|
brettw
2012/03/02 19:13:41
I don't think you need this check since the C API
yzshen1
2012/03/04 08:04:01
Because we insert an extra layer of callback in th
brettw
2012/03/05 21:32:34
Okay, I see.
yzshen1
2012/03/05 22:19:14
Thanks! Once your work of array/async out param is
| |
| 104 return callback.MayForce(PP_ERROR_BLOCKS_MAIN_THREAD); | |
| 105 if (enum_state_) | |
| 106 return callback.MayForce(PP_ERROR_INPROGRESS); | |
| 107 | |
| 108 // It will be deleted in OnEnumerateDevicesComplete(). | |
| 109 enum_state_ = new EnumerateDevicesState(devices, callback, this); | |
| 110 return get_interface<PPB_AudioInput_Dev_0_2>()->EnumerateDevices( | |
| 111 pp_resource(), &enum_state_->devices_resource, | |
| 112 PP_MakeCompletionCallback(&AudioInput_Dev::OnEnumerateDevicesComplete, | |
| 113 enum_state_)); | |
| 114 } | |
| 115 | |
| 116 int32_t AudioInput_Dev::Open(const DeviceRef_Dev& device_ref, | |
| 117 const CompletionCallback& callback) { | |
| 118 if (has_interface<PPB_AudioInput_Dev_0_2>()) { | |
| 119 return get_interface<PPB_AudioInput_Dev_0_2>()->Open( | |
| 120 pp_resource(), device_ref.pp_resource(), config_.pp_resource(), | |
| 121 audio_input_callback_, user_data_, callback.pp_completion_callback()); | |
| 122 } | |
| 123 | |
| 124 if (has_interface<PPB_AudioInput_Dev_0_1>()) { | |
| 125 if (is_null()) | |
| 126 return callback.MayForce(PP_ERROR_FAILED); | |
| 127 | |
| 128 // If the v0.1 interface is being used and there is a valid resource handle, | |
| 129 // then the default device has been successfully opened during resource | |
| 130 // creation. | |
| 131 if (device_ref.is_null()) | |
| 132 return callback.MayForce(PP_OK); | |
| 133 | |
| 134 // The v0.1 interface doesn't support devices other than the default one. | |
| 135 return callback.MayForce(PP_ERROR_NOTSUPPORTED); | |
| 136 } | |
| 137 | |
| 138 return callback.MayForce(PP_ERROR_NOINTERFACE); | |
| 37 } | 139 } |
| 38 | 140 |
| 39 bool AudioInput_Dev::StartCapture() { | 141 bool AudioInput_Dev::StartCapture() { |
| 40 return has_interface<PPB_AudioInput_Dev>() && | 142 if (has_interface<PPB_AudioInput_Dev_0_2>()) { |
| 41 get_interface<PPB_AudioInput_Dev>()->StartCapture(pp_resource()); | 143 return PP_ToBool(get_interface<PPB_AudioInput_Dev_0_2>()->StartCapture( |
| 144 pp_resource())); | |
| 145 } | |
| 146 | |
| 147 if (has_interface<PPB_AudioInput_Dev_0_1>()) { | |
| 148 return PP_ToBool(get_interface<PPB_AudioInput_Dev_0_1>()->StartCapture( | |
| 149 pp_resource())); | |
| 150 } | |
| 151 | |
| 152 return false; | |
| 42 } | 153 } |
| 43 | 154 |
| 44 bool AudioInput_Dev::StopCapture() { | 155 bool AudioInput_Dev::StopCapture() { |
| 45 return has_interface<PPB_AudioInput_Dev>() && | 156 if (has_interface<PPB_AudioInput_Dev_0_2>()) { |
| 46 get_interface<PPB_AudioInput_Dev>()->StopCapture(pp_resource()); | 157 return PP_ToBool(get_interface<PPB_AudioInput_Dev_0_2>()->StopCapture( |
| 158 pp_resource())); | |
| 159 } | |
| 160 | |
| 161 if (has_interface<PPB_AudioInput_Dev_0_1>()) { | |
| 162 return PP_ToBool(get_interface<PPB_AudioInput_Dev_0_1>()->StopCapture( | |
| 163 pp_resource())); | |
| 164 } | |
| 165 | |
| 166 return false; | |
| 167 } | |
| 168 | |
| 169 void AudioInput_Dev::Close() { | |
| 170 if (has_interface<PPB_AudioInput_Dev_0_2>()) | |
| 171 get_interface<PPB_AudioInput_Dev_0_2>()->Close(pp_resource()); | |
| 172 } | |
| 173 | |
| 174 void AudioInput_Dev::AbortEnumerateDevices() { | |
| 175 if (enum_state_) { | |
| 176 enum_state_->devices = NULL; | |
| 177 Module::Get()->core()->CallOnMainThread(0, enum_state_->callback, | |
| 178 PP_ERROR_ABORTED); | |
| 179 enum_state_->audio_input = NULL; | |
| 180 enum_state_ = NULL; | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 // static | |
| 185 void AudioInput_Dev::OnEnumerateDevicesComplete(void* user_data, | |
| 186 int32_t result) { | |
| 187 EnumerateDevicesState* enum_state = | |
| 188 static_cast<EnumerateDevicesState*>(user_data); | |
| 189 | |
| 190 bool need_to_callback = !!enum_state->audio_input; | |
| 191 | |
| 192 if (result == PP_OK) { | |
| 193 // It will take care of releasing the reference. | |
| 194 ResourceArray_Dev resources(pp::PASS_REF, | |
| 195 enum_state->devices_resource); | |
| 196 | |
| 197 if (need_to_callback) { | |
| 198 enum_state->devices->clear(); | |
| 199 for (uint32_t index = 0; index < resources.size(); ++index) { | |
| 200 DeviceRef_Dev device(resources[index]); | |
| 201 enum_state->devices->push_back(device); | |
| 202 } | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 if (need_to_callback) { | |
| 207 enum_state->audio_input->enum_state_ = NULL; | |
| 208 enum_state->callback.Run(result); | |
| 209 } | |
| 210 | |
| 211 delete enum_state; | |
| 47 } | 212 } |
| 48 | 213 |
| 49 } // namespace pp | 214 } // namespace pp |
| OLD | NEW |