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

Commit e5195dd1 authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Implement new API

This is the first swack at the new, 2-phase API. Adds the new methods
to the resolver service and makes the split name explicit on the
installer intent.

The 2nd phase will not yet be invoked; that's coming in a follow-on
change.

Bug: 25119046
Test: build & install the sample resolver and run 'adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://www.tripadvisor.com/Tourism-g33020-San_Jose_California-Vacations.html"'
Change-Id: I2df6fa64d46f17a86a2e32b19417632c594fb10f
parent 00c2ed26
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -4545,7 +4545,9 @@ package android.app {
    ctor public EphemeralResolverService();
    method public final void attachBaseContext(android.content.Context);
    method public final android.os.IBinder onBind(android.content.Intent);
    method public abstract java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int);
    method public abstract deprecated java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int);
    method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralIntentFilter(int[]);
    method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralResolveInfo(int[]);
    field public static final java.lang.String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO";
    field public static final java.lang.String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE";
  }
@@ -9189,6 +9191,7 @@ package android.content {
    field public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
    field public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
    field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
    field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
    field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
    field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
    field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
@@ -9893,18 +9896,39 @@ package android.content.pm {
    field public int reqTouchScreen;
  }
  public final class EphemeralIntentFilter implements android.os.Parcelable {
    ctor public EphemeralIntentFilter(java.lang.String, java.util.List<android.content.IntentFilter>);
    method public int describeContents();
    method public java.util.List<android.content.IntentFilter> getFilters();
    method public java.lang.String getSplitName();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralIntentFilter> CREATOR;
  }
  public final class EphemeralResolveInfo implements android.os.Parcelable {
    ctor public EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>);
    ctor public deprecated EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>);
    ctor public EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo.EphemeralDigest, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>);
    ctor public EphemeralResolveInfo(java.lang.String, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>);
    method public int describeContents();
    method public byte[] getDigestBytes();
    method public int getDigestPrefix();
    method public java.util.List<android.content.IntentFilter> getFilters();
    method public deprecated java.util.List<android.content.IntentFilter> getFilters();
    method public java.util.List<android.content.pm.EphemeralIntentFilter> getIntentFilters();
    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 static final class EphemeralResolveInfo.EphemeralDigest implements android.os.Parcelable {
    ctor public EphemeralResolveInfo.EphemeralDigest(java.lang.String);
    method public int describeContents();
    method public byte[][] getDigestBytes();
    method public int[] getDigestPrefix();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralResolveInfo.EphemeralDigest> CREATOR;
  }
  public final class FeatureGroupInfo implements android.os.Parcelable {
    ctor public FeatureGroupInfo();
    ctor public FeatureGroupInfo(android.content.pm.FeatureGroupInfo);
+52 −5
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public abstract class EphemeralResolverService extends Service {
    public static final String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO";
    public static final String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE";
    private static final String EXTRA_PREFIX = "android.app.PREFIX";
    private static final String EXTRA_HOSTNAME = "android.app.HOSTNAME";
    private Handler mHandler;

    /**
@@ -49,9 +50,29 @@ public abstract class EphemeralResolverService extends Service {
     * @param prefixMask A mask that was applied to each digest prefix. This should
     *      be used when comparing against the digest prefixes as all bits might
     *      not be set.
     * @deprecated use {@link #onGetEphemeralResolveInfo(int[])} instead
     */
    @Deprecated
    public abstract List<EphemeralResolveInfo> onEphemeralResolveInfoList(
            int digestPrefix[], int prefixMask);
            int digestPrefix[], int prefix);

    /**
     * Called to retrieve resolve info for ephemeral applications.
     *
     * @param digestPrefix The hash prefix of the ephemeral's domain.
     */
    public List<EphemeralResolveInfo> onGetEphemeralResolveInfo(int digestPrefix[]) {
        return onEphemeralResolveInfoList(digestPrefix, 0xFFFFF000);
    }

    /**
     * Called to retrieve intent filters for ephemeral applications.
     *
     * @param digestPrefix The hash prefix of the ephemeral's domain.
     */
    public List<EphemeralResolveInfo> onGetEphemeralIntentFilter(int digestPrefix[]) {
        throw new IllegalStateException("Must define");
    }

    @Override
    public final void attachBaseContext(Context base) {
@@ -64,9 +85,20 @@ public abstract class EphemeralResolverService extends Service {
        return new IEphemeralResolver.Stub() {
            @Override
            public void getEphemeralResolveInfoList(
                    IRemoteCallback callback, int digestPrefix[], int prefixMask, int sequence) {
                    IRemoteCallback callback, int digestPrefix[], int sequence) {
                final Message msg = mHandler.obtainMessage(
                        ServiceHandler.MSG_GET_EPHEMERAL_RESOLVE_INFO, sequence, 0, callback);
                final Bundle data = new Bundle();
                data.putIntArray(EXTRA_PREFIX, digestPrefix);
                msg.setData(data);
                msg.sendToTarget();
            }

            @Override
            public void getEphemeralIntentFilterList(
                    IRemoteCallback callback, int digestPrefix[], int sequence) {
                final Message msg = mHandler.obtainMessage(
                        ServiceHandler.MSG_GET_EPHEMERAL_RESOLVE_INFO, prefixMask, sequence, callback);
                        ServiceHandler.MSG_GET_EPHEMERAL_INTENT_FILTER, sequence, 0, callback);
                final Bundle data = new Bundle();
                data.putIntArray(EXTRA_PREFIX, digestPrefix);
                msg.setData(data);
@@ -77,6 +109,7 @@ public abstract class EphemeralResolverService extends Service {

    private final class ServiceHandler extends Handler {
        public static final int MSG_GET_EPHEMERAL_RESOLVE_INFO = 1;
        public static final int MSG_GET_EPHEMERAL_INTENT_FILTER = 2;

        public ServiceHandler(Looper looper) {
            super(looper, null /*callback*/, true /*async*/);
@@ -91,9 +124,23 @@ public abstract class EphemeralResolverService extends Service {
                    final IRemoteCallback callback = (IRemoteCallback) message.obj;
                    final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
                    final List<EphemeralResolveInfo> resolveInfo =
                            onEphemeralResolveInfoList(digestPrefix, message.arg1);
                            onGetEphemeralResolveInfo(digestPrefix);
                    final Bundle data = new Bundle();
                    data.putInt(EXTRA_SEQUENCE, message.arg1);
                    data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo);
                    try {
                        callback.sendResult(data);
                    } catch (RemoteException e) {
                    }
                } break;

                case MSG_GET_EPHEMERAL_INTENT_FILTER: {
                    final IRemoteCallback callback = (IRemoteCallback) message.obj;
                    final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
                    final List<EphemeralResolveInfo> resolveInfo =
                            onGetEphemeralIntentFilter(digestPrefix);
                    final Bundle data = new Bundle();
                    data.putInt(EXTRA_SEQUENCE, message.arg2);
                    data.putInt(EXTRA_SEQUENCE, message.arg1);
                    data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo);
                    try {
                        callback.sendResult(data);
+4 −1
Original line number Diff line number Diff line
@@ -21,5 +21,8 @@ import android.os.IRemoteCallback;
/** @hide */
oneway interface IEphemeralResolver {
    void getEphemeralResolveInfoList(IRemoteCallback callback, in int[] digestPrefix,
            int prefixMask, int sequence);
            int sequence);

    void getEphemeralIntentFilterList(IRemoteCallback callback, in int[] digestPrefix,
            int sequence);
}
+10 −0
Original line number Diff line number Diff line
@@ -1712,6 +1712,16 @@ public class Intent implements Parcelable, Cloneable {
     */
    public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";

    /**
     * Intent extra: An app split name.
     * <p>
     * Type: String
     * </p>
     * @hide
     */
    @SystemApi
    public static final String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";

    /**
     * Intent extra: An extra for specifying whether a result is needed.
     * <p>
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content.pm;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.IntentFilter;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.List;

/**
 * Information about an ephemeral application intent filter.
 * @hide
 */
@SystemApi
public final class EphemeralIntentFilter implements Parcelable {
    private final String mSplitName;
    /** The filters used to match domain */
    private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>();

    public EphemeralIntentFilter(@Nullable String splitName, @NonNull List<IntentFilter> filters) {
        if (filters == null || filters.size() == 0) {
            throw new IllegalArgumentException();
        }
        mSplitName = splitName;
        mFilters.addAll(filters);
    }

    EphemeralIntentFilter(Parcel in) {
        mSplitName = in.readString();
        in.readList(mFilters, null /*loader*/);
    }

    public String getSplitName() {
        return mSplitName;
    }

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

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mSplitName);
        out.writeList(mFilters);
    }

    public static final Parcelable.Creator<EphemeralIntentFilter> CREATOR
            = new Parcelable.Creator<EphemeralIntentFilter>() {
        public EphemeralIntentFilter createFromParcel(Parcel in) {
            return new EphemeralIntentFilter(in);
        }

        public EphemeralIntentFilter[] newArray(int size) {
            return new EphemeralIntentFilter[size];
        }
    };

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

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

        public EphemeralIntentFilter getEphemeralResolveInfo() {
            return mResolveInfo;
        }
    }
}
Loading