android.app.IInstantAppResolver

Here are the examples of the java api android.app.IInstantAppResolver taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

3 Examples 7

19 Source : InstantAppResolverConnection.java
with Apache License 2.0
from lulululbj

@WorkerThread
private IInstantAppResolver bind(String token) throws ConnectionException, TimeoutException, InterruptedException {
    boolean doUnbind = false;
    synchronized (mLock) {
        if (mRemoteInstance != null) {
            return mRemoteInstance;
        }
        if (mBindState == STATE_PENDING) {
            // there is a pending bind, let's see if we can use it.
            if (DEBUG_INSTANT) {
                Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
            }
            try {
                waitForBindLocked(token);
                if (mRemoteInstance != null) {
                    return mRemoteInstance;
                }
            } catch (TimeoutException e) {
                // nope, we might have to try a rebind.
                doUnbind = true;
            }
        }
        if (mBindState == STATE_BINDING) {
            // someone was binding when we called bind(), or they raced ahead while we were
            // waiting in the PENDING case; wait for their result instead. Last chance!
            if (DEBUG_INSTANT) {
                Slog.i(TAG, "[" + token + "] Another thread is binding; waiting for connection");
            }
            waitForBindLocked(token);
            // if the other thread's bindService() returned false, we could still have null.
            if (mRemoteInstance != null) {
                return mRemoteInstance;
            }
            throw new ConnectionException(ConnectionException.FAILURE_BIND);
        }
        // our time to shine! :)
        mBindState = STATE_BINDING;
    }
    // only one thread can be here at a time (the one that set STATE_BINDING)
    boolean wasBound = false;
    IInstantAppResolver instance = null;
    try {
        if (doUnbind) {
            if (DEBUG_INSTANT) {
                Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
            }
            mContext.unbindService(mServiceConnection);
        }
        if (DEBUG_INSTANT) {
            Slog.v(TAG, "[" + token + "] Binding to instant app resolver");
        }
        final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
        wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM);
        if (wasBound) {
            synchronized (mLock) {
                waitForBindLocked(token);
                instance = mRemoteInstance;
                return instance;
            }
        } else {
            Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent);
            throw new ConnectionException(ConnectionException.FAILURE_BIND);
        }
    } finally {
        synchronized (mLock) {
            if (wasBound && instance == null) {
                mBindState = STATE_PENDING;
            } else {
                mBindState = STATE_IDLE;
            }
            mLock.notifyAll();
        }
    }
}

19 Source : InstantAppResolverConnection.java
with Apache License 2.0
from lulululbj

public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(Intent sanitizedIntent, int[] hashPrefix, String token) throws ConnectionException {
    throwIfCalledOnMainThread();
    IInstantAppResolver target = null;
    try {
        try {
            target = getRemoteInstanceLazy(token);
        } catch (TimeoutException e) {
            throw new ConnectionException(ConnectionException.FAILURE_BIND);
        } catch (InterruptedException e) {
            throw new ConnectionException(ConnectionException.FAILURE_INTERRUPTED);
        }
        try {
            return mGetInstantAppResolveInfoCaller.getInstantAppResolveInfoList(target, sanitizedIntent, hashPrefix, token);
        } catch (TimeoutException e) {
            throw new ConnectionException(ConnectionException.FAILURE_CALL);
        } catch (RemoteException ignore) {
        }
    } finally {
        synchronized (mLock) {
            mLock.notifyAll();
        }
    }
    return null;
}

17 Source : InstantAppResolverConnection.java
with Apache License 2.0
from lulululbj

/**
 * Represents a remote instant app resolver. It is responsible for binding to the remote
 * service and handling all interactions in a timely manner.
 * @hide
 */
