Skip to content

Commit

Permalink
Merge pull request #88 from aboutyou/feature/sign-in-with-apple/handl…
Browse files Browse the repository at this point in the history
…e-cancellation-of-chrome-custom-tab

[sign_in_with_apple] Handle cancellation of chrome custom tab
  • Loading branch information
tp authored Jun 2, 2020
2 parents b6663d6 + 89aae02 commit a2fc0f8
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 34 deletions.
3 changes: 2 additions & 1 deletion packages/sign_in_with_apple/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## TBD
## 2.4.0

- Manual closes of the Chrome Custom Tab on Android are now reported through a `SignInWithAppleAuthorizationException` with the `code` `AuthorizationErrorCode.canceled` (same as on iOS)
- `AppleLogoPainter` is now exposed, so consumers can use it to build their own buttons

## 2.3.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
package com.aboutyou.dart_packages.sign_in_with_apple

import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.annotation.NonNull
import androidx.browser.customtabs.CustomTabsIntent
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener
import io.flutter.plugin.common.PluginRegistry.Registrar

import android.net.Uri
import android.content.Intent
import androidx.browser.customtabs.CustomTabsIntent

import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.Log

/** SignInWithApplePlugin */
public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAware, ActivityResultListener {
private val CUSTOM_TABS_REQUEST_CODE = 1001;

private var channel: MethodChannel? = null

var activity: Activity? = null

var binding: ActivityPluginBinding? = null

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.aboutyou.dart_packages.sign_in_with_apple")
Expand Down Expand Up @@ -58,7 +59,7 @@ public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAw
when (call.method) {
"isAvailable" -> result.success(true)
"performAuthorizationRequest" -> {
val _activity = activity
val _activity = binding?.activity

if (_activity == null) {
result.error("MISSING_ACTIVITY", "Plugin is not attached to an activity", call.arguments)
Expand All @@ -72,24 +73,30 @@ public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAw
return
}

SignInWithApplePlugin.lastAuthorizationRequestResult?.error("NEW_REQUEST", "A new request came in while this was still pending. The previous request (this one) was then cancelled.", null)
if (SignInWithApplePlugin.triggerMainActivityToHideChromeCustomTab != null) {
SignInWithApplePlugin.triggerMainActivityToHideChromeCustomTab!!()
lastAuthorizationRequestResult?.error("NEW_REQUEST", "A new request came in while this was still pending. The previous request (this one) was then cancelled.", null)
if (triggerMainActivityToHideChromeCustomTab != null) {
triggerMainActivityToHideChromeCustomTab!!()
}

SignInWithApplePlugin.lastAuthorizationRequestResult = result
SignInWithApplePlugin.triggerMainActivityToHideChromeCustomTab = {
val notificationIntent = _activity.getPackageManager().getLaunchIntentForPackage(_activity.getPackageName());
lastAuthorizationRequestResult = result
triggerMainActivityToHideChromeCustomTab = {
val notificationIntent = _activity.packageManager.getLaunchIntentForPackage(_activity.packageName);
notificationIntent.setPackage(null)
// Bring the Flutter activity back to the top, by popping the Chrome Custom Tab
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP;
_activity.startActivity(notificationIntent)
}

val builder = CustomTabsIntent.Builder();
val customTabsIntent = builder.build();
customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
customTabsIntent.launchUrl(_activity, Uri.parse(url));
customTabsIntent.intent.data = Uri.parse(url)

_activity.startActivityForResult(
customTabsIntent.intent,
CUSTOM_TABS_REQUEST_CODE,
customTabsIntent.startAnimationBundle
)
}
else -> {
result.notImplemented()
Expand All @@ -98,7 +105,8 @@ public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAw
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
this.binding = binding
binding.addActivityResultListener(this)
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
Expand All @@ -110,7 +118,23 @@ public class SignInWithApplePlugin: FlutterPlugin, MethodCallHandler, ActivityAw
}

override fun onDetachedFromActivity() {
activity = null
binding?.removeActivityResultListener(this)
binding = null
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
if (requestCode == CUSTOM_TABS_REQUEST_CODE) {
val _lastAuthorizationRequestResult = lastAuthorizationRequestResult

if (_lastAuthorizationRequestResult != null) {
_lastAuthorizationRequestResult.error("authorization-error/canceled", "The user closed the Custom Tab", null)

lastAuthorizationRequestResult = null
triggerMainActivityToHideChromeCustomTab = null
}
}

return false
}
}

Expand All @@ -126,6 +150,8 @@ public class SignInWithAppleCallback: Activity {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

// Note: The order is important here, as we first need to send the data to Flutter and then close the custom tab
// That way we can detect a manually closed tab in `SignInWithApplePlugin.onActivityResult` (by detecting that we're still waiting on data)
val lastAuthorizationRequestResult = SignInWithApplePlugin.lastAuthorizationRequestResult
if (lastAuthorizationRequestResult != null) {
lastAuthorizationRequestResult.success(intent?.data?.toString())
Expand Down
2 changes: 1 addition & 1 deletion packages/sign_in_with_apple/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ packages:
path: ".."
relative: true
source: path
version: "2.3.0"
version: "2.4.0"
sky_engine:
dependency: transitive
description: flutter
Expand Down
18 changes: 11 additions & 7 deletions packages/sign_in_with_apple/lib/src/sign_in_with_apple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,17 @@ class SignInWithApple {
},
).toString();

final result = await channel.invokeMethod<String>(
'performAuthorizationRequest',
<String, String>{
'url': uri,
},
);
try {
final result = await channel.invokeMethod<String>(
'performAuthorizationRequest',
<String, String>{
'url': uri,
},
);

return parseAuthorizationCredentialAppleIDFromDeeplink(Uri.parse(result));
return parseAuthorizationCredentialAppleIDFromDeeplink(Uri.parse(result));
} on PlatformException catch (exception) {
throw SignInWithAppleException.fromPlatformException(exception);
}
}
}
2 changes: 1 addition & 1 deletion packages/sign_in_with_apple/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: sign_in_with_apple
description: Flutter bridge to initiate Sign in with Apple (on iOS, macOS, and Android). Includes support for keychain entries as well as signing in with an Apple ID.
version: 2.3.0
version: 2.4.0
homepage: https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple
repository: https://github.com/aboutyou/dart_packages

Expand Down

0 comments on commit a2fc0f8

Please sign in to comment.