Loading core/java/android/app/InstantAppResolverService.java +8 −2 Original line number Diff line number Diff line Loading @@ -91,6 +91,9 @@ public abstract class InstantAppResolverService extends Service { @Override public void getInstantAppResolveInfoList( int digestPrefix[], String token, int sequence, IRemoteCallback callback) { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Phase1 called; posting"); } final SomeArgs args = SomeArgs.obtain(); args.arg1 = callback; args.arg2 = digestPrefix; Loading @@ -103,6 +106,9 @@ public abstract class InstantAppResolverService extends Service { @Override public void getInstantAppIntentFilterList( int digestPrefix[], String token, String hostName, IRemoteCallback callback) { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Phase2 called; posting"); } final SomeArgs args = SomeArgs.obtain(); args.arg1 = callback; args.arg2 = digestPrefix; Loading Loading @@ -140,7 +146,7 @@ public abstract class InstantAppResolverService extends Service { void _onGetInstantAppResolveInfo(int[] digestPrefix, String token, InstantAppResolutionCallback callback) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Instant resolver; getInstantAppResolveInfo;" Slog.d(TAG, "[" + token + "] Phase1 request;" + " prefix: " + Arrays.toString(digestPrefix)); } onGetInstantAppResolveInfo(digestPrefix, token, callback); Loading @@ -149,7 +155,7 @@ public abstract class InstantAppResolverService extends Service { void _onGetInstantAppIntentFilter(int digestPrefix[], String token, String hostName, InstantAppResolutionCallback callback) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Instant resolver; getInstantAppIntentFilter;" Slog.d(TAG, "[" + token + "] Phase2 request;" + " prefix: " + Arrays.toString(digestPrefix)); } onGetInstantAppIntentFilter(digestPrefix, token, callback); Loading services/core/java/com/android/server/pm/EphemeralResolverConnection.java +77 −55 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.os.UserHandle; import android.util.Slog; import android.util.TimedRemoteCaller; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TransferPipe; import java.io.FileDescriptor; Loading @@ -53,7 +54,9 @@ final class EphemeralResolverConnection implements DeathRecipient { private static final String TAG = "PackageManager"; // This is running in a critical section and the timeout must be sufficiently low private static final long BIND_SERVICE_TIMEOUT_MS = ("eng".equals(Build.TYPE)) ? 300 : 200; ("eng".equals(Build.TYPE)) ? 500 : 300; private static final long CALL_SERVICE_TIMEOUT_MS = ("eng".equals(Build.TYPE)) ? 200 : 100; private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; private final Object mLock = new Object(); Loading @@ -64,7 +67,9 @@ final class EphemeralResolverConnection implements DeathRecipient { /** Intent used to bind to the service */ private final Intent mIntent; private volatile boolean mBindRequested; @GuardedBy("mLock") private volatile boolean mIsBinding; @GuardedBy("mLock") private IInstantAppResolver mRemoteInstance; public EphemeralResolverConnection( Loading @@ -76,11 +81,18 @@ final class EphemeralResolverConnection implements DeathRecipient { public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[], String token) { throwIfCalledOnMainThread(); IInstantAppResolver target = null; try { return mGetEphemeralResolveInfoCaller.getEphemeralResolveInfoList( getRemoteInstanceLazy(), hashPrefix, token); } catch (RemoteException re) { } catch (TimeoutException te) { target = getRemoteInstanceLazy(token); return mGetEphemeralResolveInfoCaller .getEphemeralResolveInfoList(target, hashPrefix, token); } catch (RemoteException e) { } catch (InterruptedException | TimeoutException e) { if (target == null) { Slog.w(TAG, "[" + token + "] Timeout! Phase1 binding to instant app resolver"); } else { Slog.w(TAG, "[" + token + "] Timeout! Phase1 resolving instant app"); } } finally { synchronized (mLock) { mLock.notifyAll(); Loading @@ -107,71 +119,74 @@ final class EphemeralResolverConnection implements DeathRecipient { } }; try { getRemoteInstanceLazy() getRemoteInstanceLazy(token) .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback); } catch (RemoteException re) { } catch (TimeoutException te) { } } public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { synchronized (mLock) { pw.append(prefix).append("bound=") .append((mRemoteInstance != null) ? "true" : "false").println(); pw.flush(); try { TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd, new String[] { prefix }); } catch (IOException | TimeoutException | RemoteException e) { pw.println("Failed to dump remote instance: " + e); } } catch (RemoteException e) { } catch (InterruptedException | TimeoutException e) { Slog.w(TAG, "[" + token + "] Timeout! Phase2 binding to instant app resolver"); } } private IInstantAppResolver getRemoteInstanceLazy() throws TimeoutException { private IInstantAppResolver getRemoteInstanceLazy(String token) throws TimeoutException, InterruptedException { synchronized (mLock) { if (mRemoteInstance != null) { return mRemoteInstance; } bindLocked(); bindLocked(token); return mRemoteInstance; } } private void bindLocked() throws TimeoutException { if (mRemoteInstance != null) { return; } if (!mBindRequested) { mBindRequested = true; if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Binding to resolver service"); } mContext.bindServiceAsUser(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM); } private void waitForBind(String token) throws TimeoutException, InterruptedException { final long startMillis = SystemClock.uptimeMillis(); while (true) { while (mIsBinding) { if (mRemoteInstance != null) { break; } final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; final long remainingMillis = BIND_SERVICE_TIMEOUT_MS - elapsedMillis; if (remainingMillis <= 0) { throw new TimeoutException("Didn't bind to resolver in time."); throw new TimeoutException("[" + token + "] Didn't bind to resolver in time!"); } try { mLock.wait(remainingMillis); } catch (InterruptedException ie) { /* ignore */ } } private void bindLocked(String token) throws TimeoutException, InterruptedException { if (DEBUG_EPHEMERAL && mIsBinding && mRemoteInstance == null) { Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection"); } try { waitForBind(token); } catch (TimeoutException e) { if (DEBUG_EPHEMERAL) { Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding"); } mContext.unbindService(mServiceConnection); } if (mRemoteInstance != null) { return; } mIsBinding = true; if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Binding to instant app resolver"); } boolean wasBound = false; try { final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; wasBound = mContext .bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM); if (wasBound) { waitForBind(token); } else { Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent); } } finally { mIsBinding = wasBound && mRemoteInstance == null; mLock.notifyAll(); } } private void throwIfCalledOnMainThread() { if (Thread.currentThread() == mContext.getMainLooper().getThread()) { Loading @@ -182,13 +197,18 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void binderDied() { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Binder died"); Slog.d(TAG, "Binder to instant app resolver died"); } synchronized (mLock) { handleBinderDiedLocked(); } } private void handleBinderDiedLocked() { if (mRemoteInstance != null) { mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/); } mRemoteInstance = null; mBindRequested = false; } /** Loading @@ -203,13 +223,15 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Service connected"); Slog.d(TAG, "Connected to instant app resolver"); } synchronized (mLock) { mRemoteInstance = IInstantAppResolver.Stub.asInterface(service); mIsBinding = false; try { service.linkToDeath(EphemeralResolverConnection.this, 0 /*flags*/); mRemoteInstance = IInstantAppResolver.Stub.asInterface(service); } catch (RemoteException e) { handleBinderDiedLocked(); } mLock.notifyAll(); } Loading @@ -218,10 +240,10 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void onServiceDisconnected(ComponentName name) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Service disconnected"); Slog.d(TAG, "Disconnected from instant app resolver"); } synchronized (mLock) { mRemoteInstance = null; handleBinderDiedLocked(); } } } Loading @@ -231,7 +253,7 @@ final class EphemeralResolverConnection implements DeathRecipient { private final IRemoteCallback mCallback; public GetEphemeralResolveInfoCaller() { super(BIND_SERVICE_TIMEOUT_MS); super(CALL_SERVICE_TIMEOUT_MS); mCallback = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) throws RemoteException { Loading services/core/java/com/android/server/pm/InstantAppResolver.java +15 −8 Original line number Diff line number Diff line Loading @@ -74,11 +74,11 @@ public abstract class InstantAppResolver { public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context, EphemeralResolverConnection connection, InstantAppRequest requestObj) { if (DEBUG_EPHEMERAL) { Log.d(TAG, "Resolving phase 1"); } final long startTime = System.currentTimeMillis(); final String token = UUID.randomUUID().toString(); if (DEBUG_EPHEMERAL) { Log.d(TAG, "[" + token + "] Resolving phase 1"); } final Intent intent = requestObj.origIntent; final InstantAppDigest digest = new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/); Loading @@ -89,7 +89,7 @@ public abstract class InstantAppResolver { if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) { // No hash prefix match; there are no instant apps for this domain. if (DEBUG_EPHEMERAL) { Log.d(TAG, "No results returned"); Log.d(TAG, "[" + token + "] No results returned"); } return null; } Loading @@ -98,21 +98,24 @@ public abstract class InstantAppResolver { intent.getPackage(), digest, token); logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token, RESOLUTION_SUCCESS); if (DEBUG_EPHEMERAL && resolveInfo == null) { Log.d(TAG, "[" + token + "] No results matched"); } return resolveInfo; } public static void doInstantAppResolutionPhaseTwo(Context context, EphemeralResolverConnection connection, InstantAppRequest requestObj, ActivityInfo instantAppInstaller, Handler callbackHandler) { final long startTime = System.currentTimeMillis(); final String token = requestObj.responseObj.token; if (DEBUG_EPHEMERAL) { Log.d(TAG, "Resolving phase 2"); Log.d(TAG, "[" + token + "] Resolving phase 2"); } final long startTime = System.currentTimeMillis(); final Intent intent = requestObj.origIntent; final String hostName = intent.getData().getHost(); final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/); final int[] shaPrefix = digest.getDigestPrefix(); final String token = requestObj.responseObj.token; final PhaseTwoCallback callback = new PhaseTwoCallback() { @Override Loading Loading @@ -285,12 +288,16 @@ public abstract class InstantAppResolver { if (!matchedResolveInfoList.isEmpty()) { if (DEBUG_EPHEMERAL) { final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0); Log.d(TAG, "Found match;" Log.d(TAG, "[" + token + "] Found match;" + " package: " + info.packageName + ", split: " + info.splitName + ", versionCode: " + info.versionCode); } return matchedResolveInfoList.get(0); } else if (DEBUG_EPHEMERAL) { Log.d(TAG, "[" + token + "] No matches found" + " package: " + instantAppInfo.getPackageName() + ", versionCode: " + instantAppInfo.getVersionCode()); } } } Loading Loading
core/java/android/app/InstantAppResolverService.java +8 −2 Original line number Diff line number Diff line Loading @@ -91,6 +91,9 @@ public abstract class InstantAppResolverService extends Service { @Override public void getInstantAppResolveInfoList( int digestPrefix[], String token, int sequence, IRemoteCallback callback) { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Phase1 called; posting"); } final SomeArgs args = SomeArgs.obtain(); args.arg1 = callback; args.arg2 = digestPrefix; Loading @@ -103,6 +106,9 @@ public abstract class InstantAppResolverService extends Service { @Override public void getInstantAppIntentFilterList( int digestPrefix[], String token, String hostName, IRemoteCallback callback) { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Phase2 called; posting"); } final SomeArgs args = SomeArgs.obtain(); args.arg1 = callback; args.arg2 = digestPrefix; Loading Loading @@ -140,7 +146,7 @@ public abstract class InstantAppResolverService extends Service { void _onGetInstantAppResolveInfo(int[] digestPrefix, String token, InstantAppResolutionCallback callback) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Instant resolver; getInstantAppResolveInfo;" Slog.d(TAG, "[" + token + "] Phase1 request;" + " prefix: " + Arrays.toString(digestPrefix)); } onGetInstantAppResolveInfo(digestPrefix, token, callback); Loading @@ -149,7 +155,7 @@ public abstract class InstantAppResolverService extends Service { void _onGetInstantAppIntentFilter(int digestPrefix[], String token, String hostName, InstantAppResolutionCallback callback) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Instant resolver; getInstantAppIntentFilter;" Slog.d(TAG, "[" + token + "] Phase2 request;" + " prefix: " + Arrays.toString(digestPrefix)); } onGetInstantAppIntentFilter(digestPrefix, token, callback); Loading
services/core/java/com/android/server/pm/EphemeralResolverConnection.java +77 −55 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.os.UserHandle; import android.util.Slog; import android.util.TimedRemoteCaller; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TransferPipe; import java.io.FileDescriptor; Loading @@ -53,7 +54,9 @@ final class EphemeralResolverConnection implements DeathRecipient { private static final String TAG = "PackageManager"; // This is running in a critical section and the timeout must be sufficiently low private static final long BIND_SERVICE_TIMEOUT_MS = ("eng".equals(Build.TYPE)) ? 300 : 200; ("eng".equals(Build.TYPE)) ? 500 : 300; private static final long CALL_SERVICE_TIMEOUT_MS = ("eng".equals(Build.TYPE)) ? 200 : 100; private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; private final Object mLock = new Object(); Loading @@ -64,7 +67,9 @@ final class EphemeralResolverConnection implements DeathRecipient { /** Intent used to bind to the service */ private final Intent mIntent; private volatile boolean mBindRequested; @GuardedBy("mLock") private volatile boolean mIsBinding; @GuardedBy("mLock") private IInstantAppResolver mRemoteInstance; public EphemeralResolverConnection( Loading @@ -76,11 +81,18 @@ final class EphemeralResolverConnection implements DeathRecipient { public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[], String token) { throwIfCalledOnMainThread(); IInstantAppResolver target = null; try { return mGetEphemeralResolveInfoCaller.getEphemeralResolveInfoList( getRemoteInstanceLazy(), hashPrefix, token); } catch (RemoteException re) { } catch (TimeoutException te) { target = getRemoteInstanceLazy(token); return mGetEphemeralResolveInfoCaller .getEphemeralResolveInfoList(target, hashPrefix, token); } catch (RemoteException e) { } catch (InterruptedException | TimeoutException e) { if (target == null) { Slog.w(TAG, "[" + token + "] Timeout! Phase1 binding to instant app resolver"); } else { Slog.w(TAG, "[" + token + "] Timeout! Phase1 resolving instant app"); } } finally { synchronized (mLock) { mLock.notifyAll(); Loading @@ -107,71 +119,74 @@ final class EphemeralResolverConnection implements DeathRecipient { } }; try { getRemoteInstanceLazy() getRemoteInstanceLazy(token) .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback); } catch (RemoteException re) { } catch (TimeoutException te) { } } public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { synchronized (mLock) { pw.append(prefix).append("bound=") .append((mRemoteInstance != null) ? "true" : "false").println(); pw.flush(); try { TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd, new String[] { prefix }); } catch (IOException | TimeoutException | RemoteException e) { pw.println("Failed to dump remote instance: " + e); } } catch (RemoteException e) { } catch (InterruptedException | TimeoutException e) { Slog.w(TAG, "[" + token + "] Timeout! Phase2 binding to instant app resolver"); } } private IInstantAppResolver getRemoteInstanceLazy() throws TimeoutException { private IInstantAppResolver getRemoteInstanceLazy(String token) throws TimeoutException, InterruptedException { synchronized (mLock) { if (mRemoteInstance != null) { return mRemoteInstance; } bindLocked(); bindLocked(token); return mRemoteInstance; } } private void bindLocked() throws TimeoutException { if (mRemoteInstance != null) { return; } if (!mBindRequested) { mBindRequested = true; if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Binding to resolver service"); } mContext.bindServiceAsUser(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM); } private void waitForBind(String token) throws TimeoutException, InterruptedException { final long startMillis = SystemClock.uptimeMillis(); while (true) { while (mIsBinding) { if (mRemoteInstance != null) { break; } final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; final long remainingMillis = BIND_SERVICE_TIMEOUT_MS - elapsedMillis; if (remainingMillis <= 0) { throw new TimeoutException("Didn't bind to resolver in time."); throw new TimeoutException("[" + token + "] Didn't bind to resolver in time!"); } try { mLock.wait(remainingMillis); } catch (InterruptedException ie) { /* ignore */ } } private void bindLocked(String token) throws TimeoutException, InterruptedException { if (DEBUG_EPHEMERAL && mIsBinding && mRemoteInstance == null) { Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection"); } try { waitForBind(token); } catch (TimeoutException e) { if (DEBUG_EPHEMERAL) { Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding"); } mContext.unbindService(mServiceConnection); } if (mRemoteInstance != null) { return; } mIsBinding = true; if (DEBUG_EPHEMERAL) { Slog.v(TAG, "[" + token + "] Binding to instant app resolver"); } boolean wasBound = false; try { final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; wasBound = mContext .bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM); if (wasBound) { waitForBind(token); } else { Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent); } } finally { mIsBinding = wasBound && mRemoteInstance == null; mLock.notifyAll(); } } private void throwIfCalledOnMainThread() { if (Thread.currentThread() == mContext.getMainLooper().getThread()) { Loading @@ -182,13 +197,18 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void binderDied() { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Binder died"); Slog.d(TAG, "Binder to instant app resolver died"); } synchronized (mLock) { handleBinderDiedLocked(); } } private void handleBinderDiedLocked() { if (mRemoteInstance != null) { mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/); } mRemoteInstance = null; mBindRequested = false; } /** Loading @@ -203,13 +223,15 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Service connected"); Slog.d(TAG, "Connected to instant app resolver"); } synchronized (mLock) { mRemoteInstance = IInstantAppResolver.Stub.asInterface(service); mIsBinding = false; try { service.linkToDeath(EphemeralResolverConnection.this, 0 /*flags*/); mRemoteInstance = IInstantAppResolver.Stub.asInterface(service); } catch (RemoteException e) { handleBinderDiedLocked(); } mLock.notifyAll(); } Loading @@ -218,10 +240,10 @@ final class EphemeralResolverConnection implements DeathRecipient { @Override public void onServiceDisconnected(ComponentName name) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "Service disconnected"); Slog.d(TAG, "Disconnected from instant app resolver"); } synchronized (mLock) { mRemoteInstance = null; handleBinderDiedLocked(); } } } Loading @@ -231,7 +253,7 @@ final class EphemeralResolverConnection implements DeathRecipient { private final IRemoteCallback mCallback; public GetEphemeralResolveInfoCaller() { super(BIND_SERVICE_TIMEOUT_MS); super(CALL_SERVICE_TIMEOUT_MS); mCallback = new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) throws RemoteException { Loading
services/core/java/com/android/server/pm/InstantAppResolver.java +15 −8 Original line number Diff line number Diff line Loading @@ -74,11 +74,11 @@ public abstract class InstantAppResolver { public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context, EphemeralResolverConnection connection, InstantAppRequest requestObj) { if (DEBUG_EPHEMERAL) { Log.d(TAG, "Resolving phase 1"); } final long startTime = System.currentTimeMillis(); final String token = UUID.randomUUID().toString(); if (DEBUG_EPHEMERAL) { Log.d(TAG, "[" + token + "] Resolving phase 1"); } final Intent intent = requestObj.origIntent; final InstantAppDigest digest = new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/); Loading @@ -89,7 +89,7 @@ public abstract class InstantAppResolver { if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) { // No hash prefix match; there are no instant apps for this domain. if (DEBUG_EPHEMERAL) { Log.d(TAG, "No results returned"); Log.d(TAG, "[" + token + "] No results returned"); } return null; } Loading @@ -98,21 +98,24 @@ public abstract class InstantAppResolver { intent.getPackage(), digest, token); logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token, RESOLUTION_SUCCESS); if (DEBUG_EPHEMERAL && resolveInfo == null) { Log.d(TAG, "[" + token + "] No results matched"); } return resolveInfo; } public static void doInstantAppResolutionPhaseTwo(Context context, EphemeralResolverConnection connection, InstantAppRequest requestObj, ActivityInfo instantAppInstaller, Handler callbackHandler) { final long startTime = System.currentTimeMillis(); final String token = requestObj.responseObj.token; if (DEBUG_EPHEMERAL) { Log.d(TAG, "Resolving phase 2"); Log.d(TAG, "[" + token + "] Resolving phase 2"); } final long startTime = System.currentTimeMillis(); final Intent intent = requestObj.origIntent; final String hostName = intent.getData().getHost(); final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/); final int[] shaPrefix = digest.getDigestPrefix(); final String token = requestObj.responseObj.token; final PhaseTwoCallback callback = new PhaseTwoCallback() { @Override Loading Loading @@ -285,12 +288,16 @@ public abstract class InstantAppResolver { if (!matchedResolveInfoList.isEmpty()) { if (DEBUG_EPHEMERAL) { final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0); Log.d(TAG, "Found match;" Log.d(TAG, "[" + token + "] Found match;" + " package: " + info.packageName + ", split: " + info.splitName + ", versionCode: " + info.versionCode); } return matchedResolveInfoList.get(0); } else if (DEBUG_EPHEMERAL) { Log.d(TAG, "[" + token + "] No matches found" + " package: " + instantAppInfo.getPackageName() + ", versionCode: " + instantAppInfo.getVersionCode()); } } } Loading