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 |