Merge "Refactor EphemeralResolverService"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a485f71fd7
@@ -16,4 +16,5 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
/** @deprecated */
|
||||
parcelable EphemeralResolveInfo;
|
||||
|
||||
@@ -18,9 +18,11 @@ 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.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -29,20 +31,17 @@ import android.os.Looper;
|
||||
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.
|
||||
*
|
||||
@@ -74,90 +73,28 @@ public abstract class EphemeralResolverService extends Service {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.app;
|
||||
|
||||
import android.os.IRemoteCallback;
|
||||
|
||||
/** @hide */
|
||||
/** @hide @deprecated */
|
||||
oneway interface IEphemeralResolver {
|
||||
void getEphemeralResolveInfoList(IRemoteCallback callback, in int[] digestPrefix,
|
||||
int sequence);
|
||||
|
||||
28
core/java/android/app/IInstantAppResolver.aidl
Normal file
28
core/java/android/app/IInstantAppResolver.aidl
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
19
core/java/android/app/InstantAppResolveInfo.aidl
Normal file
19
core/java/android/app/InstantAppResolveInfo.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
** 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;
|
||||
176
core/java/android/app/InstantAppResolverService.java
Normal file
176
core/java/android/app/InstantAppResolverService.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,21 +31,21 @@ import android.content.IntentFilter;
|
||||
* @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,
|
||||
|
||||
@@ -30,31 +30,34 @@ import java.util.List;
|
||||
* 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
|
||||
@@ -64,33 +67,18 @@ public final class EphemeralIntentFilter implements Parcelable {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
|
||||
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;
|
||||
@@ -34,18 +35,13 @@ import java.util.Locale;
|
||||
* 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;
|
||||
|
||||
@@ -55,13 +51,12 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
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
|
||||
@@ -71,22 +66,11 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -95,33 +79,53 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -136,19 +140,17 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
|
||||
@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];
|
||||
}
|
||||
@@ -167,12 +169,7 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
*/
|
||||
@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*/);
|
||||
@@ -180,73 +177,24 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
|
||||
/** @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;
|
||||
}
|
||||
}
|
||||
|
||||
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()][]);
|
||||
mInstantAppDigest = new InstantAppDigest(hostName, maxDigests);
|
||||
}
|
||||
|
||||
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();
|
||||
mInstantAppDigest = in.readParcelable(null /*loader*/);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
InstantAppDigest getInstantAppDigest() {
|
||||
return mInstantAppDigest;
|
||||
}
|
||||
|
||||
public byte[][] getDigestBytes() {
|
||||
return mDigestBytes;
|
||||
return mInstantAppDigest.getDigestBytes();
|
||||
}
|
||||
|
||||
public int[] getDigestPrefix() {
|
||||
return mDigestPrefix;
|
||||
return mInstantAppDigest.getDigestPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -256,24 +204,17 @@ public final class EphemeralResolveInfo implements Parcelable {
|
||||
|
||||
@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];
|
||||
}
|
||||
|
||||
82
core/java/android/content/pm/InstantAppIntentFilter.java
Normal file
82
core/java/android/content/pm/InstantAppIntentFilter.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -19,22 +19,22 @@ package android.content.pm;
|
||||
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;
|
||||
250
core/java/android/content/pm/InstantAppResolveInfo.java
Normal file
250
core/java/android/content/pm/InstantAppResolveInfo.java
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user