Commit c06669aa authored by Peter E Conn's avatar Peter E Conn Committed by Commit Bot

🤝 Fix launching TWAs from notifications.

While moving Chrome over to androidx.browser, Strings representing
package names were replaced with Tokens that represent package names
and their signature. Strings have hashCode overridden to provide value
equality whereas Tokens don't, so checking for the existence of an
equivalent Token in a Set of Tokens doesn't work.

This change manually looks through the set of Tokens and calls
Token#matches on each one.

Bug: 1052288
Change-Id: Ia2ad8bf3272853acbd07ae36aad33e9c78fb9e8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2078548
Commit-Queue: Peter Conn <peconn@chromium.org>
Reviewed-by: default avatarMichael van Ouwerkerk <mvanouwerkerk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#745414}
parent 84b04286
......@@ -11,12 +11,14 @@ import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.browser.trusted.Token;
import androidx.browser.trusted.TrustedWebActivityService;
......@@ -234,33 +236,35 @@ public class TrustedWebActivityClient {
// Trusted Web Activities only work with https so we can shortcut here.
if (!UrlConstants.HTTPS_SCHEME.equals(origin.uri().getScheme())) return null;
Set<Token> verifiedPackages = mDelegatesManager.getAllDelegateApps(origin);
if (verifiedPackages == null || verifiedPackages.size() == 0) return null;
ComponentName componentName = searchVerifiedApps(appContext.getPackageManager(),
mDelegatesManager.getAllDelegateApps(origin), resolveInfosForUrl);
String twaPackageName = null;
String twaActivityName = null;
for (ResolveInfo info : resolveInfosForUrl) {
if (info.activityInfo == null) continue;
Token token =
Token.create(info.activityInfo.packageName, appContext.getPackageManager());
if (token == null) continue;
if (verifiedPackages.contains(token)) {
twaPackageName = info.activityInfo.packageName;
twaActivityName = info.activityInfo.name;
break;
}
}
if (twaPackageName == null) return null;
if (componentName == null) return null;
Intent intent = new Intent();
intent.setData(Uri.parse(url));
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setComponent(new ComponentName(twaPackageName, twaActivityName));
intent.setComponent(componentName);
return intent;
}
@Nullable
private static ComponentName searchVerifiedApps(@NonNull PackageManager pm,
@Nullable Set<Token> verifiedPackages, @NonNull List<ResolveInfo> resolveInfosForUrl) {
if (verifiedPackages == null || verifiedPackages.isEmpty()) return null;
for (ResolveInfo info : resolveInfosForUrl) {
if (info.activityInfo == null) continue;
for (Token v : verifiedPackages) {
if (!v.matches(info.activityInfo.packageName, pm)) continue;
return new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
}
}
return null;
}
}
......@@ -7,6 +7,8 @@ package org.chromium.chrome.browser.browserservices;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
......@@ -35,9 +37,9 @@ import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
import org.chromium.chrome.browser.notifications.StandardNotificationBuilder;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import java.util.Collections;
import java.util.concurrent.TimeoutException;
/**
* Tests the TrustedWebActivityClient.
*
......@@ -198,4 +200,40 @@ public class TrustedWebActivityClientTest {
Assert.assertEquals(mResponseHandler.mNotificationTag, NOTIFICATION_TAG);
Assert.assertEquals(mResponseHandler.mNotificationId, NOTIFICATION_ID);
}
/**
* Tests {@link TrustedWebActivityClient#createLaunchIntentForTwa}.
*/
@Test
@SmallTest
public void createLaunchIntent() {
Context context = InstrumentationRegistry.getContext();
String targetPackageName = mTargetContext.getPackageName();
// This should return null because there are no ResolveInfos.
Assert.assertNull(TrustedWebActivityClient.createLaunchIntentForTwa(
context, SCOPE.toString(), Collections.emptyList()));
ResolveInfo resolveInfo = new ResolveInfo();
// This should return null because there are no ResolveInfos with ActivityInfos.
Assert.assertNull(TrustedWebActivityClient.createLaunchIntentForTwa(
context, SCOPE.toString(), Collections.singletonList(resolveInfo)));
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = targetPackageName;
activityInfo.name = "ActivityWithDeepLink";
resolveInfo.activityInfo = activityInfo;
// This should return null because the given ResolveInfo is not for a verified app.
Assert.assertNull(TrustedWebActivityClient.createLaunchIntentForTwa(
context, SCOPE.toString(), Collections.singletonList(resolveInfo)));
ChromeApplication.getComponent().resolveTwaPermissionManager()
.addDelegateApp(Origin.create(SCOPE), targetPackageName);
Assert.assertNotNull(TrustedWebActivityClient.createLaunchIntentForTwa(
context, SCOPE.toString(), Collections.singletonList(resolveInfo)));
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment