2021-06-27 20:44:35 +00:00
|
|
|
package androidx.browser.trusted;
|
|
|
|
|
|
|
|
import android.content.ComponentName;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.pm.ResolveInfo;
|
|
|
|
import android.net.Uri;
|
|
|
|
import android.os.AsyncTask;
|
|
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.MainThread;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
2021-08-09 22:51:56 +00:00
|
|
|
import androidx.fragment.app.FragmentTransaction;
|
2021-12-17 21:59:34 +00:00
|
|
|
import b.d.b.a.a;
|
2021-06-27 20:44:35 +00:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.concurrent.Executor;
|
2021-11-02 06:38:17 +00:00
|
|
|
import y.a.b.c;
|
2021-06-27 20:44:35 +00:00
|
|
|
public final class TrustedWebActivityServiceConnectionPool {
|
|
|
|
private static final String TAG = "TWAConnectionPool";
|
|
|
|
private final Map<Uri, ConnectionHolder> mConnections = new HashMap();
|
|
|
|
private final Context mContext;
|
|
|
|
|
|
|
|
public static class BindToServiceAsyncTask extends AsyncTask<Void, Void, Exception> {
|
|
|
|
private final Context mAppContext;
|
|
|
|
private final ConnectionHolder mConnection;
|
|
|
|
private final Intent mIntent;
|
|
|
|
|
|
|
|
public BindToServiceAsyncTask(Context context, Intent intent, ConnectionHolder connectionHolder) {
|
|
|
|
this.mAppContext = context.getApplicationContext();
|
|
|
|
this.mIntent = intent;
|
|
|
|
this.mConnection = connectionHolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public Exception doInBackground(Void... voidArr) {
|
|
|
|
try {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (this.mAppContext.bindService(this.mIntent, this.mConnection, FragmentTransaction.TRANSIT_FRAGMENT_OPEN)) {
|
2021-06-27 20:44:35 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
this.mAppContext.unbindService(this.mConnection);
|
|
|
|
return new IllegalStateException("Could not bind to the service");
|
|
|
|
} catch (SecurityException e) {
|
2021-08-09 22:51:56 +00:00
|
|
|
Log.w(TrustedWebActivityServiceConnectionPool.TAG, "SecurityException while binding.", e);
|
2021-06-27 20:44:35 +00:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onPostExecute(Exception exc) {
|
|
|
|
if (exc != null) {
|
|
|
|
this.mConnection.cancel(exc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private TrustedWebActivityServiceConnectionPool(@NonNull Context context) {
|
|
|
|
this.mContext = context.getApplicationContext();
|
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
public static TrustedWebActivityServiceConnectionPool create(@NonNull Context context) {
|
|
|
|
return new TrustedWebActivityServiceConnectionPool(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
private Intent createServiceIntent(Context context, Uri uri, Set<Token> set, boolean z2) {
|
|
|
|
if (set == null || set.size() == 0) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Intent intent = new Intent();
|
|
|
|
intent.setData(uri);
|
|
|
|
intent.setAction("android.intent.action.VIEW");
|
|
|
|
String str = null;
|
|
|
|
for (ResolveInfo resolveInfo : context.getPackageManager().queryIntentActivities(intent, 65536)) {
|
|
|
|
String str2 = resolveInfo.activityInfo.packageName;
|
|
|
|
Iterator<Token> it = set.iterator();
|
|
|
|
while (true) {
|
|
|
|
if (it.hasNext()) {
|
|
|
|
if (it.next().matches(str2, context.getPackageManager())) {
|
|
|
|
str = str2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (str == null) {
|
|
|
|
if (z2) {
|
2021-08-09 22:51:56 +00:00
|
|
|
Log.w(TAG, "No TWA candidates for " + uri + " have been registered.");
|
2021-06-27 20:44:35 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Intent intent2 = new Intent();
|
|
|
|
intent2.setPackage(str);
|
2021-08-09 22:51:56 +00:00
|
|
|
intent2.setAction(TrustedWebActivityService.ACTION_TRUSTED_WEB_ACTIVITY_SERVICE);
|
2021-06-27 20:44:35 +00:00
|
|
|
ResolveInfo resolveService = context.getPackageManager().resolveService(intent2, 131072);
|
|
|
|
if (resolveService == null) {
|
|
|
|
if (z2) {
|
2021-11-05 06:48:17 +00:00
|
|
|
Log.w(TAG, "Could not find TWAService for " + str);
|
2021-06-27 20:44:35 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (z2) {
|
2021-11-05 06:48:17 +00:00
|
|
|
StringBuilder R = a.R("Found ");
|
|
|
|
R.append(resolveService.serviceInfo.name);
|
|
|
|
R.append(" to handle request for ");
|
|
|
|
R.append(uri);
|
|
|
|
Log.i(TAG, R.toString());
|
2021-06-27 20:44:35 +00:00
|
|
|
}
|
|
|
|
Intent intent3 = new Intent();
|
|
|
|
intent3.setComponent(new ComponentName(str, resolveService.serviceInfo.name));
|
|
|
|
return intent3;
|
|
|
|
}
|
|
|
|
|
|
|
|
public /* synthetic */ void a(Uri uri) {
|
|
|
|
this.mConnections.remove(uri);
|
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
@MainThread
|
2021-12-17 21:59:34 +00:00
|
|
|
public b.i.b.d.a.a<TrustedWebActivityServiceConnection> connect(@NonNull Uri uri, @NonNull Set<Token> set, @NonNull Executor executor) {
|
2021-06-27 20:44:35 +00:00
|
|
|
ConnectionHolder connectionHolder = this.mConnections.get(uri);
|
|
|
|
if (connectionHolder != null) {
|
|
|
|
return connectionHolder.getServiceWrapper();
|
|
|
|
}
|
|
|
|
Intent createServiceIntent = createServiceIntent(this.mContext, uri, set, true);
|
|
|
|
if (createServiceIntent == null) {
|
|
|
|
return FutureUtils.immediateFailedFuture(new IllegalArgumentException("No service exists for scope"));
|
|
|
|
}
|
|
|
|
ConnectionHolder connectionHolder2 = new ConnectionHolder(new c(this, uri));
|
|
|
|
this.mConnections.put(uri, connectionHolder2);
|
|
|
|
new BindToServiceAsyncTask(this.mContext, createServiceIntent, connectionHolder2).executeOnExecutor(executor, new Void[0]);
|
|
|
|
return connectionHolder2.getServiceWrapper();
|
|
|
|
}
|
|
|
|
|
|
|
|
@MainThread
|
|
|
|
public boolean serviceExistsForScope(@NonNull Uri uri, @NonNull Set<Token> set) {
|
|
|
|
return (this.mConnections.get(uri) == null && createServiceIntent(this.mContext, uri, set, false) == null) ? false : true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void unbindAllConnections() {
|
|
|
|
for (ConnectionHolder connectionHolder : this.mConnections.values()) {
|
|
|
|
this.mContext.unbindService(connectionHolder);
|
|
|
|
}
|
|
|
|
this.mConnections.clear();
|
|
|
|
}
|
|
|
|
}
|