Chromium Code Reviews| Index: remoting/ios/bridge/client_bridge.mm |
| diff --git a/remoting/ios/bridge/client_bridge.mm b/remoting/ios/bridge/client_bridge.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ed6f43b444bb1d9fc6798bd64735152ee9f6ea21 |
| --- /dev/null |
| +++ b/remoting/ios/bridge/client_bridge.mm |
| @@ -0,0 +1,167 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "remoting/ios/bridge/client_bridge.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "remoting/base/url_request_context.h" |
| +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| + |
| +#import "remoting/ios/bridge/client_controller.h" |
| + |
| +namespace remoting { |
| + |
| +ClientBridge::ClientBridge() { |
| + |
| + VLOG(1) << "Starting main message loop"; |
| + if (!base::MessageLoopForUI::IsCurrent()) { |
| + ui_loop_.reset(new base::MessageLoopForUI()); |
| + ui_loop_->Attach(); |
| + } else { |
| + ui_loop_.reset(base::MessageLoopForUI::current()); |
| + } |
| + |
| + VLOG(1) << "Spawning additional threads"; |
| + |
| + ui_task_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(), |
| + base::MessageLoop::QuitClosure()); |
| + network_task_runner_ = AutoThread::CreateWithType( |
| + "native_net", ui_task_runner_, base::MessageLoop::TYPE_IO); |
| + |
| + url_requester_ = new URLRequestContextGetter(network_task_runner_); |
| +} |
| + |
| +ClientBridge::~ClientBridge() { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + |
| + // The session must be shut down first, since it depends on our other |
| + // components' still being alive. |
| + DisconnectFromHost(); |
| + |
| + base::WaitableEvent done_event(false, false); |
| + network_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ClientBridge::DetachFromVmAndSignal, |
|
dcaiafa
2014/03/19 01:14:15
DetachFromVmAndSignal just signals the event. Do w
aboone
2014/03/21 16:42:07
Removed.
|
| + base::Unretained(this), |
| + &done_event)); |
| + done_event.Wait(); |
| + done_event.Wait(); |
|
dcaiafa
2014/03/19 01:14:15
Remove duplicate.
aboone
2014/03/21 16:42:07
Done.
|
| +} |
| + |
| +// CLIENT is requesting a new connection to a HOST |
|
dcaiafa
2014/03/19 01:14:15
nit: method description comments belong in the hea
aboone
2014/03/21 16:42:07
Done.
|
| +void ClientBridge::ConnectToHost(const char* username, |
| + const char* auth_token, |
| + const char* host_jid, |
| + const char* host_id, |
| + const char* host_pubkey, |
| + const char* pairing_id, |
| + const char* pairing_secret, |
| + ClientController* controller) { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + controller_ = controller; |
| + DCHECK(!session_); |
| + session_ = new ClientInstance(this, |
| + username, |
| + auth_token, |
| + host_jid, |
| + host_id, |
| + host_pubkey, |
| + pairing_id, |
| + pairing_secret); |
| +} |
| + |
| +// CLIENT is asking to close the connection |
| +void ClientBridge::DisconnectFromHost() { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + if (session_) { |
| + session_->Cleanup(); |
| + session_ = NULL; |
| + } |
| +} |
| +// HOST reporting connection status |
|
dcaiafa
2014/03/19 01:14:15
nit: empty line between methods.
aboone
2014/03/21 16:42:07
Done.
|
| +void ClientBridge::ReportConnectionStatus( |
| + protocol::ConnectionToHost::State state, |
| + protocol::ErrorCode error) { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + if (controller_) { |
|
dcaiafa
2014/03/19 01:14:15
Is it really valid for controller_ to be NULL here
aboone
2014/03/21 16:42:07
Done.
|
| + [controller_ reportConnectionStatus:state error:error]; |
| + } |
| +} |
| + |
| +// HOST asking for PIN |
| +void ClientBridge::DisplayAuthenticationPrompt(bool pairing_supported) { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + if (controller_) { |
| + [controller_ displayAuthenticationPrompt:pairing_supported]; |
| + } |
| +} |
| + |
| +// HOST submitting credentials for storage |
| +void ClientBridge::CommitPairingCredentials(const std::string& host, |
| + const std::string& id, |
| + const std::string& secret) { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + if (controller_) { |
| + NSString* hostString = [[NSString alloc] initWithUTF8String:host.c_str()]; |
| + NSString* idString = [[NSString alloc] initWithUTF8String:id.c_str()]; |
| + NSString* secretString = |
| + [[NSString alloc] initWithUTF8String:secret.c_str()]; |
| + [controller_ commitPairinedentials:hostString |
| + pairId:idString |
| + secret:secretString]; |
| + } |
| +} |
| + |
| +// HOST delivering a Cursor (mouse) update |
| +void ClientBridge::UpdateCursorShape( |
| + const protocol::CursorShapeInfo& cursor_shape) { |
| + DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| + if (controller_) { |
| + [controller_ |
| + updateCursorShape:webrtc::DesktopSize(cursor_shape.width(), |
| + cursor_shape.height()) |
| + hotspot:webrtc::DesktopVector(cursor_shape.hotspot_x(), |
| + cursor_shape.hotspot_y()) |
| + cursorData:(uint8_t*)cursor_shape.data().c_str()]; |
| + } |
| +} |
| + |
| +// HOST delivierying a Canvas (desktop) update |
| +void ClientBridge::RedrawCanvas(const webrtc::DesktopSize& view_size, |
| + webrtc::DesktopFrame* buffer, |
| + const webrtc::DesktopRegion& region) { |
| + if (!ui_task_runner_->BelongsToCurrentThread()) { |
| + ui_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + &ClientBridge::RedrawCanvas, this, view_size, buffer, region)); |
| + return; |
| + } |
| + if (controller_) { |
| + std::vector<webrtc::DesktopRect> regions; |
| + |
| + for (webrtc::DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) { |
| + const webrtc::DesktopRect& rect(i.rect()); |
| + |
| + regions.push_back(webrtc::DesktopRect::MakeXYWH( |
| + rect.left(), rect.top(), rect.width(), rect.height())); |
| + } |
| + |
| + [controller_ updateImageBuffer:view_size |
| + stride:buffer->stride() |
| + data:buffer->data() |
| + regions:regions]; |
| + } |
| +} |
| + |
| +FrameConsumerBridgeCallback ClientBridge::BindToFrameConsumerBridgeCallback() { |
| + return base::Bind(&ClientBridge::RedrawCanvas, base::Unretained(this)); |
|
dcaiafa
2014/03/19 01:14:15
Delete this method (see comments in client_instanc
aboone
2014/03/21 16:42:07
Done.
|
| +} |
| + |
| +void ClientBridge::DetachFromVmAndSignal(base::WaitableEvent* waiter) { |
| + waiter->Signal(); |
| +} |
| + |
| +} // namespace remoting |