final clreplaced InstantAppResolverConnection 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 = Build.IS_ENG ? 500 : 300;

    private static final long CALL_SERVICE_TIMEOUT_MS = Build.IS_ENG ? 200 : 100;

    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;

    private final Object mLock = new Object();

    private final GetInstantAppResolveInfoCaller mGetInstantAppResolveInfoCaller = new GetInstantAppResolveInfoCaller();

    private final ServiceConnection mServiceConnection = new MyServiceConnection();

    private final Context mContext;

    /**
     * Intent used to bind to the service
     */
    private final Intent mIntent;

    // no bind operation is ongoing
    private static final int STATE_IDLE = 0;

    // someone is binding and waiting
    private static final int STATE_BINDING = 1;

    // a bind is pending, but the caller is not waiting
    private static final int STATE_PENDING = 2;

    private final Handler mBgHandler;

    @GuardedBy("mLock")
    private int mBindState = STATE_IDLE;

    @GuardedBy("mLock")
    private IInstantAppResolver mRemoteInstance;

    public InstantAppResolverConnection(Context context, ComponentName componentName, String action) {
        mContext = context;
        mIntent = new Intent(action).setComponent(componentName);
        mBgHandler = BackgroundThread.getHandler();
    }

    public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(Intent sanitizedIntent, int[] hashPrefix, String token) throws ConnectionException {
        throwIfCalledOnMainThread();
        IInstantAppResolver target = null;
        try {
            try {
                target = getRemoteInstanceLazy(token);
            } catch (TimeoutException e) {
                throw new ConnectionException(ConnectionException.FAILURE_BIND);
            } catch (InterruptedException e) {
                throw new ConnectionException(ConnectionException.FAILURE_INTERRUPTED);
            }
            try {
                return mGetInstantAppResolveInfoCaller.getInstantAppResolveInfoList(target, sanitizedIntent, hashPrefix, token);
            } catch (TimeoutException e) {
                throw new ConnectionException(ConnectionException.FAILURE_CALL);
            } catch (RemoteException ignore) {
            }
        } finally {
            synchronized (mLock) {
                mLock.notifyAll();
            }
        }
        return null;
    }

    public final void getInstantAppIntentFilterList(Intent sanitizedIntent, int[] hashPrefix, String token, PhaseTwoCallback callback, Handler callbackHandler, final long startTime) throws ConnectionException {
        final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {

            @Override
            public void sendResult(Bundle data) throws RemoteException {
                final ArrayList<InstantAppResolveInfo> resolveList = data.getParcelableArrayList(InstantAppResolverService.EXTRA_RESOLVE_INFO);
                callbackHandler.post(() -> callback.onPhaseTwoResolved(resolveList, startTime));
            }
        };
        try {
            getRemoteInstanceLazy(token).getInstantAppIntentFilterList(sanitizedIntent, hashPrefix, token, remoteCallback);
        } catch (TimeoutException e) {
            throw new ConnectionException(ConnectionException.FAILURE_BIND);
        } catch (InterruptedException e) {
            throw new ConnectionException(ConnectionException.FAILURE_INTERRUPTED);
        } catch (RemoteException ignore) {
        }
    }

    @WorkerThread
    private IInstantAppResolver getRemoteInstanceLazy(String token) throws ConnectionException, TimeoutException, InterruptedException {
        long binderToken = Binder.clearCallingIdenreplacedy();
        try {
            return bind(token);
        } finally {
            Binder.restoreCallingIdenreplacedy(binderToken);
        }
    }

    @GuardedBy("mLock")
    private void waitForBindLocked(String token) throws TimeoutException, InterruptedException {
        final long startMillis = SystemClock.uptimeMillis();
        while (mBindState != STATE_IDLE) {
            if (mRemoteInstance != null) {
                break;
            }
            final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
            final long remainingMillis = BIND_SERVICE_TIMEOUT_MS - elapsedMillis;
            if (remainingMillis <= 0) {
                throw new TimeoutException("[" + token + "] Didn't bind to resolver in time!");
            }
            mLock.wait(remainingMillis);
        }
    }

    @WorkerThread
    private IInstantAppResolver bind(String token) throws ConnectionException, TimeoutException, InterruptedException {
        boolean doUnbind = false;
        synchronized (mLock) {
            if (mRemoteInstance != null) {
                return mRemoteInstance;
            }
            if (mBindState == STATE_PENDING) {
                // there is a pending bind, let's see if we can use it.
                if (DEBUG_INSTANT) {
                    Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
                }
                try {
                    waitForBindLocked(token);
                    if (mRemoteInstance != null) {
                        return mRemoteInstance;
                    }
                } catch (TimeoutException e) {
                    // nope, we might have to try a rebind.
                    doUnbind = true;
                }
            }
            if (mBindState == STATE_BINDING) {
                // someone was binding when we called bind(), or they raced ahead while we were
                // waiting in the PENDING case; wait for their result instead. Last chance!
                if (DEBUG_INSTANT) {
                    Slog.i(TAG, "[" + token + "] Another thread is binding; waiting for connection");
                }
                waitForBindLocked(token);
                // if the other thread's bindService() returned false, we could still have null.
                if (mRemoteInstance != null) {
                    return mRemoteInstance;
                }
                throw new ConnectionException(ConnectionException.FAILURE_BIND);
            }
            // our time to shine! :)
            mBindState = STATE_BINDING;
        }
        // only one thread can be here at a time (the one that set STATE_BINDING)
        boolean wasBound = false;
        IInstantAppResolver instance = null;
        try {
            if (doUnbind) {
                if (DEBUG_INSTANT) {
                    Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
                }
                mContext.unbindService(mServiceConnection);
            }
            if (DEBUG_INSTANT) {
                Slog.v(TAG, "[" + token + "] Binding to instant app resolver");
            }
            final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
            wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM);
            if (wasBound) {
                synchronized (mLock) {
                    waitForBindLocked(token);
                    instance = mRemoteInstance;
                    return instance;
                }
            } else {
                Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent);
                throw new ConnectionException(ConnectionException.FAILURE_BIND);
            }
        } finally {
            synchronized (mLock) {
                if (wasBound && instance == null) {
                    mBindState = STATE_PENDING;
                } else {
                    mBindState = STATE_IDLE;
                }
                mLock.notifyAll();
            }
        }
    }

    private void throwIfCalledOnMainThread() {
        if (Thread.currentThread() == mContext.getMainLooper().getThread()) {
            throw new RuntimeException("Cannot invoke on the main thread");
        }
    }

    @AnyThread
    void optimisticBind() {
        mBgHandler.post(() -> {
            try {
                if (bind("Optimistic Bind") != null && DEBUG_INSTANT) {
                    Slog.i(TAG, "Optimistic bind succeeded.");
                }
            } catch (ConnectionException | TimeoutException | InterruptedException e) {
                Slog.e(TAG, "Optimistic bind failed.", e);
            }
        });
    }

    @Override
    public void binderDied() {
        if (DEBUG_INSTANT) {
            Slog.d(TAG, "Binder to instant app resolver died");
        }
        synchronized (mLock) {
            handleBinderDiedLocked();
        }
        optimisticBind();
    }

    @GuardedBy("mLock")
    private void handleBinderDiedLocked() {
        if (mRemoteInstance != null) {
            try {
                mRemoteInstance.asBinder().unlinkToDeath(this, 0);
            } catch (NoSuchElementException ignore) {
            }
        }
        mRemoteInstance = null;
    }

    /**
     * Asynchronous callback when results come back from ephemeral resolution phase two.
     */
    public abstract static clreplaced PhaseTwoCallback {

        abstract void onPhaseTwoResolved(List<InstantAppResolveInfo> instantAppResolveInfoList, long startTime);
    }

    public static clreplaced ConnectionException extends Exception {

        public static final int FAILURE_BIND = 1;

        public static final int FAILURE_CALL = 2;

        public static final int FAILURE_INTERRUPTED = 3;

        public final int failure;

        public ConnectionException(int _failure) {
            failure = _failure;
        }
    }

    private final clreplaced MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DEBUG_INSTANT) {
                Slog.d(TAG, "Connected to instant app resolver");
            }
            synchronized (mLock) {
                mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
                if (mBindState == STATE_PENDING) {
                    mBindState = STATE_IDLE;
                }
                try {
                    service.linkToDeath(InstantAppResolverConnection.this, 0);
                } catch (RemoteException e) {
                    handleBinderDiedLocked();
                }
                mLock.notifyAll();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (DEBUG_INSTANT) {
                Slog.d(TAG, "Disconnected from instant app resolver");
            }
            synchronized (mLock) {
                handleBinderDiedLocked();
            }
        }
    }

    private static final clreplaced GetInstantAppResolveInfoCaller extends TimedRemoteCaller<List<InstantAppResolveInfo>> {

        private final IRemoteCallback mCallback;

        public GetInstantAppResolveInfoCaller() {
            super(CALL_SERVICE_TIMEOUT_MS);
            mCallback = new IRemoteCallback.Stub() {

                @Override
                public void sendResult(Bundle data) throws RemoteException {
                    final ArrayList<InstantAppResolveInfo> resolveList = data.getParcelableArrayList(InstantAppResolverService.EXTRA_RESOLVE_INFO);
                    int sequence = data.getInt(InstantAppResolverService.EXTRA_SEQUENCE, -1);
                    onRemoteMethodResult(resolveList, sequence);
                }
            };
        }

        public List<InstantAppResolveInfo> getInstantAppResolveInfoList(IInstantAppResolver target, Intent sanitizedIntent, int[] hashPrefix, String token) throws RemoteException, TimeoutException {
            final int sequence = onBeforeRemoteCall();
            target.getInstantAppResolveInfoList(sanitizedIntent, hashPrefix, token, sequence, mCallback);
            return getResultTimed(sequence);
        }
    }
}