From 7939cac3a21674e912008944b335f8e19788c42c Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Tue, 27 Apr 2021 14:28:46 +0200 Subject: [PATCH 1/4] add note about reusable lock instances and release of resources --- MIGRATION_GUIDE.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index a4513299..4cd81d5c 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -71,4 +71,42 @@ The core SDK has been updated to the version 2+. Since this is exposed as an API ## Changes in behavior +### Lock lifecycle + +The widget registers a Broadcast Listener to expect and handle the different lifecycle events. The listener is registered as soon as a new instance of `Lock` or `PasswordlessLock` is created with the corresponding Builder class, and the listener is unregistered when the `onDestroy` method is invoked. Forgetting to call this method would retain unnecessary resources after the authentication is complete and the widget is no longer required, or cause the callback to receive duplicated calls. + +In case you are not currently calling it, make sure to update your code adding the `lock?.onDestroy(this)` call. + +```kotlin +class MyActivity : AppCompatActivity() { + + private var lock: Lock? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val account = Auth0(this) + // Create a reusable Lock instance + lock = Lock.newBuilder(account, callback) + // Customize Lock + // .withScheme("myapp") + .build(this) + } + + private fun launchLock() { + // Invoke as many times as needed + val intent = lock!!.newIntent(this) + startActivity(intent) + } + + override fun onDestroy() { + super.onDestroy() + // Release Lock resources + lock?.onDestroy(this) + } +} +``` + +### Non-recoverable errors + The `LockCallback` will get its `onError` method invoked when an [Auth0 Rule](https://auth0.com/docs/rules) returns an `Error` or `UnauthorizedError`. This was previously handled internally by Lock, causing it to display an orange toast with a generic failure message. From this release on, if you are using Auth0 Rules and throwing custom errors, you should obtain the _cause_ of the exception and read the code or description values to understand what went wrong. \ No newline at end of file From 3b56c7a97bf36a0ac1a2b6e1a77f8796668099c8 Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Tue, 27 Apr 2021 20:31:23 +0200 Subject: [PATCH 2/4] unregister previous receiver if exists on initialization --- lib/src/main/java/com/auth0/android/lock/Lock.java | 4 +++- .../main/java/com/auth0/android/lock/PasswordlessLock.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/auth0/android/lock/Lock.java b/lib/src/main/java/com/auth0/android/lock/Lock.java index 808f4155..3b51c024 100644 --- a/lib/src/main/java/com/auth0/android/lock/Lock.java +++ b/lib/src/main/java/com/auth0/android/lock/Lock.java @@ -137,12 +137,14 @@ public void onDestroy(@NonNull Context context) { } private void initialize(@NonNull Context context) { + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); + lbm.unregisterReceiver(this.receiver); IntentFilter filter = new IntentFilter(); filter.addAction(Constants.AUTHENTICATION_ACTION); filter.addAction(Constants.SIGN_UP_ACTION); filter.addAction(Constants.CANCELED_ACTION); filter.addAction(Constants.INVALID_CONFIGURATION_ACTION); - LocalBroadcastManager.getInstance(context).registerReceiver(this.receiver, filter); + lbm.registerReceiver(this.receiver, filter); } private void processEvent(@NonNull Context context, @NonNull Intent data) { diff --git a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java index 33ccf333..fccb9d8e 100644 --- a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java +++ b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java @@ -137,11 +137,13 @@ public void onDestroy(@NonNull Context context) { } private void initialize(Context context) { + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); + lbm.unregisterReceiver(this.receiver); IntentFilter filter = new IntentFilter(); filter.addAction(Constants.AUTHENTICATION_ACTION); filter.addAction(Constants.CANCELED_ACTION); filter.addAction(Constants.INVALID_CONFIGURATION_ACTION); - LocalBroadcastManager.getInstance(context).registerReceiver(this.receiver, filter); + lbm.registerReceiver(this.receiver, filter); } private void processEvent(Context context, Intent data) { From 88665491beb00d1edd6a4935c7715e8c33fe297d Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Tue, 27 Apr 2021 20:31:50 +0200 Subject: [PATCH 3/4] don't unregister receiver after event is received --- lib/src/main/java/com/auth0/android/lock/Lock.java | 5 ++--- .../main/java/com/auth0/android/lock/PasswordlessLock.java | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/src/main/java/com/auth0/android/lock/Lock.java b/lib/src/main/java/com/auth0/android/lock/Lock.java index 3b51c024..7df524a1 100644 --- a/lib/src/main/java/com/auth0/android/lock/Lock.java +++ b/lib/src/main/java/com/auth0/android/lock/Lock.java @@ -68,7 +68,7 @@ public class Lock { @Override public void onReceive(Context context, Intent data) { - processEvent(context, data); + processEvent(data); } }; @@ -147,8 +147,7 @@ private void initialize(@NonNull Context context) { lbm.registerReceiver(this.receiver, filter); } - private void processEvent(@NonNull Context context, @NonNull Intent data) { - LocalBroadcastManager.getInstance(context).unregisterReceiver(this.receiver); + private void processEvent(@NonNull Intent data) { String action = data.getAction(); switch (action) { case Constants.AUTHENTICATION_ACTION: diff --git a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java index fccb9d8e..c652cc80 100644 --- a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java +++ b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java @@ -64,7 +64,7 @@ public class PasswordlessLock { @Override public void onReceive(@NonNull Context context, @NonNull Intent data) { - processEvent(context, data); + processEvent(data); } }; @@ -146,8 +146,7 @@ private void initialize(Context context) { lbm.registerReceiver(this.receiver, filter); } - private void processEvent(Context context, Intent data) { - LocalBroadcastManager.getInstance(context).unregisterReceiver(this.receiver); + private void processEvent(Intent data) { String action = data.getAction(); switch (action) { case Constants.AUTHENTICATION_ACTION: From 5b7f42d7025792c63b9177d9090666e6809a2408 Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Tue, 27 Apr 2021 20:32:29 +0200 Subject: [PATCH 4/4] update demo to release resources and avoid repeated receiver events --- .../main/java/com/auth0/android/lock/app/DemoActivity.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/com/auth0/android/lock/app/DemoActivity.kt b/app/src/main/java/com/auth0/android/lock/app/DemoActivity.kt index 4b4c1e17..ba54734b 100644 --- a/app/src/main/java/com/auth0/android/lock/app/DemoActivity.kt +++ b/app/src/main/java/com/auth0/android/lock/app/DemoActivity.kt @@ -162,6 +162,10 @@ class DemoActivity : AppCompatActivity() { } } + // For demo purposes because options change dynamically, we release the resources of Lock here. + // In a real app, you will have a single instance and release its resources in Activity#OnDestroy. + lock?.onDestroy(this) + // Create a new instance with the updated configuration lock = builder.build(this) startActivity(lock!!.newIntent(this)) } @@ -179,6 +183,10 @@ class DemoActivity : AppCompatActivity() { builder.useCode() } + // For demo purposes because options change dynamically, we release the resources of Lock here. + // In a real app, you will have a single instance and release its resources in Activity#OnDestroy. + passwordlessLock?.onDestroy(this) + // Create a new instance with the updated configuration passwordlessLock = builder.build(this) startActivity(passwordlessLock!!.newIntent(this)) }