blob: 8568b9d55ec65b68306d2d24ba24ffc851ebb4d6 [file] [log] [blame]
// 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.
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#include "remoting/ios/bridge/client_proxy.h"
#import "remoting/ios/data_store.h"
#import "remoting/ios/host_preferences.h"
#import "remoting/ios/bridge/client_proxy_delegate_wrapper.h"
namespace {
// The value indicating a successful connection has been established via a call
// to ReportConnectionStatus
const static int kSuccessfulConnection = 3;
// Translate a connection status code integer to a NSString description
NSString* GetStatusMsgFromInteger(NSInteger code) {
switch (code) {
case 0: // INITIALIZING
return @"Initializing connection";
case 1: // CONNECTING
return @"Connecting";
case 2: // AUTHENTICATED
return @"Authenticated";
case 3: // CONNECTED
return @"Connected";
case 4: // FAILED
return @"Connection Failed";
case 5: // CLOSED
return @"Connection closed";
default:
return @"Unknown connection state";
}
}
// Translate a connection error code integer to a NSString description
NSString* GetErrorMsgFromInteger(NSInteger code) {
switch (code) {
case 1: // PEER_IS_OFFLINE
return @"Requested host is offline.";
case 2: // SESSION_REJECTED
return @"Session was rejected by the host.";
case 3: // INCOMPATIBLE_PROTOCOL
return @"Incompatible Protocol.";
case 4: // AUTHENTICATION_FAILED
return @"Authentication Failed.";
case 5: // CHANNEL_CONNECTION_ERROR
return @"Channel Connection Error";
case 6: // SIGNALING_ERROR
return @"Signaling Error";
case 7: // SIGNALING_TIMEOUT
return @"Signaling Timeout";
case 8: // HOST_OVERLOAD
return @"Host Overload";
case 9: // UNKNOWN_ERROR
return @"An unknown error has occurred, preventing the session "
"from opening.";
default:
return @"An unknown error code has occurred.";
}
}
} // namespace
namespace remoting {
ClientProxy::ClientProxy(ClientProxyDelegateWrapper* wrapper) {
delegate_ = [wrapper delegate];
}
void ClientProxy::ReportConnectionStatus(
protocol::ConnectionToHost::State state,
protocol::ErrorCode error) {
DCHECK(delegate_);
if (state <= kSuccessfulConnection && error == protocol::ErrorCode::OK) {
// Report Progress
[delegate_ connectionStatus:GetStatusMsgFromInteger(state)];
if (state == kSuccessfulConnection) {
[delegate_ connected];
}
} else {
[delegate_ connectionStatus:GetStatusMsgFromInteger(state)];
if (error != protocol::ErrorCode::OK) {
[delegate_ connectionFailed:GetErrorMsgFromInteger(error)];
}
}
}
void ClientProxy::DisplayAuthenticationPrompt(bool pairing_supported) {
DCHECK(delegate_);
[delegate_ requestHostPin:pairing_supported];
}
void ClientProxy::CommitPairingCredentials(const std::string& hostId,
const std::string& pairId,
const std::string& pairSecret) {
DCHECK(delegate_);
NSString* nsHostId = [[NSString alloc] initWithUTF8String:hostId.c_str()];
NSString* nsPairId = [[NSString alloc] initWithUTF8String:pairId.c_str()];
NSString* nsPairSecret =
[[NSString alloc] initWithUTF8String:pairSecret.c_str()];
const HostPreferences* hostPrefs =
[[DataStore sharedStore] getHostForId:nsHostId];
if (hostPrefs == nil) {
hostPrefs = [[DataStore sharedStore] createHost:nsHostId];
}
if (hostPrefs) {
hostPrefs.pairId = nsPairId;
hostPrefs.pairSecret = nsPairSecret;
[[DataStore sharedStore] saveChanges];
}
}
void ClientProxy::RedrawCanvas(const webrtc::DesktopSize& view_size,
webrtc::DesktopFrame* buffer,
const webrtc::DesktopRegion& region) {
DCHECK(delegate_);
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()));
}
[delegate_ applyFrame:view_size
stride:buffer->stride()
data:buffer->data()
regions:regions];
}
void ClientProxy::UpdateCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {
DCHECK(delegate_);
[delegate_ applyCursor: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()];
}
} // namespace remoting