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

feat: use chrome custom tabs for auth #89

Merged
merged 3 commits into from
Sep 28, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ jobs:
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FILTER_REGEX_EXCLUDE: (.*src/Packages/Passport/Runtime/ThirdParty/.*|.*src/Packages/Passport/Runtime/Resources/.*|.*Plugins/.*)
FILTER_REGEX_EXCLUDE: (.*src/Packages/Passport/Runtime/ThirdParty/.*|.*src/Packages/Passport/Runtime/Resources/.*|.*Plugins/.*|.*src/Packages/Passport/Runtime/Assets/ImmutableAndroid.androidlib/.*)
VALIDATE_MARKDOWN: false
VALIDATE_GITLEAKS: false
18 changes: 18 additions & 0 deletions src/Packages/Passport/Editor/PassportAndroidProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#if UNITY_EDITOR

using System;
using System.IO;
using UnityEditor;
using UnityEditor.Android;
Expand All @@ -24,6 +25,23 @@ public void OnPostGenerateGradleAndroidProject(string path)

FileHelpers.CopyDirectory(passportWebFilesDir, $"{path}/src/main/assets/ImmutableSDK/Runtime/Passport");
Debug.Log($"Sucessfully copied Passport files");

AddUseAndroidX(path);
}

private void AddUseAndroidX(string path)
{
var parentDir = Directory.GetParent(path).FullName;
var gradlePath = parentDir + "/gradle.properties";

if(!File.Exists(gradlePath))
throw new Exception("gradle.properties does not exist");

var text = File.ReadAllText(gradlePath);

text += "\nandroid.useAndroidX=true\nandroid.enableJetifier=true";

File.WriteAllText(gradlePath, text);
}
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apply plugin: 'com.android.library'

dependencies {
implementation('androidx.browser:browser:1.6.0')
}

android {
compileSdkVersion 33
buildToolsVersion '30.0.3'

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
minSdkVersion 22
targetSdkVersion 33
versionCode 1
versionName '1.0'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.immutable.unity" xmlns:tools="http://schemas.android.com/tools">
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.immutable.unity;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Insets;
import android.net.Uri;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.WindowInsets;
import android.view.WindowMetrics;

import androidx.annotation.NonNull;
import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsClient;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.browser.customtabs.CustomTabsService;
import androidx.browser.customtabs.CustomTabsServiceConnection;
import androidx.browser.customtabs.CustomTabsSession;

import java.util.ArrayList;
import java.util.List;

public class ImmutableAndroid {
dom-murray marked this conversation as resolved.
Show resolved Hide resolved
private static CustomTabsServiceConnection customTabsServiceConnection;

private static int getCustomTabsHeight(Activity context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowMetrics windowMetrics = context.getWindowManager().getCurrentWindowMetrics();
Insets insets = windowMetrics.getWindowInsets()
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
return windowMetrics.getBounds().height() - insets.top - insets.bottom;
} else {
DisplayMetrics displayMetrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
}

public static void launchUrl(Activity context, String url) {
// Get all apps that can support Custom Tabs Service
// i.e. services that can handle ACTION_CUSTOM_TABS_CONNECTION intents
PackageManager packageManager = context.getPackageManager();
Intent serviceIntent = new Intent();
serviceIntent.setAction(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION);
List<ResolveInfo> resolvedList = packageManager.queryIntentServices(serviceIntent, 0);
List<String> packageNames = new ArrayList<>();
for (ResolveInfo info : resolvedList) {
if (info.serviceInfo != null) {
packageNames.add(info.serviceInfo.packageName);
}
}

if (packageNames.size() > 0) {
// Get the preferred Custom Tabs package
String customTabsPackageName = CustomTabsClient.getPackageName(context, packageNames);
if (customTabsPackageName == null) {
// Could not get the preferred Custom Tab browser, so launch URL in any browser
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} else {
customTabsServiceConnection = new CustomTabsServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
customTabsServiceConnection = null;
}

@Override
public void onCustomTabsServiceConnected(@NonNull ComponentName name, @NonNull CustomTabsClient client) {
CustomTabsSession session = client.newSession(new CustomTabsCallback());
// Need to set the session to get custom tabs to show as a bottom sheet
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(session)
.setInitialActivityHeightPx(getCustomTabsHeight(context))
.setUrlBarHidingEnabled(true)
.build();
customTabsIntent.launchUrl(context, Uri.parse(url));
}
};
CustomTabsClient.bindCustomTabsService(context, customTabsPackageName, customTabsServiceConnection);
}
} else {
// Custom Tabs not supported by any browser on the device so launch URL in any browser
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
}
}
13 changes: 12 additions & 1 deletion src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
using Cysharp.Threading.Tasks;
using System.Web;
using System.Threading;
#if UNITY_ANDROID
using UnityEngine.Android;
#endif

namespace Immutable.Passport
{
Expand Down Expand Up @@ -107,7 +110,15 @@ private async UniTask LaunchAuthUrl()

if (response?.Success == true && response?.Result != null)
{
Application.OpenURL(response.Result.Replace(" ", "+"));
string url = response.Result.Replace(" ", "+");
#if UNITY_ANDROID
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass customTabLauncher = new AndroidJavaClass("com.immutable.unity.ImmutableAndroid");
customTabLauncher.CallStatic("launchUrl", activity, url);
#else
Application.OpenURL(url);
#endif
return;
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,15 @@ public void Init(
onError = err;
onHttpError = httpErr;
#if UNITY_WEBGL
#if !UNITY_EDITOR
#if !UNITY_EDITOR
_gree_unity_webview_init();
#endif
#endif
#elif UNITY_WEBPLAYER
Application.ExternalCall("unityWebView.init");
#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_LINUX
//TODO: UNSUPPORTED
Debug.LogError("Webview is not supported on this platform.");
#elif UNITY_IPHONE || UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
#elif UNITY_IPHONE || UNITY_STANDALONE_OSX
webView = _CWebViewPlugin_Init(ua);
Singleton.Instance.onJS = ((message) => CallFromJS(message));
Singleton.Instance.onError = ((message) => CallOnError(message));
Expand All @@ -226,7 +226,7 @@ public void LoadURL(string url)
Application.ExternalCall("unityWebView.loadURL", url);
#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_LINUX
//TODO: UNSUPPORTED
#elif UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX || UNITY_IPHONE
#elif UNITY_STANDALONE_OSX || UNITY_IPHONE
if (webView == IntPtr.Zero)
return;
_CWebViewPlugin_LoadURL(webView, url);
Expand All @@ -247,7 +247,7 @@ public void EvaluateJS(string js)
Application.ExternalCall("unityWebView.evaluateJS", js);
#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_LINUX
//TODO: UNSUPPORTED
#elif UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX || UNITY_IPHONE
#elif UNITY_STANDALONE_OSX || UNITY_IPHONE
if (webView == IntPtr.Zero)
return;
_CWebViewPlugin_EvaluateJS(webView, js);
Expand Down
Loading