Commit 478229ab authored by nicholss's avatar nicholss Committed by Commit bot

Updating Pin Entry View and creating Connection Status View.

This CL connects the PIN entry view to the connection status view. It also adds a layer in the UI for connecting to the host, instead of going strait to the GLK view, we first end up on the new connection status view that will guide and inform the user about the state of their connection, prompting for PIN (or third party auth in time?). After a successful connection has been made the view is replaced with the HostViewController with the desktop rendering, etc.

Review-Url: https://codereview.chromium.org/2846603002
Cr-Commit-Position: refs/heads/master@{#468975}
parent b1c9a6c7
...@@ -20,6 +20,8 @@ source_set("main") { ...@@ -20,6 +20,8 @@ source_set("main") {
sources = [ sources = [
"app_delegate.h", "app_delegate.h",
"app_delegate.mm", "app_delegate.mm",
"client_connection_view_controller.h",
"client_connection_view_controller.mm",
"host_collection_view_cell.h", "host_collection_view_cell.h",
"host_collection_view_cell.mm", "host_collection_view_cell.mm",
"host_collection_view_controller.h", "host_collection_view_controller.h",
...@@ -27,8 +29,8 @@ source_set("main") { ...@@ -27,8 +29,8 @@ source_set("main") {
"host_view_controller.h", "host_view_controller.h",
"host_view_controller.mm", "host_view_controller.mm",
"main.mm", "main.mm",
"pin_entry_view_controller.h", "pin_entry_view.h",
"pin_entry_view_controller.mm", "pin_entry_view.mm",
"remoting_settings_view_controller.h", "remoting_settings_view_controller.h",
"remoting_settings_view_controller.mm", "remoting_settings_view_controller.mm",
"remoting_view_controller.h", "remoting_view_controller.h",
......
// Copyright 2017 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.
#ifndef REMOTING_CLIENT_IOS_APP_CLIENT_CONNECTION_VIEW_CONTROLLER_H_
#define REMOTING_CLIENT_IOS_APP_CLIENT_CONNECTION_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
// This enumerated the differnt modes this Client Connection View can be in.
typedef NS_ENUM(NSInteger, ClientConnectionViewState) {
ClientViewConnecting,
ClientViewPinPrompt,
ClientViewConnected,
};
// The host connection view controller delegate provides feedback for state
// changes on Host Connection that the calling view should respond to.
@protocol ClientConnectionViewControllerDelegate<NSObject>
// Notifies the delegate the client is connected to the host.
- (void)clientConnected;
// Gets the current host name the client is attempting to connect to.
- (NSString*)getConnectingHostName;
@end
// This is the view that shows the user feedback while the client connection is
// being established. If requested the view can also display the pin entry view.
// State communication for this view is handled by NSNotifications, it listens
// to kHostSessionStatusChanged events on the default NSNotificationCenter.
// Internally the notification is tied to [self setState] so view setup will
// work the same way if state is set directly.
@interface ClientConnectionViewController : UIViewController
// Setting state will change the view
@property(nonatomic, assign) ClientConnectionViewState state;
// This delegate is used to ask for Host Name and to notify when the connection
// has been established.
@property(weak, nonatomic) id<ClientConnectionViewControllerDelegate> delegate;
@end
#endif // REMOTING_CLIENT_IOS_APP_CLIENT_CONNECTION_VIEW_CONTROLLER_H_
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#import <GLKit/GLKit.h> #import <GLKit/GLKit.h>
#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
#import "remoting/client/ios/display/gl_display_handler.h"
#import "remoting/client/ios/session/remoting_client.h" #import "remoting/client/ios/session/remoting_client.h"
static const CGFloat kFabInset = 15.f; static const CGFloat kFabInset = 15.f;
......
// Copyright 2017 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.
#ifndef REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_H_
#define REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_H_
#import <UIKit/UIKit.h>
@protocol PinEntryDelegate<NSObject>
// Notifies the delegate that a pin has been provided and if we should pair.
@optional
- (void)didProvidePin:(NSString*)pin createPairing:(BOOL)createPairing;
@end
// This view is the container for a PIN entry box, a button to submit, and the
// option box to remember the pairing. All used for entering a PIN based
// passcode.
@interface PinEntryView : UIView
// This delegate will handle interactions on the cells in the collection.
@property(weak, nonatomic) id<PinEntryDelegate> delegate;
@end
#endif // REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_H_
// Copyright 2017 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
#import "remoting/client/ios/app/pin_entry_view.h"
#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
static const CGFloat kMargin = 5.f;
static const CGFloat kPadding = 6.f;
static const CGFloat kLineSpace = 12.f;
@interface PinEntryView () {
UISwitch* _pairingSwitch;
UILabel* _pairingLabel;
MDCFloatingButton* _pinButton;
UITextField* _pinEntry;
}
@end
@implementation PinEntryView
@synthesize delegate = _delegate;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
_pairingSwitch = [[UISwitch alloc] init];
_pairingSwitch.tintColor =
[UIColor colorWithRed:1.f green:1.f blue:1.f alpha:0.5];
_pairingSwitch.transform = CGAffineTransformMakeScale(0.5, 0.5);
[self addSubview:_pairingSwitch];
_pairingLabel = [[UILabel alloc] init];
_pairingLabel.textColor =
[UIColor colorWithRed:1.f green:1.f blue:1.f alpha:0.5];
_pairingLabel.font = [UIFont systemFontOfSize:12.f];
_pairingLabel.text = @"Remember my PIN on this device.";
[self addSubview:_pairingLabel];
_pinButton =
[MDCFloatingButton floatingButtonWithShape:MDCFloatingButtonShapeMini];
[_pinButton setTitle:@"+" forState:UIControlStateNormal];
// TODO(nicholss): Update "->" to the arrow icon.
[_pinButton setTitle:@"->" forState:UIControlStateNormal];
[_pinButton addTarget:self
action:@selector(didTapPinEntry:)
forControlEvents:UIControlEventTouchUpInside];
_pinButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_pinButton];
_pinEntry = [[UITextField alloc] init];
_pinEntry.textColor = [UIColor whiteColor];
_pinEntry.secureTextEntry = YES;
_pinEntry.keyboardType = UIKeyboardTypeNumberPad;
// TODO(nicholss): L18N this.
_pinEntry.attributedPlaceholder = [[NSAttributedString alloc]
initWithString:@"Enter PIN"
attributes:@{
NSForegroundColorAttributeName :
[UIColor colorWithRed:1.f green:1.f blue:1.f alpha:0.5]
}];
[self addSubview:_pinEntry];
}
return self;
}
#pragma mark - UIView
- (BOOL)canBecomeFirstResponder {
return [_pinEntry canBecomeFirstResponder];
}
- (BOOL)becomeFirstResponder {
return [_pinEntry becomeFirstResponder];
}
- (BOOL)endEditing:(BOOL)force {
return [_pinEntry endEditing:force];
}
- (void)layoutSubviews {
[super layoutSubviews];
[_pinButton sizeToFit];
CGFloat buttonSize = _pinButton.frame.size.width; // Assume circle.
_pinEntry.frame =
CGRectMake(kMargin, 0.f,
self.frame.size.width - kPadding - kMargin * 2.f - buttonSize,
buttonSize);
[_pinButton sizeToFit];
_pinButton.frame =
CGRectMake(self.frame.size.width - kPadding - kMargin - buttonSize, 0.f,
buttonSize, buttonSize);
[_pairingSwitch sizeToFit];
_pairingSwitch.center = CGPointMake(
kMargin + _pairingSwitch.frame.size.width / 2.f,
buttonSize + _pairingSwitch.frame.size.height / 2.f + kLineSpace);
_pairingLabel.frame =
CGRectMake(kMargin + _pairingSwitch.frame.size.width + kPadding,
buttonSize + kLineSpace, 0.f, 0.f);
[_pairingLabel sizeToFit];
}
#pragma mark - Private
- (void)didTapPinEntry:(id)sender {
[_delegate didProvidePin:_pinEntry.text createPairing:_pairingSwitch.isOn];
[_pinEntry endEditing:YES];
}
@end
// Copyright 2017 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.
#ifndef REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_CONTROLLER_H_
#define REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
typedef void (^PinEntryModalCallback)(NSString* hostPin, BOOL createPairing);
// PinEntryViewController is expected to be created, displayed and then
// destroyed after the pin entry is finished; not reused.
@interface PinEntryViewController : UIViewController
// Callback will be used to return the pin entry result.
- (id)initWithCallback:(PinEntryModalCallback)callback;
@end
#endif // REMOTING_CLIENT_IOS_APP_PIN_ENTRY_VIEW_CONTROLLER_H_
// Copyright 2017 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
#import "remoting/client/ios/app/pin_entry_view_controller.h"
#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
#import "ios/third_party/material_components_ios/src/components/NavigationBar/src/MaterialNavigationBar.h"
static const CGFloat kHostCardIconSize = 45.f;
@interface PinEntryViewController () {
PinEntryModalCallback _callback;
MDCNavigationBar* _navBar;
}
@end
@implementation PinEntryViewController
- (id)initWithCallback:(PinEntryModalCallback)callback {
self = [super init];
if (self) {
_callback = callback;
}
return self;
}
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// TODO(nicholss): Localize this file.
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:@"CANCEL"
style:UIBarButtonItemStylePlain
target:self
action:@selector(didTapCancel:)];
_navBar = [[MDCNavigationBar alloc] initWithFrame:CGRectZero];
[_navBar observeNavigationItem:self.navigationItem];
[_navBar setBackgroundColor:[UIColor blackColor]];
MDCNavigationBarTextColorAccessibilityMutator* mutator =
[[MDCNavigationBarTextColorAccessibilityMutator alloc] init];
[mutator mutate:_navBar];
[self.view addSubview:_navBar];
_navBar.translatesAutoresizingMaskIntoConstraints = NO;
UIView* entryView = [[UIView alloc] initWithFrame:CGRectZero];
[self.view addSubview:entryView];
entryView.translatesAutoresizingMaskIntoConstraints = NO;
UIImageView* imageView = [[UIImageView alloc]
initWithFrame:CGRectMake(0, 0, kHostCardIconSize, kHostCardIconSize)];
imageView.contentMode = UIViewContentModeCenter;
imageView.alpha = 0.87f;
imageView.backgroundColor = UIColor.lightGrayColor;
imageView.layer.cornerRadius = kHostCardIconSize / 2.f;
imageView.layer.masksToBounds = YES;
imageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:imageView];
UILabel* titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
titleLabel.textColor = [UIColor colorWithWhite:0 alpha:0.87f];
titleLabel.text = @"Host XXX";
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:titleLabel];
[titleLabel sizeToFit];
MDCRaisedButton* pinButton = [[MDCRaisedButton alloc] init];
[pinButton setTitle:@"->" forState:UIControlStateNormal];
[pinButton sizeToFit];
[pinButton addTarget:self
action:@selector(didTapPinEntry:)
forControlEvents:UIControlEventTouchUpInside];
pinButton.translatesAutoresizingMaskIntoConstraints = NO;
[entryView addSubview:pinButton];
UITextField* pinEntry =
[[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 10)];
pinEntry.textAlignment = NSTextAlignmentCenter;
pinEntry.secureTextEntry = YES;
pinEntry.autoresizingMask = UIViewAutoresizingFlexibleWidth;
pinEntry.keyboardType = UIKeyboardTypeNumberPad;
pinEntry.attributedPlaceholder =
[[NSAttributedString alloc] initWithString:@"Enter PIN"];
[entryView addSubview:pinEntry];
pinEntry.translatesAutoresizingMaskIntoConstraints = NO;
[pinEntry sizeToFit];
NSDictionary* views = @{
@"entryView" : entryView,
@"navBar" : _navBar,
@"imageView" : imageView,
@"titleLabel" : titleLabel,
@"pinEntry" : pinEntry,
@"pinButton" : pinButton
};
NSDictionary* metrics = @{
@"imageEdge" : @150.0,
@"padding" : @15.0,
@"imageSize" : @45.0,
@"buttonSize" : @70.0
};
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"|[navBar]|"
options:0
metrics:metrics
views:views]];
[self.view addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:@"|-[imageView(==imageSize)]-|"
options:0
metrics:metrics
views:views]];
[self.view addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:@"|-[titleLabel]-|"
options:NSLayoutFormatAlignAllCenterX
metrics:metrics
views:views]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"|[entryView]|"
options:0
metrics:metrics
views:views]];
NSString* vViewConstraint =
@"V:|[navBar]-[imageView(==imageSize)]-[titleLabel]-[entryView]|";
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:vViewConstraint
options:0
metrics:metrics
views:views]];
[entryView addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:
@"|-[pinEntry]-[pinButton(==buttonSize)]-|"
options:NSLayoutFormatAlignAllCenterY
metrics:metrics
views:views]];
[entryView addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|->=padding-[pinButton]"
options:0
metrics:metrics
views:views]];
[entryView
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|->=padding-[pinEntry]"
options:0
metrics:metrics
views:views]];
[entryView layoutIfNeeded];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
#pragma mark - Private
- (void)didTapPinEntry:(id)sender {
NSLog(@"%@ was tapped.", NSStringFromClass([sender class]));
}
- (void)didTapCancel:(id)sender {
NSLog(@"%@ was tapped.", NSStringFromClass([sender class]));
}
@end
...@@ -13,10 +13,11 @@ ...@@ -13,10 +13,11 @@
#import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h" #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h"
#import "ios/third_party/material_components_ios/src/components/Dialogs/src/MaterialDialogs.h" #import "ios/third_party/material_components_ios/src/components/Dialogs/src/MaterialDialogs.h"
#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
#import "remoting/client/ios/app/client_connection_view_controller.h"
#import "remoting/client/ios/app/host_collection_view_controller.h" #import "remoting/client/ios/app/host_collection_view_controller.h"
#import "remoting/client/ios/app/host_view_controller.h" #import "remoting/client/ios/app/host_view_controller.h"
#import "remoting/client/ios/app/pin_entry_view_controller.h"
#import "remoting/client/ios/app/remoting_settings_view_controller.h" #import "remoting/client/ios/app/remoting_settings_view_controller.h"
#import "remoting/client/ios/domain/client_session_details.h"
#import "remoting/client/ios/facade/remoting_service.h" #import "remoting/client/ios/facade/remoting_service.h"
#import "remoting/client/ios/session/remoting_client.h" #import "remoting/client/ios/session/remoting_client.h"
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
static CGFloat kHostInset = 5.f; static CGFloat kHostInset = 5.f;
@interface RemotingViewController ()<HostCollectionViewControllerDelegate, @interface RemotingViewController ()<HostCollectionViewControllerDelegate,
ClientConnectionViewControllerDelegate,
UIViewControllerAnimatedTransitioning, UIViewControllerAnimatedTransitioning,
UIViewControllerTransitioningDelegate> { UIViewControllerTransitioningDelegate> {
bool _isAuthenticated; bool _isAuthenticated;
...@@ -34,6 +36,7 @@ static CGFloat kHostInset = 5.f; ...@@ -34,6 +36,7 @@ static CGFloat kHostInset = 5.f;
MDCAppBar* _appBar; MDCAppBar* _appBar;
HostCollectionViewController* _collectionViewController; HostCollectionViewController* _collectionViewController;
RemotingService* _remotingService; RemotingService* _remotingService;
RemotingClient* _client;
} }
@end @end
...@@ -82,6 +85,12 @@ static CGFloat kHostInset = 5.f; ...@@ -82,6 +85,12 @@ static CGFloat kHostInset = 5.f;
target:self target:self
action:@selector(didSelectRefresh)]; action:@selector(didSelectRefresh)];
self.navigationItem.rightBarButtonItem = refreshButton; self.navigationItem.rightBarButtonItem = refreshButton;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(hostSessionStatusChanged:)
name:kHostSessionStatusChanged
object:nil];
} }
return self; return self;
} }
...@@ -146,11 +155,26 @@ static CGFloat kHostInset = 5.f; ...@@ -146,11 +155,26 @@ static CGFloat kHostInset = 5.f;
[_collectionViewController.collectionView reloadData]; [_collectionViewController.collectionView reloadData];
} }
#pragma mark - ClientConnectionViewControllerDelegate
- (void)clientConnected {
HostViewController* hostViewController =
[[HostViewController alloc] initWithClient:_client];
[self presentViewController:hostViewController animated:YES completion:nil];
}
- (NSString*)getConnectingHostName {
if (_client) {
return _client.hostInfo.hostName;
}
return nil;
}
#pragma mark - HostCollectionViewControllerDelegate #pragma mark - HostCollectionViewControllerDelegate
- (void)didSelectCell:(HostCollectionViewCell*)cell - (void)didSelectCell:(HostCollectionViewCell*)cell
completion:(void (^)())completionBlock { completion:(void (^)())completionBlock {
RemotingClient* client = [[RemotingClient alloc] init]; _client = [[RemotingClient alloc] init];
[_remotingService [_remotingService
callbackWithAccessToken:base::BindBlockArc(^( callbackWithAccessToken:base::BindBlockArc(^(
...@@ -159,37 +183,17 @@ static CGFloat kHostInset = 5.f; ...@@ -159,37 +183,17 @@ static CGFloat kHostInset = 5.f;
const std::string& access_token) { const std::string& access_token) {
// TODO(nicholss): Check status. // TODO(nicholss): Check status.
HostInfo* hostInfo = cell.hostInfo; HostInfo* hostInfo = cell.hostInfo;
DCHECK(hostInfo); [_client connectToHost:hostInfo
DCHECK(hostInfo.jabberId); username:base::SysUTF8ToNSString(user_email)
DCHECK(hostInfo.hostId); accessToken:base::SysUTF8ToNSString(access_token)];
DCHECK(hostInfo.publicKey);
remoting::ConnectToHostInfo info;
info.username = user_email;
info.auth_token = access_token;
info.host_jid = base::SysNSStringToUTF8(hostInfo.jabberId);
info.host_id = base::SysNSStringToUTF8(hostInfo.hostId);
info.host_pubkey = base::SysNSStringToUTF8(hostInfo.publicKey);
// TODO(nicholss): If iOS supports pairing, pull the stored data and
// insert it here.
info.pairing_id = "";
info.pairing_secret = "";
// TODO(nicholss): I am not sure about the following fields yet.
// info.capabilities =
// info.flags =
// info.host_version =
// info.host_os =
// info.host_os_version =
[client connectToHost:info];
})]; })];
HostViewController* hostViewController = ClientConnectionViewController* clientConnectionViewController =
[[HostViewController alloc] initWithClient:client]; [[ClientConnectionViewController alloc] init];
clientConnectionViewController.delegate = self;
// TODO(nicholss): Add feedback on status of request. [self presentViewController:clientConnectionViewController
[self presentViewController:hostViewController animated:YES completion:nil]; animated:YES
completion:nil];
completionBlock(); completionBlock();
} }
...@@ -231,6 +235,10 @@ animationControllerForDismissedController:(UIViewController*)dismissed { ...@@ -231,6 +235,10 @@ animationControllerForDismissedController:(UIViewController*)dismissed {
#pragma mark - Private #pragma mark - Private
- (void)hostSessionStatusChanged:(NSNotification*)notification {
NSLog(@"hostSessionStatusChanged: %@", [notification userInfo]);
}
- (void)closeViewController { - (void)closeViewController {
[self dismissViewControllerAnimated:true completion:nil]; [self dismissViewControllerAnimated:true completion:nil];
} }
...@@ -239,17 +247,14 @@ animationControllerForDismissedController:(UIViewController*)dismissed { ...@@ -239,17 +247,14 @@ animationControllerForDismissedController:(UIViewController*)dismissed {
// TODO(nicholss) implement this. // TODO(nicholss) implement this.
NSLog(@"Should refresh..."); NSLog(@"Should refresh...");
_dialogTransitionController = [[MDCDialogTransitionController alloc] init]; _dialogTransitionController = [[MDCDialogTransitionController alloc] init];
PinEntryViewController* vc =
[[PinEntryViewController alloc] initWithCallback:nil];
vc.modalPresentationStyle = UIModalPresentationCustom;
vc.transitioningDelegate = _dialogTransitionController;
[self presentViewController:vc animated:YES completion:nil];
} }
- (void)didSelectSettings { - (void)didSelectSettings {
RemotingSettingsViewController* settingsVC = RemotingSettingsViewController* settingsViewController =
[RemotingSettingsViewController new]; [[RemotingSettingsViewController alloc] init];
[self presentViewController:settingsVC animated:YES completion:nil]; [self presentViewController:settingsViewController
animated:YES
completion:nil];
} }
- (void)presentStatus { - (void)presentStatus {
......
...@@ -8,6 +8,8 @@ import("//remoting/build/config/remoting_build.gni") ...@@ -8,6 +8,8 @@ import("//remoting/build/config/remoting_build.gni")
source_set("domain") { source_set("domain") {
sources = [ sources = [
"client_session_details.h",
"client_session_details.mm",
"host_info.h", "host_info.h",
"host_info.mm", "host_info.mm",
"user_info.h", "user_info.h",
......
// Copyright 2017 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.
#ifndef REMOTING_CLIENT_IOS_DOMAIN_CLIENT_SESSION_DETAILS_H_
#define REMOTING_CLIENT_IOS_DOMAIN_CLIENT_SESSION_DETAILS_H_
#import <Foundation/Foundation.h>
@class HostInfo;
// Session states that map to |remoting::protocol::ConnectionToHost::State| with
// the added state of PinPrompt. This can be used to track the state of the
// session for the duration of the connection.
typedef NS_ENUM(NSInteger, SessionState) {
SessionInitializing,
SessionConnecting,
SessionPinPrompt,
SessionAuthenticated,
SessionConnected,
SessionFailed,
SessionClosed,
};
// The current state of a session and data needed for session context.
@interface ClientSessionDetails : NSObject
// This is the object that describes the host this session is centered around.
@property(nonatomic) HostInfo* hostInfo;
// The current state of the session.
@property(nonatomic, assign) SessionState state;
@end
#endif // REMOTING_CLIENT_IOS_DOMAIN_CLIENT_SESSION_DETAILS_H_
// Copyright 2017 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
#import "remoting/client/ios/domain/client_session_details.h"
#import "remoting/client/ios/domain/host_info.h"
@implementation ClientSessionDetails
@synthesize hostInfo = _hostInfo;
@synthesize state = _state;
- (NSString*)description {
return
[NSString stringWithFormat:@"ClientSessionDetails: state=%d hostInfo=%@",
(int)_state, _hostInfo];
}
@end
...@@ -73,4 +73,10 @@ ...@@ -73,4 +73,10 @@
} }
} }
- (NSString*)description {
return
[NSString stringWithFormat:@"HostInfo: name=%@ status=%@ updatedTime= %@",
_hostName, _status, _updatedTime];
}
@end @end
...@@ -7,18 +7,36 @@ ...@@ -7,18 +7,36 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "remoting/client/ios/display/gl_display_handler.h"
#include "remoting/protocol/connection_to_host.h" #include "remoting/protocol/connection_to_host.h"
#include "remoting/protocol/session.h"
namespace remoting {
struct ConnectToHostInfo;
}
@class HostInfo;
@class GlDisplayHandler;
// A list of notifications that will be sent out for different types of Remoting
// Client events.
//
extern NSString* const kHostSessionStatusChanged;
extern NSString* const kHostSessionPinProvided;
// List of keys in user info from events.
extern NSString* const kSessionDetails;
extern NSString* const kSessonStateErrorCode;
extern NSString* const kHostSessionPin;
// Remoting Client is the entry point for starting a session with a remote
// host. This object should not be reused. Remoting Client will use the default
// NSNotificationCenter to signal session state changes using the key
// |kHostSessionStatusChanged|. It expects to receive an event back on
// |kHostSessionPinProvided| when the session is asking for a PIN authenication.
@interface RemotingClient : NSObject @interface RemotingClient : NSObject
- (void)connectToHost:(const remoting::ConnectToHostInfo&)info; // Connect to a given host.
// |hostInfo| is all the details around a host.
// |username| is the username to be used when connecting.
// |accessToken| is the oAuth access token to provided to create the session.
- (void)connectToHost:(HostInfo*)hostInfo
username:(NSString*)username
accessToken:(NSString*)accessToken;
// Mirrors the native client session delegate interface: // Mirrors the native client session delegate interface:
...@@ -37,7 +55,10 @@ struct ConnectToHostInfo; ...@@ -37,7 +55,10 @@ struct ConnectToHostInfo;
- (void)handleExtensionMessageOfType:(NSString*)type message:(NSString*)message; - (void)handleExtensionMessageOfType:(NSString*)type message:(NSString*)message;
// The display handler tied to the remoting client used to display the host.
@property(nonatomic, strong) GlDisplayHandler* displayHandler; @property(nonatomic, strong) GlDisplayHandler* displayHandler;
// The host info used to make the remoting client connection.
@property(nonatomic, readonly) HostInfo* hostInfo;
@end @end
......
...@@ -9,17 +9,33 @@ ...@@ -9,17 +9,33 @@
#import "remoting/client/ios/session/remoting_client.h" #import "remoting/client/ios/session/remoting_client.h"
#import "base/mac/bind_objc_block.h" #import "base/mac/bind_objc_block.h"
#import "ios/third_party/material_components_ios/src/components/Dialogs/src/MaterialDialogs.h"
#import "remoting/client/ios/display/gl_display_handler.h"
#import "remoting/client/ios/domain/client_session_details.h"
#import "remoting/client/ios/domain/host_info.h"
#include "base/strings/sys_string_conversions.h"
#include "remoting/client/chromoting_client_runtime.h" #include "remoting/client/chromoting_client_runtime.h"
#include "remoting/client/chromoting_session.h" #include "remoting/client/chromoting_session.h"
#include "remoting/client/connect_to_host_info.h" #include "remoting/client/connect_to_host_info.h"
#include "remoting/client/ios/session/remoting_client_session_delegate.h" #include "remoting/client/ios/session/remoting_client_session_delegate.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/video_renderer.h" #include "remoting/protocol/video_renderer.h"
NSString* const kHostSessionStatusChanged = @"kHostSessionStatusChanged";
NSString* const kHostSessionPinProvided = @"kHostSessionPinProvided";
NSString* const kSessionDetails = @"kSessionDetails";
NSString* const kSessonStateErrorCode = @"kSessonStateErrorCode";
NSString* const kHostSessionPin = @"kHostSessionPin";
@interface RemotingClient () { @interface RemotingClient () {
remoting::ChromotingClientRuntime* _runtime; remoting::ChromotingClientRuntime* _runtime;
std::unique_ptr<remoting::ChromotingSession> _session; std::unique_ptr<remoting::ChromotingSession> _session;
remoting::RemotingClientSessonDelegate* _sessonDelegate; remoting::RemotingClientSessonDelegate* _sessonDelegate;
ClientSessionDetails* _sessionDetails;
// Call _secretFetchedCallback on the network thread.
remoting::protocol::SecretFetchedCallback _secretFetchedCallback;
} }
@end @end
...@@ -32,12 +48,44 @@ ...@@ -32,12 +48,44 @@
if (self) { if (self) {
_runtime = remoting::ChromotingClientRuntime::GetInstance(); _runtime = remoting::ChromotingClientRuntime::GetInstance();
_sessonDelegate = new remoting::RemotingClientSessonDelegate(self); _sessonDelegate = new remoting::RemotingClientSessonDelegate(self);
_sessionDetails = [[ClientSessionDetails alloc] init];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(hostSessionPinProvided:)
name:kHostSessionPinProvided
object:nil];
} }
return self; return self;
} }
- (void)connectToHost:(const remoting::ConnectToHostInfo&)info { - (void)connectToHost:(HostInfo*)hostInfo
remoting::ConnectToHostInfo hostInfo(info); username:(NSString*)username
accessToken:(NSString*)accessToken {
DCHECK(hostInfo);
DCHECK(hostInfo.jabberId);
DCHECK(hostInfo.hostId);
DCHECK(hostInfo.publicKey);
_sessionDetails.hostInfo = hostInfo;
remoting::ConnectToHostInfo info;
info.username = base::SysNSStringToUTF8(username);
info.auth_token = base::SysNSStringToUTF8(accessToken);
info.host_jid = base::SysNSStringToUTF8(hostInfo.jabberId);
info.host_id = base::SysNSStringToUTF8(hostInfo.hostId);
info.host_pubkey = base::SysNSStringToUTF8(hostInfo.publicKey);
// TODO(nicholss): If iOS supports pairing, pull the stored data and
// insert it here.
info.pairing_id = "";
info.pairing_secret = "";
// TODO(nicholss): I am not sure about the following fields yet.
// info.capabilities =
// info.flags =
// info.host_version =
// info.host_os =
// info.host_os_version =
remoting::protocol::ClientAuthenticationConfig client_auth_config; remoting::protocol::ClientAuthenticationConfig client_auth_config;
client_auth_config.host_id = info.host_id; client_auth_config.host_id = info.host_id;
...@@ -46,9 +94,14 @@ ...@@ -46,9 +94,14 @@
client_auth_config.fetch_secret_callback = base::BindBlockArc( client_auth_config.fetch_secret_callback = base::BindBlockArc(
^(bool pairing_supported, const remoting::protocol::SecretFetchedCallback& ^(bool pairing_supported, const remoting::protocol::SecretFetchedCallback&
secret_fetched_callback) { secret_fetched_callback) {
NSLog(@"TODO(nicholss): Implement the FetchSecretCallback."); _secretFetchedCallback = secret_fetched_callback;
// TODO(nicholss): For now we pass back a junk number. _sessionDetails.state = SessionPinPrompt;
secret_fetched_callback.Run("000000"); [[NSNotificationCenter defaultCenter]
postNotificationName:kHostSessionStatusChanged
object:self
userInfo:[NSDictionary
dictionaryWithObject:_sessionDetails
forKey:kSessionDetails]];
}); });
// TODO(nicholss): Add audio support to iOS. // TODO(nicholss): Add audio support to iOS.
...@@ -61,18 +114,69 @@ ...@@ -61,18 +114,69 @@
_session.reset(new remoting::ChromotingSession( _session.reset(new remoting::ChromotingSession(
_sessonDelegate->GetWeakPtr(), _sessonDelegate->GetWeakPtr(),
[_displayHandler CreateCursorShapeStub], [_displayHandler CreateCursorShapeStub],
[_displayHandler CreateVideoRenderer], audioPlayer, hostInfo, [_displayHandler CreateVideoRenderer], audioPlayer, info,
client_auth_config)); client_auth_config));
_session->Connect(); _session->Connect();
})); }));
} }
#pragma mark - Eventing
- (void)hostSessionPinProvided:(NSNotification*)notification {
NSString* pin = [[notification userInfo] objectForKey:kHostSessionPin];
if (_secretFetchedCallback) {
_runtime->network_task_runner()->PostTask(
FROM_HERE, base::BindBlockArc(^{
_secretFetchedCallback.Run(base::SysNSStringToUTF8(pin));
}));
}
}
#pragma mark - Properties
- (HostInfo*)hostInfo {
return _sessionDetails.hostInfo;
}
#pragma mark - ChromotingSession::Delegate #pragma mark - ChromotingSession::Delegate
- (void)onConnectionState:(remoting::protocol::ConnectionToHost::State)state - (void)onConnectionState:(remoting::protocol::ConnectionToHost::State)state
error:(remoting::protocol::ErrorCode)error { error:(remoting::protocol::ErrorCode)error {
NSLog(@"TODO(nicholss): implement this, onConnectionState: %d %d.", state, switch (state) {
error); case remoting::protocol::ConnectionToHost::INITIALIZING:
NSLog(@"State --> INITIALIZING");
_sessionDetails.state = SessionInitializing;
break;
case remoting::protocol::ConnectionToHost::CONNECTING:
NSLog(@"State --> CONNECTING");
_sessionDetails.state = SessionConnecting;
break;
case remoting::protocol::ConnectionToHost::AUTHENTICATED:
NSLog(@"State --> AUTHENTICATED");
_sessionDetails.state = SessionAuthenticated;
break;
case remoting::protocol::ConnectionToHost::CONNECTED:
NSLog(@"State --> CONNECTED");
_sessionDetails.state = SessionConnected;
break;
case remoting::protocol::ConnectionToHost::FAILED:
NSLog(@"State --> FAILED");
_sessionDetails.state = SessionFailed;
break;
case remoting::protocol::ConnectionToHost::CLOSED:
NSLog(@"State --> CLOSED");
_sessionDetails.state = SessionClosed;
break;
default:
LOG(ERROR) << "onConnectionState, unknown state: " << state;
}
// TODO(nicholss): Send along the error code when we know what to do about it.
[[NSNotificationCenter defaultCenter]
postNotificationName:kHostSessionStatusChanged
object:self
userInfo:[NSDictionary dictionaryWithObject:_sessionDetails
forKey:kSessionDetails]];
} }
- (void)commitPairingCredentialsForHost:(NSString*)host - (void)commitPairingCredentialsForHost:(NSString*)host
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment