Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DX-3060] feat: support custom windows webview #260

Merged
merged 7 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,7 @@ sample/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
sample/AltTester.log

# Crashes
sample/mono_crash*
sample/mono_crash*

# Vuplex
sample/Assets/Vuplex*
8 changes: 4 additions & 4 deletions sample/Assets/Scenes/SelectAuthMethod.unity
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 416242725}
m_HandleRect: {fileID: 416242724}
m_Direction: 0
m_Value: 1
m_Size: 0.99999994
m_Value: 0
m_Size: 1
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
Expand Down Expand Up @@ -1407,8 +1407,8 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 167431872}
m_HandleRect: {fileID: 167431871}
m_Direction: 2
m_Value: 0
m_Size: 1
m_Value: 1
m_Size: 0.99999994
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
Expand Down
7 changes: 5 additions & 2 deletions sample/ProjectSettings/ProjectSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ PlayerSettings:
- m_BuildTarget: iOSSupport
m_APIs: 10000000
m_Automatic: 1
- m_BuildTarget: WindowsStandaloneSupport
m_APIs: 02000000
m_Automatic: 1
m_BuildTargetVRSettings: []
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0
Expand Down Expand Up @@ -773,7 +776,7 @@ PlayerSettings:
platformArchitecture: {}
scriptingBackend:
Android: 1
Standalone: 1
Standalone: 0
il2cppCompilerConfiguration: {}
managedStrippingLevel:
EmbeddedLinux: 1
Expand All @@ -794,7 +797,7 @@ PlayerSettings:
allowUnsafeCode: 0
useDeterministicCompilation: 1
enableRoslynAnalyzers: 1
selectedPlatform: 2
selectedPlatform: 0
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
using System;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
using VoltstroStudios.UnityWebBrowser.Core;
#else
using Immutable.Browser.Gree;
#endif
using Immutable.Browser.Core;
using Immutable.Passport.Model;
using UnityEngine;
Expand All @@ -19,8 +14,10 @@ namespace Immutable.Passport.Core

