fix(android): When chrome is not installed/enabled or the default browser (#2261)

Fixes #2225 
- Set Chrome app has a hard requirement for seamless user experience
with app link.
- Check if Chrome is not installed/enabled, then show an error toast.
- If Chrome is not set as the default browser, use the Chrome stable
version package name to force open the sign-in flow in Chrome.

Fixes #2184 
- Closing webview moves back to sign-in page.




_Applinks is supported in Firefox but is disabled by default
(https://support.mozilla.org/en-US/kb/set-firefox-android-open-links-native-apps)
..why 🤦‍♂️??_

Later based on user's browser we can update the redirected page to
include instructions to enable the link, something like this:


![Screenshot_1696581921](https://github.com/firezone/firezone/assets/1523745/2587b3de-7e85-4b82-aa99-61e58b8dc0b3)

---------

Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
This commit is contained in:
Pratik Velani
2023-10-07 02:30:04 +05:30
committed by GitHub
parent 802d9aa769
commit 8dbdda9faf
4 changed files with 58 additions and 10 deletions

View File

@@ -4,7 +4,7 @@ package dev.firezone.android.features.auth.ui
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
@@ -14,6 +14,7 @@ import dev.firezone.android.R
import dev.firezone.android.core.presentation.MainActivity
import dev.firezone.android.databinding.ActivityAuthBinding
import dev.firezone.android.util.CustomTabsHelper
import java.lang.Exception
@AndroidEntryPoint
class AuthActivity : AppCompatActivity(R.layout.activity_auth) {
@@ -38,14 +39,10 @@ class AuthActivity : AppCompatActivity(R.layout.activity_auth) {
private fun setupActionObservers() {
viewModel.actionLiveData.observe(this) { action ->
Log.d("AuthActivity", "setupActionObservers: $action")
when (action) {
is AuthViewModel.ViewAction.LaunchAuthFlow -> setupWebView(action.url)
is AuthViewModel.ViewAction.NavigateToSignInFragment -> {
startActivity(
Intent(this, MainActivity::class.java),
)
finish()
navigateToSignIn()
}
is AuthViewModel.ViewAction.ShowError -> showError()
else -> {}
@@ -54,10 +51,40 @@ class AuthActivity : AppCompatActivity(R.layout.activity_auth) {
}
private fun setupWebView(url: String) {
val intent = CustomTabsIntent.Builder().build()
intent.intent.setPackage(CustomTabsHelper.getPackageNameToUse(this@AuthActivity))
intent.launchUrl(this@AuthActivity, Uri.parse(url))
if (CustomTabsHelper.checkIfChromeIsInstalled(this)) {
val intent = CustomTabsIntent.Builder().build()
val packageName = CustomTabsHelper.getPackageNameToUse(this)
if (CustomTabsHelper.checkIfChromeAppIsDefault()) {
if (packageName != null) {
intent.intent.setPackage(packageName)
}
} else {
intent.intent.setPackage(CustomTabsHelper.STABLE_PACKAGE)
}
try {
intent.launchUrl(this@AuthActivity, Uri.parse(url))
finish()
} catch (e: Exception) {
showChromeAppRequiredError()
}
} else {
showChromeAppRequiredError()
}
}
private fun showChromeAppRequiredError() {
Toast.makeText(this, getString(R.string.signing_in_requires_chrome_browser), Toast.LENGTH_LONG).show()
navigateToSignIn()
}
private fun navigateToSignIn() {
startActivity(
Intent(this, MainActivity::class.java),
)
finish()
}
private fun showError() {
AlertDialog.Builder(this)
.setTitle(R.string.error_dialog_title)

View File

@@ -34,7 +34,6 @@ internal class SignInFragment : Fragment(R.layout.fragment_sign_in) {
AuthActivity::class.java,
),
)
requireActivity().finish()
}
btSettings.setOnClickListener {
findNavController().navigate(

View File

@@ -3,7 +3,10 @@ package dev.firezone.android.util
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
class CustomTabsHelper {
companion object {
val STABLE_PACKAGE = "com.android.chrome"
@@ -46,5 +49,23 @@ class CustomTabsHelper {
}
return sPackageNameToUse
}
fun checkIfChromeAppIsDefault() =
sPackageNameToUse == STABLE_PACKAGE ||
sPackageNameToUse == BETA_PACKAGE ||
sPackageNameToUse == DEV_PACKAGE ||
sPackageNameToUse == LOCAL_PACKAGE
fun checkIfChromeIsInstalled(context: Context): Boolean = try {
val info = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.packageManager.getPackageInfo(STABLE_PACKAGE, PackageManager.PackageInfoFlags.of(0L))
} else {
@Suppress("DEPRECATION")
context.packageManager.getPackageInfo(STABLE_PACKAGE, 0)
}
info.applicationInfo.enabled
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
}

View File

@@ -27,6 +27,7 @@
<string name="request_permission">Request Permission</string>
<string name="enter_team_id">Enter team id</string>
<string name="sign_in_debug_user">Sign In (Debug User)</string>
<string name="signing_in_requires_chrome_browser">Signing in requires chrome browser</string>
<!-- Error Dialog -->
</resources>