| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "extensions/browser/api/webcam_private/visca_webcam.h" | 5 #include "extensions/browser/api/webcam_private/visca_webcam.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "content/public/browser/browser_thread.h" | 9 #include "content/public/browser/browser_thread.h" |
| 10 | 10 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 Send(kSetAddressCommand, | 139 Send(kSetAddressCommand, |
| 140 base::Bind(&ViscaWebcam::OnAddressSetCompleted, | 140 base::Bind(&ViscaWebcam::OnAddressSetCompleted, |
| 141 weak_ptr_factory_.GetWeakPtr(), open_callback)); | 141 weak_ptr_factory_.GetWeakPtr(), open_callback)); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 | 144 |
| 145 void ViscaWebcam::OnAddressSetCompleted( | 145 void ViscaWebcam::OnAddressSetCompleted( |
| 146 const OpenCompleteCallback& open_callback, | 146 const OpenCompleteCallback& open_callback, |
| 147 bool success, | 147 bool success, |
| 148 const std::vector<char>& response) { | 148 const std::vector<char>& response) { |
| 149 commands_.pop_front(); |
| 149 if (!success) { | 150 if (!success) { |
| 150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 151 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 151 base::Bind(open_callback, false)); | 152 base::Bind(open_callback, false)); |
| 152 } else { | 153 } else { |
| 153 Send(kClearAllCommand, | 154 Send(kClearAllCommand, |
| 154 base::Bind(&ViscaWebcam::OnClearAllCompleted, | 155 base::Bind(&ViscaWebcam::OnClearAllCompleted, |
| 155 weak_ptr_factory_.GetWeakPtr(), open_callback)); | 156 weak_ptr_factory_.GetWeakPtr(), open_callback)); |
| 156 } | 157 } |
| 157 } | 158 } |
| 158 | 159 |
| 159 void ViscaWebcam::OnClearAllCompleted(const OpenCompleteCallback& open_callback, | 160 void ViscaWebcam::OnClearAllCompleted(const OpenCompleteCallback& open_callback, |
| 160 bool success, | 161 bool success, |
| 161 const std::vector<char>& response) { | 162 const std::vector<char>& response) { |
| 163 commands_.pop_front(); |
| 162 if (!success) { | 164 if (!success) { |
| 163 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 165 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 164 base::Bind(open_callback, false)); | 166 base::Bind(open_callback, false)); |
| 165 } else { | 167 } else { |
| 166 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 168 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 167 base::Bind(open_callback, true)); | 169 base::Bind(open_callback, true)); |
| 168 // Get the current pan and tilt position to initilize |pan| and |tilt|. | |
| 169 int value; | |
| 170 Send(kGetPanTiltCommand, | |
| 171 base::Bind(&ViscaWebcam::OnCommandCompleted, | |
| 172 weak_ptr_factory_.GetWeakPtr(), INQUIRY_PAN_TILT, &value)); | |
| 173 } | 170 } |
| 174 } | 171 } |
| 175 | 172 |
| 176 void ViscaWebcam::Send(const std::vector<char>& command, | 173 void ViscaWebcam::Send(const std::vector<char>& command, |
| 177 const CommandCompleteCallback& callback) { | 174 const CommandCompleteCallback& callback) { |
| 178 if (!commands_.empty() || | 175 commands_.push_back(std::make_pair(command, callback)); |
| 179 !serial_connection_->Send( | 176 // If this is the only command in the queue, send it now. |
| 180 command, base::Bind(&ViscaWebcam::OnSendCompleted, | 177 if (commands_.size() == 1) { |
| 181 weak_ptr_factory_.GetWeakPtr(), callback))) { | 178 serial_connection_->Send( |
| 182 commands_.push_back(std::make_pair(command, callback)); | 179 command, base::Bind(&ViscaWebcam::OnSendCompleted, |
| 180 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 183 } | 181 } |
| 184 } | 182 } |
| 185 | 183 |
| 186 void ViscaWebcam::OnSendCompleted(const CommandCompleteCallback& callback, | 184 void ViscaWebcam::OnSendCompleted(const CommandCompleteCallback& callback, |
| 187 int bytes_sent, | 185 int bytes_sent, |
| 188 api::serial::SendError error) { | 186 api::serial::SendError error) { |
| 189 if (error == api::serial::SEND_ERROR_NONE) { | 187 if (error == api::serial::SEND_ERROR_NONE) { |
| 190 ReceiveLoop(callback); | 188 ReceiveLoop(callback); |
| 191 } else { | 189 } else { |
| 192 const std::vector<char> response; | 190 const std::vector<char> response; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 226 } |
| 229 } | 227 } |
| 230 } else { | 228 } else { |
| 231 // Clear |data_buffer_|. | 229 // Clear |data_buffer_|. |
| 232 std::vector<char> response; | 230 std::vector<char> response; |
| 233 response.swap(data_buffer_); | 231 response.swap(data_buffer_); |
| 234 callback.Run(false, response); | 232 callback.Run(false, response); |
| 235 } | 233 } |
| 236 } | 234 } |
| 237 | 235 |
| 238 void ViscaWebcam::OnCommandCompleted(CommandType type, | 236 void ViscaWebcam::OnCommandCompleted(const SetPTZCompleteCallback& callback, |
| 239 int* value, | |
| 240 bool success, | 237 bool success, |
| 241 const std::vector<char>& response) { | 238 const std::vector<char>& response) { |
| 242 // TODO(xdai): Error handling according to |response|. | 239 // TODO(xdai): Error handling according to |response|. |
| 243 if (!success) | 240 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 244 return; | 241 base::Bind(callback, success)); |
| 245 | 242 commands_.pop_front(); |
| 246 switch (type) { | |
| 247 case COMMAND: | |
| 248 break; | |
| 249 case INQUIRY_PAN: | |
| 250 pan_ = ((int(response[2]) & 0x0F) << 12) + | |
| 251 ((int(response[3]) & 0x0F) << 8) + | |
| 252 ((int(response[4]) & 0x0F) << 4) + (int(response[5]) & 0x0F); | |
| 253 *value = pan_; | |
| 254 break; | |
| 255 case INQUIRY_TILT: | |
| 256 tilt_ = ((int(response[6]) & 0x0F) << 12) + | |
| 257 ((int(response[7]) & 0x0F) << 8) + | |
| 258 ((int(response[8]) & 0x0F) << 4) + (int(response[9]) & 0x0F); | |
| 259 *value = tilt_; | |
| 260 break; | |
| 261 case INQUIRY_PAN_TILT: | |
| 262 pan_ = ((int(response[2]) & 0x0F) << 12) + | |
| 263 ((int(response[3]) & 0x0F) << 8) + | |
| 264 ((int(response[4]) & 0x0F) << 4) + (int(response[5]) & 0x0F); | |
| 265 tilt_ = ((int(response[6]) & 0x0F) << 12) + | |
| 266 ((int(response[7]) & 0x0F) << 8) + | |
| 267 ((int(response[8]) & 0x0F) << 4) + (int(response[9]) & 0x0F); | |
| 268 break; | |
| 269 case INQUIRY_ZOOM: | |
| 270 *value = ((int(response[2]) & 0x0F) << 12) + | |
| 271 ((int(response[3]) & 0x0F) << 8) + | |
| 272 ((int(response[4]) & 0x0F) << 4) + (int(response[5]) & 0x0F); | |
| 273 break; | |
| 274 } | |
| 275 | 243 |
| 276 // If there are pending commands, process the next one. | 244 // If there are pending commands, process the next one. |
| 277 if (!commands_.empty()) { | 245 if (!commands_.empty()) { |
| 278 const std::vector<char> command = commands_.front().first; | 246 const std::vector<char> next_command = commands_.front().first; |
| 279 const CommandCompleteCallback callback = commands_.front().second; | 247 const CommandCompleteCallback next_callback = commands_.front().second; |
| 280 commands_.pop_front(); | |
| 281 serial_connection_->Send( | 248 serial_connection_->Send( |
| 282 command, base::Bind(&ViscaWebcam::OnSendCompleted, | 249 next_command, |
| 283 weak_ptr_factory_.GetWeakPtr(), callback)); | 250 base::Bind(&ViscaWebcam::OnSendCompleted, |
| 251 weak_ptr_factory_.GetWeakPtr(), next_callback)); |
| 284 } | 252 } |
| 285 } | 253 } |
| 286 | 254 |
| 287 void ViscaWebcam::Reset(bool pan, bool tilt, bool zoom) { | 255 void ViscaWebcam::OnInquiryCompleted(InquiryType type, |
| 288 int value; | 256 const GetPTZCompleteCallback& callback, |
| 289 // pan and tilt are always reset together in Visca Webcams. | 257 bool success, |
| 290 if (pan || tilt) { | 258 const std::vector<char>& response) { |
| 291 Send(kResetPanTiltCommand, | 259 int value = 0; |
| 292 base::Bind(&ViscaWebcam::OnCommandCompleted, | 260 if (!success) { |
| 293 weak_ptr_factory_.GetWeakPtr(), COMMAND, &value)); | 261 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 262 base::Bind(callback, false, value)); |
| 263 } else { |
| 264 switch (type) { |
| 265 case INQUIRY_PAN: |
| 266 // See kGetPanTiltCommand for the format of response. |
| 267 pan_ = ((int(response[2]) & 0x0F) << 12) + |
| 268 ((int(response[3]) & 0x0F) << 8) + |
| 269 ((int(response[4]) & 0x0F) << 4) + (int(response[5]) & 0x0F); |
| 270 value = pan_; |
| 271 break; |
| 272 case INQUIRY_TILT: |
| 273 // See kGetPanTiltCommand for the format of response. |
| 274 tilt_ = ((int(response[6]) & 0x0F) << 12) + |
| 275 ((int(response[7]) & 0x0F) << 8) + |
| 276 ((int(response[8]) & 0x0F) << 4) + (int(response[9]) & 0x0F); |
| 277 value = tilt_; |
| 278 break; |
| 279 case INQUIRY_ZOOM: |
| 280 // See kGetZoomCommand for the format of response. |
| 281 value = ((int(response[2]) & 0x0F) << 12) + |
| 282 ((int(response[3]) & 0x0F) << 8) + |
| 283 ((int(response[4]) & 0x0F) << 4) + (int(response[5]) & 0x0F); |
| 284 break; |
| 285 } |
| 286 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 287 base::Bind(callback, true, value)); |
| 294 } | 288 } |
| 295 if (zoom) { | 289 commands_.pop_front(); |
| 296 const int default_zoom = 1; | 290 |
| 297 SetZoom(default_zoom); | 291 // If there are pending commands, process the next one. |
| 292 if (!commands_.empty()) { |
| 293 const std::vector<char> next_command = commands_.front().first; |
| 294 const CommandCompleteCallback next_callback = commands_.front().second; |
| 295 serial_connection_->Send( |
| 296 next_command, |
| 297 base::Bind(&ViscaWebcam::OnSendCompleted, |
| 298 weak_ptr_factory_.GetWeakPtr(), next_callback)); |
| 298 } | 299 } |
| 299 } | 300 } |
| 300 | 301 |
| 301 bool ViscaWebcam::GetPan(int* value) { | 302 void ViscaWebcam::GetPan(const GetPTZCompleteCallback& callback) { |
| 302 Send(kGetPanTiltCommand, | 303 Send(kGetPanTiltCommand, |
| 303 base::Bind(&ViscaWebcam::OnCommandCompleted, | 304 base::Bind(&ViscaWebcam::OnInquiryCompleted, |
| 304 weak_ptr_factory_.GetWeakPtr(), INQUIRY_PAN, value)); | 305 weak_ptr_factory_.GetWeakPtr(), INQUIRY_PAN, callback)); |
| 305 return true; | |
| 306 } | 306 } |
| 307 | 307 |
| 308 bool ViscaWebcam::GetTilt(int* value) { | 308 void ViscaWebcam::GetTilt(const GetPTZCompleteCallback& callback) { |
| 309 Send(kGetPanTiltCommand, | 309 Send(kGetPanTiltCommand, |
| 310 base::Bind(&ViscaWebcam::OnCommandCompleted, | 310 base::Bind(&ViscaWebcam::OnInquiryCompleted, |
| 311 weak_ptr_factory_.GetWeakPtr(), INQUIRY_TILT, value)); | 311 weak_ptr_factory_.GetWeakPtr(), INQUIRY_TILT, callback)); |
| 312 return true; | |
| 313 } | 312 } |
| 314 | 313 |
| 315 bool ViscaWebcam::GetZoom(int* value) { | 314 void ViscaWebcam::GetZoom(const GetPTZCompleteCallback& callback) { |
| 316 Send(kGetZoomCommand, | 315 Send(kGetZoomCommand, |
| 317 base::Bind(&ViscaWebcam::OnCommandCompleted, | 316 base::Bind(&ViscaWebcam::OnInquiryCompleted, |
| 318 weak_ptr_factory_.GetWeakPtr(), INQUIRY_ZOOM, value)); | 317 weak_ptr_factory_.GetWeakPtr(), INQUIRY_ZOOM, callback)); |
| 319 return true; | |
| 320 } | 318 } |
| 321 | 319 |
| 322 bool ViscaWebcam::SetPan(int value) { | 320 void ViscaWebcam::SetPan(int value, const SetPTZCompleteCallback& callback) { |
| 323 pan_ = value; | 321 pan_ = value; |
| 324 std::vector<char> command = kSetPanTiltCommand; | 322 std::vector<char> command = kSetPanTiltCommand; |
| 325 command[6] |= ((pan_ & 0xF000) >> 12); | 323 command[6] |= ((pan_ & 0xF000) >> 12); |
| 326 command[7] |= ((pan_ & 0x0F00) >> 8); | 324 command[7] |= ((pan_ & 0x0F00) >> 8); |
| 327 command[8] |= ((pan_ & 0x00F0) >> 4); | 325 command[8] |= ((pan_ & 0x00F0) >> 4); |
| 328 command[9] |= (pan_ & 0x000F); | 326 command[9] |= (pan_ & 0x000F); |
| 329 command[10] |= ((tilt_ & 0xF000) >> 12); | 327 command[10] |= ((tilt_ & 0xF000) >> 12); |
| 330 command[11] |= ((tilt_ & 0x0F00) >> 8); | 328 command[11] |= ((tilt_ & 0x0F00) >> 8); |
| 331 command[12] |= ((tilt_ & 0x00F0) >> 4); | 329 command[12] |= ((tilt_ & 0x00F0) >> 4); |
| 332 command[13] |= (tilt_ & 0x000F); | 330 command[13] |= (tilt_ & 0x000F); |
| 333 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, | 331 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 334 weak_ptr_factory_.GetWeakPtr(), COMMAND, &value)); | 332 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 335 return true; | |
| 336 } | 333 } |
| 337 | 334 |
| 338 bool ViscaWebcam::SetTilt(int value) { | 335 void ViscaWebcam::SetTilt(int value, const SetPTZCompleteCallback& callback) { |
| 339 tilt_ = value; | 336 tilt_ = value; |
| 340 std::vector<char> command = kSetPanTiltCommand; | 337 std::vector<char> command = kSetPanTiltCommand; |
| 341 command[6] |= ((pan_ & 0xF000) >> 12); | 338 command[6] |= ((pan_ & 0xF000) >> 12); |
| 342 command[7] |= ((pan_ & 0x0F00) >> 8); | 339 command[7] |= ((pan_ & 0x0F00) >> 8); |
| 343 command[8] |= ((pan_ & 0x00F0) >> 4); | 340 command[8] |= ((pan_ & 0x00F0) >> 4); |
| 344 command[9] |= (pan_ & 0x000F); | 341 command[9] |= (pan_ & 0x000F); |
| 345 command[10] |= ((tilt_ & 0xF000) >> 12); | 342 command[10] |= ((tilt_ & 0xF000) >> 12); |
| 346 command[11] |= ((tilt_ & 0x0F00) >> 8); | 343 command[11] |= ((tilt_ & 0x0F00) >> 8); |
| 347 command[12] |= ((tilt_ & 0x00F0) >> 4); | 344 command[12] |= ((tilt_ & 0x00F0) >> 4); |
| 348 command[13] |= (tilt_ & 0x000F); | 345 command[13] |= (tilt_ & 0x000F); |
| 349 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, | 346 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 350 weak_ptr_factory_.GetWeakPtr(), COMMAND, &value)); | 347 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 351 return true; | |
| 352 } | 348 } |
| 353 | 349 |
| 354 bool ViscaWebcam::SetZoom(int value) { | 350 void ViscaWebcam::SetZoom(int value, const SetPTZCompleteCallback& callback) { |
| 355 std::vector<char> command = kSetZoomCommand; | 351 std::vector<char> command = kSetZoomCommand; |
| 356 command[4] |= ((value & 0xF000) >> 12); | 352 command[4] |= ((value & 0xF000) >> 12); |
| 357 command[5] |= ((value & 0x0F00) >> 8); | 353 command[5] |= ((value & 0x0F00) >> 8); |
| 358 command[6] |= ((value & 0x00F0) >> 4); | 354 command[6] |= ((value & 0x00F0) >> 4); |
| 359 command[7] |= (value & 0x000F); | 355 command[7] |= (value & 0x000F); |
| 360 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, | 356 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 361 weak_ptr_factory_.GetWeakPtr(), COMMAND, &value)); | 357 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 362 return true; | |
| 363 } | 358 } |
| 364 | 359 |
| 365 bool ViscaWebcam::SetPanDirection(PanDirection direction) { | 360 void ViscaWebcam::SetPanDirection(PanDirection direction, |
| 361 const SetPTZCompleteCallback& callback) { |
| 366 std::vector<char> command = kPTStopCommand; | 362 std::vector<char> command = kPTStopCommand; |
| 367 switch (direction) { | 363 switch (direction) { |
| 368 case PAN_STOP: | 364 case PAN_STOP: |
| 369 break; | 365 break; |
| 370 case PAN_RIGHT: | 366 case PAN_RIGHT: |
| 371 command = kPTRightCommand; | 367 command = kPTRightCommand; |
| 372 break; | 368 break; |
| 373 case PAN_LEFT: | 369 case PAN_LEFT: |
| 374 command = kPTLeftCommand; | 370 command = kPTLeftCommand; |
| 375 break; | 371 break; |
| 376 } | 372 } |
| 377 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, | 373 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 378 weak_ptr_factory_.GetWeakPtr(), COMMAND, &pan_)); | 374 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 379 return true; | |
| 380 } | 375 } |
| 381 | 376 |
| 382 bool ViscaWebcam::SetTiltDirection(TiltDirection direction) { | 377 void ViscaWebcam::SetTiltDirection(TiltDirection direction, |
| 378 const SetPTZCompleteCallback& callback) { |
| 383 std::vector<char> command = kPTStopCommand; | 379 std::vector<char> command = kPTStopCommand; |
| 384 switch (direction) { | 380 switch (direction) { |
| 385 case TILT_STOP: | 381 case TILT_STOP: |
| 386 break; | 382 break; |
| 387 case TILT_UP: | 383 case TILT_UP: |
| 388 command = kPTUpCommand; | 384 command = kPTUpCommand; |
| 389 break; | 385 break; |
| 390 case TILT_DOWN: | 386 case TILT_DOWN: |
| 391 command = kPTDownCommand; | 387 command = kPTDownCommand; |
| 392 break; | 388 break; |
| 393 } | 389 } |
| 394 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, | 390 Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 395 weak_ptr_factory_.GetWeakPtr(), COMMAND, &tilt_)); | 391 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 396 return true; | 392 } |
| 393 |
| 394 void ViscaWebcam::Reset(bool pan, |
| 395 bool tilt, |
| 396 bool zoom, |
| 397 const SetPTZCompleteCallback& callback) { |
| 398 // pan and tilt are always reset together in Visca Webcams. |
| 399 if (pan || tilt) { |
| 400 Send(kResetPanTiltCommand, |
| 401 base::Bind(&ViscaWebcam::OnCommandCompleted, |
| 402 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 403 } |
| 404 if (zoom) { |
| 405 const int default_zoom = 1; |
| 406 SetZoom(default_zoom, callback); |
| 407 } |
| 397 } | 408 } |
| 398 | 409 |
| 399 } // namespace extensions | 410 } // namespace extensions |
| OLD | NEW |