OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 6 #error "This file requires ARC support." |
| 7 #endif |
| 8 |
| 9 #import "remoting/ios/ui/host_list_view_controller.h" |
| 10 |
| 11 #include "google_apis/google_api_keys.h" |
| 12 |
| 13 #import "remoting/ios/host.h" |
| 14 #import "remoting/ios/host_cell.h" |
| 15 #import "remoting/ios/host_refresh.h" |
| 16 #import "remoting/ios/utility.h" |
| 17 #import "remoting/ios/ui/host_view_controller.h" |
| 18 |
| 19 @interface HostListViewController (Private) |
| 20 // Calledback from _updateDisplayTimer |
| 21 - (void)checkLoginStatus; |
| 22 - (void)refreshHostList; |
| 23 - (GTMOAuth2Authentication*)AuthorizationAgent; |
| 24 - (BOOL)isSignedIn; |
| 25 - (NSString*)signedInUsername; |
| 26 - (void)displayLoginStatus; |
| 27 - (void)signInUser; |
| 28 // Callback from GTMOAuth2ViewControllerTouch |
| 29 - (void)viewController:(GTMOAuth2ViewControllerTouch*)viewController |
| 30 finishedWithAuth:(GTMOAuth2Authentication*)authResult |
| 31 error:(NSError*)error; |
| 32 @end |
| 33 |
| 34 @implementation HostListViewController |
| 35 |
| 36 // Override UIViewController |
| 37 // Create google+ service for google authentication and oAuth2 autherization. |
| 38 // Check signed in credintials shortly after a |
| 39 // short delay of |_updateDisplayTimer| |
| 40 - (void)viewDidLoad { |
| 41 [super viewDidLoad]; |
| 42 |
| 43 NSString* clientId = |
| 44 [NSString stringWithUTF8String:google_apis::GetOAuth2ClientID( |
| 45 google_apis::CLIENT_REMOTING).c_str()]; |
| 46 |
| 47 // Ensure the google_apis lib has keys |
| 48 // If this check fails then google_apis was not built right |
| 49 // TODO (aboone) |
| 50 // For now we specify the preproccer macros for |
| 51 // GOOGLE_CLIENT_SECRET_REMOTING and GOOGLE_CLIENT_ID_REMOTING when building |
| 52 // the google_apis target. The values may be developer specific, and should |
| 53 // be well know to the project staff. |
| 54 // See http://www.chromium.org/developers/how-tos/api-keys for more general |
| 55 // information. |
| 56 DCHECK(![clientId isEqualToString:@"dummytoken"]); |
| 57 |
| 58 [_tableHostList setDataSource:self]; |
| 59 [_tableHostList setDelegate:self]; |
| 60 |
| 61 _plusService = [[GTLServicePlus alloc] init]; |
| 62 _plusService.authorizer = [GTMOAuth2ViewControllerTouch |
| 63 authForGoogleFromKeychainForName:kKeychainItemName |
| 64 clientID:clientId |
| 65 clientSecret: |
| 66 [NSString stringWithUTF8String: |
| 67 google_apis::GetOAuth2ClientSecret( |
| 68 google_apis::CLIENT_REMOTING) |
| 69 .c_str()]]; |
| 70 |
| 71 [self displayLoginStatus]; |
| 72 _updateDisplayTimer = |
| 73 [NSTimer scheduledTimerWithTimeInterval:0.4 |
| 74 target:self |
| 75 selector:@selector(checkLoginStatus) |
| 76 userInfo:nil |
| 77 repeats:NO]; |
| 78 _versionInfo.title = [Utility appVersionNumberDisplayString]; |
| 79 } |
| 80 |
| 81 // Override UIViewController |
| 82 // check for segues defined in the storyboard by identifier, and set a few |
| 83 // properties before transitioning |
| 84 - (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender { |
| 85 if ([segue.identifier isEqualToString:@"ConnectToHost"]) { |
| 86 // the designationViewController type is defined by the storyboard |
| 87 HostViewController* hostView = |
| 88 static_cast<HostViewController*>(segue.destinationViewController); |
| 89 // set selected properties before returning |
| 90 [hostView setHostDetails: |
| 91 [self hostAtIndex:[_tableHostList indexPathForCell:sender]] |
| 92 authorization:[self AuthorizationAgent]]; |
| 93 } |
| 94 } |
| 95 |
| 96 // @protocol HostRefreshDelegate, remember received host list for the table |
| 97 // view to refresh from |
| 98 - (void)hostListRefresh:(NSArray*)hostList { |
| 99 _hostList = hostList; |
| 100 [_refreshActivityIndicator stopAnimating]; |
| 101 [_tableHostList reloadData]; |
| 102 } |
| 103 |
| 104 // @protocol UITableViewDataSource |
| 105 // Only have 1 section and it contains all the hosts |
| 106 - (NSInteger)tableView:(UITableView*)tableView |
| 107 numberOfRowsInSection:(NSInteger)section { |
| 108 return [_hostList count]; |
| 109 } |
| 110 |
| 111 // @protocol UITableViewDataSource |
| 112 // Convert a host entry to a table row |
| 113 - (HostCell*)tableView:(UITableView*)tableView |
| 114 cellForRowAtIndexPath:(NSIndexPath*)indexPath { |
| 115 static NSString* CellIdentifier = @"HostStatusCell"; |
| 116 |
| 117 HostCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier |
| 118 forIndexPath:indexPath]; |
| 119 |
| 120 Host* host = [self hostAtIndex:indexPath]; |
| 121 cell.labelHostName.text = host.hostName; |
| 122 cell.labelStatus.text = host.status; |
| 123 |
| 124 UIColor* statColor = nil; |
| 125 if ([host.status isEqualToString:@"ONLINE"]) { |
| 126 statColor = [[UIColor alloc] initWithRed:0 green:1 blue:0 alpha:1]; |
| 127 } else { |
| 128 statColor = [[UIColor alloc] initWithRed:1 green:0 blue:0 alpha:1]; |
| 129 } |
| 130 [cell.labelStatus setTextColor:statColor]; |
| 131 |
| 132 return cell; |
| 133 } |
| 134 |
| 135 // @protocol UITableViewDataSource |
| 136 // Rows are not editable via standared UI mechanisms |
| 137 - (BOOL)tableView:(UITableView*)tableView |
| 138 canEditRowAtIndexPath:(NSIndexPath*)indexPath { |
| 139 return NO; |
| 140 } |
| 141 |
| 142 - (IBAction)btnRefreshHostList:(id)sender { |
| 143 [self refreshHostList]; |
| 144 } |
| 145 |
| 146 - (IBAction)btnAccount:(id)sender { |
| 147 [self signInUser]; |
| 148 } |
| 149 |
| 150 // Called when _updateDisplayTimer has expired, short time after the view was |
| 151 // loaded |
| 152 - (void)checkLoginStatus { |
| 153 if (_updateDisplayTimer) { |
| 154 [_updateDisplayTimer invalidate]; |
| 155 _updateDisplayTimer = nil; |
| 156 } |
| 157 if (![self isSignedIn]) { |
| 158 [self signInUser]; |
| 159 } else { |
| 160 [self refreshHostList]; |
| 161 } |
| 162 } |
| 163 |
| 164 - (void)refreshHostList { |
| 165 HostRefresh* hostRefresh = [[HostRefresh alloc] init]; |
| 166 [_refreshActivityIndicator startAnimating]; |
| 167 [hostRefresh refreshHostList:[self AuthorizationAgent] delegate:self]; |
| 168 } |
| 169 |
| 170 // Get the Google+ service's authorization agent |
| 171 - (GTMOAuth2Authentication*)AuthorizationAgent { |
| 172 return _plusService.authorizer; |
| 173 } |
| 174 |
| 175 - (BOOL)isSignedIn { |
| 176 return ([self signedInUsername] != nil); |
| 177 } |
| 178 |
| 179 - (NSString*)signedInUsername { |
| 180 BOOL isSignedIn = [self AuthorizationAgent].canAuthorize; |
| 181 if (isSignedIn) { |
| 182 return [self AuthorizationAgent].userEmail; |
| 183 } else { |
| 184 return nil; |
| 185 } |
| 186 } |
| 187 |
| 188 - (void)displayLoginStatus { |
| 189 NSString* userName = [self signedInUsername]; |
| 190 |
| 191 if (userName == nil) { |
| 192 userName = @"Not logged in"; |
| 193 } |
| 194 |
| 195 [_btnAccountObject setTitle:userName forState:UIControlStateNormal]; |
| 196 } |
| 197 |
| 198 // Launch the google.com authentication and autherization process. If a user is |
| 199 // already signed in, begin by signing out so another account could be |
| 200 // signed in. |
| 201 - (void)signInUser { |
| 202 if ([self isSignedIn]) { |
| 203 // Sign out |
| 204 [GTMOAuth2ViewControllerTouch |
| 205 removeAuthFromKeychainForName:kKeychainItemName]; |
| 206 _plusService.authorizer = nil; |
| 207 } |
| 208 [self presentViewController: |
| 209 // When the signin is complete a http redirection occurs, and the user |
| 210 // will see the output. We do not want the user to notice this |
| 211 // transition. Wrapping the oAuth2 Controller in a |
| 212 // UINavigationController causes the view to render as a blank (black) |
| 213 // page when a http redirection occurs. |
| 214 [[UINavigationController alloc] |
| 215 initWithRootViewController: |
| 216 [[GTMOAuth2ViewControllerTouch alloc] |
| 217 initWithScope: |
| 218 [NSString stringWithUTF8String: |
| 219 remoting::GetOauthScope().c_str()] |
| 220 clientID: |
| 221 [NSString |
| 222 stringWithUTF8String: |
| 223 google_apis::GetOAuth2ClientID( |
| 224 google_apis::CLIENT_REMOTING).c_str()] |
| 225 clientSecret: |
| 226 [NSString |
| 227 stringWithUTF8String: |
| 228 google_apis::GetOAuth2ClientSecret( |
| 229 google_apis::CLIENT_REMOTING).c_str()] |
| 230 keychainItemName:kKeychainItemName |
| 231 delegate:self |
| 232 finishedSelector: |
| 233 @selector(viewController:finishedWithAuth:error:)]] |
| 234 animated:YES |
| 235 completion:nil]; |
| 236 } |
| 237 |
| 238 // Callback from GTMOAuth2ViewControllerTouch |
| 239 // Handle completion of the authentication process, and updates the service |
| 240 // with the new credentials. |
| 241 - (void)viewController:(GTMOAuth2ViewControllerTouch*)viewController |
| 242 finishedWithAuth:(GTMOAuth2Authentication*)authResult |
| 243 error:(NSError*)error { |
| 244 |
| 245 [viewController.presentingViewController dismissViewControllerAnimated:NO |
| 246 completion:nil]; |
| 247 |
| 248 if (error != nil) { |
| 249 [Utility showAlert:@"Authentication Error" |
| 250 message:error.localizedDescription]; |
| 251 _plusService.authorizer = nil; |
| 252 } else { |
| 253 _plusService.authorizer = authResult; |
| 254 } |
| 255 [self displayLoginStatus]; |
| 256 [self refreshHostList]; |
| 257 } |
| 258 |
| 259 - (Host*)hostAtIndex:(NSIndexPath*)indexPath { |
| 260 return [_hostList objectAtIndex:indexPath.row]; |
| 261 } |
| 262 |
| 263 @end |
OLD | NEW |