diff --git a/WordPress/src/main/AndroidManifest.xml b/WordPress/src/main/AndroidManifest.xml
index f75b6256df59..f86f5b173287 100644
--- a/WordPress/src/main/AndroidManifest.xml
+++ b/WordPress/src/main/AndroidManifest.xml
@@ -1167,6 +1167,9 @@
+
+
+
diff --git a/WordPress/src/main/java/org/wordpress/android/modules/AppConfigModule.java b/WordPress/src/main/java/org/wordpress/android/modules/AppConfigModule.java
index 7ae8ff7c5549..b71f2adcd2ba 100644
--- a/WordPress/src/main/java/org/wordpress/android/modules/AppConfigModule.java
+++ b/WordPress/src/main/java/org/wordpress/android/modules/AppConfigModule.java
@@ -1,7 +1,6 @@
package org.wordpress.android.modules;
import android.content.Context;
-import android.os.Build;
import android.util.Base64;
import androidx.annotation.NonNull;
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java
index c0832377670c..ae34dd22e879 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java
@@ -152,6 +152,10 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Attempt Login if this activity was created in response to a user confirming login
mLoginHelper.tryLoginWithDataString(getIntent().getDataString());
+ // Start preloading the WordPress.com login page if needed – this avoids visual hitches
+ // when displaying that screen
+ mLoginHelper.bindCustomTabsService(this);
+
if (mLoginHelper.isLoggedIn()) {
this.loggedInAndFinish(new ArrayList(), true);
return;
@@ -477,7 +481,7 @@ public void showWPcomLoginScreen(@NonNull Context context) {
.setShowTitle(false)
.build();
- intent.launchUrl(this, mLoginHelper.loginUri());
+ intent.launchUrl(this, mLoginHelper.getWpcomLoginUri());
}
@Override
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/WPcomLoginHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/WPcomLoginHelper.kt
index 9e5df8233f9c..1eaf892dad40 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/WPcomLoginHelper.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/login/WPcomLoginHelper.kt
@@ -1,7 +1,13 @@
package org.wordpress.android.ui.accounts.login
+import android.content.ComponentName
+import android.content.Context
import android.net.Uri
import android.util.Log
+import androidx.browser.customtabs.CustomTabsCallback
+import androidx.browser.customtabs.CustomTabsClient
+import androidx.browser.customtabs.CustomTabsServiceConnection
+import androidx.browser.customtabs.CustomTabsSession
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
@@ -14,13 +20,12 @@ import kotlin.coroutines.CoroutineContext
class WPcomLoginHelper @Inject constructor(
private val loginClient: WPcomLoginClient,
private val accountStore: AccountStore,
- private val appSecrets: AppSecrets
+ appSecrets: AppSecrets
) {
private val context: CoroutineContext = Dispatchers.IO
- fun loginUri(): Uri {
- return loginClient.loginUri(appSecrets.redirectUri)
- }
+ val wpcomLoginUri = loginClient.loginUri(appSecrets.redirectUri)
+ private val customTabsServiceConnection = ServiceConnection(wpcomLoginUri)
fun tryLoginWithDataString(data: String?) {
if (data == null) {
@@ -44,7 +49,47 @@ class WPcomLoginHelper @Inject constructor(
context.cancel()
}
+ fun bindCustomTabsService(context: Context) {
+ customTabsServiceConnection.bind(context)
+ }
+
private fun codeFromAuthorizationUri(string: String): String? {
return Uri.parse(string).getQueryParameter("code")
}
}
+
+class ServiceConnection(
+ var uri: Uri
+): CustomTabsServiceConnection() {
+ private var client: CustomTabsClient? = null
+ private var session: CustomTabsSession? = null
+
+ override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) {
+ client.warmup(0)
+ this.client = client
+
+ val session = client.newSession(CustomTabsCallback())
+ session?.mayLaunchUrl(uri, null, null)
+ session?.mayLaunchUrl(Uri.parse("https://wordpress.com/log-in/"), null, null)
+
+ this.session = session
+ }
+
+ override fun onServiceDisconnected(name: ComponentName?) {
+ this.client = null
+ this.session = null
+ }
+
+ fun bind(context: Context) {
+ // Do nothing if there is an existing service connection
+ if (this.client != null) {
+ return
+ }
+
+ // Get the default browser package name, this will be null if
+ // the default browser does not provide a CustomTabsService
+ val packageName = CustomTabsClient.getPackageName(context, null) ?: return
+
+ CustomTabsClient.bindCustomTabsService(context, packageName, this)
+ }
+}