core/java/android/app/ITaskStackListener.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IEphemeralResolver.aidl \
+ core/java/android/app/IInstantAppResolver.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/IProcessObserver.aidl \
field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
- field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+ field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
field public static final int BATTERY_STATUS_FULL = 5; // 0x5
field public static final int VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION = 3; // 0x3
}
- public abstract class EphemeralResolverService extends android.app.Service {
+ public abstract deprecated class EphemeralResolverService extends android.app.InstantAppResolverService {
ctor public EphemeralResolverService();
- method public final void attachBaseContext(android.content.Context);
method public android.os.Looper getLooper();
- method public final android.os.IBinder onBind(android.content.Intent);
method public abstract deprecated java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int);
method public android.content.pm.EphemeralResolveInfo onGetEphemeralIntentFilter(java.lang.String);
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";
}
public class ExpandableListActivity extends android.app.Activity implements android.widget.ExpandableListView.OnChildClickListener android.widget.ExpandableListView.OnGroupCollapseListener android.widget.ExpandableListView.OnGroupExpandListener android.view.View.OnCreateContextMenuListener {
field public static final int TRANSIT_UNSET = -1; // 0xffffffff
}
+ public abstract class InstantAppResolverService extends android.app.Service {
+ ctor public InstantAppResolverService();
+ method public final void attachBaseContext(android.content.Context);
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public void onGetInstantAppIntentFilter(int[], android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ method public void onGetInstantAppResolveInfo(int[], android.app.InstantAppResolverService.InstantAppResolutionCallback);
+ 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";
+ }
+
+ public static final class InstantAppResolverService.InstantAppResolutionCallback {
+ method public void onInstantAppResolveInfo(java.util.List<android.content.pm.InstantAppResolveInfo>);
+ }
+
public class Instrumentation {
ctor public Instrumentation();
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
field public int reqTouchScreen;
}
- public final class EphemeralIntentFilter implements android.os.Parcelable {
+ public final deprecated 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();
field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralIntentFilter> CREATOR;
}
- public final class EphemeralResolveInfo implements android.os.Parcelable {
+ public final deprecated class EphemeralResolveInfo implements android.os.Parcelable {
ctor public deprecated EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>);
ctor public deprecated EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo.EphemeralDigest, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>);
ctor public EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo.EphemeralDigest, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>, int);
field public int version;
}
+ public final class InstantAppIntentFilter implements android.os.Parcelable {
+ ctor public InstantAppIntentFilter(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.InstantAppIntentFilter> CREATOR;
+ }
+
+ public final class InstantAppResolveInfo implements android.os.Parcelable {
+ ctor public InstantAppResolveInfo(android.content.pm.InstantAppResolveInfo.InstantAppDigest, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>, int);
+ ctor public InstantAppResolveInfo(java.lang.String, java.lang.String, java.util.List<android.content.pm.InstantAppIntentFilter>);
+ method public int describeContents();
+ method public byte[] getDigestBytes();
+ method public int getDigestPrefix();
+ method public java.util.List<android.content.pm.InstantAppIntentFilter> getIntentFilters();
+ method public java.lang.String getPackageName();
+ method public int getVersionCode();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.content.pm.InstantAppResolveInfo> CREATOR;
+ field public static final java.lang.String SHA_ALGORITHM = "SHA-256";
+ }
+
+ public static final class InstantAppResolveInfo.InstantAppDigest implements android.os.Parcelable {
+ ctor public InstantAppResolveInfo.InstantAppDigest(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.InstantAppResolveInfo.InstantAppDigest> CREATOR;
+ }
+
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public InstrumentationInfo();
ctor public InstrumentationInfo(android.content.pm.InstrumentationInfo);
field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
- field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+ field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
field public static final int BATTERY_STATUS_FULL = 5; // 0x5
field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
- field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+ field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
field public static final int BATTERY_STATUS_FULL = 5; // 0x5
package android.app;
+/** @deprecated */
parcelable EphemeralResolveInfo;
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.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import java.util.ArrayList;
import java.util.List;
/**
* Base class for implementing the resolver service.
* @hide
+ * @deprecated use InstantAppResolverService instead
*/
+@Deprecated
@SystemApi
-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;
-
+public abstract class EphemeralResolverService extends InstantAppResolverService {
/**
* Called to retrieve resolve info for ephemeral applications.
*
throw new IllegalStateException("Must define");
}
- /**
- * Returns a {@link Looper} to perform service operations on.
- */
+ @Override
public Looper getLooper() {
- return getBaseContext().getMainLooper();
+ return super.getLooper();
}
@Override
- public final void attachBaseContext(Context base) {
- super.attachBaseContext(base);
- mHandler = new ServiceHandler(getLooper());
+ void _onGetInstantAppResolveInfo(int[] digestPrefix, InstantAppResolutionCallback callback) {
+ final List<EphemeralResolveInfo> response = onGetEphemeralResolveInfo(digestPrefix);
+ final int responseSize = response == null ? 0 : response.size();
+ final List<InstantAppResolveInfo> resultList = new ArrayList<>(responseSize);
+ for (int i = 0; i < responseSize; i++) {
+ resultList.add(response.get(i).getInstantAppResolveInfo());
+ }
+ callback.onInstantAppResolveInfo(resultList);
}
@Override
- public final IBinder onBind(Intent intent) {
- return new IEphemeralResolver.Stub() {
- @Override
- public void getEphemeralResolveInfoList(
- 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, String hostName, int sequence) {
- final Message msg = mHandler.obtainMessage(
- ServiceHandler.MSG_GET_EPHEMERAL_INTENT_FILTER, sequence, 0, callback);
- final Bundle data = new Bundle();
- data.putString(EXTRA_HOSTNAME, hostName);
- msg.setData(data);
- msg.sendToTarget();
- }
- };
- }
-
- 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*/);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void handleMessage(Message message) {
- final int action = message.what;
- switch (action) {
- case MSG_GET_EPHEMERAL_RESOLVE_INFO: {
- final IRemoteCallback callback = (IRemoteCallback) message.obj;
- final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
- final List<EphemeralResolveInfo> resolveInfo =
- 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 String hostName = message.getData().getString(EXTRA_HOSTNAME);
- final EphemeralResolveInfo resolveInfo = onGetEphemeralIntentFilter(hostName);
- final Bundle data = new Bundle();
- data.putInt(EXTRA_SEQUENCE, message.arg1);
- data.putParcelable(EXTRA_RESOLVE_INFO, resolveInfo);
- try {
- callback.sendResult(data);
- } catch (RemoteException e) {
- }
- } break;
-
- default: {
- throw new IllegalArgumentException("Unknown message: " + action);
- }
- }
- }
+ void _onGetInstantAppIntentFilter(int[] digestPrefix, String hostName,
+ InstantAppResolutionCallback callback) {
+ final EphemeralResolveInfo response = onGetEphemeralIntentFilter(hostName);
+ final List<InstantAppResolveInfo> resultList = new ArrayList<>(1);
+ resultList.add(response.getInstantAppResolveInfo());
+ callback.onInstantAppResolveInfo(resultList);
}
}
import android.os.IRemoteCallback;
-/** @hide */
+/** @hide @deprecated */
oneway interface IEphemeralResolver {
void getEphemeralResolveInfoList(IRemoteCallback callback, in int[] digestPrefix,
int sequence);
--- /dev/null
+/*
+ * Copyright (C) 2017 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.app;
+
+import android.os.IRemoteCallback;
+
+/** @hide */
+oneway interface IInstantAppResolver {
+ void getInstantAppResolveInfoList(in int[] digestPrefix,
+ int sequence, IRemoteCallback callback);
+
+ void getInstantAppIntentFilterList(in int[] digestPrefix,
+ int sequence, String hostName, IRemoteCallback callback);
+}
--- /dev/null
+/*
+** Copyright 2017, 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.app;
+
+parcelable InstantAppResolveInfo;
--- /dev/null
+/*
+ * Copyright (C) 2017 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.app;
+
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.InstantAppResolveInfo;
+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 java.util.List;
+
+/**
+ * Base class for implementing the resolver service.
+ * @hide
+ */
+@SystemApi
+public abstract class InstantAppResolverService extends Service {
+ public static final String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO";
+ public static final String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE";
+ static final String EXTRA_PREFIX = "android.app.PREFIX";
+ static final String EXTRA_HOSTNAME = "android.app.HOSTNAME";
+ Handler mHandler;
+
+ /**
+ * Called to retrieve resolve info for instant applications.
+ *
+ * @param digestPrefix The hash prefix of the instant app's domain.
+ */
+ public void onGetInstantAppResolveInfo(
+ int digestPrefix[], InstantAppResolutionCallback callback) {
+ throw new IllegalStateException("Must define");
+ }
+
+ /**
+ * Called to retrieve intent filters for instant applications.
+ *
+ * @param digestPrefix The hash prefix of the instant app's domain.
+ */
+ public void onGetInstantAppIntentFilter(
+ int digestPrefix[], InstantAppResolutionCallback callback) {
+ throw new IllegalStateException("Must define");
+ }
+
+ /**
+ * Returns a {@link Looper} to perform service operations on.
+ */
+ Looper getLooper() {
+ return getBaseContext().getMainLooper();
+ }
+
+ @Override
+ public final void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ mHandler = new ServiceHandler(getLooper());
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return new IInstantAppResolver.Stub() {
+ @Override
+ public void getInstantAppResolveInfoList(
+ int digestPrefix[], int sequence, IRemoteCallback callback) {
+ final Message msg = mHandler.obtainMessage(
+ ServiceHandler.MSG_GET_INSTANT_APP_RESOLVE_INFO, sequence, 0, callback);
+ final Bundle data = new Bundle();
+ data.putIntArray(EXTRA_PREFIX, digestPrefix);
+ msg.setData(data);
+ msg.sendToTarget();
+ }
+
+ @Override
+ public void getInstantAppIntentFilterList(
+ int digestPrefix[], int sequence, String hostName, IRemoteCallback callback) {
+ final Message msg = mHandler.obtainMessage(
+ ServiceHandler.MSG_GET_INSTANT_APP_INTENT_FILTER, sequence, 0, callback);
+ final Bundle data = new Bundle();
+ data.putString(EXTRA_HOSTNAME, hostName);
+ data.putIntArray(EXTRA_PREFIX, digestPrefix);
+ msg.setData(data);
+ msg.sendToTarget();
+ }
+ };
+ }
+
+ /**
+ * Callback to post results from instant app resolution.
+ */
+ public static final class InstantAppResolutionCallback {
+ private final IRemoteCallback mCallback;
+ private final int mSequence;
+ InstantAppResolutionCallback(int sequence, IRemoteCallback callback) {
+ mCallback = callback;
+ mSequence = sequence;
+ }
+
+ public void onInstantAppResolveInfo(List<InstantAppResolveInfo> resolveInfo) {
+ final Bundle data = new Bundle();
+ data.putInt(EXTRA_SEQUENCE, mSequence);
+ data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo);
+ try {
+ mCallback.sendResult(data);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Deprecated
+ void _onGetInstantAppResolveInfo(int[] digestPrefix, InstantAppResolutionCallback callback) {
+ onGetInstantAppResolveInfo(digestPrefix, callback);
+ }
+ @Deprecated
+ void _onGetInstantAppIntentFilter(int digestPrefix[], String hostName,
+ InstantAppResolutionCallback callback) {
+ onGetInstantAppIntentFilter(digestPrefix, 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*/);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void handleMessage(Message message) {
+ final int action = message.what;
+ switch (action) {
+ case MSG_GET_INSTANT_APP_RESOLVE_INFO: {
+ final IRemoteCallback callback = (IRemoteCallback) message.obj;
+ final int sequence = message.arg1;
+ final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
+ _onGetInstantAppResolveInfo(
+ digestPrefix, new InstantAppResolutionCallback(sequence, callback));
+ } break;
+
+ case MSG_GET_INSTANT_APP_INTENT_FILTER: {
+ final IRemoteCallback callback = (IRemoteCallback) message.obj;
+ final int sequence = message.arg1;
+ final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
+ final String hostName = message.getData().getString(EXTRA_HOSTNAME);
+ _onGetInstantAppIntentFilter(
+ digestPrefix, hostName,
+ new InstantAppResolutionCallback(sequence, callback));
+ } break;
+
+ default: {
+ throw new IllegalArgumentException("Unknown message: " + action);
+ }
+ }
+ }
+ }
+}
* @hide
*/
public final class AuxiliaryResolveInfo extends IntentFilter {
- /** Resolved information returned from the external ephemeral resolver */
- public final EphemeralResolveInfo resolveInfo;
+ /** Resolved information returned from the external instant resolver */
+ public final InstantAppResolveInfo resolveInfo;
/** The resolved package. Copied from {@link #resolveInfo}. */
public final String packageName;
/** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
public final String splitName;
- /** Whether or not ephemeral resolution needs the second phase */
+ /** Whether or not instant resolution needs the second phase */
public final boolean needsPhaseTwo;
- /** Opaque token to track the ephemeral application resolution */
+ /** Opaque token to track the instant application resolution */
public final String token;
/** The version code of the package */
public final int versionCode;
/** Create a response for installing an instant application. */
- public AuxiliaryResolveInfo(@NonNull EphemeralResolveInfo resolveInfo,
+ public AuxiliaryResolveInfo(@NonNull InstantAppResolveInfo resolveInfo,
@NonNull IntentFilter orig,
@Nullable String splitName,
@NonNull String token,
* Information about an ephemeral application intent filter.
* @hide
*/
+@Deprecated
@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>();
+ private final InstantAppIntentFilter mInstantAppIntentFilter;
public EphemeralIntentFilter(@Nullable String splitName, @NonNull List<IntentFilter> filters) {
- if (filters == null || filters.size() == 0) {
- throw new IllegalArgumentException();
- }
- mSplitName = splitName;
- mFilters.addAll(filters);
+ mInstantAppIntentFilter = new InstantAppIntentFilter(splitName, filters);
+ }
+
+ EphemeralIntentFilter(@NonNull InstantAppIntentFilter intentFilter) {
+ mInstantAppIntentFilter = intentFilter;
}
EphemeralIntentFilter(Parcel in) {
- mSplitName = in.readString();
- in.readList(mFilters, null /*loader*/);
+ mInstantAppIntentFilter = in.readParcelable(null /*loader*/);
}
public String getSplitName() {
- return mSplitName;
+ return mInstantAppIntentFilter.getSplitName();
}
public List<IntentFilter> getFilters() {
- return mFilters;
+ return mInstantAppIntentFilter.getFilters();
+ }
+
+ /** @hide */
+ InstantAppIntentFilter getInstantAppIntentFilter() {
+ return mInstantAppIntentFilter;
}
@Override
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeString(mSplitName);
- out.writeList(mFilters);
+ out.writeParcelable(mInstantAppIntentFilter, flags);
}
public static final Parcelable.Creator<EphemeralIntentFilter> CREATOR
= new Parcelable.Creator<EphemeralIntentFilter>() {
+ @Override
public EphemeralIntentFilter createFromParcel(Parcel in) {
return new EphemeralIntentFilter(in);
}
-
+ @Override
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;
- }
- }
}
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.IntentFilter;
+import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
* Information about an ephemeral application.
* @hide
*/
+@Deprecated
@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 final EphemeralDigest mDigest;
- private final String mPackageName;
- /** The filters used to match domain */
- private final List<EphemeralIntentFilter> mFilters;
- /** The version code of the app that this class resolves to */
- private final int mVersionCode;
- /** Filters only for legacy clients */
+ private final InstantAppResolveInfo mInstantAppResolveInfo;
@Deprecated
private final List<IntentFilter> mLegacyFilters;
if (uri == null || packageName == null || filters == null || filters.isEmpty()) {
throw new IllegalArgumentException();
}
- mDigest = new EphemeralDigest(uri.getHost());
- mPackageName = packageName;
- mFilters = new ArrayList<EphemeralIntentFilter>();
- mFilters.add(new EphemeralIntentFilter(packageName, filters));
+ final List<EphemeralIntentFilter> ephemeralFilters = new ArrayList<>(1);
+ ephemeralFilters.add(new EphemeralIntentFilter(packageName, filters));
+ mInstantAppResolveInfo = new InstantAppResolveInfo(uri.getHost(), packageName,
+ createInstantAppIntentFilterList(ephemeralFilters));
mLegacyFilters = new ArrayList<IntentFilter>(filters.size());
mLegacyFilters.addAll(filters);
- mVersionCode = -1;
}
@Deprecated
}
public EphemeralResolveInfo(@NonNull EphemeralDigest digest, @Nullable String packageName,
- @Nullable List<EphemeralIntentFilter> filters, int versionConde) {
- // validate arguments
- if ((packageName == null && (filters != null && filters.size() != 0))
- || (packageName != null && (filters == null || filters.size() == 0))) {
- throw new IllegalArgumentException();
- }
- mDigest = digest;
- if (filters != null) {
- mFilters = new ArrayList<EphemeralIntentFilter>(filters.size());
- mFilters.addAll(filters);
- } else {
- mFilters = null;
- }
+ @Nullable List<EphemeralIntentFilter> filters, int versionCode) {
+ mInstantAppResolveInfo = new InstantAppResolveInfo(
+ digest.getInstantAppDigest(), packageName,
+ createInstantAppIntentFilterList(filters), versionCode);
mLegacyFilters = null;
- mPackageName = packageName;
- mVersionCode = versionConde;
}
public EphemeralResolveInfo(@NonNull String hostName, @Nullable String packageName,
}
EphemeralResolveInfo(Parcel in) {
- mDigest = in.readParcelable(null /*loader*/);
- mPackageName = in.readString();
- mFilters = new ArrayList<EphemeralIntentFilter>();
- in.readList(mFilters, null /*loader*/);
- mVersionCode = in.readInt();
+ mInstantAppResolveInfo = in.readParcelable(null /*loader*/);
mLegacyFilters = new ArrayList<IntentFilter>();
in.readList(mLegacyFilters, null /*loader*/);
}
+ /** @hide */
+ public InstantAppResolveInfo getInstantAppResolveInfo() {
+ return mInstantAppResolveInfo;
+ }
+
+ private static List<InstantAppIntentFilter> createInstantAppIntentFilterList(
+ List<EphemeralIntentFilter> filters) {
+ if (filters == null) {
+ return null;
+ }
+ final int filterCount = filters.size();
+ final List<InstantAppIntentFilter> returnList = new ArrayList<>(filterCount);
+ for (int i = 0; i < filterCount; i++) {
+ returnList.add(filters.get(i).getInstantAppIntentFilter());
+ }
+ return returnList;
+ }
+
public byte[] getDigestBytes() {
- return mDigest.getDigestBytes()[0];
+ return mInstantAppResolveInfo.getDigestBytes();
}
public int getDigestPrefix() {
- return mDigest.getDigestPrefix()[0];
+ return mInstantAppResolveInfo.getDigestPrefix();
}
public String getPackageName() {
- return mPackageName;
+ return mInstantAppResolveInfo.getPackageName();
}
public List<EphemeralIntentFilter> getIntentFilters() {
- return mFilters;
+ final List<InstantAppIntentFilter> filters = mInstantAppResolveInfo.getIntentFilters();
+ final int filterCount = filters.size();
+ final List<EphemeralIntentFilter> returnList = new ArrayList<>(filterCount);
+ for (int i = 0; i < filterCount; i++) {
+ returnList.add(new EphemeralIntentFilter(filters.get(i)));
+ }
+ return returnList;
}
public int getVersionCode() {
- return mVersionCode;
+ return mInstantAppResolveInfo.getVersionCode();
}
@Deprecated
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(mDigest, flags);
- out.writeString(mPackageName);
- out.writeList(mFilters);
- out.writeInt(mVersionCode);
+ out.writeParcelable(mInstantAppResolveInfo, flags);
out.writeList(mLegacyFilters);
}
public static final Parcelable.Creator<EphemeralResolveInfo> CREATOR
= new Parcelable.Creator<EphemeralResolveInfo>() {
+ @Override
public EphemeralResolveInfo createFromParcel(Parcel in) {
return new EphemeralResolveInfo(in);
}
-
+ @Override
public EphemeralResolveInfo[] newArray(int size) {
return new EphemeralResolveInfo[size];
}
*/
@SystemApi
public static final class EphemeralDigest implements Parcelable {
- private static final int DIGEST_MASK = 0xfffff000;
- 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 */
- private final int[] mDigestPrefix;
+ private final InstantAppDigest mInstantAppDigest;
public EphemeralDigest(@NonNull String hostName) {
this(hostName, -1 /*maxDigests*/);
/** @hide */
public EphemeralDigest(@NonNull String hostName, int maxDigests) {
- if (hostName == null) {
- throw new IllegalArgumentException();
- }
- mDigestBytes = generateDigest(hostName.toLowerCase(Locale.ENGLISH), maxDigests);
- mDigestPrefix = new int[mDigestBytes.length];
- for (int i = 0; i < mDigestBytes.length; i++) {
- mDigestPrefix[i] =
- ((mDigestBytes[i][0] & 0xFF) << 24
- | (mDigestBytes[i][1] & 0xFF) << 16
- | (mDigestBytes[i][2] & 0xFF) << 8
- | (mDigestBytes[i][3] & 0xFF) << 0)
- & DIGEST_MASK;
- }
+ mInstantAppDigest = new InstantAppDigest(hostName, maxDigests);
}
- private static byte[][] generateDigest(String hostName, int maxDigests) {
- ArrayList<byte[]> digests = new ArrayList<>();
- try {
- final MessageDigest digest = MessageDigest.getInstance(SHA_ALGORITHM);
- if (maxDigests <= 0) {
- final byte[] hostBytes = hostName.getBytes();
- digests.add(digest.digest(hostBytes));
- } else {
- int prevDot = hostName.lastIndexOf('.');
- prevDot = hostName.lastIndexOf('.', prevDot - 1);
- // shortcut for short URLs
- if (prevDot < 0) {
- digests.add(digest.digest(hostName.getBytes()));
- } else {
- byte[] hostBytes =
- hostName.substring(prevDot + 1, hostName.length()).getBytes();
- digests.add(digest.digest(hostBytes));
- int digestCount = 1;
- while (prevDot >= 0 && digestCount < maxDigests) {
- prevDot = hostName.lastIndexOf('.', prevDot - 1);
- hostBytes =
- hostName.substring(prevDot + 1, hostName.length()).getBytes();
- digests.add(digest.digest(hostBytes));
- digestCount++;
- }
- }
- }
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalStateException("could not find digest algorithm");
- }
- return digests.toArray(new byte[digests.size()][]);
+ EphemeralDigest(Parcel in) {
+ mInstantAppDigest = in.readParcelable(null /*loader*/);
}
- EphemeralDigest(Parcel in) {
- final int digestCount = in.readInt();
- if (digestCount == -1) {
- mDigestBytes = null;
- } else {
- mDigestBytes = new byte[digestCount][];
- for (int i = 0; i < digestCount; i++) {
- mDigestBytes[i] = in.createByteArray();
- }
- }
- mDigestPrefix = in.createIntArray();
+ /** @hide */
+ InstantAppDigest getInstantAppDigest() {
+ return mInstantAppDigest;
}
public byte[][] getDigestBytes() {
- return mDigestBytes;
+ return mInstantAppDigest.getDigestBytes();
}
public int[] getDigestPrefix() {
- return mDigestPrefix;
+ return mInstantAppDigest.getDigestPrefix();
}
@Override
@Override
public void writeToParcel(Parcel out, int flags) {
- if (mDigestBytes == null) {
- out.writeInt(-1);
- } else {
- out.writeInt(mDigestBytes.length);
- for (int i = 0; i < mDigestBytes.length; i++) {
- out.writeByteArray(mDigestBytes[i]);
- }
- }
- out.writeIntArray(mDigestPrefix);
+ out.writeParcelable(mInstantAppDigest, flags);
}
@SuppressWarnings("hiding")
public static final Parcelable.Creator<EphemeralDigest> CREATOR =
new Parcelable.Creator<EphemeralDigest>() {
+ @Override
public EphemeralDigest createFromParcel(Parcel in) {
return new EphemeralDigest(in);
}
-
+ @Override
public EphemeralDigest[] newArray(int size) {
return new EphemeralDigest[size];
}
--- /dev/null
+/*
+ * Copyright (C) 2017 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 instant application intent filter.
+ * @hide
+ */
+@SystemApi
+public final class InstantAppIntentFilter implements Parcelable {
+ private final String mSplitName;
+ /** The filters used to match domain */
+ private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>();
+
+ public InstantAppIntentFilter(@Nullable String splitName, @NonNull List<IntentFilter> filters) {
+ if (filters == null || filters.size() == 0) {
+ throw new IllegalArgumentException();
+ }
+ mSplitName = splitName;
+ mFilters.addAll(filters);
+ }
+
+ InstantAppIntentFilter(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<InstantAppIntentFilter> CREATOR
+ = new Parcelable.Creator<InstantAppIntentFilter>() {
+ @Override
+ public InstantAppIntentFilter createFromParcel(Parcel in) {
+ return new InstantAppIntentFilter(in);
+ }
+ @Override
+ public InstantAppIntentFilter[] newArray(int size) {
+ return new InstantAppIntentFilter[size];
+ }
+ };
+}
import android.content.Intent;
/**
- * Information needed to make an ephemeral application resolution request.
+ * Information needed to make an instant application resolution request.
* @hide
*/
-public final class EphemeralRequest {
- /** Response from the first phase of ephemeral application resolution */
+public final class InstantAppRequest {
+ /** Response from the first phase of instant application resolution */
public final AuxiliaryResolveInfo responseObj;
- /** The original intent that triggered ephemeral application resolution */
+ /** The original intent that triggered instant application resolution */
public final Intent origIntent;
/** Resolved type of the intent */
public final String resolvedType;
- /** The name of the package requesting the ephemeral application */
+ /** The name of the package requesting the instant application */
public final String callingPackage;
- /** ID of the user requesting the ephemeral application */
+ /** ID of the user requesting the instant application */
public final int userId;
- public EphemeralRequest(AuxiliaryResolveInfo responseObj, Intent origIntent,
+ public InstantAppRequest(AuxiliaryResolveInfo responseObj, Intent origIntent,
String resolvedType, String callingPackage, int userId) {
this.responseObj = responseObj;
this.origIntent = origIntent;
--- /dev/null
+/*
+ * Copyright (C) 2017 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.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Information about an instant application.
+ * @hide
+ */
+@SystemApi
+public final class InstantAppResolveInfo implements Parcelable {
+ /** Algorithm that will be used to generate the domain digest */
+ public static final String SHA_ALGORITHM = "SHA-256";
+
+ private final InstantAppDigest mDigest;
+ private final String mPackageName;
+ /** The filters used to match domain */
+ private final List<InstantAppIntentFilter> mFilters;
+ /** The version code of the app that this class resolves to */
+ private final int mVersionCode;
+
+ public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
+ @Nullable List<InstantAppIntentFilter> filters, int versionConde) {
+ // validate arguments
+ if ((packageName == null && (filters != null && filters.size() != 0))
+ || (packageName != null && (filters == null || filters.size() == 0))) {
+ throw new IllegalArgumentException();
+ }
+ mDigest = digest;
+ if (filters != null) {
+ mFilters = new ArrayList<InstantAppIntentFilter>(filters.size());
+ mFilters.addAll(filters);
+ } else {
+ mFilters = null;
+ }
+ mPackageName = packageName;
+ mVersionCode = versionConde;
+ }
+
+ public InstantAppResolveInfo(@NonNull String hostName, @Nullable String packageName,
+ @Nullable List<InstantAppIntentFilter> filters) {
+ this(new InstantAppDigest(hostName), packageName, filters, -1 /*versionCode*/);
+ }
+
+ InstantAppResolveInfo(Parcel in) {
+ mDigest = in.readParcelable(null /*loader*/);
+ mPackageName = in.readString();
+ mFilters = new ArrayList<InstantAppIntentFilter>();
+ in.readList(mFilters, null /*loader*/);
+ mVersionCode = in.readInt();
+ }
+
+ public byte[] getDigestBytes() {
+ return mDigest.getDigestBytes()[0];
+ }
+
+ public int getDigestPrefix() {
+ return mDigest.getDigestPrefix()[0];
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public List<InstantAppIntentFilter> getIntentFilters() {
+ return mFilters;
+ }
+
+ public int getVersionCode() {
+ return mVersionCode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(mDigest, flags);
+ out.writeString(mPackageName);
+ out.writeList(mFilters);
+ out.writeInt(mVersionCode);
+ }
+
+ public static final Parcelable.Creator<InstantAppResolveInfo> CREATOR
+ = new Parcelable.Creator<InstantAppResolveInfo>() {
+ public InstantAppResolveInfo createFromParcel(Parcel in) {
+ return new InstantAppResolveInfo(in);
+ }
+
+ public InstantAppResolveInfo[] newArray(int size) {
+ return new InstantAppResolveInfo[size];
+ }
+ };
+
+ /**
+ * Helper class to generate and store each of the digests and prefixes
+ * sent to the Instant App Resolver.
+ * <p>
+ * Since intent filters may want to handle multiple hosts within a
+ * domain [eg “*.google.com”], the resolver is presented with multiple
+ * hash prefixes. For example, "a.b.c.d.e" generates digests for
+ * "d.e", "c.d.e", "b.c.d.e" and "a.b.c.d.e".
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class InstantAppDigest implements Parcelable {
+ private static final int DIGEST_MASK = 0xfffff000;
+ 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 */
+ private final int[] mDigestPrefix;
+
+ public InstantAppDigest(@NonNull String hostName) {
+ this(hostName, -1 /*maxDigests*/);
+ }
+
+ /** @hide */
+ public InstantAppDigest(@NonNull String hostName, int maxDigests) {
+ if (hostName == null) {
+ throw new IllegalArgumentException();
+ }
+ mDigestBytes = generateDigest(hostName.toLowerCase(Locale.ENGLISH), maxDigests);
+ mDigestPrefix = new int[mDigestBytes.length];
+ for (int i = 0; i < mDigestBytes.length; i++) {
+ mDigestPrefix[i] =
+ ((mDigestBytes[i][0] & 0xFF) << 24
+ | (mDigestBytes[i][1] & 0xFF) << 16
+ | (mDigestBytes[i][2] & 0xFF) << 8
+ | (mDigestBytes[i][3] & 0xFF) << 0)
+ & DIGEST_MASK;
+ }
+ }
+
+ private static byte[][] generateDigest(String hostName, int maxDigests) {
+ ArrayList<byte[]> digests = new ArrayList<>();
+ try {
+ final MessageDigest digest = MessageDigest.getInstance(SHA_ALGORITHM);
+ if (maxDigests <= 0) {
+ final byte[] hostBytes = hostName.getBytes();
+ digests.add(digest.digest(hostBytes));
+ } else {
+ int prevDot = hostName.lastIndexOf('.');
+ prevDot = hostName.lastIndexOf('.', prevDot - 1);
+ // shortcut for short URLs
+ if (prevDot < 0) {
+ digests.add(digest.digest(hostName.getBytes()));
+ } else {
+ byte[] hostBytes =
+ hostName.substring(prevDot + 1, hostName.length()).getBytes();
+ digests.add(digest.digest(hostBytes));
+ int digestCount = 1;
+ while (prevDot >= 0 && digestCount < maxDigests) {
+ prevDot = hostName.lastIndexOf('.', prevDot - 1);
+ hostBytes =
+ hostName.substring(prevDot + 1, hostName.length()).getBytes();
+ digests.add(digest.digest(hostBytes));
+ digestCount++;
+ }
+ }
+ }
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("could not find digest algorithm");
+ }
+ return digests.toArray(new byte[digests.size()][]);
+ }
+
+ InstantAppDigest(Parcel in) {
+ final int digestCount = in.readInt();
+ if (digestCount == -1) {
+ mDigestBytes = null;
+ } else {
+ mDigestBytes = new byte[digestCount][];
+ for (int i = 0; i < digestCount; i++) {
+ mDigestBytes[i] = in.createByteArray();
+ }
+ }
+ mDigestPrefix = in.createIntArray();
+ }
+
+ public byte[][] getDigestBytes() {
+ return mDigestBytes;
+ }
+
+ public int[] getDigestPrefix() {
+ return mDigestPrefix;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ if (mDigestBytes == null) {
+ out.writeInt(-1);
+ } else {
+ out.writeInt(mDigestBytes.length);
+ for (int i = 0; i < mDigestBytes.length; i++) {
+ out.writeByteArray(mDigestBytes[i]);
+ }
+ }
+ out.writeIntArray(mDigestPrefix);
+ }
+
+ @SuppressWarnings("hiding")
+ public static final Parcelable.Creator<InstantAppDigest> CREATOR =
+ new Parcelable.Creator<InstantAppDigest>() {
+ @Override
+ public InstantAppDigest createFromParcel(Parcel in) {
+ return new InstantAppDigest(in);
+ }
+ @Override
+ public InstantAppDigest[] newArray(int size) {
+ return new InstantAppDigest[size];
+ }
+ };
+ }
+}
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
-import com.android.server.pm.EphemeralResolver;
+import com.android.server.pm.InstantAppResolver;
import com.android.server.wm.WindowManagerService;
import java.util.ArrayList;
mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
auxiliaryResponse, originalIntent, resolvedType, callingPackage, userId);
}
- return EphemeralResolver.buildEphemeralInstallerIntent(originalIntent,
- callingPackage, resolvedType, userId, auxiliaryResponse.packageName,
- auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
- auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
+ return InstantAppResolver.buildEphemeralInstallerIntent(originalIntent,
+ callingPackage, resolvedType, userId, auxiliaryResponse.packageName,
+ auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
+ auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
}
void postStartActivityUncheckedProcessing(
package com.android.server.pm;
-import android.app.EphemeralResolverService;
-import android.app.IEphemeralResolver;
+import android.app.IInstantAppResolver;
+import android.app.InstantAppResolverService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.InstantAppResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
private final Intent mIntent;
private volatile boolean mBindRequested;
- private IEphemeralResolver mRemoteInstance;
+ private IInstantAppResolver mRemoteInstance;
public EphemeralResolverConnection(Context context, ComponentName componentName) {
mContext = context;
mIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE).setComponent(componentName);
}
- public final List<EphemeralResolveInfo> getEphemeralResolveInfoList(int hashPrefix[]) {
+ public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[]) {
throwIfCalledOnMainThread();
try {
return mGetEphemeralResolveInfoCaller.getEphemeralResolveInfoList(
return null;
}
- public final void getEphemeralIntentFilterList(String hostName, PhaseTwoCallback callback,
- Handler callbackHandler, final int sequence) {
+ public final void getInstantAppIntentFilterList(int hashPrefix[], String hostName,
+ PhaseTwoCallback callback, Handler callbackHandler, final int sequence) {
final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) throws RemoteException {
- final EphemeralResolveInfo ephemeralResolveInfo =
- data.getParcelable(EphemeralResolverService.EXTRA_RESOLVE_INFO);
+ final ArrayList<InstantAppResolveInfo> resolveList =
+ data.getParcelableArrayList(
+ InstantAppResolverService.EXTRA_RESOLVE_INFO);
callbackHandler.post(new Runnable() {
@Override
public void run() {
- callback.onPhaseTwoResolved(ephemeralResolveInfo, sequence);
+ callback.onPhaseTwoResolved(resolveList, sequence);
}
});
}
};
try {
getRemoteInstanceLazy()
- .getEphemeralIntentFilterList(remoteCallback, hostName, sequence);
+ .getInstantAppIntentFilterList(hashPrefix, sequence, hostName, remoteCallback);
} catch (RemoteException re) {
} catch (TimeoutException te) {
}
}
}
- private IEphemeralResolver getRemoteInstanceLazy() throws TimeoutException {
+ private IInstantAppResolver getRemoteInstanceLazy() throws TimeoutException {
synchronized (mLock) {
if (mRemoteInstance != null) {
return mRemoteInstance;
* Asynchronous callback when results come back from ephemeral resolution phase two.
*/
public abstract static class PhaseTwoCallback {
- abstract void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo, int sequence);
+ abstract void onPhaseTwoResolved(
+ List<InstantAppResolveInfo> instantAppResolveInfoList, int sequence);
}
private final class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mLock) {
- mRemoteInstance = IEphemeralResolver.Stub.asInterface(service);
+ mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
mLock.notifyAll();
}
}
}
private static final class GetEphemeralResolveInfoCaller
- extends TimedRemoteCaller<List<EphemeralResolveInfo>> {
+ extends TimedRemoteCaller<List<InstantAppResolveInfo>> {
private final IRemoteCallback mCallback;
public GetEphemeralResolveInfoCaller() {
mCallback = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) throws RemoteException {
- final ArrayList<EphemeralResolveInfo> resolveList =
+ final ArrayList<InstantAppResolveInfo> resolveList =
data.getParcelableArrayList(
- EphemeralResolverService.EXTRA_RESOLVE_INFO);
+ InstantAppResolverService.EXTRA_RESOLVE_INFO);
int sequence =
- data.getInt(EphemeralResolverService.EXTRA_SEQUENCE, -1);
+ data.getInt(InstantAppResolverService.EXTRA_SEQUENCE, -1);
onRemoteMethodResult(resolveList, sequence);
}
};
}
- public List<EphemeralResolveInfo> getEphemeralResolveInfoList(
- IEphemeralResolver target, int hashPrefix[])
+ public List<InstantAppResolveInfo> getEphemeralResolveInfoList(
+ IInstantAppResolver target, int hashPrefix[])
throws RemoteException, TimeoutException {
final int sequence = onBeforeRemoteCall();
- target.getEphemeralResolveInfoList(mCallback, hashPrefix, sequence);
+ target.getInstantAppResolveInfoList(hashPrefix, sequence, mCallback);
return getResultTimed(sequence);
}
}
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
-import android.content.pm.EphemeralIntentFilter;
-import android.content.pm.EphemeralRequest;
-import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.InstantAppRequest;
import android.content.pm.AuxiliaryResolveInfo;
-import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
+import android.content.pm.InstantAppIntentFilter;
+import android.content.pm.InstantAppResolveInfo;
+import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
import java.util.UUID;
/** @hide */
-public abstract class EphemeralResolver {
- public static AuxiliaryResolveInfo doEphemeralResolutionPhaseOne(Context context,
- EphemeralResolverConnection connection, EphemeralRequest requestObj) {
+public abstract class InstantAppResolver {
+ public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context,
+ EphemeralResolverConnection connection, InstantAppRequest requestObj) {
final Intent intent = requestObj.origIntent;
- final EphemeralDigest digest =
- new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
+ final InstantAppDigest digest =
+ new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/);
final int[] shaPrefix = digest.getDigestPrefix();
- final List<EphemeralResolveInfo> ephemeralResolveInfoList =
- connection.getEphemeralResolveInfoList(shaPrefix);
- if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
- // No hash prefix match; there are no ephemeral apps for this domain.
+ final List<InstantAppResolveInfo> instantAppResolveInfoList =
+ connection.getInstantAppResolveInfoList(shaPrefix);
+ if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) {
+ // No hash prefix match; there are no instant apps for this domain.
return null;
}
final String token = UUID.randomUUID().toString();
- return EphemeralResolver.filterEphemeralIntent(ephemeralResolveInfoList,
+ return InstantAppResolver.filterInstantAppIntent(instantAppResolveInfoList,
intent, requestObj.resolvedType, requestObj.userId,
intent.getPackage(), digest, token);
}
- public static void doEphemeralResolutionPhaseTwo(Context context,
- EphemeralResolverConnection connection, EphemeralRequest requestObj,
- ActivityInfo ephemeralInstaller, Handler callbackHandler) {
+ public static void doInstantAppResolutionPhaseTwo(Context context,
+ EphemeralResolverConnection connection, InstantAppRequest requestObj,
+ ActivityInfo instantAppInstaller, Handler callbackHandler) {
final Intent intent = requestObj.origIntent;
final String hostName = intent.getData().getHost();
- final EphemeralDigest digest = new EphemeralDigest(hostName, 5 /*maxDigests*/);
+ final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/);
+ final int[] shaPrefix = digest.getDigestPrefix();
final PhaseTwoCallback callback = new PhaseTwoCallback() {
@Override
- void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo,
+ void onPhaseTwoResolved(List<InstantAppResolveInfo> instantAppResolveInfoList,
int sequence) {
final String packageName;
final String splitName;
final int versionCode;
- if (ephemeralResolveInfo != null) {
- final ArrayList<EphemeralResolveInfo> ephemeralResolveInfoList =
- new ArrayList<EphemeralResolveInfo>(1);
- ephemeralResolveInfoList.add(ephemeralResolveInfo);
- final AuxiliaryResolveInfo ephemeralIntentInfo =
- EphemeralResolver.filterEphemeralIntent(
- ephemeralResolveInfoList, intent, null /*resolvedType*/,
+ if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
+ final AuxiliaryResolveInfo instantAppIntentInfo =
+ InstantAppResolver.filterInstantAppIntent(
+ instantAppResolveInfoList, intent, null /*resolvedType*/,
0 /*userId*/, intent.getPackage(), digest,
requestObj.responseObj.token);
- if (ephemeralIntentInfo != null
- && ephemeralIntentInfo.resolveInfo != null) {
- packageName = ephemeralIntentInfo.resolveInfo.getPackageName();
- splitName = ephemeralIntentInfo.splitName;
- versionCode = ephemeralIntentInfo.resolveInfo.getVersionCode();
+ if (instantAppIntentInfo != null
+ && instantAppIntentInfo.resolveInfo != null) {
+ packageName = instantAppIntentInfo.resolveInfo.getPackageName();
+ splitName = instantAppIntentInfo.splitName;
+ versionCode = instantAppIntentInfo.resolveInfo.getVersionCode();
} else {
packageName = null;
splitName = null;
requestObj.responseObj.token,
false /*needsPhaseTwo*/);
installerIntent.setComponent(new ComponentName(
- ephemeralInstaller.packageName, ephemeralInstaller.name));
+ instantAppInstaller.packageName, instantAppInstaller.name));
context.startActivity(installerIntent);
}
};
- connection.getEphemeralIntentFilterList(
- hostName, callback, callbackHandler, 0 /*sequence*/);
+ connection.getInstantAppIntentFilterList(
+ shaPrefix, hostName, callback, callbackHandler, 0 /*sequence*/);
}
/**
- * Builds and returns an intent to launch the ephemeral installer.
+ * Builds and returns an intent to launch the instant installer.
*/
public static Intent buildEphemeralInstallerIntent(@NonNull Intent origIntent,
@NonNull String callingPackage,
@NonNull String resolvedType,
int userId,
- @NonNull String ephemeralPackageName,
- @Nullable String ephemeralSplitName,
+ @NonNull String instantAppPackageName,
+ @Nullable String instantAppSplitName,
int versionCode,
@Nullable String token,
boolean needsPhaseTwo) {
- // Construct the intent that launches the ephemeral installer
+ // Construct the intent that launches the instant installer
int flags = origIntent.getFlags();
final Intent intent = new Intent();
intent.setFlags(flags
new IntentSender(successIntentTarget));
} catch (RemoteException ignore) { /* ignore; same process */ }
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName);
- intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, instantAppPackageName);
+ intent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
intent.putExtra(Intent.EXTRA_VERSION_CODE, versionCode);
}
return intent;
}
- private static AuxiliaryResolveInfo filterEphemeralIntent(
- List<EphemeralResolveInfo> ephemeralResolveInfoList,
+ private static AuxiliaryResolveInfo filterInstantAppIntent(
+ List<InstantAppResolveInfo> instantAppResolveInfoList,
Intent intent, String resolvedType, int userId, String packageName,
- EphemeralDigest digest, String token) {
+ InstantAppDigest digest, String token) {
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
// Go in reverse order so we match the narrowest scope first.
for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
- for (EphemeralResolveInfo ephemeralInfo : ephemeralResolveInfoList) {
- if (!Arrays.equals(digestBytes[i], ephemeralInfo.getDigestBytes())) {
+ for (InstantAppResolveInfo instantAppInfo : instantAppResolveInfoList) {
+ if (!Arrays.equals(digestBytes[i], instantAppInfo.getDigestBytes())) {
continue;
}
if (packageName != null
- && !packageName.equals(ephemeralInfo.getPackageName())) {
+ && !packageName.equals(instantAppInfo.getPackageName())) {
continue;
}
- final List<EphemeralIntentFilter> ephemeralFilters =
- ephemeralInfo.getIntentFilters();
+ final List<InstantAppIntentFilter> instantAppFilters =
+ instantAppInfo.getIntentFilters();
// No filters; we need to start phase two
- if (ephemeralFilters == null || ephemeralFilters.isEmpty()) {
- return new AuxiliaryResolveInfo(ephemeralInfo,
+ if (instantAppFilters == null || instantAppFilters.isEmpty()) {
+ return new AuxiliaryResolveInfo(instantAppInfo,
new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
null /*splitName*/, token, true /*needsPhase2*/);
}
// We have a domain match; resolve the filters to see if anything matches.
- final PackageManagerService.EphemeralIntentResolver ephemeralResolver =
+ final PackageManagerService.EphemeralIntentResolver instantAppResolver =
new PackageManagerService.EphemeralIntentResolver();
- for (int j = ephemeralFilters.size() - 1; j >= 0; --j) {
- final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j);
- final List<IntentFilter> splitFilters = ephemeralFilter.getFilters();
+ 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(ephemeralInfo,
- splitFilters.get(k), ephemeralFilter.getSplitName(),
+ new AuxiliaryResolveInfo(instantAppInfo,
+ splitFilters.get(k), instantAppFilter.getSplitName(),
token, false /*needsPhase2*/);
- ephemeralResolver.addFilter(intentInfo);
+ instantAppResolver.addFilter(intentInfo);
}
}
- List<AuxiliaryResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
+ List<AuxiliaryResolveInfo> matchedResolveInfoList = instantAppResolver.queryIntent(
intent, resolvedType, false /*defaultOnly*/, userId);
if (!matchedResolveInfoList.isEmpty()) {
return matchedResolveInfoList.get(0);
}
}
}
- // Hash or filter mis-match; no ephemeral apps for this domain.
+ // Hash or filter mis-match; no instant apps for this domain.
return null;
}
}
import android.content.pm.AppsQueryHelper;
import android.content.pm.ChangedPackages;
import android.content.pm.ComponentInfo;
-import android.content.pm.EphemeralRequest;
-import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.InstantAppRequest;
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstantAppInfo;
+import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
break;
}
case INSTANT_APP_RESOLUTION_PHASE_TWO: {
- EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext,
+ InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
mInstantAppResolverConnection,
- (EphemeralRequest) msg.obj,
+ (InstantAppRequest) msg.obj,
mInstantAppInstallerActivity,
mHandler);
}
Intent origIntent, String resolvedType, String callingPackage,
int userId) {
final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
- new EphemeralRequest(responseObj, origIntent, resolvedType,
+ new InstantAppRequest(responseObj, origIntent, resolvedType,
callingPackage, userId));
mHandler.sendMessage(msg);
}
}
if (addEphemeral) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
- final EphemeralRequest requestObject = new EphemeralRequest(
+ final InstantAppRequest requestObject = new InstantAppRequest(
null /*responseObj*/, intent /*origIntent*/, resolvedType,
null /*callingPackage*/, userId);
final AuxiliaryResolveInfo auxiliaryResponse =
- EphemeralResolver.doEphemeralResolutionPhaseOne(
+ InstantAppResolver.doInstantAppResolutionPhaseOne(
mContext, mInstantAppResolverConnection, requestObject);
if (auxiliaryResponse != null) {
if (DEBUG_EPHEMERAL) {
* would be needed to apply ordering. If the intent resolver becomes re-entrant,
* this needs to be contained entirely within {@link #filterResults()}.
*/
- final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
+ final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
@Override
protected AuxiliaryResolveInfo[] newArray(int size) {
}
final String packageName = responseObj.resolveInfo.getPackageName();
final Integer order = responseObj.getOrder();
- final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
+ final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
mOrderResult.get(packageName);
// ordering is enabled and this item's order isn't high enough
if (lastOrderResult != null && lastOrderResult.first >= order) {
return null;
}
- final EphemeralResolveInfo res = responseObj.resolveInfo;
+ final InstantAppResolveInfo res = responseObj.resolveInfo;
if (order > 0) {
// non-zero order, enable ordering
mOrderResult.put(packageName, new Pair<>(order, res));
}
int resultSize = results.size();
for (int i = 0; i < resultSize; i++) {
- final EphemeralResolveInfo info = results.get(i).resolveInfo;
+ final InstantAppResolveInfo info = results.get(i).resolveInfo;
final String packageName = info.getPackageName();
- final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
+ final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
if (savedInfo == null) {
// package doesn't having ordering
continue;