Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7440f177 authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Fix ephemeral post-install launching

Provide the ephemeral installer with some additional pieces of information:
1) instead of de-referencing the URL a second time, give the installer the
   exact package name
2) instead of relying on ephemeral apps to define verified links, give the
   installer a pending intent to launch when the ephemeral is installed
3) give the installer a pending intent to launch if the installer fails,
   for whatever reason, to install the ephemeral app

Bug: 25119046
Change-Id: I45f50481caee09d5d09451e4b2492e64b0faae82
parent c14fb58d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -8701,6 +8701,8 @@ package android.content {
    field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
    field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
    field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
    field public static final java.lang.String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
    field public static final java.lang.String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";
    field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
    field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
    field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
@@ -9449,6 +9451,18 @@ package android.content.pm {
    field protected static final java.lang.String TAG = "ContainerEncryptionParams";
  }
  public final class EphemeralResolveInfo implements android.os.Parcelable {
    ctor public EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>);
    method public int describeContents();
    method public byte[] getDigestBytes();
    method public int getDigestPrefix();
    method public java.util.List<android.content.IntentFilter> getFilters();
    method public java.lang.String getPackageName();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralResolveInfo> CREATOR;
    field public static final java.lang.String SHA_ALGORITHM = "SHA-256";
  }
  public final class FeatureGroupInfo implements android.os.Parcelable {
    ctor public FeatureGroupInfo();
    ctor public FeatureGroupInfo(android.content.pm.FeatureGroupInfo);
+14 −0
Original line number Diff line number Diff line
@@ -3686,6 +3686,20 @@ public class Intent implements Parcelable, Cloneable {
     */
    public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";

    /**
     * A {@link IntentSender} to start after ephemeral installation success.
     * @hide
     */
    @SystemApi
    public static final String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";

    /**
     * A {@link IntentSender} to start after ephemeral installation failure.
     * @hide
     */
    @SystemApi
    public static final String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";

    /**
     * A Bundle forming a mapping of potential target package names to different extras Bundles
     * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
+59 −33
Original line number Diff line number Diff line
@@ -14,8 +14,10 @@
 * limitations under the License.
 */

package com.android.internal.app;
package android.content.pm;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Parcel;
@@ -27,22 +29,47 @@ import java.util.ArrayList;
import java.util.List;

/**
 * Information that is returned when resolving ephemeral
 * applications.
 * Information about an ephemeral application.
 * @hide
 */
@SystemApi
public final class EphemeralResolveInfo implements Parcelable {
    /** Algorithm that will be used to generate the domain digest */
    public static final String SHA_ALGORITHM = "SHA-256";
    private byte[] mDigestBytes;
    private int mDigestPrefix;

    /** Full digest of the domain hash */
    private final byte[] mDigestBytes;
    /** The first 4 bytes of the domain hash */
    private final int mDigestPrefix;
    private final String mPackageName;
    /** The filters used to match domain */
    private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>();

    public EphemeralResolveInfo(Uri uri, List<IntentFilter> filters) {
        generateDigest(uri);
    public EphemeralResolveInfo(@NonNull Uri uri, @NonNull String packageName,
            @NonNull List<IntentFilter> filters) {
        // validate arguments
        if (uri == null
                || packageName == null
                || filters == null
                || filters.size() == 0) {
            throw new IllegalArgumentException();
        }

        mDigestBytes = generateDigest(uri);
        mDigestPrefix =
                mDigestBytes[0] << 24
                | mDigestBytes[1] << 16
                | mDigestBytes[2] << 8
                | mDigestBytes[3] << 0;
        mFilters.addAll(filters);
        mPackageName = packageName;
    }

    private EphemeralResolveInfo(Parcel in) {
        readFromParcel(in);
    EphemeralResolveInfo(Parcel in) {
        mDigestBytes = in.createByteArray();
        mDigestPrefix = in.readInt();
        mPackageName = in.readString();
        in.readList(mFilters, null /*loader*/);
    }

    public byte[] getDigestBytes() {
@@ -53,21 +80,19 @@ public final class EphemeralResolveInfo implements Parcelable {
        return mDigestPrefix;
    }

    public String getPackageName() {
        return mPackageName;
    }

    public List<IntentFilter> getFilters() {
        return mFilters;
    }

    private void generateDigest(Uri uri) {
    private static byte[] generateDigest(Uri uri) {
        try {
            final MessageDigest digest = MessageDigest.getInstance(SHA_ALGORITHM);
            final byte[] hostBytes = uri.getHost().getBytes();
            final byte[] digestBytes = digest.digest(hostBytes);
            mDigestBytes = digestBytes;
            mDigestPrefix =
                    digestBytes[0] << 24
                    | digestBytes[1] << 16
                    | digestBytes[2] << 8
                    | digestBytes[3] << 0;
            return digest.digest(hostBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("could not find digest algorithm");
        }
@@ -80,26 +105,12 @@ public final class EphemeralResolveInfo implements Parcelable {

    @Override
    public void writeToParcel(Parcel out, int flags) {
        if (mDigestBytes == null) {
            out.writeInt(0);
        } else {
            out.writeInt(mDigestBytes.length);
        out.writeByteArray(mDigestBytes);
        }
        out.writeInt(mDigestPrefix);
        out.writeString(mPackageName);
        out.writeList(mFilters);
    }

    private void readFromParcel(Parcel in) {
        int digestBytesSize = in.readInt();
        if (digestBytesSize > 0) {
            mDigestBytes = new byte[digestBytesSize];
            in.readByteArray(mDigestBytes);
        }
        mDigestPrefix = in.readInt();
        in.readList(mFilters, null /*loader*/);
    }

    public static final Parcelable.Creator<EphemeralResolveInfo> CREATOR
            = new Parcelable.Creator<EphemeralResolveInfo>() {
        public EphemeralResolveInfo createFromParcel(Parcel in) {
@@ -110,4 +121,19 @@ public final class EphemeralResolveInfo implements Parcelable {
            return new EphemeralResolveInfo[size];
        }
    };

    /** @hide */
    public static final class EphemeralResolveIntentInfo extends IntentFilter {
        private final EphemeralResolveInfo mResolveInfo;

        public EphemeralResolveIntentInfo(@NonNull IntentFilter orig,
                @NonNull EphemeralResolveInfo resolveInfo) {
            super(orig);
            this.mResolveInfo = resolveInfo;
        }

        public EphemeralResolveInfo getEphemeralResolveInfo() {
            return mResolveInfo;
        }
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -60,6 +60,19 @@ public class ResolveInfo implements Parcelable {
     */
    public ProviderInfo providerInfo;

    /**
     * The ephemeral application that corresponds to this resolution match. This will
     * only be set in specific circumstances.
     * @hide
     */
    public EphemeralResolveInfo ephemeralResolveInfo;

    /**
     * A ResolveInfo that points at the ephemeral installer.
     * @hide
     */
    public ResolveInfo ephemeralInstaller;

    /**
     * The IntentFilter that was matched for this ResolveInfo.
     */
+3 −0
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.internal.app;

import android.annotation.SystemApi;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.EphemeralResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -33,6 +35,7 @@ import java.util.List;
 * Base class for implementing the resolver service.
 * @hide
 */
@SystemApi
public abstract class EphemeralResolverService extends Service {
    public static final String EXTRA_RESOLVE_INFO = "com.android.internal.app.RESOLVE_INFO";
    public static final String EXTRA_SEQUENCE = "com.android.internal.app.SEQUENCE";
Loading