summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-01-31 09:57:26 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-01-31 09:57:26 +0000
commit397c38d01711b1fb21882b41f5ced0ba98edab6e (patch)
tree6e620d7efaeb1d26411ff58a9da5fddb00b54bdc
parent4b4539b6b0e1e6c8986aa0127470d1ce8651c124 (diff)
parent860b8ba71938e9860a31881c1d1431877f9d01a2 (diff)
Merge "Revert "Adds generic intent Instant App resolution""
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt11
-rw-r--r--core/java/android/app/EphemeralResolverService.java12
-rw-r--r--core/java/android/app/IInstantAppResolver.aidl8
-rw-r--r--core/java/android/app/InstantAppResolverService.java107
-rw-r--r--core/java/android/content/Intent.java50
-rw-r--r--core/java/android/content/pm/AuxiliaryResolveInfo.java99
-rw-r--r--core/java/android/content/pm/InstantAppResolveInfo.java96
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java13
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java30
-rw-r--r--services/core/java/com/android/server/pm/EphemeralResolverConnection.java28
-rw-r--r--services/core/java/com/android/server/pm/InstantAppResolver.java322
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java182
14 files changed, 324 insertions, 645 deletions
diff --git a/api/current.txt b/api/current.txt
index 7f07f810afa7..dda165f1fdc6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10050,7 +10050,6 @@ package android.content {
field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
field public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 4096; // 0x1000
- field public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 2048; // 0x800
field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 524288; // 0x80000
field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
diff --git a/api/system-current.txt b/api/system-current.txt
index 08ac295c9361..034ee3090fc4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -311,10 +311,8 @@ package android.app {
ctor public InstantAppResolverService();
method public final void attachBaseContext(android.content.Context);
method public final android.os.IBinder onBind(android.content.Intent);
- method public deprecated void onGetInstantAppIntentFilter(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method public void onGetInstantAppIntentFilter(android.content.Intent, int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method public deprecated void onGetInstantAppResolveInfo(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
- method public void onGetInstantAppResolveInfo(android.content.Intent, int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method public void onGetInstantAppIntentFilter(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method public void onGetInstantAppResolveInfo(int[], java.lang.String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
}
public static final class InstantAppResolverService.InstantAppResolutionCallback {
@@ -823,14 +821,12 @@ package android.content {
field public static final java.lang.String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
field public static final java.lang.String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
field public static final java.lang.String EXTRA_FORCE_FACTORY_RESET = "android.intent.extra.FORCE_FACTORY_RESET";
- field public static final java.lang.String EXTRA_INSTANT_APP_BUNDLES = "android.intent.extra.INSTANT_APP_BUNDLES";
field public static final java.lang.String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID";
field public static final java.lang.String EXTRA_PACKAGES = "android.intent.extra.PACKAGES";
field public static final java.lang.String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
field public static final java.lang.String EXTRA_REASON = "android.intent.extra.REASON";
field public static final java.lang.String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
field public static final java.lang.String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
- field public static final java.lang.String EXTRA_UNKNOWN_INSTANT_APP = "android.intent.extra.UNKNOWN_INSTANT_APP";
}
public class IntentFilter implements android.os.Parcelable {
@@ -873,7 +869,6 @@ package android.content.pm {
ctor public InstantAppResolveInfo(android.content.pm.InstantAppResolveInfo.InstantAppDigest, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>, int);
ctor public InstantAppResolveInfo(android.content.pm.InstantAppResolveInfo.InstantAppDigest, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>, long, android.os.Bundle);
ctor public InstantAppResolveInfo(java.lang.String, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>);
- ctor public InstantAppResolveInfo(android.os.Bundle);
method public int describeContents();
method public byte[] getDigestBytes();
method public int getDigestPrefix();
@@ -882,7 +877,6 @@ package android.content.pm {
method public long getLongVersionCode();
method public java.lang.String getPackageName();
method public deprecated int getVersionCode();
- method public boolean shouldLetInstallerDecide();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.pm.InstantAppResolveInfo> CREATOR;
}
@@ -894,7 +888,6 @@ package android.content.pm {
method public int[] getDigestPrefix();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.pm.InstantAppResolveInfo.InstantAppDigest> CREATOR;
- field public static final android.content.pm.InstantAppResolveInfo.InstantAppDigest UNDEFINED;
}
public final class IntentFilterVerificationInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/EphemeralResolverService.java b/core/java/android/app/EphemeralResolverService.java
index d1c244136ec9..427a0386e87c 100644
--- a/core/java/android/app/EphemeralResolverService.java
+++ b/core/java/android/app/EphemeralResolverService.java
@@ -17,10 +17,20 @@
package android.app;
import android.annotation.SystemApi;
+import android.app.Service;
+import android.app.InstantAppResolverService.InstantAppResolutionCallback;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.EphemeralResolveInfo;
import android.content.pm.InstantAppResolveInfo;
import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
@@ -75,6 +85,7 @@ public abstract class EphemeralResolverService extends InstantAppResolverService
return super.getLooper();
}
+ @Override
void _onGetInstantAppResolveInfo(int[] digestPrefix, String token,
InstantAppResolutionCallback callback) {
if (DEBUG_EPHEMERAL) {
@@ -90,6 +101,7 @@ public abstract class EphemeralResolverService extends InstantAppResolverService
callback.onInstantAppResolveInfo(resultList);
}
+ @Override
void _onGetInstantAppIntentFilter(int[] digestPrefix, String token,
String hostName, InstantAppResolutionCallback callback) {
if (DEBUG_EPHEMERAL) {
diff --git a/core/java/android/app/IInstantAppResolver.aidl b/core/java/android/app/IInstantAppResolver.aidl
index ae200578d829..805d8c057d27 100644
--- a/core/java/android/app/IInstantAppResolver.aidl
+++ b/core/java/android/app/IInstantAppResolver.aidl
@@ -16,15 +16,13 @@
package android.app;
-import android.content.Intent;
import android.os.IRemoteCallback;
/** @hide */
oneway interface IInstantAppResolver {
- void getInstantAppResolveInfoList(in Intent sanitizedIntent, in int[] hostDigestPrefix,
+ void getInstantAppResolveInfoList(in int[] digestPrefix,
String token, int sequence, IRemoteCallback callback);
- void getInstantAppIntentFilterList(in Intent sanitizedIntent, in int[] hostDigestPrefix,
- String token, IRemoteCallback callback);
-
+ void getInstantAppIntentFilterList(in int[] digestPrefix,
+ String token, String hostName, IRemoteCallback callback);
}
diff --git a/core/java/android/app/InstantAppResolverService.java b/core/java/android/app/InstantAppResolverService.java
index 89aff36f883a..c5dc86c79ef9 100644
--- a/core/java/android/app/InstantAppResolverService.java
+++ b/core/java/android/app/InstantAppResolverService.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.SystemApi;
+import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.InstantAppResolveInfo;
@@ -34,7 +35,6 @@ import android.util.Slog;
import com.android.internal.os.SomeArgs;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
/**
@@ -53,65 +53,23 @@ public abstract class InstantAppResolverService extends Service {
Handler mHandler;
/**
- * Called to retrieve resolve info for instant applications immediately.
+ * Called to retrieve resolve info for instant applications.
*
* @param digestPrefix The hash prefix of the instant app's domain.
- * @deprecated should implement {@link #onGetInstantAppResolveInfo(Intent, int[], String,
- * InstantAppResolutionCallback)}
*/
- @Deprecated
public void onGetInstantAppResolveInfo(
int digestPrefix[], String token, InstantAppResolutionCallback callback) {
throw new IllegalStateException("Must define");
}
/**
- * Called to retrieve intent filters for instant applications from potentially expensive
- * sources.
+ * Called to retrieve intent filters for instant applications.
*
* @param digestPrefix The hash prefix of the instant app's domain.
- * @deprecated should implement {@link #onGetInstantAppIntentFilter(Intent, int[], String,
- * InstantAppResolutionCallback)}
*/
- @Deprecated
public void onGetInstantAppIntentFilter(
int digestPrefix[], String token, InstantAppResolutionCallback callback) {
- throw new IllegalStateException("Must define onGetInstantAppIntentFilter");
- }
-
- /**
- * Called to retrieve resolve info for instant applications immediately.
- *
- * @param sanitizedIntent The sanitized {@link Intent} used for resolution.
- * @param hostDigestPrefix The hash prefix of the instant app's domain.
- */
- public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
- String token, InstantAppResolutionCallback callback) {
- // if not overridden, forward to old methods and filter out non-web intents
- if (sanitizedIntent.isBrowsableWebIntent()) {
- onGetInstantAppResolveInfo(hostDigestPrefix, token, callback);
- } else {
- callback.onInstantAppResolveInfo(Collections.emptyList());
- }
- }
-
- /**
- * Called to retrieve intent filters for instant applications from potentially expensive
- * sources.
- *
- * @param sanitizedIntent The sanitized {@link Intent} used for resolution.
- * @param hostDigestPrefix The hash prefix of the instant app's domain or null if no host is
- * defined.
- */
- public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
- String token, InstantAppResolutionCallback callback) {
- Log.e(TAG, "New onGetInstantAppIntentFilter is not overridden");
- // if not overridden, forward to old methods and filter out non-web intents
- if (sanitizedIntent.isBrowsableWebIntent()) {
- onGetInstantAppIntentFilter(hostDigestPrefix, token, callback);
- } else {
- callback.onInstantAppResolveInfo(Collections.emptyList());
- }
+ throw new IllegalStateException("Must define");
}
/**
@@ -131,8 +89,8 @@ public abstract class InstantAppResolverService extends Service {
public final IBinder onBind(Intent intent) {
return new IInstantAppResolver.Stub() {
@Override
- public void getInstantAppResolveInfoList(Intent sanitizedIntent, int[] digestPrefix,
- String token, int sequence, IRemoteCallback callback) {
+ public void getInstantAppResolveInfoList(
+ int digestPrefix[], String token, int sequence, IRemoteCallback callback) {
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "[" + token + "] Phase1 called; posting");
}
@@ -140,14 +98,14 @@ public abstract class InstantAppResolverService extends Service {
args.arg1 = callback;
args.arg2 = digestPrefix;
args.arg3 = token;
- args.arg4 = sanitizedIntent;
- mHandler.obtainMessage(ServiceHandler.MSG_GET_INSTANT_APP_RESOLVE_INFO,
- sequence, 0, args).sendToTarget();
+ mHandler.obtainMessage(
+ ServiceHandler.MSG_GET_INSTANT_APP_RESOLVE_INFO, sequence, 0, args)
+ .sendToTarget();
}
@Override
- public void getInstantAppIntentFilterList(Intent sanitizedIntent,
- int[] digestPrefix, String token, IRemoteCallback callback) {
+ public void getInstantAppIntentFilterList(
+ int digestPrefix[], String token, String hostName, IRemoteCallback callback) {
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "[" + token + "] Phase2 called; posting");
}
@@ -155,9 +113,9 @@ public abstract class InstantAppResolverService extends Service {
args.arg1 = callback;
args.arg2 = digestPrefix;
args.arg3 = token;
- args.arg4 = sanitizedIntent;
- mHandler.obtainMessage(ServiceHandler.MSG_GET_INSTANT_APP_INTENT_FILTER,
- callback).sendToTarget();
+ args.arg4 = hostName;
+ mHandler.obtainMessage(
+ ServiceHandler.MSG_GET_INSTANT_APP_INTENT_FILTER, callback).sendToTarget();
}
};
}
@@ -184,9 +142,29 @@ public abstract class InstantAppResolverService extends Service {
}
}
+ @Deprecated
+ void _onGetInstantAppResolveInfo(int[] digestPrefix, String token,
+ InstantAppResolutionCallback callback) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.d(TAG, "[" + token + "] Phase1 request;"
+ + " prefix: " + Arrays.toString(digestPrefix));
+ }
+ onGetInstantAppResolveInfo(digestPrefix, token, callback);
+ }
+ @Deprecated
+ void _onGetInstantAppIntentFilter(int digestPrefix[], String token, String hostName,
+ InstantAppResolutionCallback callback) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.d(TAG, "[" + token + "] Phase2 request;"
+ + " prefix: " + Arrays.toString(digestPrefix));
+ }
+ onGetInstantAppIntentFilter(digestPrefix, token, callback);
+ }
+
private final class ServiceHandler extends Handler {
public static final int MSG_GET_INSTANT_APP_RESOLVE_INFO = 1;
public static final int MSG_GET_INSTANT_APP_INTENT_FILTER = 2;
+
public ServiceHandler(Looper looper) {
super(looper, null /*callback*/, true /*async*/);
}
@@ -201,13 +179,9 @@ public abstract class InstantAppResolverService extends Service {
final IRemoteCallback callback = (IRemoteCallback) args.arg1;
final int[] digestPrefix = (int[]) args.arg2;
final String token = (String) args.arg3;
- final Intent intent = (Intent) args.arg4;
final int sequence = message.arg1;
- if (DEBUG_EPHEMERAL) {
- Slog.d(TAG, "[" + token + "] Phase1 request;"
- + " prefix: " + Arrays.toString(digestPrefix));
- }
- onGetInstantAppResolveInfo(intent, digestPrefix, token,
+ _onGetInstantAppResolveInfo(
+ digestPrefix, token,
new InstantAppResolutionCallback(sequence, callback));
} break;
@@ -216,12 +190,9 @@ public abstract class InstantAppResolverService extends Service {
final IRemoteCallback callback = (IRemoteCallback) args.arg1;
final int[] digestPrefix = (int[]) args.arg2;
final String token = (String) args.arg3;
- final Intent intent = (Intent) args.arg4;
- if (DEBUG_EPHEMERAL) {
- Slog.d(TAG, "[" + token + "] Phase2 request;"
- + " prefix: " + Arrays.toString(digestPrefix));
- }
- onGetInstantAppIntentFilter(intent, digestPrefix, token,
+ final String hostName = (String) args.arg4;
+ _onGetInstantAppIntentFilter(
+ digestPrefix, token, hostName,
new InstantAppResolutionCallback(-1 /*sequence*/, callback));
} break;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b3c8737a2831..e02a29494296 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -50,7 +50,6 @@ import android.provider.DocumentsContract;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
@@ -4473,15 +4472,7 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_INSTANT_APP_ACTION = "android.intent.extra.INSTANT_APP_ACTION";
/**
- * An array of {@link Bundle}s containing details about resolved instant apps..
- * @hide
- */
- @SystemApi
- public static final String EXTRA_INSTANT_APP_BUNDLES =
- "android.intent.extra.INSTANT_APP_BUNDLES";
-
- /**
- * A {@link Bundle} of metadata that describes the instant application that needs to be
+ * A {@link Bundle} of metadata that describes the instanta application that needs to be
* installed. This data is populated from the response to
* {@link android.content.pm.InstantAppResolveInfo#getExtras()} as provided by the registered
* instant application resolver.
@@ -4491,16 +4482,6 @@ public class Intent implements Parcelable, Cloneable {
"android.intent.extra.INSTANT_APP_EXTRAS";
/**
- * A boolean value indicating that the instant app resolver was unable to state with certainty
- * that it did or did not have an app for the sanitized {@link Intent} defined at
- * {@link #EXTRA_INTENT}.
- * @hide
- */
- @SystemApi
- public static final String EXTRA_UNKNOWN_INSTANT_APP =
- "android.intent.extra.UNKNOWN_INSTANT_APP";
-
- /**
* The version code of the app to install components from.
* @deprecated Use {@link #EXTRA_LONG_VERSION_CODE).
* @hide
@@ -5048,7 +5029,6 @@ public class Intent implements Parcelable, Cloneable {
FLAG_GRANT_PREFIX_URI_PERMISSION,
FLAG_DEBUG_TRIAGED_MISSING,
FLAG_IGNORE_EPHEMERAL,
- FLAG_ACTIVITY_MATCH_EXTERNAL,
FLAG_ACTIVITY_NO_HISTORY,
FLAG_ACTIVITY_SINGLE_TOP,
FLAG_ACTIVITY_NEW_TASK,
@@ -5092,7 +5072,6 @@ public class Intent implements Parcelable, Cloneable {
FLAG_INCLUDE_STOPPED_PACKAGES,
FLAG_DEBUG_TRIAGED_MISSING,
FLAG_IGNORE_EPHEMERAL,
- FLAG_ACTIVITY_MATCH_EXTERNAL,
FLAG_ACTIVITY_NO_HISTORY,
FLAG_ACTIVITY_SINGLE_TOP,
FLAG_ACTIVITY_NEW_TASK,
@@ -5496,14 +5475,6 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000;
-
- /**
- * If set, resolution of this intent may take place via an instant app not
- * yet on the device if there does not yet exist an app on device to
- * resolve it.
- */
- public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 0x00000800;
-
/**
* If set, when sending a broadcast only registered receivers will be
* called -- no BroadcastReceiver components will be launched.
@@ -10057,25 +10028,6 @@ public class Intent implements Parcelable, Cloneable {
}
}
- /** @hide */
- public boolean hasWebURI() {
- if (getData() == null) {
- return false;
- }
- final String scheme = getScheme();
- if (TextUtils.isEmpty(scheme)) {
- return false;
- }
- return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
- }
-
- /** @hide */
- public boolean isBrowsableWebIntent() {
- return ACTION_VIEW.equals(mAction)
- && hasCategory(CATEGORY_BROWSABLE)
- && hasWebURI();
- }
-
/**
* @hide
*/
diff --git a/core/java/android/content/pm/AuxiliaryResolveInfo.java b/core/java/android/content/pm/AuxiliaryResolveInfo.java
index 202df50dda6f..6bdcefbe974e 100644
--- a/core/java/android/content/pm/AuxiliaryResolveInfo.java
+++ b/core/java/android/content/pm/AuxiliaryResolveInfo.java
@@ -21,10 +21,6 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
-import android.os.Bundle;
-
-import java.util.Collections;
-import java.util.List;
/**
* Auxiliary application resolution response.
@@ -35,95 +31,56 @@ import java.util.List;
* hasn't been installed.
* @hide
*/
-public final class AuxiliaryResolveInfo {
+public final class AuxiliaryResolveInfo extends IntentFilter {
+ /** Resolved information returned from the external instant resolver */
+ public final InstantAppResolveInfo resolveInfo;
+ /** The resolved package. Copied from {@link #resolveInfo}. */
+ public final String packageName;
/** The activity to launch if there's an installation failure. */
public final ComponentName installFailureActivity;
+ /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
+ public final String splitName;
/** Whether or not instant resolution needs the second phase */
public final boolean needsPhaseTwo;
/** Opaque token to track the instant application resolution */
public final String token;
+ /** The version code of the package */
+ public final long versionCode;
/** An intent to start upon failure to install */
public final Intent failureIntent;
- /** The matching filters for this resolve info. */
- public final List<AuxiliaryFilter> filters;
/** Create a response for installing an instant application. */
- public AuxiliaryResolveInfo(@NonNull String token,
+ public AuxiliaryResolveInfo(@NonNull InstantAppResolveInfo resolveInfo,
+ @NonNull IntentFilter orig,
+ @Nullable String splitName,
+ @NonNull String token,
boolean needsPhase2,
- @Nullable Intent failureIntent,
- @Nullable List<AuxiliaryFilter> filters) {
+ @Nullable Intent failureIntent) {
+ super(orig);
+ this.resolveInfo = resolveInfo;
+ this.packageName = resolveInfo.getPackageName();
+ this.splitName = splitName;
this.token = token;
this.needsPhaseTwo = needsPhase2;
+ this.versionCode = resolveInfo.getVersionCode();
this.failureIntent = failureIntent;
- this.filters = filters;
this.installFailureActivity = null;
}
/** Create a response for installing a split on demand. */
- public AuxiliaryResolveInfo(@Nullable ComponentName failureActivity,
- @Nullable Intent failureIntent,
- @Nullable List<AuxiliaryFilter> filters) {
+ public AuxiliaryResolveInfo(@NonNull String packageName,
+ @Nullable String splitName,
+ @Nullable ComponentName failureActivity,
+ long versionCode,
+ @Nullable Intent failureIntent) {
super();
+ this.packageName = packageName;
this.installFailureActivity = failureActivity;
- this.filters = filters;
+ this.splitName = splitName;
+ this.versionCode = versionCode;
+ this.resolveInfo = null;
this.token = null;
this.needsPhaseTwo = false;
this.failureIntent = failureIntent;
}
-
- /** Create a response for installing a split on demand. */
- public AuxiliaryResolveInfo(@Nullable ComponentName failureActivity,
- String packageName, long versionCode, String splitName) {
- this(failureActivity, null, Collections.singletonList(
- new AuxiliaryResolveInfo.AuxiliaryFilter(packageName, versionCode, splitName)));
- }
-
- /** @hide */
- public static final class AuxiliaryFilter extends IntentFilter {
- /** Resolved information returned from the external instant resolver */
- public final InstantAppResolveInfo resolveInfo;
- /** The resolved package. Copied from {@link #resolveInfo}. */
- public final String packageName;
- /** The version code of the package */
- public final long versionCode;
- /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
- public final String splitName;
- /** The extras to pass on to the installer for this filter. */
- public final Bundle extras;
-
- public AuxiliaryFilter(IntentFilter orig, InstantAppResolveInfo resolveInfo,
- String splitName, Bundle extras) {
- super(orig);
- this.resolveInfo = resolveInfo;
- this.packageName = resolveInfo.getPackageName();
- this.versionCode = resolveInfo.getLongVersionCode();
- this.splitName = splitName;
- this.extras = extras;
- }
-
- public AuxiliaryFilter(InstantAppResolveInfo resolveInfo,
- String splitName, Bundle extras) {
- this.resolveInfo = resolveInfo;
- this.packageName = resolveInfo.getPackageName();
- this.versionCode = resolveInfo.getLongVersionCode();
- this.splitName = splitName;
- this.extras = extras;
- }
-
- public AuxiliaryFilter(String packageName, long versionCode, String splitName) {
- this.resolveInfo = null;
- this.packageName = packageName;
- this.versionCode = versionCode;
- this.splitName = splitName;
- this.extras = null;
- }
-
- @Override
- public String toString() {
- return "AuxiliaryFilter{"
- + "packageName='" + packageName + '\''
- + ", versionCode=" + versionCode
- + ", splitName='" + splitName + '\'' + '}';
- }
- }
} \ No newline at end of file
diff --git a/core/java/android/content/pm/InstantAppResolveInfo.java b/core/java/android/content/pm/InstantAppResolveInfo.java
index 112c5dae6731..19cb9323ba93 100644
--- a/core/java/android/content/pm/InstantAppResolveInfo.java
+++ b/core/java/android/content/pm/InstantAppResolveInfo.java
@@ -19,7 +19,6 @@ package android.content.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,35 +26,11 @@ import android.os.Parcelable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
- * Describes an externally resolvable instant application. There are three states that this class
- * can represent: <p/>
- * <ul>
- * <li>
- * The first, usable only for non http/s intents, implies that the resolver cannot
- * immediately resolve this intent and would prefer that resolution be deferred to the
- * instant app installer. Represent this state with {@link #InstantAppResolveInfo(Bundle)}.
- * If the {@link android.content.Intent} has the scheme set to http/s and a set of digest
- * prefixes were passed into one of the resolve methods in
- * {@link android.app.InstantAppResolverService}, this state cannot be used.
- * </li>
- * <li>
- * The second represents a partial match and is constructed with any of the other
- * constructors. By setting one or more of the {@link Nullable}arguments to null, you
- * communicate to the resolver in response to
- * {@link android.app.InstantAppResolverService#onGetInstantAppResolveInfo(Intent, int[],
- * String, InstantAppResolverService.InstantAppResolutionCallback)}
- * that you need a 2nd round of resolution to complete the request.
- * </li>
- * <li>
- * The third represents a complete match and is constructed with all @Nullable parameters
- * populated.
- * </li>
- * </ul>
+ * Information about an instant application.
* @hide
*/
@SystemApi
@@ -63,8 +38,6 @@ public final class InstantAppResolveInfo implements Parcelable {
/** Algorithm that will be used to generate the domain digest */
private static final String SHA_ALGORITHM = "SHA-256";
- private static final byte[] EMPTY_DIGEST = new byte[0];
-
private final InstantAppDigest mDigest;
private final String mPackageName;
/** The filters used to match domain */
@@ -73,30 +46,15 @@ public final class InstantAppResolveInfo implements Parcelable {
private final long mVersionCode;
/** Data about the app that should be passed along to the Instant App installer on resolve */
private final Bundle mExtras;
- /**
- * A flag that indicates that the resolver is aware that an app may match, but would prefer
- * that the installer get the sanitized intent to decide. This should not be used for
- * resolutions that include a host and will be ignored in such cases.
- */
- private final boolean mShouldLetInstallerDecide;
- /** Constructor for intent-based InstantApp resolution results. */
public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
@Nullable List<InstantAppIntentFilter> filters, int versionCode) {
this(digest, packageName, filters, (long) versionCode, null /* extras */);
}
- /** Constructor for intent-based InstantApp resolution results with extras. */
public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
@Nullable List<InstantAppIntentFilter> filters, long versionCode,
@Nullable Bundle extras) {
- this(digest, packageName, filters, versionCode, extras, false);
- }
-
- /** Constructor for intent-based InstantApp resolution results with extras. */
- private InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
- @Nullable List<InstantAppIntentFilter> filters, long versionCode,
- @Nullable Bundle extras, boolean shouldLetInstallerDecide) {
// validate arguments
if ((packageName == null && (filters != null && filters.size() != 0))
|| (packageName != null && (filters == null || filters.size() == 0))) {
@@ -104,7 +62,7 @@ public final class InstantAppResolveInfo implements Parcelable {
}
mDigest = digest;
if (filters != null) {
- mFilters = new ArrayList<>(filters.size());
+ mFilters = new ArrayList<InstantAppIntentFilter>(filters.size());
mFilters.addAll(filters);
} else {
mFilters = null;
@@ -112,48 +70,25 @@ public final class InstantAppResolveInfo implements Parcelable {
mPackageName = packageName;
mVersionCode = versionCode;
mExtras = extras;
- mShouldLetInstallerDecide = shouldLetInstallerDecide;
}
- /** Constructor for intent-based InstantApp resolution results by hostname. */
public InstantAppResolveInfo(@NonNull String hostName, @Nullable String packageName,
@Nullable List<InstantAppIntentFilter> filters) {
this(new InstantAppDigest(hostName), packageName, filters, -1 /*versionCode*/,
null /* extras */);
}
- /**
- * Constructor that creates a "let the installer decide" response with optional included
- * extras.
- */
- public InstantAppResolveInfo(@Nullable Bundle extras) {
- this(InstantAppDigest.UNDEFINED, null, null, -1, extras, true);
- }
-
InstantAppResolveInfo(Parcel in) {
- mShouldLetInstallerDecide = in.readBoolean();
+ mDigest = in.readParcelable(null /*loader*/);
+ mPackageName = in.readString();
+ mFilters = new ArrayList<InstantAppIntentFilter>();
+ in.readList(mFilters, null /*loader*/);
+ mVersionCode = in.readLong();
mExtras = in.readBundle();
- if (mShouldLetInstallerDecide) {
- mDigest = InstantAppDigest.UNDEFINED;
- mPackageName = null;
- mFilters = Collections.emptyList();
- mVersionCode = -1;
- } else {
- mDigest = in.readParcelable(null /*loader*/);
- mPackageName = in.readString();
- mFilters = new ArrayList<>();
- in.readList(mFilters, null /*loader*/);
- mVersionCode = in.readLong();
- }
- }
-
- /** Returns true if the installer should be notified that it should query for packages. */
- public boolean shouldLetInstallerDecide() {
- return mShouldLetInstallerDecide;
}
public byte[] getDigestBytes() {
- return mDigest.mDigestBytes.length > 0 ? mDigest.getDigestBytes()[0] : EMPTY_DIGEST;
+ return mDigest.getDigestBytes()[0];
}
public int getDigestPrefix() {
@@ -192,15 +127,11 @@ public final class InstantAppResolveInfo implements Parcelable {
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeBoolean(mShouldLetInstallerDecide);
- out.writeBundle(mExtras);
- if (mShouldLetInstallerDecide) {
- return;
- }
out.writeParcelable(mDigest, flags);
out.writeString(mPackageName);
out.writeList(mFilters);
out.writeLong(mVersionCode);
+ out.writeBundle(mExtras);
}
public static final Parcelable.Creator<InstantAppResolveInfo> CREATOR
@@ -228,9 +159,7 @@ public final class InstantAppResolveInfo implements Parcelable {
@SystemApi
public static final class InstantAppDigest implements Parcelable {
private static final int DIGEST_MASK = 0xfffff000;
-
- public static final InstantAppDigest UNDEFINED =
- new InstantAppDigest(new byte[][]{}, new int[]{});
+ private static final int DIGEST_PREFIX_COUNT = 5;
/** Full digest of the domain hashes */
private final byte[][] mDigestBytes;
/** The first 4 bytes of the domain hashes */
@@ -257,11 +186,6 @@ public final class InstantAppResolveInfo implements Parcelable {
}
}
- private InstantAppDigest(byte[][] digestBytes, int[] prefix) {
- this.mDigestPrefix = prefix;
- this.mDigestBytes = digestBytes;
- }
-
private static byte[][] generateDigest(String hostName, int maxDigests) {
ArrayList<byte[]> digests = new ArrayList<>();
try {
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 1dfff5efcab5..2ab2d20ed20d 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -103,14 +103,11 @@ public class ResolverListController {
List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
for (int i = 0, N = intents.size(); i < N; i++) {
final Intent intent = intents.get(i);
- int flags = PackageManager.MATCH_DEFAULT_ONLY
- | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
- | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0);
- if (intent.isBrowsableWebIntent()
- || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
- flags |= PackageManager.MATCH_INSTANT;
- }
- final List<ResolveInfo> infos = mpm.queryIntentActivities(intent, flags);
+ final List<ResolveInfo> infos = mpm.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY
+ | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
+ | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0)
+ | PackageManager.MATCH_INSTANT);
// Remove any activities that are not exported.
int totalSize = infos.size();
for (int j = totalSize - 1; j >= 0 ; j--) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index bf3882587693..6beafcb94ead 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1251,14 +1251,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
synchronized (mService) {
try {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "resolveIntent");
- int modifiedFlags = flags
- | PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS;
- if (intent.isBrowsableWebIntent()
- || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
- modifiedFlags |= PackageManager.MATCH_INSTANT;
- }
return mService.getPackageManagerInternalLocked().resolveIntent(
- intent, resolvedType, modifiedFlags, userId, true);
+ intent, resolvedType, PackageManager.MATCH_INSTANT
+ | PackageManager.MATCH_DEFAULT_ONLY | flags
+ | ActivityManagerService.STOCK_PM_FLAGS, userId, true);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index eab88aa45e44..8fd754af1a0f 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -31,7 +31,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
@@ -790,7 +789,7 @@ class ActivityStarter {
// Instead, launch the ephemeral installer. Once the installer is finished, it
// starts either the intent we resolved here [on install error] or the ephemeral
// app [on install success].
- if (rInfo != null && rInfo.isInstantAppAvailable) {
+ if (rInfo != null && rInfo.auxiliaryInfo != null) {
intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
callingPackage, verificationBundle, resolvedType, userId);
resolvedType = null;
@@ -850,27 +849,22 @@ class ActivityStarter {
/**
* Creates a launch intent for the given auxiliary resolution data.
*/
- private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
+ private @NonNull Intent createLaunchIntent(@NonNull AuxiliaryResolveInfo auxiliaryResponse,
Intent originalIntent, String callingPackage, Bundle verificationBundle,
String resolvedType, int userId) {
- if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
+ if (auxiliaryResponse.needsPhaseTwo) {
// request phase two resolution
mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
auxiliaryResponse, originalIntent, resolvedType, callingPackage,
verificationBundle, userId);
}
return InstantAppResolver.buildEphemeralInstallerIntent(
- originalIntent,
- InstantAppResolver.sanitizeIntent(originalIntent),
- auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
- callingPackage,
- verificationBundle,
- resolvedType,
- userId,
- auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
- auxiliaryResponse == null ? null : auxiliaryResponse.token,
- auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
- auxiliaryResponse == null ? null : auxiliaryResponse.filters);
+ Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE, originalIntent,
+ auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
+ resolvedType, userId, auxiliaryResponse.packageName, auxiliaryResponse.splitName,
+ auxiliaryResponse.installFailureActivity, auxiliaryResponse.versionCode,
+ auxiliaryResponse.token, auxiliaryResponse.resolveInfo.getExtras(),
+ auxiliaryResponse.needsPhaseTwo);
}
void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
@@ -930,12 +924,12 @@ class ActivityStarter {
// Don't modify the client's object!
intent = new Intent(intent);
if (componentSpecified
- && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
- && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
+ && intent.getData() != null
+ && Intent.ACTION_VIEW.equals(intent.getAction())
&& mService.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
// intercept intents targeted directly to the ephemeral installer the
- // ephemeral installer should never be started with a raw Intent; instead
+ // ephemeral installer should never be started with a raw URL; instead
// adjust the intent so it looks like a "normal" instant app launch
intent.setComponent(null /*component*/);
componentSpecified = false;
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 6d6c960eed7e..b5ddf8c511f1 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -43,7 +43,6 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeoutException;
@@ -85,8 +84,8 @@ final class EphemeralResolverConnection implements DeathRecipient {
mIntent = new Intent(action).setComponent(componentName);
}
- public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(Intent sanitizedIntent,
- int hashPrefix[], String token) throws ConnectionException {
+ public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[],
+ String token) throws ConnectionException {
throwIfCalledOnMainThread();
IInstantAppResolver target = null;
try {
@@ -99,7 +98,7 @@ final class EphemeralResolverConnection implements DeathRecipient {
}
try {
return mGetEphemeralResolveInfoCaller
- .getEphemeralResolveInfoList(target, sanitizedIntent, hashPrefix, token);
+ .getEphemeralResolveInfoList(target, hashPrefix, token);
} catch (TimeoutException e) {
throw new ConnectionException(ConnectionException.FAILURE_CALL);
} catch (RemoteException ignore) {
@@ -112,22 +111,26 @@ final class EphemeralResolverConnection implements DeathRecipient {
return null;
}
- public final void getInstantAppIntentFilterList(Intent sanitizedIntent, int hashPrefix[],
- String token, PhaseTwoCallback callback, Handler callbackHandler, final long startTime)
- throws ConnectionException {
+ public final void getInstantAppIntentFilterList(int hashPrefix[], String token,
+ String hostName, PhaseTwoCallback callback, Handler callbackHandler,
+ final long startTime) throws ConnectionException {
final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) throws RemoteException {
final ArrayList<InstantAppResolveInfo> resolveList =
data.getParcelableArrayList(
InstantAppResolverService.EXTRA_RESOLVE_INFO);
- callbackHandler.post(() -> callback.onPhaseTwoResolved(resolveList, startTime));
+ callbackHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onPhaseTwoResolved(resolveList, startTime);
+ }
+ });
}
};
try {
getRemoteInstanceLazy(token)
- .getInstantAppIntentFilterList(sanitizedIntent, hashPrefix, token,
- remoteCallback);
+ .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback);
} catch (TimeoutException e) {
throw new ConnectionException(ConnectionException.FAILURE_BIND);
} catch (InterruptedException e) {
@@ -334,11 +337,10 @@ final class EphemeralResolverConnection implements DeathRecipient {
}
public List<InstantAppResolveInfo> getEphemeralResolveInfoList(
- IInstantAppResolver target, Intent sanitizedIntent, int hashPrefix[], String token)
+ IInstantAppResolver target, int hashPrefix[], String token)
throws RemoteException, TimeoutException {
final int sequence = onBeforeRemoteCall();
- target.getInstantAppResolveInfoList(sanitizedIntent, hashPrefix, token, sequence,
- mCallback);
+ target.getInstantAppResolveInfoList(hashPrefix, token, sequence, mCallback);
return getResultTimed(sequence);
}
}
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 55212cc6b3d8..30072d45ccab 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -40,14 +40,11 @@ import android.content.pm.InstantAppIntentFilter;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
import android.metrics.LogMaker;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -56,12 +53,8 @@ import com.android.server.pm.EphemeralResolverConnection.PhaseTwoCallback;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.UUID;
/** @hide */
@@ -86,7 +79,6 @@ public abstract class InstantAppResolver {
public @interface ResolutionStatus {}
private static MetricsLogger sMetricsLogger;
-
private static MetricsLogger getLogger() {
if (sMetricsLogger == null) {
sMetricsLogger = new MetricsLogger();
@@ -94,49 +86,26 @@ public abstract class InstantAppResolver {
return sMetricsLogger;
}
- /**
- * Returns an intent with potential PII removed from the original intent. Fields removed
- * include extras and the host + path of the data, if defined.
- */
- public static Intent sanitizeIntent(Intent origIntent) {
- final Intent sanitizedIntent;
- sanitizedIntent = new Intent(origIntent.getAction());
- Set<String> categories = origIntent.getCategories();
- if (categories != null) {
- for (String category : categories) {
- sanitizedIntent.addCategory(category);
- }
- }
- Uri sanitizedUri = origIntent.getData() == null
- ? null
- : Uri.fromParts(origIntent.getScheme(), "", "");
- sanitizedIntent.setDataAndType(sanitizedUri, origIntent.getType());
- sanitizedIntent.addFlags(origIntent.getFlags());
- sanitizedIntent.setPackage(origIntent.getPackage());
- return sanitizedIntent;
- }
-
- public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(
+ public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context,
EphemeralResolverConnection connection, InstantAppRequest requestObj) {
final long startTime = System.currentTimeMillis();
final String token = UUID.randomUUID().toString();
if (DEBUG_EPHEMERAL) {
Log.d(TAG, "[" + token + "] Phase1; resolving");
}
- final Intent origIntent = requestObj.origIntent;
- final Intent sanitizedIntent = sanitizeIntent(origIntent);
-
- final InstantAppDigest digest = getInstantAppDigest(origIntent);
+ final Intent intent = requestObj.origIntent;
+ final InstantAppDigest digest =
+ new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/);
final int[] shaPrefix = digest.getDigestPrefix();
AuxiliaryResolveInfo resolveInfo = null;
@ResolutionStatus int resolutionStatus = RESOLUTION_SUCCESS;
try {
final List<InstantAppResolveInfo> instantAppResolveInfoList =
- connection.getInstantAppResolveInfoList(sanitizedIntent, shaPrefix, token);
+ connection.getInstantAppResolveInfoList(shaPrefix, token);
if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
resolveInfo = InstantAppResolver.filterInstantAppIntent(
- instantAppResolveInfoList, origIntent, requestObj.resolvedType,
- requestObj.userId, origIntent.getPackage(), digest, token);
+ instantAppResolveInfoList, intent, requestObj.resolvedType,
+ requestObj.userId, intent.getPackage(), digest, token);
}
} catch (ConnectionException e) {
if (e.failure == ConnectionException.FAILURE_BIND) {
@@ -166,12 +135,6 @@ public abstract class InstantAppResolver {
return resolveInfo;
}
- private static InstantAppDigest getInstantAppDigest(Intent origIntent) {
- return origIntent.getData() != null && !TextUtils.isEmpty(origIntent.getData().getHost())
- ? new InstantAppDigest(origIntent.getData().getHost(), 5 /*maxDigests*/)
- : InstantAppDigest.UNDEFINED;
- }
-
public static void doInstantAppResolutionPhaseTwo(Context context,
EphemeralResolverConnection connection, InstantAppRequest requestObj,
ActivityInfo instantAppInstaller, Handler callbackHandler) {
@@ -180,53 +143,73 @@ public abstract class InstantAppResolver {
if (DEBUG_EPHEMERAL) {
Log.d(TAG, "[" + token + "] Phase2; resolving");
}
- final Intent origIntent = requestObj.origIntent;
- final Intent sanitizedIntent = sanitizeIntent(origIntent);
- final InstantAppDigest digest = getInstantAppDigest(origIntent);
+ final Intent intent = requestObj.origIntent;
+ final String hostName = intent.getData().getHost();
+ final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/);
final int[] shaPrefix = digest.getDigestPrefix();
final PhaseTwoCallback callback = new PhaseTwoCallback() {
@Override
void onPhaseTwoResolved(List<InstantAppResolveInfo> instantAppResolveInfoList,
long startTime) {
+ final String packageName;
+ final String splitName;
+ final long versionCode;
final Intent failureIntent;
+ final Bundle extras;
if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
final AuxiliaryResolveInfo instantAppIntentInfo =
InstantAppResolver.filterInstantAppIntent(
- instantAppResolveInfoList, origIntent, null /*resolvedType*/,
- 0 /*userId*/, origIntent.getPackage(), digest, token);
- if (instantAppIntentInfo != null) {
+ instantAppResolveInfoList, intent, null /*resolvedType*/,
+ 0 /*userId*/, intent.getPackage(), digest, token);
+ if (instantAppIntentInfo != null
+ && instantAppIntentInfo.resolveInfo != null) {
+ packageName = instantAppIntentInfo.resolveInfo.getPackageName();
+ splitName = instantAppIntentInfo.splitName;
+ versionCode = instantAppIntentInfo.resolveInfo.getVersionCode();
failureIntent = instantAppIntentInfo.failureIntent;
+ extras = instantAppIntentInfo.resolveInfo.getExtras();
} else {
+ packageName = null;
+ splitName = null;
+ versionCode = -1;
failureIntent = null;
+ extras = null;
}
} else {
+ packageName = null;
+ splitName = null;
+ versionCode = -1;
failureIntent = null;
+ extras = null;
}
final Intent installerIntent = buildEphemeralInstallerIntent(
+ Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE,
requestObj.origIntent,
- sanitizedIntent,
failureIntent,
requestObj.callingPackage,
requestObj.verificationBundle,
requestObj.resolvedType,
requestObj.userId,
+ packageName,
+ splitName,
requestObj.responseObj.installFailureActivity,
+ versionCode,
token,
- false /*needsPhaseTwo*/,
- requestObj.responseObj.filters);
+ extras,
+ false /*needsPhaseTwo*/);
installerIntent.setComponent(new ComponentName(
instantAppInstaller.packageName, instantAppInstaller.name));
logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO, startTime, token,
- requestObj.responseObj.filters != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);
+ packageName != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);
context.startActivity(installerIntent);
}
};
try {
- connection.getInstantAppIntentFilterList(sanitizedIntent, shaPrefix, token, callback,
- callbackHandler, startTime);
+ connection.getInstantAppIntentFilterList(
+ shaPrefix, token, hostName, callback, callbackHandler, startTime);
} catch (ConnectionException e) {
@ResolutionStatus int resolutionStatus = RESOLUTION_FAILURE;
if (e.failure == ConnectionException.FAILURE_BIND) {
@@ -248,20 +231,23 @@ public abstract class InstantAppResolver {
* Builds and returns an intent to launch the instant installer.
*/
public static Intent buildEphemeralInstallerIntent(
+ @NonNull String action,
@NonNull Intent origIntent,
- @NonNull Intent sanitizedIntent,
- @Nullable Intent failureIntent,
+ @NonNull Intent failureIntent,
@NonNull String callingPackage,
@Nullable Bundle verificationBundle,
@NonNull String resolvedType,
int userId,
+ @NonNull String instantAppPackageName,
+ @Nullable String instantAppSplitName,
@Nullable ComponentName installFailureActivity,
+ long versionCode,
@Nullable String token,
- boolean needsPhaseTwo,
- List<AuxiliaryResolveInfo.AuxiliaryFilter> filters) {
+ @Nullable Bundle extras,
+ boolean needsPhaseTwo) {
// Construct the intent that launches the instant installer
int flags = origIntent.getFlags();
- final Intent intent = new Intent();
+ final Intent intent = new Intent(action);
intent.setFlags(flags
| Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK
@@ -274,23 +260,20 @@ public abstract class InstantAppResolver {
intent.putExtra(Intent.EXTRA_EPHEMERAL_HOSTNAME, origIntent.getData().getHost());
}
intent.putExtra(Intent.EXTRA_INSTANT_APP_ACTION, origIntent.getAction());
- intent.putExtra(Intent.EXTRA_INTENT, sanitizedIntent);
+ if (extras != null) {
+ intent.putExtra(Intent.EXTRA_INSTANT_APP_EXTRAS, extras);
+ }
- if (needsPhaseTwo) {
- intent.setAction(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
- } else {
- // We have all of the data we need; just start the installer without a second phase
+ // We have all of the data we need; just start the installer without a second phase
+ if (!needsPhaseTwo) {
+ // Intent that is launched if the package couldn't be installed for any reason.
if (failureIntent != null || installFailureActivity != null) {
- // Intent that is launched if the package couldn't be installed for any reason.
try {
final Intent onFailureIntent;
if (installFailureActivity != null) {
onFailureIntent = new Intent();
onFailureIntent.setComponent(installFailureActivity);
- if (filters != null && filters.size() == 1) {
- onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME,
- filters.get(0).splitName);
- }
+ onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
onFailureIntent.putExtra(Intent.EXTRA_INTENT, origIntent);
} else {
onFailureIntent = failureIntent;
@@ -326,35 +309,17 @@ public abstract class InstantAppResolver {
intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS,
new IntentSender(successIntentTarget));
} catch (RemoteException ignore) { /* ignore; same process */ }
+
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, instantAppPackageName);
+ intent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
+ intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) (versionCode & 0x7fffffff));
+ intent.putExtra(Intent.EXTRA_LONG_VERSION_CODE, versionCode);
+ intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
if (verificationBundle != null) {
intent.putExtra(Intent.EXTRA_VERIFICATION_BUNDLE, verificationBundle);
}
- intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
-
- if (filters != null) {
- Bundle resolvableFilters[] = new Bundle[filters.size()];
- for (int i = 0, max = filters.size(); i < max; i++) {
- Bundle resolvableFilter = new Bundle();
- AuxiliaryResolveInfo.AuxiliaryFilter filter = filters.get(i);
- resolvableFilter.putBoolean(Intent.EXTRA_UNKNOWN_INSTANT_APP,
- filter.resolveInfo != null
- && filter.resolveInfo.shouldLetInstallerDecide());
- resolvableFilter.putString(Intent.EXTRA_PACKAGE_NAME, filter.packageName);
- resolvableFilter.putString(Intent.EXTRA_SPLIT_NAME, filter.splitName);
- resolvableFilter.putLong(Intent.EXTRA_LONG_VERSION_CODE, filter.versionCode);
- resolvableFilter.putBundle(Intent.EXTRA_INSTANT_APP_EXTRAS, filter.extras);
- resolvableFilters[i] = resolvableFilter;
- if (i == 0) {
- // for backwards compat, always set the first result on the intent and add
- // the int version code
- intent.putExtras(resolvableFilter);
- intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) filter.versionCode);
- }
- }
- intent.putExtra(Intent.EXTRA_INSTANT_APP_BUNDLES, resolvableFilters);
- }
- intent.setAction(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
}
+
return intent;
}
@@ -365,131 +330,66 @@ public abstract class InstantAppResolver {
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
final Intent failureIntent = new Intent(origIntent);
- boolean requiresSecondPhase = false;
failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
failureIntent.setLaunchToken(token);
- ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
- boolean isWebIntent = origIntent.isBrowsableWebIntent();
- for (InstantAppResolveInfo instantAppResolveInfo : instantAppResolveInfoList) {
- if (shaPrefix.length > 0 && instantAppResolveInfo.shouldLetInstallerDecide()) {
- Slog.e(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest"
- + " provided; ignoring");
- continue;
- }
- byte[] filterDigestBytes = instantAppResolveInfo.getDigestBytes();
- // Only include matching digests if we have a prefix and we're either dealing with a
- // web intent or the resolveInfo specifies digest details.
- if (shaPrefix.length > 0 && (isWebIntent || filterDigestBytes.length > 0)) {
- boolean matchFound = false;
- // Go in reverse order so we match the narrowest scope first.
- for (int i = shaPrefix.length - 1; i >= 0; --i) {
- if (Arrays.equals(digestBytes[i], filterDigestBytes)) {
- matchFound = true;
- break;
- }
- }
- if (!matchFound) {
+ // Go in reverse order so we match the narrowest scope first.
+ for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
+ for (InstantAppResolveInfo instantAppInfo : instantAppResolveInfoList) {
+ if (!Arrays.equals(digestBytes[i], instantAppInfo.getDigestBytes())) {
continue;
}
- }
- // We matched a resolve info; resolve the filters to see if anything matches completely.
- List<AuxiliaryResolveInfo.AuxiliaryFilter> matchFilters = computeResolveFilters(
- origIntent, resolvedType, userId, packageName, token, instantAppResolveInfo);
- if (matchFilters != null) {
- if (matchFilters.isEmpty()) {
- requiresSecondPhase = true;
+ if (packageName != null
+ && !packageName.equals(instantAppInfo.getPackageName())) {
+ continue;
}
- if (filters == null) {
- filters = new ArrayList<>(matchFilters);
- } else {
- filters.addAll(matchFilters);
+ final List<InstantAppIntentFilter> instantAppFilters =
+ instantAppInfo.getIntentFilters();
+ // No filters; we need to start phase two
+ if (instantAppFilters == null || instantAppFilters.isEmpty()) {
+ if (DEBUG_EPHEMERAL) {
+ Log.d(TAG, "No app filters; go to phase 2");
+ }
+ return new AuxiliaryResolveInfo(instantAppInfo,
+ new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
+ null /*splitName*/, token, true /*needsPhase2*/,
+ null /*failureIntent*/);
}
- }
- }
- if (filters != null && !filters.isEmpty()) {
- return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters);
- }
- // Hash or filter mis-match; no instant apps for this domain.
- return null;
- }
-
- /**
- * Returns one of three states: <p/>
- * <ul>
- * <li>{@code null} if there are no matches will not be; resolution is unnecessary.</li>
- * <li>An empty list signifying that a 2nd phase of resolution is required.</li>
- * <li>A populated list meaning that matches were found and should be sent directly to the
- * installer</li>
- * </ul>
- *
- */
- private static List<AuxiliaryResolveInfo.AuxiliaryFilter> computeResolveFilters(
- Intent origIntent, String resolvedType, int userId, String packageName, String token,
- InstantAppResolveInfo instantAppInfo) {
- if (instantAppInfo.shouldLetInstallerDecide()) {
- return Collections.singletonList(
- new AuxiliaryResolveInfo.AuxiliaryFilter(
- instantAppInfo, null /* splitName */,
- instantAppInfo.getExtras()));
- }
- if (packageName != null
- && !packageName.equals(instantAppInfo.getPackageName())) {
- return null;
- }
- final List<InstantAppIntentFilter> instantAppFilters =
- instantAppInfo.getIntentFilters();
- if (instantAppFilters == null || instantAppFilters.isEmpty()) {
- // No filters on web intent; no matches, 2nd phase unnecessary.
- if (origIntent.isBrowsableWebIntent()) {
- return null;
- }
- // No filters; we need to start phase two
- if (DEBUG_EPHEMERAL) {
- Log.d(TAG, "No app filters; go to phase 2");
- }
- return Collections.emptyList();
- }
- final PackageManagerService.EphemeralIntentResolver instantAppResolver =
- new PackageManagerService.EphemeralIntentResolver();
- for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
- final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
- final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
- if (splitFilters == null || splitFilters.isEmpty()) {
- continue;
- }
- for (int k = splitFilters.size() - 1; k >= 0; --k) {
- IntentFilter filter = splitFilters.get(k);
- Iterator<IntentFilter.AuthorityEntry> authorities =
- filter.authoritiesIterator();
- // ignore http/s-only filters.
- if ((authorities == null || !authorities.hasNext())
- && (filter.hasDataScheme("http") || filter.hasDataScheme("https"))
- && filter.hasAction(Intent.ACTION_VIEW)
- && filter.hasCategory(Intent.CATEGORY_BROWSABLE)) {
- continue;
+ // We have a domain match; resolve the filters to see if anything matches.
+ final PackageManagerService.EphemeralIntentResolver instantAppResolver =
+ new PackageManagerService.EphemeralIntentResolver();
+ for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
+ final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
+ final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
+ if (splitFilters == null || splitFilters.isEmpty()) {
+ continue;
+ }
+ for (int k = splitFilters.size() - 1; k >= 0; --k) {
+ final AuxiliaryResolveInfo intentInfo =
+ new AuxiliaryResolveInfo(instantAppInfo,
+ splitFilters.get(k), instantAppFilter.getSplitName(),
+ token, false /*needsPhase2*/, failureIntent);
+ instantAppResolver.addFilter(intentInfo);
+ }
}
- instantAppResolver.addFilter(
- new AuxiliaryResolveInfo.AuxiliaryFilter(
- filter,
- instantAppInfo,
- instantAppFilter.getSplitName(),
- instantAppInfo.getExtras()
- ));
- }
- }
- List<AuxiliaryResolveInfo.AuxiliaryFilter> matchedResolveInfoList =
- instantAppResolver.queryIntent(
+ List<AuxiliaryResolveInfo> matchedResolveInfoList = instantAppResolver.queryIntent(
origIntent, resolvedType, false /*defaultOnly*/, userId);
- if (!matchedResolveInfoList.isEmpty()) {
- if (DEBUG_EPHEMERAL) {
- Log.d(TAG, "[" + token + "] Found match(es); " + matchedResolveInfoList);
+ if (!matchedResolveInfoList.isEmpty()) {
+ if (DEBUG_EPHEMERAL) {
+ final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0);
+ Log.d(TAG, "[" + token + "] Found match;"
+ + " package: " + info.packageName
+ + ", split: " + info.splitName
+ + ", versionCode: " + info.versionCode);
+ }
+ return matchedResolveInfoList.get(0);
+ } else if (DEBUG_EPHEMERAL) {
+ Log.d(TAG, "[" + token + "] No matches found"
+ + " package: " + instantAppInfo.getPackageName()
+ + ", versionCode: " + instantAppInfo.getVersionCode());
+ }
}
- return matchedResolveInfoList;
- } else if (DEBUG_EPHEMERAL) {
- Log.d(TAG, "[" + token + "] No matches found"
- + " package: " + instantAppInfo.getPackageName()
- + ", versionCode: " + instantAppInfo.getVersionCode());
}
+ // Hash or filter mis-match; no instant apps for this domain.
return null;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 18c5ffdc2ff5..c6b55cc1d555 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3595,35 +3595,24 @@ Slog.e("TODD",
}
private @Nullable ActivityInfo getInstantAppInstallerLPr() {
- String[] orderedActions = Build.IS_ENG
- ? new String[]{
- Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
- Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
- Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE}
- : new String[]{
- Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
- Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE};
+ final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
final int resolveFlags =
MATCH_DIRECT_BOOT_AWARE
- | MATCH_DIRECT_BOOT_UNAWARE
- | Intent.FLAG_IGNORE_EPHEMERAL
- | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
- final Intent intent = new Intent();
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
- List<ResolveInfo> matches = null;
- for (String action : orderedActions) {
- intent.setAction(action);
+ | MATCH_DIRECT_BOOT_UNAWARE
+ | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
+ List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
+ resolveFlags, UserHandle.USER_SYSTEM);
+ // temporarily look for the old action
+ if (matches.isEmpty()) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
+ }
+ intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
resolveFlags, UserHandle.USER_SYSTEM);
- if (matches.isEmpty()) {
- if (DEBUG_EPHEMERAL) {
- Slog.d(TAG, "Instant App installer not found with " + action);
- }
- } else {
- break;
- }
}
Iterator<ResolveInfo> iter = matches.iterator();
while (iter.hasNext()) {
@@ -3631,8 +3620,7 @@ Slog.e("TODD",
final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
if (ps != null) {
final PermissionsState permissionsState = ps.getPermissionsState();
- if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
- || Build.IS_ENG) {
+ if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
continue;
}
}
@@ -4791,7 +4779,10 @@ Slog.e("TODD",
flags |= PackageManager.MATCH_INSTANT;
} else {
final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
- final boolean allowMatchInstant = wantInstantApps
+ final boolean allowMatchInstant =
+ (wantInstantApps
+ && Intent.ACTION_VIEW.equals(intent.getAction())
+ && hasWebURI(intent))
|| (wantMatchInstant && canViewInstantApps(callingUid, userId));
flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
| PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
@@ -5981,14 +5972,8 @@ Slog.e("TODD",
if (!skipPackageCheck && intent.getPackage() != null) {
return false;
}
- if (!intent.isBrowsableWebIntent()) {
- // for non web intents, we should not resolve externally if an app already exists to
- // handle it or if the caller didn't explicitly request it.
- if ((resolvedActivities != null && resolvedActivities.size() != 0)
- || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
- return false;
- }
- } else if (intent.getData() == null) {
+ final boolean isWebUri = hasWebURI(intent);
+ if (!isWebUri || intent.getData().getHost() == null) {
return false;
}
// Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
@@ -6386,7 +6371,7 @@ Slog.e("TODD",
if (matches.get(i).getTargetUserId() == targetUserId) return true;
}
}
- if (intent.hasWebURI()) {
+ if (hasWebURI(intent)) {
// cross-profile app linking works only towards the parent.
final int callingUid = Binder.getCallingUid();
final UserInfo parent = getProfileParent(sourceUserId);
@@ -6561,7 +6546,7 @@ Slog.e("TODD",
sortResult = true;
}
}
- if (intent.hasWebURI()) {
+ if (hasWebURI(intent)) {
CrossProfileDomainInfo xpDomainInfo = null;
final UserInfo parent = getProfileParent(userId);
if (parent != null) {
@@ -6647,6 +6632,7 @@ Slog.e("TODD",
if (ps.getInstantApp(userId)) {
final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
final int status = (int)(packedStatus >> 32);
+ final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
// there's a local instant application installed, but, the user has
// chosen to never use it; skip resolution and don't acknowledge
@@ -6678,8 +6664,9 @@ Slog.e("TODD",
null /*responseObj*/, intent /*origIntent*/, resolvedType,
null /*callingPackage*/, userId, null /*verificationBundle*/,
resolveForStart);
- auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
- mInstantAppResolverConnection, requestObject);
+ auxiliaryResponse =
+ InstantAppResolver.doInstantAppResolutionPhaseOne(
+ mContext, mInstantAppResolverConnection, requestObject);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
} else {
// we have an instant application locally, but, we can't admit that since
@@ -6688,40 +6675,35 @@ Slog.e("TODD",
// instant application available externally. when it comes time to start
// the instant application, we'll do the right thing.
final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
- auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
- ai.packageName, ai.versionCode, null /* splitName */);
+ auxiliaryResponse = new AuxiliaryResolveInfo(
+ ai.packageName, null /*splitName*/, null /*failureActivity*/,
+ ai.versionCode, null /*failureIntent*/);
}
}
- if (intent.isBrowsableWebIntent() && auxiliaryResponse == null) {
- return result;
- }
- final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
- if (ps == null) {
- return result;
- }
- final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
- ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
- mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
- ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
- | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
- // add a non-generic filter
- ephemeralInstaller.filter = new IntentFilter();
- if (intent.getAction() != null) {
- ephemeralInstaller.filter.addAction(intent.getAction());
- }
- if (intent.getData() != null && intent.getData().getPath() != null) {
- ephemeralInstaller.filter.addDataPath(
- intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
- }
- ephemeralInstaller.isInstantAppAvailable = true;
- // make sure this resolver is the default
- ephemeralInstaller.isDefault = true;
- ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
- if (DEBUG_EPHEMERAL) {
- Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+ if (auxiliaryResponse != null) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+ }
+ final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
+ final PackageSetting ps =
+ mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
+ if (ps != null) {
+ ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
+ mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
+ ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
+ ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
+ // make sure this resolver is the default
+ ephemeralInstaller.isDefault = true;
+ ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+ | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+ // add a non-generic filter
+ ephemeralInstaller.filter = new IntentFilter(intent.getAction());
+ ephemeralInstaller.filter.addDataPath(
+ intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
+ ephemeralInstaller.isInstantAppAvailable = true;
+ result.add(ephemeralInstaller);
+ }
}
-
- result.add(ephemeralInstaller);
return result;
}
@@ -6836,11 +6818,10 @@ Slog.e("TODD",
final ResolveInfo info = resolveInfos.get(i);
// allow activities that are defined in the provided package
if (allowDynamicSplits
- && info.activityInfo != null
&& info.activityInfo.splitName != null
&& !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
info.activityInfo.splitName)) {
- if (mInstantAppInstallerActivity == null) {
+ if (mInstantAppInstallerInfo == null) {
if (DEBUG_INSTALL) {
Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
}
@@ -6852,15 +6833,14 @@ Slog.e("TODD",
if (DEBUG_INSTALL) {
Slog.v(TAG, "Adding installer to the ResolveInfo list");
}
- final ResolveInfo installerInfo = new ResolveInfo(
- mInstantAppInstallerInfo);
+ final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
final ComponentName installFailureActivity = findInstallFailureActivity(
info.activityInfo.packageName, filterCallingUid, userId);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
+ info.activityInfo.packageName, info.activityInfo.splitName,
installFailureActivity,
- info.activityInfo.packageName,
info.activityInfo.applicationInfo.versionCode,
- info.activityInfo.splitName);
+ null /*failureIntent*/);
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
@@ -6877,7 +6857,6 @@ Slog.e("TODD",
installerInfo.priority = info.priority;
installerInfo.preferredOrder = info.preferredOrder;
installerInfo.isDefault = info.isDefault;
- installerInfo.isInstantAppAvailable = true;
resolveInfos.set(i, installerInfo);
continue;
}
@@ -6935,6 +6914,17 @@ Slog.e("TODD",
return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
}
+ private static boolean hasWebURI(Intent intent) {
+ if (intent.getData() == null) {
+ return false;
+ }
+ final String scheme = intent.getScheme();
+ if (TextUtils.isEmpty(scheme)) {
+ return false;
+ }
+ return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
+ }
+
private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
int userId) {
@@ -7607,13 +7597,11 @@ Slog.e("TODD",
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
- final ResolveInfo installerInfo = new ResolveInfo(
- mInstantAppInstallerInfo);
+ final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
- null /* installFailureActivity */,
- info.serviceInfo.packageName,
- info.serviceInfo.applicationInfo.versionCode,
- info.serviceInfo.splitName);
+ info.serviceInfo.packageName, info.serviceInfo.splitName,
+ null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
+ null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7729,13 +7717,11 @@ Slog.e("TODD",
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
- final ResolveInfo installerInfo = new ResolveInfo(
- mInstantAppInstallerInfo);
+ final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
- null /*failureActivity*/,
- info.providerInfo.packageName,
- info.providerInfo.applicationInfo.versionCode,
- info.providerInfo.splitName);
+ info.providerInfo.packageName, info.providerInfo.splitName,
+ null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
+ null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -11777,7 +11763,7 @@ Slog.e("TODD",
mInstantAppInstallerActivity.exported = true;
mInstantAppInstallerActivity.enabled = true;
mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
- mInstantAppInstallerInfo.priority = 1;
+ mInstantAppInstallerInfo.priority = 0;
mInstantAppInstallerInfo.preferredOrder = 1;
mInstantAppInstallerInfo.isDefault = true;
mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -13227,8 +13213,7 @@ Slog.e("TODD",
}
static final class EphemeralIntentResolver
- extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
- AuxiliaryResolveInfo.AuxiliaryFilter> {
+ extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
/**
* The result that has the highest defined order. Ordering applies on a
* per-package basis. Mapping is from package name to Pair of order and
@@ -13243,19 +13228,18 @@ Slog.e("TODD",
final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
@Override
- protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
- return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
+ protected AuxiliaryResolveInfo[] newArray(int size) {
+ return new AuxiliaryResolveInfo[size];
}
@Override
- protected boolean isPackageForFilter(String packageName,
- AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
+ protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
return true;
}
@Override
- protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
- AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
+ protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
+ int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
@@ -13276,7 +13260,7 @@ Slog.e("TODD",
}
@Override
- protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
+ protected void filterResults(List<AuxiliaryResolveInfo> results) {
// only do work if ordering is enabled [most of the time it won't be]
if (mOrderResult.size() == 0) {
return;