Error when opening Chrome on Android 13 via adb

Recently I’ve started adapting our test framework for new Android release, and encountered an unexpected error when opening Chrome on Android 13 via adb. Since solving this issue required some investigation and a knowledge of Android development, I’ve decided to write a blog post about it.

TL;DR: Use the correct command below to launch the browser:

adb shell am start -a android.intent.action.VIEW -d https://google.com -n com.android.chrome/com.google.android.apps.chrome.IntentDispatcher --es "com.android.browser.application_id" "some_package"

Those, who want to know all the nitty gritty details, please keep reading.

First, let me show you the command I’ve used for launching the browser and the error message:

❯ adb shell am start -a android.intent.action.VIEW -d google.com -n com.android.chrome/com.google.android.apps.chrome.Main --es "com.android.browser.application_id" "some_package"
Starting: Intent { act=android.intent.action.VIEW dat= cmp=com.android.chrome/com.google.android.apps.chrome.Main (has extras) }
Error type 3
Error: Activity class {com.android.chrome/com.google.android.apps.chrome.Main} does not exist.

On the first glance it looks like com.google.android.apps.chrome.Main activity doesn’t exist, but if we launch Chrome and get a name of the current activity using command adb shell dumpsys activity top | grep ACTIVITY, then we it will show that indeed it is com.google.android.apps.chrome.Main.

To solve this mystery, we need to take a look at the Android 13 changelog, and particularly at this bit:

Screenshot of change "Intent filters block non-matching intents" in Android 13

You can read in detail about this change here and here, but simply speaking in our case it means that we must ensure that all parameters in our am start command match <intent-filter> declaration in Chrome manifest file.

In order to obtain Chrome manifest file we need to get Chrome apk file, and one way to do that is to download it from APKMirror. After downloading the file, we can simply drag and drop it in Android Studio and find AndroidManifest.xml in the displayed file list.

Screenshot of Chrome apk file list

Next, let’s find Main activity in the manifest and take a look at its intent filter:

<activity-alias
	android:name="com.google.android.apps.chrome.Main"
	android:exported="true"
	android:targetActivity="org.chromium.chrome.browser.ChromeTabbedActivity">

	<intent-filter>

		<action
			android:name="android.intent.action.MAIN" />

		<category
			android:name="android.intent.category.DEFAULT" />

		<category
			android:name="android.intent.category.LAUNCHER" />

		<category
			android:name="android.intent.category.BROWSABLE" />

		<category
			android:name="android.intent.category.APP_BROWSER" />
	</intent-filter>

	<meta-data
		android:name="android.app.shortcuts"
		android:resource="@ref/0x7f180021" />

	<intent-filter>

		<action
			android:name="org.chromium.chrome.browser.dummy.action" />

		<category
			android:name="com.google.intent.category.DAYDREAM" />

		<category
			android:name="com.google.intent.category.CARDBOARD" />
	</intent-filter>

	<intent-filter>

		<action
			android:name="com.samsung.android.support.REMOTE_ACTION" />
	</intent-filter>

	<meta-data
		android:name="com.samsung.android.support.REMOTE_ACTION"
		android:resource="@ref/0x7f180033" />
</activity-alias>

If we look carefully, we will notice that it doesn’t have android.intent.action.VIEW, which we use in am start command! Let’s find who does:

<activity-alias
	android:name="com.google.android.apps.chrome.IntentDispatcher"
	android:exported="true"
	android:targetActivity="org.chromium.chrome.browser.document.ChromeLauncherActivity">

	<intent-filter>

		<action
			android:name="android.intent.action.MAIN" />

		<category
			android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
	</intent-filter>

	<intent-filter>

		<action
			android:name="android.intent.action.VIEW" />

		<category
			android:name="android.intent.category.DEFAULT" />

		<data
			android:scheme="googlechrome" />

		<data
			android:scheme="http" />

		<data
			android:scheme="https" />

		<data
			android:scheme="about" />

		<category
			android:name="android.intent.category.BROWSABLE" />
	</intent-filter>

Apparently, it belongs to com.google.android.apps.chrome.IntentDispatcher activity. Note, that category in this filter is set to android.intent.category.DEFAULT, and luckily this matches our am start command, where we omit specifying the category, which means that DEFAULT category will be used.

Now lets’s try to launch the Chrome again after replacing activity name in the command:

❯ adb shell am start -a android.intent.action.VIEW -d google.com -n com.android.chrome/com.google.android.apps.chrome.IntentDispatcher --es "com.android.browser.application_id" "some_package"
Starting: Intent { act=android.intent.action.VIEW dat= cmp=com.android.chrome/com.google.android.apps.chrome.IntentDispatcher (has extras) }
Error type 3
Error: Activity class {com.android.chrome/com.google.android.apps.chrome.IntentDispatcher} does not exist.

Unfortunately, the command still fails. And the reason is that data (i.e. URL specified with “-d” flag) doesn’t start with http/https protocol prefix as required by the intent filter (see the <data> attribute).

Let’s fix that and try again:

❯ adb shell am start -a android.intent.action.VIEW -d https://google.com -n com.android.chrome/com.google.android.apps.chrome.IntentDispatcher --es "com.android.browser.application_id" "some_package"
Starting: Intent { act=android.intent.action.VIEW dat=https://google.com/... cmp=com.android.chrome/com.google.android.apps.chrome.IntentDispatcher (has extras) }

Voila, Chrome was successfully launched and opened our URL.

You might wonder, why so many code snippets for launching Chrome via adb which can be found on the internet (including my own popular post about most useful adb commands for testing) specify Main activity instead of IntentDispatcher? I guess there could be two possible reasons:

  1. In the older versions of Chrome that was the correct activity to use (the oldest Chrome I’ve checked – v94, Aug 2021 – already used IntentDispatcher).
  2. The person who came up with this command for the first time made a mistake, and no one noticed it because Android was not strict about the filters until now.

To summarize, in order to fix error when opening Chrome on Android 13 use the following command:

adb shell am start -a android.intent.action.VIEW -d https://google.com -n com.android.chrome/com.google.android.apps.chrome.IntentDispatcher --es "com.android.browser.application_id" "some_package"

By the way, this command should be used not only on Android 13, but on other Android versions as well, providing that a relatively new version of Chrome is installed there (see reason #1 above).

One thought on “Error when opening Chrome on Android 13 via adb

  1. HR 2022-09-14 / 18:06

    Thank you, great article.

Leave a Reply

Your email address will not be published.