123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- // <copyright file="AndroidTokenClient.cs" company="Google Inc.">
- // Copyright (C) 2015 Google Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // </copyright>
- #if UNITY_ANDROID
- namespace GooglePlayGames.Android
- {
- using System;
- using System.Linq;
- using BasicApi;
- using OurUtils;
- using UnityEngine;
- using System.Collections.Generic;
- internal class AndroidTokenClient : TokenClient
- {
- private const string HelperFragmentClass = "com.google.games.bridge.HelperFragment";
- // These are the configuration values.
- private bool requestEmail;
- private bool requestAuthCode;
- private bool requestIdToken;
- private List<string> oauthScopes;
- private string webClientId;
- private bool forceRefresh;
- private bool hidePopups;
- private string accountName;
- // These are the results
- private AndroidJavaObject account;
- private string email;
- private string authCode;
- private string idToken;
- public void SetRequestAuthCode(bool flag, bool forceRefresh)
- {
- requestAuthCode = flag;
- this.forceRefresh = forceRefresh;
- }
- public void SetRequestEmail(bool flag)
- {
- requestEmail = flag;
- }
- public void SetRequestIdToken(bool flag)
- {
- requestIdToken = flag;
- }
- public void SetWebClientId(string webClientId)
- {
- this.webClientId = webClientId;
- }
- public void SetHidePopups(bool flag)
- {
- this.hidePopups = flag;
- }
- public void SetAccountName(string accountName)
- {
- this.accountName = accountName;
- }
- public void AddOauthScopes(params string[] scopes)
- {
- if (scopes != null)
- {
- if (oauthScopes == null)
- {
- oauthScopes = new List<string>();
- }
- oauthScopes.AddRange(scopes);
- }
- }
- public void Signout()
- {
- account = null;
- authCode = null;
- email = null;
- idToken = null;
- PlayGamesHelperObject.RunOnGameThread(() =>
- {
- Debug.Log("Calling Signout in token client");
- AndroidJavaClass cls = new AndroidJavaClass(HelperFragmentClass);
- cls.CallStatic("signOut", AndroidHelperFragment.GetActivity());
- });
- }
- /// <summary>Gets the email selected by the current player.</summary>
- /// <remarks>This is not necessarily the email address of the player. It
- /// is just the account selected by the player from a list of accounts
- /// present on the device.
- /// </remarks>
- /// <returns>A string representing the email.</returns>
- public string GetEmail()
- {
- return email;
- }
- public string GetAuthCode()
- {
- return authCode;
- }
- /// <summary>Gets the OpenID Connect ID token for authentication with a server backend.</summary>
- /// <param name="serverClientId">Server client ID from console.developers.google.com or the Play Games
- /// services console.</param>
- /// <param name="idTokenCallback"> A callback to be invoked after token is retrieved. Will be passed null value
- /// on failure. </param>
- public string GetIdToken()
- {
- return idToken;
- }
- public void FetchTokens(bool silent, Action<int> callback)
- {
- PlayGamesHelperObject.RunOnGameThread(() => DoFetchToken(silent, callback));
- }
- public void RequestPermissions(string[] scopes, Action<SignInStatus> callback)
- {
- using (var bridgeClass = new AndroidJavaClass(HelperFragmentClass))
- using (var currentActivity = AndroidHelperFragment.GetActivity())
- using (var task =
- bridgeClass.CallStatic<AndroidJavaObject>("showRequestPermissionsUi", currentActivity,
- oauthScopes.Union(scopes).ToArray()))
- {
- AndroidTaskUtils.AddOnSuccessListener<AndroidJavaObject>(task, /* disposeResult= */ false,
- accountWithNewScopes =>
- {
- if (accountWithNewScopes == null)
- {
- callback(SignInStatus.InternalError);
- return;
- }
- account = accountWithNewScopes;
- email = account.Call<string>("getEmail");
- idToken = account.Call<string>("getIdToken");
- authCode = account.Call<string>("getServerAuthCode");
- oauthScopes = oauthScopes.Union(scopes).ToList();
- callback(SignInStatus.Success);
- });
- AndroidTaskUtils.AddOnFailureListener(task, e =>
- {
- if (!Misc.IsApiException(e)) {
- OurUtils.Logger.e("Exception requesting new permissions" +
- e.Call<string>("toString"));
- return;
- }
- var failCode = SignInHelper.ToSignInStatus(e.Call<int>("getStatusCode"));
- OurUtils.Logger.e("Exception requesting new permissions: " + failCode);
- callback(failCode);
- });
- }
- }
- /// <summary>Returns whether or not user has given permissions for given scopes.</summary>
- /// <param name="scopes">array of scopes</param>
- /// <returns><c>true</c>, if given, <c>false</c> otherwise.</returns>
- public bool HasPermissions(string[] scopes)
- {
- using (var bridgeClass = new AndroidJavaClass(HelperFragmentClass))
- using (var currentActivity = AndroidHelperFragment.GetActivity())
- {
- return bridgeClass.CallStatic<bool>("hasPermissions", currentActivity, scopes);
- }
- }
- private void DoFetchToken(bool silent, Action<int> callback)
- {
- try
- {
- using (var bridgeClass = new AndroidJavaClass(HelperFragmentClass))
- using (var currentActivity = AndroidHelperFragment.GetActivity())
- using (var pendingResult = bridgeClass.CallStatic<AndroidJavaObject>(
- "fetchToken",
- currentActivity,
- silent,
- requestAuthCode,
- requestEmail,
- requestIdToken,
- webClientId,
- forceRefresh,
- oauthScopes.ToArray(),
- hidePopups,
- accountName))
- {
- pendingResult.Call("setResultCallback", new ResultCallbackProxy(
- tokenResult =>
- {
- account = tokenResult.Call<AndroidJavaObject>("getAccount");
- authCode = tokenResult.Call<string>("getAuthCode");
- email = tokenResult.Call<string>("getEmail");
- idToken = tokenResult.Call<string>("getIdToken");
- callback(tokenResult.Call<int>("getStatusCode"));
- }));
- }
- }
- catch (Exception e)
- {
- OurUtils.Logger.e("Exception launching token request: " + e.Message);
- OurUtils.Logger.e(e.ToString());
- }
- }
- public AndroidJavaObject GetAccount()
- {
- return account;
- }
- /// <summary>
- /// Gets another server auth code.
- /// </summary>
- /// <remarks>This method should be called after authenticating, and exchanging
- /// the initial server auth code for a token. This is implemented by signing in
- /// silently, which if successful returns almost immediately and with a new
- /// server auth code.
- /// </remarks>
- /// <param name="reAuthenticateIfNeeded">Calls Authenticate if needed when
- /// retrieving another auth code. </param>
- /// <param name="callback">Callback.</param>
- public void GetAnotherServerAuthCode(bool reAuthenticateIfNeeded, Action<string> callback)
- {
- PlayGamesHelperObject.RunOnGameThread(() => DoGetAnotherServerAuthCode(reAuthenticateIfNeeded, callback));
- }
- private void DoGetAnotherServerAuthCode(bool reAuthenticateIfNeeded, Action<string> callback)
- {
- try
- {
- using (var bridgeClass = new AndroidJavaClass(HelperFragmentClass))
- using (var currentActivity = AndroidHelperFragment.GetActivity())
- using (var pendingResult = bridgeClass.CallStatic<AndroidJavaObject>(
- "fetchToken",
- currentActivity,
- /* silent= */ reAuthenticateIfNeeded,
- /* requestAuthCode= */ true,
- /* requestEmail= */ false,
- /* requestIdToken= */ false,
- webClientId,
- /* forceRefresh= */ false,
- oauthScopes.ToArray(),
- /* hidePopups= */ true,
- /* accountName= */ ""))
- {
- pendingResult.Call("setResultCallback", new ResultCallbackProxy(
- tokenResult => { callback(tokenResult.Call<string>("getAuthCode")); }));
- }
- }
- catch (Exception e)
- {
- OurUtils.Logger.e("Exception launching token request: " + e.Message);
- OurUtils.Logger.e(e.ToString());
- }
- }
- private class ResultCallbackProxy : AndroidJavaProxy
- {
- private Action<AndroidJavaObject> mCallback;
- public ResultCallbackProxy(Action<AndroidJavaObject> callback)
- : base("com/google/android/gms/common/api/ResultCallback")
- {
- mCallback = callback;
- }
- public void onResult(AndroidJavaObject tokenResult)
- {
- mCallback(tokenResult);
- }
- }
- }
- }
- #endif
|