public interface IBrowserCommunicationsManager
{
#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX
event OnUnityPostMessageDelegate OnAuthPostMessage;
event OnUnityPostMessageErrorDelegate OnPostMessageError;
#endif
void SetCallTimeout(int ms);
void LaunchAuthURL(string url, string redirectUri);
UniTask<string> Call(string fxName, string data = null, bool ignoreTimeout = false, Nullable<long> timeoutMs = null);
Expand Down Expand Up @@ -60,8 +57,10 @@ public BrowserCommunicationsManager(IWebBrowserClient webBrowserClient)
{
this.webBrowserClient = webBrowserClient;
this.webBrowserClient.OnUnityPostMessage += InvokeOnUnityPostMessage;
#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX
this.webBrowserClient.OnAuthPostMessage += InvokeOnAuthPostMessage;
this.webBrowserClient.OnPostMessageError += InvokeOnPostMessageError;
#endif
}

#region Unity to Browser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ public async UniTask Init(string clientId, string environment, string redirectUr
{
this.redirectUri = redirectUri;
this.logoutRedirectUri = logoutRedirectUri;

#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX
this.communicationsManager.OnAuthPostMessage += OnDeepLinkActivated;
this.communicationsManager.OnPostMessageError += OnPostMessageError;
#endif

var versionInfo = new VersionInfo
{
Expand Down
103 changes: 79 additions & 24 deletions src/Packages/Passport/Runtime/Scripts/Public/Passport.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Collections.Generic;
using System;
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
#if !IMMUTABLE_CUSTOM_BROWSER
using VoltstroStudios.UnityWebBrowser.Core;
#else
#endif
#elif (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX
using Immutable.Browser.Gree;
#endif
using Immutable.Passport.Event;
Expand All @@ -20,69 +22,86 @@ public class Passport
private const string TAG = "[Passport]";

public static Passport Instance { get; private set; }
private PassportImpl passportImpl = null;

#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
private readonly IWebBrowserClient webBrowserClient = new WebBrowserClient();
#else
private readonly IWebBrowserClient webBrowserClient = new GreeBrowserClient();
#endif
private IWebBrowserClient webBrowserClient;

// Keeps track of the latest received deeplink
private static string deeplink = null;
private static bool readySignalReceived = false;
private PassportImpl passportImpl = null;

/// <summary>
/// Passport auth events
/// </summary>
/// <seealso cref="Immutable.Passport.Event.PassportAuthEvent" />
public event OnAuthEventDelegate OnAuthEvent;

private Passport()
{
// Handle clean-up tasks when the application is quitting
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
Application.quitting += OnQuit;
#elif UNITY_IPHONE || UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
// Handle deeplinks for iOS and macOS
Application.deepLinkActivated += OnDeepLinkActivated;

// Check if there is a deep link URL provided on application start
if (!string.IsNullOrEmpty(Application.absoluteURL))
{
// Cold start and Application.absoluteURL not null so process Deep Link.
// Handle the deep link if provided during a cold start
OnDeepLinkActivated(Application.absoluteURL);
}
#endif
}

/// <summary>
/// Initialises Passport
/// Initialises Passport with the specified parameters.
/// This sets up the Passport instance, configures the web browser, and waits for the ready signal.
/// </summary>
/// <param name="clientId">The client ID</param>
/// <param name="environment">The environment to connect to</param>
/// <param name="redirectUri">(Android, iOS and macOS only) The URL to which auth will redirect the browser after authorisation has been granted by the user</param>
/// <param name="logoutRedirectUri">(Android, iOS and macOS only) The URL to which auth will redirect the browser after log out is complete</param>
/// <param name="engineStartupTimeoutMs">(Windows only) Timeout time for waiting for the engine to start (in milliseconds)</param>
/// <param name="redirectUri">(Android, iOS, and macOS only) The URL where the browser will redirect after successful authentication.</param>
/// <param name="logoutRedirectUri">(Android, iOS, and macOS only) The URL where the browser will redirect after logout is complete.</param>
/// <param name="engineStartupTimeoutMs">(Windows only) Timeout duration in milliseconds to wait for the default Windows browser engine to start.</param>
/// <param name="webBrowserClient">(Windows only) Custom Windows browser to use instead of the default browser in the SDK.</param>
public static UniTask<Passport> Init(
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
string clientId, string environment, string redirectUri = null, string logoutRedirectUri = null, int engineStartupTimeoutMs = 30000
string clientId,
string environment,
string redirectUri = null,
string logoutRedirectUri = null,
int engineStartupTimeoutMs = 30000,
IWindowsWebBrowserClient windowsWebBrowserClient = null
#else
string clientId, string environment, string redirectUri = null, string logoutRedirectUri = null
string clientId,
string environment,
string redirectUri = null,
string logoutRedirectUri = null
#endif
)
{
if (Instance == null)
{
Debug.Log($"{TAG} Initialising Passport...");
Instance = new Passport();
// Wait until we get a ready signal

// Start initialisation process
return Instance.Initialise(
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
engineStartupTimeoutMs
engineStartupTimeoutMs, windowsWebBrowserClient
#endif
)
.ContinueWith(async () =>
{
// Wait for the ready signal
Debug.Log($"{TAG} Waiting for ready signal...");
await UniTask.WaitUntil(() => readySignalReceived == true);
})
.ContinueWith(async () =>
{
if (readySignalReceived == true)
{
// Initialise Passport with provided parameters
await Instance.GetPassportImpl().Init(clientId, environment, redirectUri, logoutRedirectUri, deeplink);
return Instance;
}
Expand All @@ -95,43 +114,79 @@ public static UniTask<Passport> Init(
}
else
{
// Return the existing instance if already initialised
readySignalReceived = true;
return UniTask.FromResult(Instance);
}
}

/// <summary>
/// Initialises the appropriate web browser and sets up browser communication.
/// </summary>
/// <param name="engineStartupTimeoutMs">(Windows only) Timeout duration in milliseconds to wait for the default Windows browser engine to start.</param>
/// <param name="webBrowserClient">(Windows only) Custom Windows browser to use instead of the default browser in the SDK.</param>
private async UniTask Initialise(
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
int engineStartupTimeoutMs
int engineStartupTimeoutMs, IWindowsWebBrowserClient windowsWebBrowserClient
#endif
)
{
try
{
BrowserCommunicationsManager communicationsManager = new BrowserCommunicationsManager(webBrowserClient);
communicationsManager.OnReady += () => readySignalReceived = true;
// Initialise the web browser client
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
await ((WebBrowserClient)webBrowserClient).Init(engineStartupTimeoutMs);
if (windowsWebBrowserClient != null)
{
// Use the provided custom Windows browser client
this.webBrowserClient = new WindowsWebBrowserClientAdapter(windowsWebBrowserClient);
await ((WindowsWebBrowserClientAdapter)this.webBrowserClient).Init();
}
else
{
#if IMMUTABLE_CUSTOM_BROWSER
throw new PassportException("When 'IMMUTABLE_CUSTOM_BROWSER' is defined in Scripting Define Symbols, " +
" 'windowsWebBrowserClient' must not be null.");
#else
// Initialise with default Windows browser client
this.webBrowserClient = new WebBrowserClient();
await ((WebBrowserClient)this.webBrowserClient).Init(engineStartupTimeoutMs);
#endif
}
#elif (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX
// Initialise default browser client for Android, iOS, and macOS
webBrowserClient = new GreeBrowserClient();
#else
throw new PassportException("Platform not supported");
#endif

// Set up browser communication
BrowserCommunicationsManager communicationsManager = new BrowserCommunicationsManager(webBrowserClient);
// Mark ready when browser is initialised and game bridge file is loaded
communicationsManager.OnReady += () => readySignalReceived = true;

// Set up Passport implementation
passportImpl = new PassportImpl(communicationsManager);
// Subscribe to Passport authentication events
passportImpl.OnAuthEvent += OnPassportAuthEvent;
}
catch (Exception ex)
{
// Reset values
// Reset everything on error
readySignalReceived = false;
Instance = null;
throw ex;
}
}


#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
/// <summary>
/// Handles clean-up when the application quits.
/// </summary>
private void OnQuit()
{
// Need to clean up UWB resources when quitting the game in the editor
// as the child engine process would still be alive
Debug.Log($"{TAG} Quitting the Player");
((WebBrowserClient)webBrowserClient).Dispose();
webBrowserClient.Dispose();
Instance = null;
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX

using Immutable.Browser.Core;
using UnityEngine;
using System.IO;
Expand All @@ -7,9 +9,7 @@ namespace Immutable.Browser.Gree
public class GreeBrowserClient : IWebBrowserClient
{
private const string TAG = "[GreeBrowserClient]";
private const string ANDROID_DATA_DIRECTORY = "android_asset";
private const string MAC_DATA_DIRECTORY = "/Resources/Data";
private const string MAC_EDITOR_RESOURCES_DIRECTORY = "Packages/com.immutable.passport/Runtime/Resources";

private readonly WebViewObject webViewObject;
public event OnUnityPostMessageDelegate OnUnityPostMessage;
public event OnUnityPostMessageDelegate OnAuthPostMessage;
Expand All @@ -29,19 +29,8 @@ public GreeBrowserClient()
auth: InvokeOnAuthPostMessage,
log: InvokeOnLogMessage
);
#if UNITY_ANDROID && !UNITY_EDITOR
string filePath = Constants.SCHEME_FILE + ANDROID_DATA_DIRECTORY + Constants.PASSPORT_DATA_DIRECTORY_NAME + Constants.PASSPORT_HTML_FILE_NAME;
#elif UNITY_EDITOR_OSX
string filePath = Constants.SCHEME_FILE + Path.GetFullPath(MAC_EDITOR_RESOURCES_DIRECTORY) + Constants.PASSPORT_HTML_FILE_NAME;
#elif UNITY_STANDALONE_OSX
string filePath = Constants.SCHEME_FILE + Path.GetFullPath(Application.dataPath) + MAC_DATA_DIRECTORY + Constants.PASSPORT_DATA_DIRECTORY_NAME + Constants.PASSPORT_HTML_FILE_NAME;
filePath = filePath.Replace(" ", "%20");
#elif UNITY_IPHONE
string filePath = Path.GetFullPath(Application.dataPath) + Constants.PASSPORT_DATA_DIRECTORY_NAME + Constants.PASSPORT_HTML_FILE_NAME;
#else
string filePath = Constants.SCHEME_FILE + Path.GetFullPath(Application.dataPath) + Constants.PASSPORT_DATA_DIRECTORY_NAME + Constants.PASSPORT_HTML_FILE_NAME;
#endif
webViewObject.LoadURL(filePath);

webViewObject.LoadURL(GameBridge.GetFilePath());
}

private void InvokeOnPostMessageError(string id, string message)
Expand Down Expand Up @@ -96,4 +85,6 @@ public void ClearStorage()
#endif

}
}
}

#endif

This file was deleted.

Loading
Loading