Appauth-android: ActivityNotFoundException (No browser installed on device)

Created on 2 Mar 2020  ·  16Comments  ·  Source: openid/AppAuth-Android

How to handle the case where no browser is installed on the device ? Can't we launch the authorization request from an webview ?

enhancement

All 16 comments

we are facing something similar:

Caused by android.content.ActivityNotFoundException
       at net.openid.appauth.AuthorizationService.prepareAuthorizationRequestIntent + 372(AuthorizationService.java:372)
       at net.openid.appauth.AuthorizationService.getAuthorizationRequestIntent + 267(AuthorizationService.java:267)
       at com.volvocars.openid.SignInActivity.signIn + 62(SignInActivity.java:62)
       at com.volvocars.openid.SignInActivity.onCreate + 36(SignInActivity.java:36)
       at android.app.Activity.performCreate + 7183(Activity.java:7183)
       at android.app.Instrumentation.callActivityOnCreate + 1220(Instrumentation.java:1220)
       at android.app.ActivityThread.performLaunchActivity + 2910(ActivityThread.java:2910)
       at android.app.ActivityThread.handleLaunchActivity + 3032(ActivityThread.java:3032)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage + 1696(ActivityThread.java:1696)
       at android.os.Handler.dispatchMessage + 105(Handler.java:105)
       at android.os.Looper.loop + 164(Looper.java:164)
       at android.app.ActivityThread.main + 6944(ActivityThread.java:6944)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run + 327(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main + 1374(ZygoteInit.java:1374)

Devices
samsung 45%
Sony 31%
HMD Global 10%
bq 9%
Other… 5%

Operating Systems
9 - 43%
10 - 39%
7 - 11%
8 - 7%

How can we get a proper callback for this? We need to show an error message to the user to tell them to install some browsers, but getAuthorizationRequestIntent doesn't return forever if there is no activity to handle it.

@kiskunk You should be able to do something like:

try  {
  val authIntent =  authService. getAuthorizationRequestIntent(authRequest)
  myMethodToStartAuthFlow(authIntent)
}catch(err) {
  when (err) {
     is ActivityNotFoundException -> showBrowserRequiredMessage()
     else -> showGenericError()
}

We were surprised by the number of devices encountering this as well. We now catch this and present the user a message letting them know they require a browser to continue.

It sounds like throwing a formally documented exception on calls that require browsers would be helpful here. No guarantees can be provided as to when this can be implemented, but it's a reasonable request.

difficult

We also see this problem in our logs. We actually have one Testdevice (Samsung S7) where this error occured for whatever reasons.

Setup: Chrome (default), Firefox and Opera are installed.

We found that this line in BrowserSelector.java:

List<ResolveInfo> resolvedActivityList =
                pm.queryIntentActivities(BROWSER_INTENT, queryFlag);

resolves only for the Opera Browser which let everything fail

Note: I have another S7 with the same setup where this error does not occur 🤷‍♀️

We experience the same problem. I tried to solve this with various approaches, but I have not really found any good way to handle this. (right now using try/catch)

Would be nice with more insight or this error solved
Screenshot 2020-09-07 at 09 43 38

According to Firebase we have crashes

  • 67% samsung
  • 15% Sony
  • 8% asus
  • 8% LGE
  • 2% Lenovo

Android versions:

  • 61% Android 8
  • 26% Android 7
  • 10% Android 10
  • 3% Android 6

We've been observing this crash on few of our Android users in production. I have managed to reproduce the crash with the sample project in this repo, but only if I choose the "Authorize Auth0" option. There are no browsers installed on the device (Android 10).

We've been using version 5.0.0 of this library, since this seemed to have been handled already: https://github.com/FormidableLabs/react-native-app-auth/pull/443 But it keeps happening. I don't seem to be able to get the error mentioned in the README (browser_not_found (Android only) - no suitable browser installed), only a crash.

I cannot tell for sure if the users experiencing this have no browsers installed or they have an non supported one.

We've had this issue on a few Android devices that had installed some other browser, in particular "Photon Browser". It was being used by users to run Flash apps. It would cause no browsers to be returned even if Chrome was installed and set as the default browser. Uninstalling "Photon Browser" solved the problem. This was on Android 11 running on Samsung device.

We've experienced the same bug a while ago. If the Opera browser (or Opera beta) is set as default browser a login isn't possible at all. As @jannisveerkamp said the following intent only resolves the Opera browser which isn't able to handle it:

List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(BROWSER_INTENT, queryFlag);

Other browsers installed on the same device don't have any impact on that.

We've tested it on a lot of different devices and found out that the bug only occurs on devices running Android 7 or below. We've also tested about 50 different browsers and couldn't reproduce that strange behavior with another browser.

We've added a workaround for that bug in our fork. The important parts occur in this two commits:
https://github.com/dm-Mobile-SE-Developer/AppAuth-Android/commit/d8786fee1500f1f9da63ef8d19730a57f789b8cc
https://github.com/dm-Mobile-SE-Developer/AppAuth-Android/commit/e2d98fc3e64fbfb75e39d807a6a317a738fc879d

But of course we would be very interested in a fix or workaround in the official repository.

@SuddenH4X You can use BrowserDenyList to work around your issue.
I also encourage to reach out to the individual browser developers if you find issues with their products.

Keeping this issue open as the OP's question refers to a different use-case.

We have gotten a customer review from a Samsung Galaxy S10+ Android 11 device, and it sounds similar to what @pablocoberly wrote.

Unfortunately I can't reproduce it with my Samsung A70 Android 11 test device :(. Having Chrome, Opera, Photon Browser installed; Chrome gets opened in the app auth login custom tab. When trying to change the default browser, I can only make Opera or Chrome a default browser, Photon is not shown there at all.

We had answered to the user's review:

Many thanks for your feedback! We are very sorry you were not able to use the login as intended. We have analyzed the problem. Could you please try to uninstall all browsers except for Chrome? The issue could be caused by Opera or the Photon Browser. After these are removed, the issue should be gone. If this did not solve the issue, please write our support at ....

Unfortunately it did not solve the issue, but the user also did not contact the support, so we are still unsure how to proceed :( The user added this to their review:

I've followed the developer's advice by uninstalling other EU browsers, it doesn't work any better.

I recommend filtering for chrome, this solved all our issues:

const val CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"


    private fun createAppAuthConfiguration(connectionBuilder: ConnectionBuilder = DefaultConnectionBuilder.INSTANCE): AppAuthConfiguration {
        val builder = AppAuthConfiguration.Builder().setConnectionBuilder(connectionBuilder)
        if (isPackageInstalled(context, CUSTOM_TAB_PACKAGE_NAME)) {
            builder.setBrowserMatcher { it.packageName == CUSTOM_TAB_PACKAGE_NAME }
        }
        return builder.build()
    }

for isPackageInstalled we use

    fun isPackageInstalled(context: Context, packageName: String): Boolean {
        return try {
            context.packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

@carstenhag is it possible your customer is using an MDM solution and the app is installed in the sandbox?
If so it's quite possible their IT didn't install a browser in their Secure Folder.

I was able to reproduce this issue on an Android 7 emulator with Opera, Chrome and the WebView browser installed. What I found was that once Opera is set as a default browser, both ResolveInfo resolvedDefaultActivity = pm.resolveActivity(BROWSER_INTENT, 0); and List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(BROWSER_INTENT, queryFlag); only return the Opera browser. Even after trying the following Opera is the only browser returned:

  1. Setting another browser as default
  2. Restarting the device
  3. Clearing Opera's app data

The only things that worked were:

  1. Setting the default browser to another and performing "Reset app preferences" (see attached image)
  2. Uninstalling Opera
    image

The workaround mentioned above by @SuddenH4X worked so I guess we just have to fork the repo and go ahead with that as we have a user with this issue.

Was this page helpful?
0 / 5 - 0 ratings