Skip to content

Instantly share code, notes, and snippets.

@seaders
Last active August 29, 2015 14:26
Show Gist options
  • Save seaders/9786b9372023af87b1c3 to your computer and use it in GitHub Desktop.
Save seaders/9786b9372023af87b1c3 to your computer and use it in GitHub Desktop.
Patch file to update 0.9.21 of `play-games-plugin-for-unity` to enable getting of a user's access token.
diff --git a/Assets/GooglePlayGames/BasicApi/DummyClient.cs b/Assets/GooglePlayGames/BasicApi/DummyClient.cs
index 337469f..cc7f754 100644
--- a/Assets/GooglePlayGames/BasicApi/DummyClient.cs
+++ b/Assets/GooglePlayGames/BasicApi/DummyClient.cs
@@ -43,6 +43,18 @@ public class DummyClient : IPlayGamesClient
LogUsage();
}
+ public string GetAccessToken()
+ {
+ LogUsage();
+ return "DummyAccessToken";
+ }
+
+ public string GetIdToken()
+ {
+ LogUsage();
+ return "DummyIdToken";
+ }
+
public string GetUserId()
{
LogUsage();
diff --git a/Assets/GooglePlayGames/BasicApi/IPlayGamesClient.cs b/Assets/GooglePlayGames/BasicApi/IPlayGamesClient.cs
index aa766a5..33d535d 100644
--- a/Assets/GooglePlayGames/BasicApi/IPlayGamesClient.cs
+++ b/Assets/GooglePlayGames/BasicApi/IPlayGamesClient.cs
@@ -82,6 +82,20 @@ namespace GooglePlayGames.BasicApi
string GetUserDisplayName();
/// <summary>
+ /// Returns an access token.
+ /// </summary>
+ /// <returns>An access token. <code>null</code> if they are not logged
+ /// in</returns>
+ string GetAccessToken();
+
+ /// <summary>
+ /// Returns an id token, which can be verified server side, if they are logged in.
+ /// </summary>
+ /// <returns>An it token. <code>null</code> if they are not logged
+ /// in</returns>
+ string GetIdToken();
+
+ /// <summary>
/// Returns the user's avatar url, if they are logged in and have an avatar.
/// </summary>
/// <returns>The URL to load the avatar image. <code>null</code> if they are not logged
diff --git a/Assets/GooglePlayGames/Editor/GPGSAndroidSetupUI.cs b/Assets/GooglePlayGames/Editor/GPGSAndroidSetupUI.cs
index 0b9feb8..7950a69 100644
--- a/Assets/GooglePlayGames/Editor/GPGSAndroidSetupUI.cs
+++ b/Assets/GooglePlayGames/Editor/GPGSAndroidSetupUI.cs
@@ -21,6 +21,9 @@ namespace GooglePlayGames
public class GPGSAndroidSetupUI : EditorWindow
{
+ private const string GameInfoPath = "Assets/GooglePlayGames/GameInfo.cs";
+
+ private string mClientId = string.Empty;
private string mAppId = string.Empty;
[MenuItem("Window/Google Play Games/Setup/Android setup...", false, 1)]
@@ -28,12 +31,13 @@ namespace GooglePlayGames
{
EditorWindow window = EditorWindow.GetWindow(
typeof(GPGSAndroidSetupUI), true, GPGSStrings.AndroidSetup.Title);
- window.minSize = new Vector2(400, 200);
+ window.minSize = new Vector2(400, 300);
}
public void OnEnable()
{
mAppId = GPGSProjectSettings.Instance.Get("proj.AppId");
+ mClientId = GPGSProjectSettings.Instance.Get(GPGSUtil.ANDROIDCLIENTIDKEY);
}
public void OnGUI()
@@ -46,11 +50,21 @@ namespace GooglePlayGames
GUILayout.Label(GPGSStrings.Setup.AppId, EditorStyles.boldLabel);
GUILayout.Label(GPGSStrings.Setup.AppIdBlurb);
+
GUILayout.Space(10);
mAppId = EditorGUILayout.TextField(GPGSStrings.Setup.AppId,
mAppId,GUILayout.Width(300));
+ // Client ID field
+ GUILayout.Label(GPGSStrings.Setup.ClientIdTitle, EditorStyles.boldLabel);
+ GUILayout.Label(GPGSStrings.AndroidSetup.ClientIdBlurb);
+
+ mClientId = EditorGUILayout.TextField(GPGSStrings.Setup.ClientId,
+ mClientId, GUILayout.Width(450));
+
+ GUILayout.Space(10);
+
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
@@ -72,7 +86,7 @@ namespace GooglePlayGames
public void DoSetup()
{
- if (PerformSetup(mAppId, null))
+ if (PerformSetup(mClientId, mAppId, null))
{
EditorUtility.DisplayDialog(GPGSStrings.Success,
GPGSStrings.AndroidSetup.SetupComplete, GPGSStrings.Ok);
@@ -86,13 +100,25 @@ namespace GooglePlayGames
/// </summary>
/// <param name="appId">App identifier.</param>
/// <param name="nearbySvcId">Optional nearby connection serviceId</param>
- public static bool PerformSetup(string appId, string nearbySvcId)
+ public static bool PerformSetup(string clientId, string appId, string nearbySvcId)
{
- // check for valid app id
- if (!GPGSUtil.LooksLikeValidAppId(appId))
+ if( !string.IsNullOrEmpty(clientId) )
{
- GPGSUtil.Alert(GPGSStrings.Setup.AppIdError);
- return false;
+ if (!GPGSUtil.LooksLikeValidClientId(clientId))
+ {
+ GPGSUtil.Alert(GPGSStrings.Setup.ClientIdError);
+ return false;
+ }
+ appId = clientId.Split('-')[0];
+ }
+ else
+ {
+ // check for valid app id
+ if (!GPGSUtil.LooksLikeValidAppId(appId))
+ {
+ GPGSUtil.Alert(GPGSStrings.Setup.AppIdError);
+ return false;
+ }
}
if (nearbySvcId != null)
@@ -104,7 +130,9 @@ namespace GooglePlayGames
}
GPGSProjectSettings.Instance.Set("proj.AppId", appId);
+ GPGSProjectSettings.Instance.Set(GPGSUtil.ANDROIDCLIENTIDKEY, clientId);
GPGSProjectSettings.Instance.Save();
+ GPGSUtil.UpdateGameInfo();
// check that Android SDK is there
if (!GPGSUtil.HasAndroidSdk())
@@ -119,6 +147,8 @@ namespace GooglePlayGames
// Generate AndroidManifest.xml
GPGSUtil.GenerateAndroidManifest();
+
+ FillInAppData(GameInfoPath, GameInfoPath, clientId);
// refresh assets, and we're done
AssetDatabase.Refresh();
@@ -127,5 +157,21 @@ namespace GooglePlayGames
return true;
}
+
+ /// <summary>
+ /// Helper function to do search and replace of the client and bundle ids.
+ /// </summary>
+ /// <param name="sourcePath">Source path.</param>
+ /// <param name="outputPath">Output path.</param>
+ /// <param name="clientId">Client identifier.</param>
+ /// <param name="bundleId">Bundle identifier.</param>
+ private static void FillInAppData(string sourcePath,
+ string outputPath,
+ string clientId)
+ {
+ string fileBody = GPGSUtil.ReadFully(sourcePath);
+ fileBody = fileBody.Replace(GPGSUtil.ANDROIDCLIENTIDPLACEHOLDER, clientId);
+ GPGSUtil.WriteFile(outputPath, fileBody);
+ }
}
}
diff --git a/Assets/GooglePlayGames/Editor/GPGSIOSSetupUI.cs b/Assets/GooglePlayGames/Editor/GPGSIOSSetupUI.cs
index 996862f..beeef79 100644
--- a/Assets/GooglePlayGames/Editor/GPGSIOSSetupUI.cs
+++ b/Assets/GooglePlayGames/Editor/GPGSIOSSetupUI.cs
@@ -67,10 +67,10 @@ namespace GooglePlayGames
GUILayout.Space(10);
// Client ID field
- GUILayout.Label(GPGSStrings.IOSSetup.ClientIdTitle, EditorStyles.boldLabel);
+ GUILayout.Label(GPGSStrings.Setup.ClientIdTitle, EditorStyles.boldLabel);
GUILayout.Label(GPGSStrings.IOSSetup.ClientIdBlurb);
- mClientId = EditorGUILayout.TextField(GPGSStrings.IOSSetup.ClientId,
+ mClientId = EditorGUILayout.TextField(GPGSStrings.Setup.ClientId,
mClientId, GUILayout.Width(450));
GUILayout.Space(10);
@@ -114,8 +114,8 @@ namespace GooglePlayGames
string clientId, string bundleId)
{
string fileBody = GPGSUtil.ReadFully(sourcePath);
- fileBody = fileBody.Replace("__CLIENTID__", clientId);
- fileBody = fileBody.Replace("__BUNDLEID__", bundleId);
+ fileBody = fileBody.Replace(GPGSUtil.IOSCLIENTIDPLACEHOLDER, clientId);
+ fileBody = fileBody.Replace(GPGSUtil.IOSBUNDLEIDPLACEHOLDER, bundleId);
GPGSUtil.WriteFile(outputPath, fileBody);
}
@@ -143,7 +143,7 @@ namespace GooglePlayGames
if (!GPGSUtil.LooksLikeValidClientId(clientId))
{
- GPGSUtil.Alert(GPGSStrings.IOSSetup.ClientIdError);
+ GPGSUtil.Alert(GPGSStrings.Setup.ClientIdError);
return false;
}
if (!GPGSUtil.LooksLikeValidBundleId(bundleId))
diff --git a/Assets/GooglePlayGames/Editor/GPGSPostBuild.cs b/Assets/GooglePlayGames/Editor/GPGSPostBuild.cs
index cbdf515..bf92bdf 100644
--- a/Assets/GooglePlayGames/Editor/GPGSPostBuild.cs
+++ b/Assets/GooglePlayGames/Editor/GPGSPostBuild.cs
@@ -38,6 +38,8 @@ namespace GooglePlayGames
private const string UrlTypes = "CFBundleURLTypes";
private const string UrlBundleName = "CFBundleURLName";
private const string UrlScheme = "CFBundleURLSchemes";
+ private const string PrincipalClass = "NSPrincipalClass";
+ private const string PrincipalClassName = "CustomWebViewApplication";
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
@@ -116,6 +118,7 @@ namespace GooglePlayGames
var gamesSchemeIndex = GamesUrlSchemeIndex(buddy);
EnsureGamesUrlScheme(buddy, gamesSchemeIndex);
+ EnsurePrincipalClass(buddy);
}
@@ -133,6 +136,16 @@ namespace GooglePlayGames
GetBundleId());
}
+ /// <summary>
+ /// Ensures the PrincipalClass is set and correct.
+ /// </summary>
+ /// <param name="buddy">Buddy.</param>
+ private static void EnsurePrincipalClass(PlistBuddyHelper buddy)
+ {
+ buddy.RemoveEntry(PrincipalClass);
+ buddy.AddString(PrincipalClass, PrincipalClassName);
+ }
+
private static string GetBundleId()
{
return GPGSProjectSettings.Instance.Get("ios.BundleId", null);
diff --git a/Assets/GooglePlayGames/Editor/GPGSStrings.cs b/Assets/GooglePlayGames/Editor/GPGSStrings.cs
index d161f32..8abcc9a 100644
--- a/Assets/GooglePlayGames/Editor/GPGSStrings.cs
+++ b/Assets/GooglePlayGames/Editor/GPGSStrings.cs
@@ -45,6 +45,11 @@ namespace GooglePlayGames
public const string AppIdError = "The App Id does not appear to be valid. " +
"It must consist solely of digits, usually 10 or more.";
+
+ public const string ClientIdTitle = "Oauth Client ID";
+ public const string ClientId = "Client ID";
+ public const string ClientIdError = "The Client ID does not appear to be valid. " +
+ "It should end in .apps.googleusercontent.com.";
public const string NearbyServiceId = "Nearby Connection Service ID";
public const string NearbyServiceBlurb = "Enter the service id that identifies the " +
@@ -62,15 +67,10 @@ namespace GooglePlayGames
public const string Blurb = "To configure Google Play Games for iOS in this project,\n" +
"please enter the information below and click on the Setup button.";
- public const string ClientIdTitle = "Oauth Client ID";
- public const string ClientId = "Client ID";
public const string ClientIdBlurb = "Enter your oauth2 client ID below. To obtain this\n" +
"ID, generate an iOS linked app in Developer Console. Example:\n" +
"123456789012-jafwiawoijjfe.apps.googleusercontent.com";
- public const string ClientIdError = "The Client ID does not appear to be valid. " +
- "It should end in .apps.googleusercontent.com.";
-
public const string BundleIdTitle = "Bundle Identifier";
public const string BundleId = "Bundle ID";
public const string BundleIdBlurb = "Enter your application's bundle identifier below.\n" +
@@ -95,6 +95,10 @@ namespace GooglePlayGames
public const string Blurb = "To configure Google Play Games in this project,\n" +
"please enter the information below and click on the Setup button.";
+ public const string ClientIdBlurb = "Enter your oauth2 client ID below. To obtain this\n" +
+ "ID, generate an Android linked app in Developer Console. Example:\n" +
+ "123456789012-jafwiawoijjfe.apps.googleusercontent.com";
+
public const string PkgName = "Package name";
public const string PkgNameBlurb = "Enter your application's package name below.\n" +
"(for example, com.example.lorem.ipsum).";
diff --git a/Assets/GooglePlayGames/Editor/GPGSUtil.cs b/Assets/GooglePlayGames/Editor/GPGSUtil.cs
index 531b3ff..9692115 100644
--- a/Assets/GooglePlayGames/Editor/GPGSUtil.cs
+++ b/Assets/GooglePlayGames/Editor/GPGSUtil.cs
@@ -27,10 +27,14 @@ namespace GooglePlayGames
public const string SERVICEIDKEY = "App.NearbdServiceId";
public const string APPIDPLACEHOLDER = "___APP_ID___";
public const string APPIDKEY = "proj.AppId";
- public const string IOSCLIENTIDPLACEHOLDER = "__CLIENTID__";
+
+ public const string ANDROIDCLIENTIDPLACEHOLDER = "__ANDROID_CLIENTID__";
+ public const string ANDROIDCLIENTIDKEY = "and.ClientId";
+
+ public const string IOSCLIENTIDPLACEHOLDER = "__IOS_CLIENTID__";
public const string IOSCLIENTIDKEY = "ios.ClientId";
- public const string IOSBUNDLEIDKEY = "ios.BundleId";
public const string IOSBUNDLEIDPLACEHOLDER = "__BUNDLEID__";
+ public const string IOSBUNDLEIDKEY = "ios.BundleId";
private const string GameInfoPath = "Assets/GooglePlayGames/GameInfo.cs";
private const string GameInfoTemplatePath = "Assets/GooglePlayGames/Editor/GameInfo.template";
@@ -240,10 +244,16 @@ namespace GooglePlayGames
fileBody = fileBody.Replace(SERVICEIDPLACEHOLDER, appId);
}
- var clientId = GPGSProjectSettings.Instance.Get(IOSCLIENTIDKEY, null);
- if (clientId != null)
+ var iosClientId = GPGSProjectSettings.Instance.Get(IOSCLIENTIDKEY, null);
+ if (iosClientId != null)
+ {
+ fileBody = fileBody.Replace(IOSCLIENTIDPLACEHOLDER, iosClientId);
+ }
+
+ var andClientId = GPGSProjectSettings.Instance.Get(ANDROIDCLIENTIDKEY, null);
+ if (andClientId != null)
{
- fileBody = fileBody.Replace(IOSCLIENTIDPLACEHOLDER, clientId);
+ fileBody = fileBody.Replace(ANDROIDCLIENTIDPLACEHOLDER, andClientId);
}
var bundleId = GPGSProjectSettings.Instance.Get(IOSBUNDLEIDKEY, null);
diff --git a/Assets/GooglePlayGames/Editor/GameInfo.template b/Assets/GooglePlayGames/Editor/GameInfo.template
index 61bcb0c..74fad6c 100644
--- a/Assets/GooglePlayGames/Editor/GameInfo.template
+++ b/Assets/GooglePlayGames/Editor/GameInfo.template
@@ -14,7 +14,8 @@ public static class GameInfo {
private const string UnescapedIosClientId = "CLIENTID";
public const string ApplicationId = "__APPID__"; // Filled in automatically
- public const string IosClientId = "__CLIENTID__"; // Filled in automatically
+ public const string IosClientId = "__IOS_CLIENTID__"; // Filled in automatically
+ public const string AndroidClientId = "__ANDROID_CLIENTID__"; // Filled in automatically
public const string NearbyConnectionServiceId = "__NEARBY_SERVICE_ID__";
public static bool ApplicationIdInitialized() {
diff --git a/Assets/GooglePlayGames/Editor/template-AndroidManifest.txt b/Assets/GooglePlayGames/Editor/template-AndroidManifest.txt
index 4ee1ffb..21edd1e 100644
--- a/Assets/GooglePlayGames/Editor/template-AndroidManifest.txt
+++ b/Assets/GooglePlayGames/Editor/template-AndroidManifest.txt
@@ -8,6 +8,9 @@
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+ <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
+
<application>
<!-- Required for Nearby Connections API -->
diff --git a/Assets/GooglePlayGames/GameInfo.cs b/Assets/GooglePlayGames/GameInfo.cs
index b025844..5268af3 100644
--- a/Assets/GooglePlayGames/GameInfo.cs
+++ b/Assets/GooglePlayGames/GameInfo.cs
@@ -32,6 +32,7 @@ namespace GooglePlayGames
// Filled in automatically
public const string IosClientId = "__CLIENTID__";
+ public const string AndroidClientId = "__ANDROID_CLIENTID__";
private const string UnescapedApplicationId = "APPID";
private const string UnescapedIosClientId = "CLIENTID";
diff --git a/Assets/GooglePlayGames/ISocialPlatform/PlayGamesLocalUser.cs b/Assets/GooglePlayGames/ISocialPlatform/PlayGamesLocalUser.cs
index 5fd823b..f147a2c 100644
--- a/Assets/GooglePlayGames/ISocialPlatform/PlayGamesLocalUser.cs
+++ b/Assets/GooglePlayGames/ISocialPlatform/PlayGamesLocalUser.cs
@@ -132,6 +132,20 @@ namespace GooglePlayGames
}
/// <summary>
+ /// Gets an id token for the user.
+ /// </summary>
+ /// <returns>
+ /// An id token for the user.
+ /// </returns>
+ public new string idToken
+ {
+ get
+ {
+ return authenticated ? mPlatform.GetIdToken() : string.Empty;
+ }
+ }
+
+ /// <summary>
/// Returns true (since this is the local user).
/// </summary>
public new bool isFriend
diff --git a/Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs b/Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs
index f27de44..4eac68a 100644
--- a/Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs
+++ b/Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs
@@ -360,6 +360,36 @@ namespace GooglePlayGames
return mClient.GetUserId();
}
+
+ /// <summary>
+ /// Returns an id token for the user.
+ /// </summary>
+ /// <returns>
+ /// An id token for the user.
+ /// </returns>
+ public string GetIdToken()
+ {
+ if (mClient != null)
+ {
+ return mClient.GetIdToken();
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Returns an id token for the user.
+ /// </summary>
+ /// <returns>
+ /// An id token for the user.
+ /// </returns>
+ public string GetAccessToken()
+ {
+ if (mClient != null)
+ {
+ return mClient.GetAccessToken();
+ }
+ return null;
+ }
/// <summary>
/// Returns the achievement corresponding to the passed achievement identifier.
diff --git a/Assets/GooglePlayGames/Platforms/Native/NativeClient.cs b/Assets/GooglePlayGames/Platforms/Native/NativeClient.cs
index 7d6bdae..0aea274 100644
--- a/Assets/GooglePlayGames/Platforms/Native/NativeClient.cs
+++ b/Assets/GooglePlayGames/Platforms/Native/NativeClient.cs
@@ -27,6 +27,7 @@ namespace GooglePlayGames.Native
using System.Collections.Generic;
using GooglePlayGames.BasicApi.Events;
using GooglePlayGames.BasicApi.Quests;
+ using C = GooglePlayGames.Native.Cwrapper.InternalHooks;
using Types = GooglePlayGames.Native.Cwrapper.Types;
using Status = GooglePlayGames.Native.Cwrapper.CommonErrorStatus;
using UnityEngine;
@@ -285,6 +286,133 @@ namespace GooglePlayGames.Native
AndroidJNIHelper.DeleteJNIArgArray(objectArray, jArgs);
}
}
+
+ private AndroidJavaObject GetApiClient(GameServices services) {
+ //return JavaUtils.JavaObjectFromPointer(GooglePlayGames.Native.Cwrapper.InternalHooks.InternalHooks_GetApiClient(services.AsHandle()));
+ using (var currentActivity = GetActivity()) {
+ using (AndroidJavaClass jc_plus = new AndroidJavaClass("com.google.android.gms.plus.Plus")) {
+ using (AndroidJavaObject jc_builder = new AndroidJavaObject("com.google.android.gms.common.api.GoogleApiClient$Builder",currentActivity)) {
+ jc_builder.Call<AndroidJavaObject> ("addApi", jc_plus.GetStatic<AndroidJavaObject>("API"));
+ jc_builder.Call<AndroidJavaObject> ("addScope", jc_plus.GetStatic<AndroidJavaObject>("SCOPE_PLUS_LOGIN"));
+ AndroidJavaObject client = jc_builder.Call<AndroidJavaObject> ("build");
+ client.Call ("connect");
+
+ int ct = 100;
+ while( ( !client.Call<bool>("isConnected") ) && (ct-- != 0) )
+ {
+ System.Threading.Thread.Sleep(100);
+ }
+ return client;
+ }
+ }
+ }
+ //return JavaUtils.JavaObjectFromPointer(C.InternalHooks_GetApiClient(services.AsHandle()));
+ }
+
+ private string GetEmail() {
+ if (!this.IsAuthenticated())
+ {
+ Debug.Log("Cannot get API client - not authenticated");
+ return null;
+ }
+
+ string email;
+ using (AndroidJavaClass jc_plus = new AndroidJavaClass("com.google.android.gms.plus.Plus")) {
+ using (AndroidJavaObject jo_plusAccountApi = jc_plus.GetStatic<AndroidJavaObject>("AccountApi")) {
+ Debug.Log("jo_plusAccountApi: " + (jo_plusAccountApi == null ? "NULL" : jo_plusAccountApi.ToString()));
+ using (var apiClient = GetApiClient(mServices)) {
+ Debug.Log("apiClient: " + (apiClient == null ? "NULL" : apiClient.ToString()));
+ email = jo_plusAccountApi.Call<string>("getAccountName", apiClient);
+ Logger.d("Player email: " + email);
+ }
+ }
+ }
+ return email;
+ }
+
+ /// <summary>Gets the access token currently associated with the Unity activity.</summary>
+ /// <returns>The OAuth 2.0 access token.</returns>
+ public string GetAccessToken()
+ {
+ if (!this.IsAuthenticated())
+ {
+ Debug.Log("Cannot get API client - not authenticated");
+ return null;
+ }
+
+ string token = null;
+ string email = GetEmail() ?? "NULL";
+ string scope = "oauth2:https://www.googleapis.com/auth/plus.me";
+
+ using (AndroidJavaClass unityActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"),
+ googleAuthUtil = new AndroidJavaClass("com.google.android.gms.auth.GoogleAuthUtil"))
+ {
+ using(AndroidJavaObject currentActivity =
+ unityActivity.GetStatic<AndroidJavaObject>("currentActivity"))
+ {
+ token = googleAuthUtil.CallStatic<string>("getToken", currentActivity, email, scope);
+ }
+ }
+
+ return token;
+ }
+
+ public string GetIdToken() {
+ if (!this.IsAuthenticated())
+ {
+ Debug.Log("Cannot get API client - not authenticated");
+ return null;
+ }
+
+ if( String.IsNullOrEmpty(GameInfo.AndroidClientId) || ("__ANDROID_CLIENTID__" == GameInfo.AndroidClientId) )
+ {
+ throw new Exception("Client ID has not been set, cannot request id token.");
+ }
+ string token = null;
+ Debug.Log("Before GetEmail");
+ string email = GetEmail() ?? "NULL";
+ Debug.Log("After GetEmail email: " + email);
+ string scope = "audience:server:client_id:" + GameInfo.AndroidClientId;
+ using (AndroidJavaClass jc_unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"),
+ jc_gau = new AndroidJavaClass("com.google.android.gms.auth.GoogleAuthUtil")) {
+ using(AndroidJavaObject jo_Activity = jc_unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
+ token = jc_gau.CallStatic<string>("getToken", jo_Activity, email, scope);
+ }
+ }
+ Debug.Log("Token " + token);
+ return token;
+ }
+
+ #elif UNITY_IOS
+
+ [System.Runtime.InteropServices.DllImport("__Internal")]
+ private static extern string _GooglePlayGetIdToken();
+
+ public string GetIdToken()
+ {
+ if (!this.IsAuthenticated())
+ {
+ Debug.Log("Cannot get API client - not authenticated");
+ return null;
+ }
+
+ return _GooglePlayGetIdToken();
+ }
+
+ [System.Runtime.InteropServices.DllImport("__Internal")]
+ private static extern string _GooglePlayGetAccessToken();
+
+ public string GetAccessToken()
+ {
+ if (!this.IsAuthenticated())
+ {
+ Debug.Log("Cannot get API client - not authenticated");
+ return null;
+ }
+
+ return _GooglePlayGetAccessToken();
+ }
+
#endif
internal static PlatformConfiguration CreatePlatformConfiguration()
diff --git a/Assets/GooglePlayGames/Platforms/Native/PInvoke/GameServicesBuilder.cs b/Assets/GooglePlayGames/Platforms/Native/PInvoke/GameServicesBuilder.cs
index 8598900..a8af67b 100644
--- a/Assets/GooglePlayGames/Platforms/Native/PInvoke/GameServicesBuilder.cs
+++ b/Assets/GooglePlayGames/Platforms/Native/PInvoke/GameServicesBuilder.cs
@@ -49,6 +49,11 @@ namespace GooglePlayGames.Native.PInvoke
{
C.GameServices_Builder_EnableSnapshots(SelfPtr());
}
+
+ internal void AddOauthScope(string scope)
+ {
+ C.GameServices_Builder_AddOauthScope(SelfPtr(), scope);
+ }
[AOT.MonoPInvokeCallback(typeof(C.OnAuthActionFinishedCallback))]
private static void InternalAuthFinishedCallback(Types.AuthOperation op,
diff --git a/Assets/Plugins/iOS/CustomWebViewApplication.h b/Assets/Plugins/iOS/CustomWebViewApplication.h
new file mode 100644
index 0000000..7880c2b
--- /dev/null
+++ b/Assets/Plugins/iOS/CustomWebViewApplication.h
@@ -0,0 +1,16 @@
+#ifndef Unity_iPhone_CustomWebViewApplication_h
+#define Unity_iPhone_CustomWebViewApplication_h
+
+#import <UIKit/UIKit.h>
+
+#define ApplicationOpenGoogleAuthNotification @"ApplicationOpenGoogleAuthNotification"
+
+@interface CustomWebViewApplication : UIApplication<UIWebViewDelegate>
+{
+}
+
+- (BOOL)openURL:(NSURL*)url;
+
+@end
+
+#endif
diff --git a/Assets/Plugins/iOS/CustomWebViewApplication.mm b/Assets/Plugins/iOS/CustomWebViewApplication.mm
new file mode 100644
index 0000000..94335fd
--- /dev/null
+++ b/Assets/Plugins/iOS/CustomWebViewApplication.mm
@@ -0,0 +1,133 @@
+#import "CustomWebViewApplication.h"
+
+#include "UnityAppController.h"
+
+#import <GTMOAuth2Authentication.h>
+#import <GooglePlus/GooglePlus.h>
+
+@interface CustomWebViewApplication()
+
+@end
+
+@implementation CustomWebViewApplication
+
+- (BOOL)openURL:(NSURL*)url {
+
+ if( [ [url absoluteString] hasPrefix:@"googlechrome-x-callback:" ] )
+ {
+ return NO;
+ }
+ else if( [ [url absoluteString] hasPrefix:@"https://accounts.google.com/o/oauth2/auth" ] )
+ {
+ [self ShowWeb:url];
+
+ return NO;
+
+ }
+
+ return [super openURL:url];
+}
+
+- (void) ShowWeb:(NSURL *)url {
+ UnityPause(true);
+
+ UIWebView *webview=[ [UIWebView alloc] initWithFrame:[ [UIScreen mainScreen] bounds ] ];
+ NSURLRequest *nsrequest=[NSURLRequest requestWithURL:url];
+
+ webview.backgroundColor = [UIColor whiteColor];
+ webview.scalesPageToFit = YES;
+
+ [webview setDelegate:self];
+ [webview loadRequest:nsrequest];
+ [GetAppController().rootViewController.view addSubview:webview];
+ webview.delegate = self;
+}
+
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
+{
+ NSLog(@"Error : %@",error);
+}
+
+- (void)webViewDidFinishLoad:(UIWebView *)webView
+{
+ // finished loading, hide the activity indicator in the status bar
+ [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
+}
+
+- (BOOL) webView:(UIWebView *)webView
+ shouldStartLoadWithRequest:(NSURLRequest *)request
+ navigationType:(UIWebViewNavigationType)navigationType
+{
+ NSString* bundleID = [ [NSBundle mainBundle] bundleIdentifier ];
+
+ if ( [ [ [request URL] absoluteString ] hasPrefix:[NSString stringWithFormat:@"%@:/oauth2callback", bundleID] ] ) {
+ [GPPURLHandler handleURL:request.URL sourceApplication:@"com.apple.mobilesafari" annotation:nil];
+ [GetAppController().rootViewController.navigationController popViewControllerAnimated:YES];
+ [webView removeFromSuperview];
+ UnityPause(false);
+ return NO;
+ }
+ return YES;
+}
+
+@end
+
+#ifndef CUSTOM_MAKE_STRING_COPY
+#define CUSTOM_MAKE_STRING_COPY
+
+char* __MakeStringCopy(NSString* nstring)
+{
+ if( (!nstring) || (nil == nstring) || ( nstring == (id)[NSNull null] ) || (0 == nstring.length) )
+ {
+ return NULL;
+ }
+
+ const char* string = [nstring UTF8String];
+ if (string == NULL)
+ {
+ return NULL;
+ }
+
+ char* res = (char*)malloc(strlen(string) + 1);
+ strcpy(res, string);
+ return res;
+}
+
+#endif
+
+extern "C"
+{
+ const char* _GooglePlayGetIdToken()
+ {
+ const char* idToken = nil;
+ GPPSignIn* gp = [GPPSignIn sharedInstance];
+
+ NSString* user;
+ if( [gp authentication] )
+ {
+ idToken = __MakeStringCopy( [gp idToken] );
+ user = [gp userID];
+ }
+
+ NSLog(@"\n\tOS: 'iOS',\n\tBundleId: '%@',\n\tUser: '%@',\n\t idToken: '%s'",
+ [ [NSBundle mainBundle] bundleIdentifier ], user, idToken);
+ return idToken ? idToken : "";
+ }
+
+ const char* _GooglePlayGetAccessToken()
+ {
+ const char* accessToken = nil;
+ GPPSignIn* gp = [GPPSignIn sharedInstance];
+
+ NSString* user;
+ if( [gp authentication] )
+ {
+ accessToken = __MakeStringCopy( [ [gp authentication] accessToken ] );
+ user = [gp userID];
+ }
+
+ NSLog(@"\n\tOS: 'iOS',\n\tBundleId: '%@',\n\tUser: '%@',\n\t AccessToken: '%s'",
+ [ [NSBundle mainBundle] bundleIdentifier ], user, accessToken);
+ return accessToken ? accessToken : "";
+ }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment