| Index: remoting/ios/ui/host_list_view_controller.mm
|
| diff --git a/remoting/ios/ui/host_list_view_controller.mm b/remoting/ios/ui/host_list_view_controller.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b31cab344b190b7d306cd522c0c5cd1d96d3e928
|
| --- /dev/null
|
| +++ b/remoting/ios/ui/host_list_view_controller.mm
|
| @@ -0,0 +1,263 @@
|
| +// 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
|
| +
|
| +#import "remoting/ios/ui/host_list_view_controller.h"
|
| +
|
| +#include "google_apis/google_api_keys.h"
|
| +
|
| +#import "remoting/ios/host.h"
|
| +#import "remoting/ios/host_cell.h"
|
| +#import "remoting/ios/host_refresh.h"
|
| +#import "remoting/ios/utility.h"
|
| +#import "remoting/ios/ui/host_view_controller.h"
|
| +
|
| +@interface HostListViewController (Private)
|
| +// Calledback from _updateDisplayTimer
|
| +- (void)checkLoginStatus;
|
| +- (void)refreshHostList;
|
| +- (GTMOAuth2Authentication*)AuthorizationAgent;
|
| +- (BOOL)isSignedIn;
|
| +- (NSString*)signedInUsername;
|
| +- (void)displayLoginStatus;
|
| +- (void)signInUser;
|
| +// Callback from GTMOAuth2ViewControllerTouch
|
| +- (void)viewController:(GTMOAuth2ViewControllerTouch*)viewController
|
| + finishedWithAuth:(GTMOAuth2Authentication*)authResult
|
| + error:(NSError*)error;
|
| +@end
|
| +
|
| +@implementation HostListViewController
|
| +
|
| +// Override UIViewController
|
| +// Create google+ service for google authentication and oAuth2 autherization.
|
| +// Check signed in credintials shortly after a
|
| +// short delay of |_updateDisplayTimer|
|
| +- (void)viewDidLoad {
|
| + [super viewDidLoad];
|
| +
|
| + NSString* clientId =
|
| + [NSString stringWithUTF8String:google_apis::GetOAuth2ClientID(
|
| + google_apis::CLIENT_REMOTING).c_str()];
|
| +
|
| + // Ensure the google_apis lib has keys
|
| + // If this check fails then google_apis was not built right
|
| + // TODO (aboone)
|
| + // For now we specify the preproccer macros for
|
| + // GOOGLE_CLIENT_SECRET_REMOTING and GOOGLE_CLIENT_ID_REMOTING when building
|
| + // the google_apis target. The values may be developer specific, and should
|
| + // be well know to the project staff.
|
| + // See http://www.chromium.org/developers/how-tos/api-keys for more general
|
| + // information.
|
| + DCHECK(![clientId isEqualToString:@"dummytoken"]);
|
| +
|
| + [_tableHostList setDataSource:self];
|
| + [_tableHostList setDelegate:self];
|
| +
|
| + _plusService = [[GTLServicePlus alloc] init];
|
| + _plusService.authorizer = [GTMOAuth2ViewControllerTouch
|
| + authForGoogleFromKeychainForName:kKeychainItemName
|
| + clientID:clientId
|
| + clientSecret:
|
| + [NSString stringWithUTF8String:
|
| + google_apis::GetOAuth2ClientSecret(
|
| + google_apis::CLIENT_REMOTING)
|
| + .c_str()]];
|
| +
|
| + [self displayLoginStatus];
|
| + _updateDisplayTimer =
|
| + [NSTimer scheduledTimerWithTimeInterval:0.4
|
| + target:self
|
| + selector:@selector(checkLoginStatus)
|
| + userInfo:nil
|
| + repeats:NO];
|
| + _versionInfo.title = [Utility appVersionNumberDisplayString];
|
| +}
|
| +
|
| +// Override UIViewController
|
| +// check for segues defined in the storyboard by identifier, and set a few
|
| +// properties before transitioning
|
| +- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender {
|
| + if ([segue.identifier isEqualToString:@"ConnectToHost"]) {
|
| + // the designationViewController type is defined by the storyboard
|
| + HostViewController* hostView =
|
| + static_cast<HostViewController*>(segue.destinationViewController);
|
| + // set selected properties before returning
|
| + [hostView setHostDetails:
|
| + [self hostAtIndex:[_tableHostList indexPathForCell:sender]]
|
| + authorization:[self AuthorizationAgent]];
|
| + }
|
| +}
|
| +
|
| +// @protocol HostRefreshDelegate, remember received host list for the table
|
| +// view to refresh from
|
| +- (void)hostListRefresh:(NSArray*)hostList {
|
| + _hostList = hostList;
|
| + [_refreshActivityIndicator stopAnimating];
|
| + [_tableHostList reloadData];
|
| +}
|
| +
|
| +// @protocol UITableViewDataSource
|
| +// Only have 1 section and it contains all the hosts
|
| +- (NSInteger)tableView:(UITableView*)tableView
|
| + numberOfRowsInSection:(NSInteger)section {
|
| + return [_hostList count];
|
| +}
|
| +
|
| +// @protocol UITableViewDataSource
|
| +// Convert a host entry to a table row
|
| +- (HostCell*)tableView:(UITableView*)tableView
|
| + cellForRowAtIndexPath:(NSIndexPath*)indexPath {
|
| + static NSString* CellIdentifier = @"HostStatusCell";
|
| +
|
| + HostCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
|
| + forIndexPath:indexPath];
|
| +
|
| + Host* host = [self hostAtIndex:indexPath];
|
| + cell.labelHostName.text = host.hostName;
|
| + cell.labelStatus.text = host.status;
|
| +
|
| + UIColor* statColor = nil;
|
| + if ([host.status isEqualToString:@"ONLINE"]) {
|
| + statColor = [[UIColor alloc] initWithRed:0 green:1 blue:0 alpha:1];
|
| + } else {
|
| + statColor = [[UIColor alloc] initWithRed:1 green:0 blue:0 alpha:1];
|
| + }
|
| + [cell.labelStatus setTextColor:statColor];
|
| +
|
| + return cell;
|
| +}
|
| +
|
| +// @protocol UITableViewDataSource
|
| +// Rows are not editable via standared UI mechanisms
|
| +- (BOOL)tableView:(UITableView*)tableView
|
| + canEditRowAtIndexPath:(NSIndexPath*)indexPath {
|
| + return NO;
|
| +}
|
| +
|
| +- (IBAction)btnRefreshHostList:(id)sender {
|
| + [self refreshHostList];
|
| +}
|
| +
|
| +- (IBAction)btnAccount:(id)sender {
|
| + [self signInUser];
|
| +}
|
| +
|
| +// Called when _updateDisplayTimer has expired, short time after the view was
|
| +// loaded
|
| +- (void)checkLoginStatus {
|
| + if (_updateDisplayTimer) {
|
| + [_updateDisplayTimer invalidate];
|
| + _updateDisplayTimer = nil;
|
| + }
|
| + if (![self isSignedIn]) {
|
| + [self signInUser];
|
| + } else {
|
| + [self refreshHostList];
|
| + }
|
| +}
|
| +
|
| +- (void)refreshHostList {
|
| + HostRefresh* hostRefresh = [[HostRefresh alloc] init];
|
| + [_refreshActivityIndicator startAnimating];
|
| + [hostRefresh refreshHostList:[self AuthorizationAgent] delegate:self];
|
| +}
|
| +
|
| +// Get the Google+ service's authorization agent
|
| +- (GTMOAuth2Authentication*)AuthorizationAgent {
|
| + return _plusService.authorizer;
|
| +}
|
| +
|
| +- (BOOL)isSignedIn {
|
| + return ([self signedInUsername] != nil);
|
| +}
|
| +
|
| +- (NSString*)signedInUsername {
|
| + BOOL isSignedIn = [self AuthorizationAgent].canAuthorize;
|
| + if (isSignedIn) {
|
| + return [self AuthorizationAgent].userEmail;
|
| + } else {
|
| + return nil;
|
| + }
|
| +}
|
| +
|
| +- (void)displayLoginStatus {
|
| + NSString* userName = [self signedInUsername];
|
| +
|
| + if (userName == nil) {
|
| + userName = @"Not logged in";
|
| + }
|
| +
|
| + [_btnAccountObject setTitle:userName forState:UIControlStateNormal];
|
| +}
|
| +
|
| +// Launch the google.com authentication and autherization process. If a user is
|
| +// already signed in, begin by signing out so another account could be
|
| +// signed in.
|
| +- (void)signInUser {
|
| + if ([self isSignedIn]) {
|
| + // Sign out
|
| + [GTMOAuth2ViewControllerTouch
|
| + removeAuthFromKeychainForName:kKeychainItemName];
|
| + _plusService.authorizer = nil;
|
| + }
|
| + [self presentViewController:
|
| + // When the signin is complete a http redirection occurs, and the user
|
| + // will see the output. We do not want the user to notice this
|
| + // transition. Wrapping the oAuth2 Controller in a
|
| + // UINavigationController causes the view to render as a blank (black)
|
| + // page when a http redirection occurs.
|
| + [[UINavigationController alloc]
|
| + initWithRootViewController:
|
| + [[GTMOAuth2ViewControllerTouch alloc]
|
| + initWithScope:
|
| + [NSString stringWithUTF8String:
|
| + remoting::GetOauthScope().c_str()]
|
| + clientID:
|
| + [NSString
|
| + stringWithUTF8String:
|
| + google_apis::GetOAuth2ClientID(
|
| + google_apis::CLIENT_REMOTING).c_str()]
|
| + clientSecret:
|
| + [NSString
|
| + stringWithUTF8String:
|
| + google_apis::GetOAuth2ClientSecret(
|
| + google_apis::CLIENT_REMOTING).c_str()]
|
| + keychainItemName:kKeychainItemName
|
| + delegate:self
|
| + finishedSelector:
|
| + @selector(viewController:finishedWithAuth:error:)]]
|
| + animated:YES
|
| + completion:nil];
|
| +}
|
| +
|
| +// Callback from GTMOAuth2ViewControllerTouch
|
| +// Handle completion of the authentication process, and updates the service
|
| +// with the new credentials.
|
| +- (void)viewController:(GTMOAuth2ViewControllerTouch*)viewController
|
| + finishedWithAuth:(GTMOAuth2Authentication*)authResult
|
| + error:(NSError*)error {
|
| +
|
| + [viewController.presentingViewController dismissViewControllerAnimated:NO
|
| + completion:nil];
|
| +
|
| + if (error != nil) {
|
| + [Utility showAlert:@"Authentication Error"
|
| + message:error.localizedDescription];
|
| + _plusService.authorizer = nil;
|
| + } else {
|
| + _plusService.authorizer = authResult;
|
| + }
|
| + [self displayLoginStatus];
|
| + [self refreshHostList];
|
| +}
|
| +
|
| +- (Host*)hostAtIndex:(NSIndexPath*)indexPath {
|
| + return [_hostList objectAtIndex:indexPath.row];
|
| +}
|
| +
|
| +@end
|
|
|