Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if !defined(__has_feature) || !__has_feature(objc_arc) | 5 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 6 #error "This file requires ARC support." | 6 #error "This file requires ARC support." |
| 7 #endif | 7 #endif |
| 8 | 8 |
| 9 #import <Foundation/Foundation.h> | 9 #import <Foundation/Foundation.h> |
| 10 | 10 |
| 11 #import "base/mac/bind_objc_block.h" | |
| 11 #import "remoting/client/ios/facade/remoting_service.h" | 12 #import "remoting/client/ios/facade/remoting_service.h" |
|
joedow
2017/04/05 22:30:56
In the header the includes were listed before the
nicholss
2017/04/07 18:16:15
Objc guide says this:
The standard order for head
| |
| 12 | 13 |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/strings/sys_string_conversions.h" | |
| 16 #include "net/url_request/url_request_context_getter.h" | |
| 17 #include "remoting/base/oauth_token_getter.h" | |
| 18 #include "remoting/base/oauth_token_getter_impl.h" | |
| 19 #include "remoting/client/ios/facade/host_info.h" | |
| 20 #include "remoting/client/ios/facade/host_list_fetcher.h" | |
| 14 | 21 |
| 15 @interface RemotingService () | 22 const char kOauthRedirectUrl[] = |
| 23 "https://chromoting-oauth.talkgadget." | |
| 24 "google.com/talkgadget/oauth/chrome-remote-desktop/dev"; | |
|
joedow
2017/04/05 22:30:56
Typically file scoped vars are put into an anonymo
nicholss
2017/04/07 18:16:16
I have not seen any Obj-C files use namespace yet.
| |
| 16 | 25 |
| 17 @property(nonatomic, copy) NSString* authorizationCode; | 26 std::unique_ptr<remoting::OAuthTokenGetter> |
| 27 CreateOAuthTokenGetterWithAuthorizationCode( | |
| 28 std::string auth_code, | |
|
joedow
2017/04/05 22:30:55
pass string by const ref, unless ObjC is different
nicholss
2017/04/07 18:16:16
This is Obj-C++ so const rules still work the same
| |
| 29 const remoting::OAuthTokenGetter::CredentialsUpdatedCallback& | |
| 30 on_credentials_update) { | |
| 31 std::unique_ptr<remoting::OAuthTokenGetter::OAuthIntermediateCredentials> | |
| 32 oauth_credentials( | |
| 33 new remoting::OAuthTokenGetter::OAuthIntermediateCredentials( | |
| 34 auth_code, false)); | |
|
joedow
2017/04/05 22:30:55
nit: it can be useful to add a comment to bare tru
nicholss
2017/04/07 18:16:15
Done.
| |
| 35 oauth_credentials->oauth_redirect_uri = kOauthRedirectUrl; | |
| 36 | |
| 37 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter( | |
| 38 new remoting::OAuthTokenGetterImpl( | |
| 39 std::move(oauth_credentials), on_credentials_update, | |
| 40 [[RemotingService SharedInstance] runtime]->url_requester(), true)); | |
| 41 return oauth_tokenGetter; | |
| 42 } | |
| 43 | |
| 44 std::unique_ptr<remoting::OAuthTokenGetter> CreateOAuthTokenWithRefreshToken( | |
| 45 std::string refresh_token, | |
|
joedow
2017/04/05 22:30:55
pass by const ref for these?
nicholss
2017/04/07 18:16:16
Done.
| |
| 46 std::string email) { | |
| 47 std::unique_ptr<remoting::OAuthTokenGetter::OAuthAuthorizationCredentials> | |
| 48 oauth_credentials( | |
| 49 new remoting::OAuthTokenGetter::OAuthAuthorizationCredentials( | |
| 50 email, refresh_token, false)); | |
| 51 | |
| 52 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter( | |
| 53 new remoting::OAuthTokenGetterImpl( | |
| 54 std::move(oauth_credentials), | |
| 55 [[RemotingService SharedInstance] runtime]->url_requester(), true)); | |
| 56 return oauth_tokenGetter; | |
| 57 } | |
| 58 | |
| 59 @interface RemotingService () { | |
| 60 remoting::ChromotingClientRuntime* _runtime; | |
| 61 std::unique_ptr<remoting::OAuthTokenGetter> _tokenGetter; | |
| 62 UserInfo* _user; | |
| 63 NSArray<HostInfo*>* _hosts; | |
| 64 id<RemotingAuthenticationDelegate> _authDelegate; | |
| 65 id<RemotingHostListDelegate> _hostListDelegate; | |
| 66 remoting::HostListFetcher* _hostListFetcher; | |
| 67 } | |
| 18 | 68 |
| 19 @end | 69 @end |
| 20 | 70 |
| 21 // | 71 // |
| 22 // RemodingService will act as the facade to the C++ layer that has not been | 72 // RemodingService will act as the facade to the C++ layer that has not been |
| 23 // implemented/integrated yet. | 73 // implemented/integrated yet. |
| 24 // TODO(nicholss): Implement/Integrate this class. At the moment it is being | 74 // TODO(nicholss): Implement/Integrate this class. At the moment it is being |
| 25 // used to generate fake data to implement the UI of the app. | 75 // used to generate fake data to implement the UI of the app. |
| 76 // Update: Half implemented now. User is still fake, but now real hosts lists. | |
| 26 // | 77 // |
| 27 @implementation RemotingService | 78 @implementation RemotingService |
| 28 | 79 |
| 29 @synthesize authorizationCode = _authorizationCode; | 80 // RemotingService is a singleton. |
| 81 + (RemotingService*)SharedInstance { | |
| 82 static RemotingService* sharedInstance = nil; | |
| 83 static dispatch_once_t guard; | |
| 84 dispatch_once(&guard, ^{ | |
| 85 sharedInstance = [[RemotingService alloc] init]; | |
| 86 }); | |
| 87 return sharedInstance; | |
| 88 } | |
| 89 | |
| 90 - (instancetype)init { | |
| 91 self = [super init]; | |
| 92 if (self) { | |
| 93 _user = nil; | |
| 94 _hosts = nil; | |
| 95 _runtime = remoting::ChromotingClientRuntime::GetInstance(); | |
| 96 _hostListFetcher = new remoting::HostListFetcher(_runtime->url_requester()); | |
| 97 } | |
| 98 return self; | |
| 99 } | |
| 100 | |
| 101 #pragma mark - RemotingService Implementation | |
| 102 | |
| 103 // TODO(nicholss): isAuthenticated needs to just kick off a request to | |
| 104 // authenticate a user. and more than one controller might want to be a delegate | |
| 105 // for this info so need to change this to be more of the registration types. | |
| 106 // The remoting_service might also want to be registered for authentication | |
| 107 // changes and it can update it's cache as it needs. | |
| 108 | |
| 109 - (void)setAuthenticationDelegate:(id<RemotingAuthenticationDelegate>)delegate { | |
| 110 _authDelegate = delegate; | |
|
joedow
2017/04/05 22:30:55
Are you using nil as a way to unregister here? I
nicholss
2017/04/07 18:16:16
add and set would imply that there can be more tha
| |
| 111 if (_authDelegate) { | |
| 112 [_authDelegate nowAuthenticated:[self isAuthenticated]]; | |
| 113 } | |
| 114 if (!_user && _tokenGetter) { | |
| 115 _tokenGetter->CallWithToken(base::BindBlockArc( | |
| 116 ^(remoting::OAuthTokenGetter::Status status, | |
| 117 const std::string& user_email, const std::string& access_token) { | |
| 118 if (status == remoting::OAuthTokenGetter::Status::SUCCESS) { | |
| 119 _user = [[UserInfo alloc] init]; | |
| 120 _user.userEmail = | |
| 121 [NSString stringWithCString:user_email.c_str() | |
| 122 encoding:[NSString defaultCStringEncoding]]; | |
| 123 } else { | |
| 124 _user = nil; | |
| 125 } | |
| 126 if (_authDelegate) { | |
| 127 [_authDelegate nowAuthenticated:[self isAuthenticated]]; | |
| 128 } | |
| 129 })); | |
| 130 } | |
| 131 } | |
| 30 | 132 |
| 31 - (BOOL)isAuthenticated { | 133 - (BOOL)isAuthenticated { |
| 32 return self.authorizationCode != nil; | 134 if (_user) { |
| 135 return YES; | |
| 136 } | |
| 137 return NO; | |
| 138 } | |
| 139 | |
| 140 - (void)startHostListFetchWith:(NSString*)accessToken { | |
| 141 NSLog(@"startHostListFetchWith : %@ %@", accessToken, _authDelegate); | |
| 142 if (_authDelegate) { | |
| 143 [_authDelegate nowAuthenticated:YES]; | |
| 144 | |
| 145 _hostListFetcher->RetrieveHostlist( | |
| 146 base::SysNSStringToUTF8(accessToken), | |
| 147 base::BindBlockArc(^(const std::vector<remoting::HostInfo>& hostlist) { | |
| 148 NSMutableArray<HostInfo*>* hosts = | |
| 149 [NSMutableArray arrayWithCapacity:hostlist.size()]; | |
| 150 std::string status; | |
| 151 for (const remoting::HostInfo& host_info : hostlist) { | |
| 152 remoting::HostStatus host_status = host_info.status; | |
| 153 if (host_status == remoting::kHostStatusOnline) { | |
|
joedow
2017/04/05 22:30:55
nit: you could make this a switch with a default s
nicholss
2017/04/07 18:16:16
I like it. Nice idea.
| |
| 154 status = "ONLINE"; | |
| 155 } else if (host_status == remoting::kHostStatusOffline) { | |
| 156 status = "OFFLINE"; | |
| 157 } else { | |
| 158 status = "UNKNOWN"; | |
|
joedow
2017/04/05 22:30:56
Log UNREACHED() here?
nicholss
2017/04/07 18:16:16
was not able to find usage of UNREACHED() , can yo
joedow
2017/04/10 16:09:59
Sorry, the macro is 'NOTREACHED()'.
nicholss
2017/04/10 17:49:53
Thanks! Updated.
| |
| 159 } | |
| 160 | |
| 161 // TODO(nicholss): Not yet integrated: createdTime, hostVersion, | |
| 162 // kind, offlineReason. Add them as the app will need this info. | |
| 163 HostInfo* host = [[HostInfo alloc] init]; | |
| 164 host.hostId = | |
| 165 [NSString stringWithCString:host_info.host_id.c_str() | |
| 166 encoding:[NSString defaultCStringEncoding]]; | |
| 167 host.hostName = | |
| 168 [NSString stringWithCString:host_info.host_name.c_str() | |
| 169 encoding:[NSString defaultCStringEncoding]]; | |
| 170 host.jabberId = | |
| 171 [NSString stringWithCString:host_info.host_jid.c_str() | |
| 172 encoding:[NSString defaultCStringEncoding]]; | |
| 173 host.publicKey = | |
| 174 [NSString stringWithCString:host_info.public_key.c_str() | |
| 175 encoding:[NSString defaultCStringEncoding]]; | |
| 176 host.status = | |
| 177 [NSString stringWithCString:status.c_str() | |
| 178 encoding:[NSString defaultCStringEncoding]]; | |
| 179 [hosts addObject:host]; | |
| 180 } | |
| 181 _hosts = hosts; | |
| 182 [_hostListDelegate hostListUpdated]; | |
| 183 })); | |
| 184 } | |
| 33 } | 185 } |
| 34 | 186 |
| 35 - (void)authenticateWithAuthorizationCode:(NSString*)authorizationCode { | 187 - (void)authenticateWithAuthorizationCode:(NSString*)authorizationCode { |
| 36 self.authorizationCode = authorizationCode; | 188 _tokenGetter = CreateOAuthTokenGetterWithAuthorizationCode( |
| 189 std::string(base::SysNSStringToUTF8(authorizationCode)), | |
| 190 base::BindBlockArc( | |
| 191 ^(const std::string& user_email, const std::string& refresh_token) { | |
| 192 // TODO(nicholss): Do something with these new creds. | |
| 193 VLOG(1) << "New Creds: " << user_email << " " << refresh_token; | |
| 194 })); | |
| 195 } | |
| 196 | |
| 197 - (void)authenticateWithRefreshToken:(NSString*)refreshToken | |
| 198 emai:(NSString*)email { | |
| 199 _tokenGetter = CreateOAuthTokenWithRefreshToken( | |
| 200 std::string(base::SysNSStringToUTF8(refreshToken)), | |
| 201 base::SysNSStringToUTF8(email)); | |
| 37 } | 202 } |
| 38 | 203 |
| 39 - (UserInfo*)getUser { | 204 - (UserInfo*)getUser { |
| 40 if (![self isAuthenticated]) { | 205 if (![self isAuthenticated]) { |
| 41 return nil; | 206 return nil; |
| 42 } | 207 } |
| 43 | 208 |
| 44 NSMutableString* json = [[NSMutableString alloc] init]; | 209 NSMutableString* json = [[NSMutableString alloc] init]; |
| 45 [json appendString:@"{"]; | 210 [json appendString:@"{"]; |
| 46 [json appendString:@"\"userId\":\"AABBCC123\","]; | 211 [json appendString:@"\"userId\":\"AABBCC123\","]; |
| 47 [json appendString:@"\"userFullName\":\"John Smith\","]; | 212 [json appendString:@"\"userFullName\":\"John Smith\","]; |
| 48 [json appendString:@"\"userEmail\":\"john@example.com\","]; | 213 [json appendString:@"\"userEmail\":\"john@example.com\","]; |
| 49 [json appendString:@"}"]; | 214 [json appendString:@"}"]; |
| 50 | 215 |
| 51 NSMutableData* data = [NSMutableData | 216 NSMutableData* data = [NSMutableData |
| 52 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; | 217 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; |
| 53 | 218 |
| 54 UserInfo* user = [UserInfo parseListFromJSON:data]; | 219 UserInfo* user = [UserInfo parseListFromJSON:data]; |
| 55 return user; | 220 return user; |
| 56 } | 221 } |
| 57 | 222 |
| 223 - (void)setHostListDelegate:(id<RemotingHostListDelegate>)delegate { | |
| 224 bool attemptUpdate = (_hostListDelegate != delegate); | |
| 225 _hostListDelegate = delegate; | |
| 226 if (attemptUpdate && _hostListDelegate && _tokenGetter) { | |
| 227 _tokenGetter->CallWithToken(base::BindBlockArc( | |
| 228 ^(remoting::OAuthTokenGetter::Status status, | |
| 229 const std::string& user_email, const std::string& access_token) { | |
| 230 NSString* accessToken = | |
| 231 [NSString stringWithCString:access_token.c_str() | |
| 232 encoding:[NSString defaultCStringEncoding]]; | |
| 233 [self startHostListFetchWith:accessToken]; | |
| 234 })); | |
| 235 } | |
| 236 } | |
| 237 | |
| 58 - (NSArray<HostInfo*>*)getHosts { | 238 - (NSArray<HostInfo*>*)getHosts { |
| 59 if (![self isAuthenticated]) { | 239 if (![self isAuthenticated]) { |
| 60 return nil; | 240 return nil; |
| 61 } | 241 } |
| 62 | 242 return _hosts; |
| 63 NSMutableString* json = [[NSMutableString alloc] init]; | |
| 64 [json | |
| 65 appendString:@"{\"data\":{\"kind\":\"chromoting#hostList\",\"items\":["]; | |
| 66 [json appendString:@"{"]; | |
| 67 [json appendString:@"\"createdTime\":\"2000-01-01T00:00:01.000Z\","]; | |
| 68 [json appendString:@"\"hostId\":\"Host1\","]; | |
| 69 [json appendString:@"\"hostName\":\"HostName1\","]; | |
| 70 [json appendString:@"\"hostVersion\":\"2.22.5.4\","]; | |
| 71 [json appendString:@"\"kind\":\"Chromoting#host\","]; | |
| 72 [json appendString:@"\"jabberId\":\"JabberingOn\","]; | |
| 73 [json appendString:@"\"publicKey\":\"AAAAABBBBBZZZZZ\","]; | |
| 74 [json appendString:@"\"status\":\"TESTING\","]; | |
| 75 [json appendString:@"\"updatedTime\":\"2000-01-01T00:00:01.000Z\""]; | |
| 76 [json appendString:@"},"]; | |
| 77 [json appendString:@"{"]; | |
| 78 [json appendString:@"\"createdTime\":\"2000-01-01T00:00:01.000Z\","]; | |
| 79 [json appendString:@"\"hostId\":\"Host2\","]; | |
| 80 [json appendString:@"\"hostName\":\"HostName2\","]; | |
| 81 [json appendString:@"\"hostVersion\":\"2.22.5.4\","]; | |
| 82 [json appendString:@"\"kind\":\"Chromoting#host\","]; | |
| 83 [json appendString:@"\"jabberId\":\"JabberingOn\","]; | |
| 84 [json appendString:@"\"publicKey\":\"AAAAABBBBBZZZZZ\","]; | |
| 85 [json appendString:@"\"status\":\"ONLINE\","]; | |
| 86 [json appendString:@"\"updatedTime\":\"2000-01-01T00:00:01.000Z\""]; | |
| 87 [json appendString:@"}"]; | |
| 88 [json appendString:@"]}}"]; | |
| 89 | |
| 90 NSMutableData* data = [NSMutableData | |
| 91 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; | |
| 92 | |
| 93 NSMutableArray<HostInfo*>* hosts = [HostInfo parseListFromJSON:data]; | |
| 94 return hosts; | |
| 95 } | 243 } |
| 96 | 244 |
| 97 // RemotingService is a singleton. | 245 - (remoting::ChromotingClientRuntime*)runtime { |
| 98 + (RemotingService*)sharedInstance { | 246 return _runtime; |
|
joedow
2017/04/05 22:30:56
Can you just return 'remoting::ChromotingClientRun
nicholss
2017/04/07 18:16:15
Done.
| |
| 99 static RemotingService* sharedInstance = nil; | |
| 100 static dispatch_once_t guard; | |
| 101 dispatch_once(&guard, ^{ | |
| 102 sharedInstance = [[RemotingService alloc] init]; | |
| 103 }); | |
| 104 return sharedInstance; | |
| 105 } | 247 } |
| 106 | 248 |
| 107 @end | 249 @end |
| OLD | NEW |