Skip to content

Commit 1c64c30

Browse files
committed
Copied the existing iOS source files unmodified to the new native staging area.
Change-Id: I5fe3a810f1cac8b766fd3b6a7f3abea2e3bedc7e
1 parent c550322 commit 1c64c30

File tree

4 files changed

+526
-0
lines changed

4 files changed

+526
-0
lines changed

staging/native/src/ios/GoogleSignIn.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#import <GoogleSignIn/GIDSignIn.h>
17+
@interface GoogleSignInHandler
18+
: NSObject <GIDSignInDelegate, GIDSignInUIDelegate>
19+
20+
@end
+345
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#import "GoogleSignIn.h"
17+
#import <GoogleSignIn/GIDAuthentication.h>
18+
#import <GoogleSignIn/GIDGoogleUser.h>
19+
#import <GoogleSignIn/GIDProfileData.h>
20+
#import <GoogleSignIn/GIDSignIn.h>
21+
22+
#import <memory>
23+
24+
// These values are in the Unity plugin code. The iOS specific
25+
// codes are mapped to these.
26+
static const int kStatusCodeSuccessCached = -1;
27+
static const int kStatusCodeSuccess = 0;
28+
static const int kStatusCodeApiNotConnected = 1;
29+
static const int kStatusCodeCanceled = 2;
30+
static const int kStatusCodeInterrupted = 3;
31+
static const int kStatusCodeInvalidAccount = 4;
32+
static const int kStatusCodeTimeout = 5;
33+
static const int kStatusCodeDeveloperError = 6;
34+
static const int kStatusCodeInternalError = 7;
35+
static const int kStatusCodeNetworkError = 8;
36+
static const int kStatusCodeError = 9;
37+
38+
/**
39+
* Helper method to pause the Unity player. This is done when showing any UI.
40+
*/
41+
void UnpauseUnityPlayer() {
42+
dispatch_async(dispatch_get_main_queue(), ^{
43+
if (UnityIsPaused() > 0) {
44+
UnityPause(0);
45+
}
46+
});
47+
}
48+
49+
// result for pending operation. Access to this should be protected using the
50+
// resultLock.
51+
struct SignInResult {
52+
int result_code;
53+
bool finished;
54+
};
55+
56+
std::unique_ptr<SignInResult> currentResult_;
57+
58+
NSRecursiveLock *resultLock = [NSRecursiveLock alloc];
59+
60+
@implementation GoogleSignInHandler
61+
62+
/**
63+
* Overload the presenting of the UI so we can pause the Unity player.
64+
*/
65+
- (void)signIn:(GIDSignIn *)signIn
66+
presentViewController:(UIViewController *)viewController {
67+
UnityPause(true);
68+
[UnityGetGLViewController() presentViewController:viewController
69+
animated:YES
70+
completion:nil];
71+
}
72+
73+
/**
74+
* Overload the dismissing so we can resume the Unity player.
75+
*/
76+
- (void)signIn:(GIDSignIn *)signIn
77+
dismissViewController:(UIViewController *)viewController {
78+
UnityPause(false);
79+
[UnityGetGLViewController() dismissViewControllerAnimated:YES completion:nil];
80+
}
81+
82+
/**
83+
* The sign-in flow has finished and was successful if |error| is |nil|.
84+
* Map the errors from the iOS SDK back to the Android values for consistency's
85+
* sake in the Unity layer.
86+
*/
87+
- (void)signIn:(GIDSignIn *)signIn
88+
didSignInForUser:(GIDGoogleUser *)user
89+
withError:(NSError *)_error {
90+
if (_error == nil) {
91+
if (currentResult_) {
92+
currentResult_->result_code = kStatusCodeSuccess;
93+
currentResult_->finished = true;
94+
} else {
95+
NSLog(@"No currentResult to set status on!");
96+
}
97+
NSLog(@"didSignInForUser: SUCCESS");
98+
} else {
99+
NSLog(@"didSignInForUser: %@", _error.localizedDescription);
100+
if (currentResult_) {
101+
switch (_error.code) {
102+
case kGIDSignInErrorCodeUnknown:
103+
currentResult_->result_code = kStatusCodeError;
104+
break;
105+
case kGIDSignInErrorCodeKeychain:
106+
currentResult_->result_code = kStatusCodeInternalError;
107+
break;
108+
case kGIDSignInErrorCodeNoSignInHandlersInstalled:
109+
currentResult_->result_code = kStatusCodeDeveloperError;
110+
break;
111+
case kGIDSignInErrorCodeHasNoAuthInKeychain:
112+
currentResult_->result_code = kStatusCodeError;
113+
break;
114+
case kGIDSignInErrorCodeCanceled:
115+
currentResult_->result_code = kStatusCodeCanceled;
116+
break;
117+
default:
118+
NSLog(@"Unmapped error code: %ld, returning Error",
119+
static_cast<long>(_error.code));
120+
currentResult_->result_code = kStatusCodeError;
121+
}
122+
123+
currentResult_->finished = true;
124+
UnpauseUnityPlayer();
125+
} else {
126+
NSLog(@"No currentResult to set status on!");
127+
}
128+
}
129+
}
130+
131+
// Finished disconnecting |user| from the app successfully if |error| is |nil|.
132+
- (void)signIn:(GIDSignIn *)signIn
133+
didDisconnectWithUser:(GIDGoogleUser *)user
134+
withError:(NSError *)_error {
135+
if (_error == nil) {
136+
NSLog(@"didDisconnectWithUser: SUCCESS");
137+
} else {
138+
NSLog(@"didDisconnectWithUser: %@", _error);
139+
}
140+
}
141+
142+
@end
143+
144+
/**
145+
* These are the external "C" methods that are imported by the Unity C# code.
146+
* The parameters are intended to be primative, easy to marshall.
147+
*/
148+
extern "C" {
149+
/**
150+
* This method does nothing in the iOS implementation. It is here
151+
* to make the API uniform between Android and iOS.
152+
*/
153+
void *GoogleSignIn_Create(void *data) { return NULL; }
154+
155+
void GoogleSignIn_EnableDebugLogging(void *unused, bool flag) {
156+
if (flag) {
157+
NSLog(@"GoogleSignIn: No optional logging available on iOS");
158+
}
159+
}
160+
161+
/**
162+
* Configures the GIDSignIn instance. The first parameter is unused in iOS.
163+
* It is here to make the API between Android and iOS uniform.
164+
*/
165+
bool GoogleSignIn_Configure(void *unused, bool useGameSignIn,
166+
const char *webClientId, bool requestAuthCode,
167+
bool forceTokenRefresh, bool requestEmail,
168+
bool requestIdToken, bool hidePopups,
169+
const char **additionalScopes, int scopeCount,
170+
const char *accountName) {
171+
if (webClientId) {
172+
[GIDSignIn sharedInstance].serverClientID =
173+
[NSString stringWithUTF8String:webClientId];
174+
}
175+
176+
[GIDSignIn sharedInstance].shouldFetchBasicProfile = true;
177+
178+
int scopeSize = scopeCount;
179+
180+
if (scopeSize) {
181+
NSMutableArray *tmpary =
182+
[[NSMutableArray alloc] initWithCapacity:scopeSize];
183+
for (int i = 0; i < scopeCount; i++) {
184+
[tmpary addObject:[NSString stringWithUTF8String:additionalScopes[i]]];
185+
}
186+
187+
[GIDSignIn sharedInstance].scopes = tmpary;
188+
}
189+
190+
if (accountName) {
191+
[GIDSignIn sharedInstance].loginHint =
192+
[NSString stringWithUTF8String:accountName];
193+
}
194+
195+
return !useGameSignIn;
196+
}
197+
198+
/**
199+
Starts the sign-in process. Returns and error result if error, null otherwise.
200+
*/
201+
static SignInResult *startSignIn() {
202+
bool busy = false;
203+
[resultLock lock];
204+
if (!currentResult_ || currentResult_->finished) {
205+
currentResult_.reset(new SignInResult());
206+
currentResult_->result_code = 0;
207+
currentResult_->finished = false;
208+
} else {
209+
busy = true;
210+
}
211+
[resultLock unlock];
212+
213+
if (busy) {
214+
NSLog(@"ERROR: There is already a pending sign-in operation.");
215+
// Returned to the caller, should be deleted by calling
216+
// GoogleSignIn_DisposeFuture().
217+
return new SignInResult{.result_code = kStatusCodeDeveloperError,
218+
.finished = true};
219+
}
220+
return nullptr;
221+
}
222+
223+
/**
224+
* Sign-In. The return value is a pointer to the currentResult object.
225+
*/
226+
void *GoogleSignIn_SignIn() {
227+
SignInResult *result = startSignIn();
228+
if (!result) {
229+
[[GIDSignIn sharedInstance] signIn];
230+
result = currentResult_.get();
231+
}
232+
return result;
233+
}
234+
235+
/**
236+
* Attempt a silent sign-in. Return value is the pointer to the currentResult
237+
* object.
238+
*/
239+
void *GoogleSignIn_SignInSilently() {
240+
SignInResult *result = startSignIn();
241+
if (!result) {
242+
[[GIDSignIn sharedInstance] signInSilently];
243+
result = currentResult_.get();
244+
}
245+
return result;
246+
}
247+
248+
void GoogleSignIn_Signout() {
249+
GIDSignIn *signIn = [GIDSignIn sharedInstance];
250+
[signIn signOut];
251+
}
252+
253+
void GoogleSignIn_Disconnect() {
254+
GIDSignIn *signIn = [GIDSignIn sharedInstance];
255+
[signIn disconnect];
256+
}
257+
258+
bool GoogleSignIn_Pending(SignInResult *result) {
259+
volatile bool ret;
260+
[resultLock lock];
261+
ret = !result->finished;
262+
[resultLock unlock];
263+
return ret;
264+
}
265+
266+
GIDGoogleUser *GoogleSignIn_Result(SignInResult *result) {
267+
if (result && result->finished) {
268+
GIDGoogleUser *guser = [GIDSignIn sharedInstance].currentUser;
269+
return guser;
270+
}
271+
return nullptr;
272+
}
273+
274+
int GoogleSignIn_Status(SignInResult *result) {
275+
if (result) {
276+
return result->result_code;
277+
}
278+
return kStatusCodeDeveloperError;
279+
}
280+
281+
void GoogleSignIn_DisposeFuture(SignInResult *result) {
282+
if (result == currentResult_.get()) {
283+
currentResult_.reset(nullptr);
284+
} else {
285+
delete result;
286+
}
287+
}
288+
289+
/**
290+
* Private helper function to copy NSString to char*. If the destination is
291+
* non-null, the contents of src are copied up to len bytes (using strncpy). The
292+
* then len is returned. Otherwise returns length of the string to copy + 1.
293+
*/
294+
static size_t CopyNSString(NSString *src, char *dest, size_t len) {
295+
if (dest && src && len) {
296+
const char *string = [src UTF8String];
297+
strncpy(dest, string, len);
298+
return len;
299+
}
300+
return src ? src.length + 1 : 0;
301+
}
302+
303+
size_t GoogleSignIn_GetServerAuthCode(GIDGoogleUser *guser, char *buf,
304+
size_t len) {
305+
NSString *val = [guser serverAuthCode];
306+
return CopyNSString(val, buf, len);
307+
}
308+
309+
size_t GoogleSignIn_GetDisplayName(GIDGoogleUser *guser, char *buf,
310+
size_t len) {
311+
NSString *val = [guser.profile name];
312+
return CopyNSString(val, buf, len);
313+
}
314+
315+
size_t GoogleSignIn_GetEmail(GIDGoogleUser *guser, char *buf, size_t len) {
316+
NSString *val = [guser.profile email];
317+
return CopyNSString(val, buf, len);
318+
}
319+
320+
size_t GoogleSignIn_GetFamilyName(GIDGoogleUser *guser, char *buf, size_t len) {
321+
NSString *val = [guser.profile familyName];
322+
return CopyNSString(val, buf, len);
323+
}
324+
325+
size_t GoogleSignIn_GetGivenName(GIDGoogleUser *guser, char *buf, size_t len) {
326+
NSString *val = [guser.profile givenName];
327+
return CopyNSString(val, buf, len);
328+
}
329+
330+
size_t GoogleSignIn_GetIdToken(GIDGoogleUser *guser, char *buf, size_t len) {
331+
NSString *val = [guser.authentication idToken];
332+
return CopyNSString(val, buf, len);
333+
}
334+
335+
size_t GoogleSignIn_GetImageUrl(GIDGoogleUser *guser, char *buf, size_t len) {
336+
NSURL *url = [guser.profile imageURLWithDimension:128];
337+
NSString *val = url ? [url absoluteString] : nullptr;
338+
return CopyNSString(val, buf, len);
339+
}
340+
341+
size_t GoogleSignIn_GetUserId(GIDGoogleUser *guser, char *buf, size_t len) {
342+
NSString *val = [guser userID];
343+
return CopyNSString(val, buf, len);
344+
}
345+
} // extern "C"

0 commit comments

Comments
 (0)