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

Commit c4c1de30 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor ListenerMultiplexer with new capabilities"

parents afded3d0 87b8cc38
Loading
Loading
Loading
Loading
+52 −34
Original line number Diff line number Diff line
@@ -38,71 +38,86 @@ public interface ListenerExecutor {
        void operate(TListener listener) throws Exception;

        /**
         * Called before this operation is to be run. Some operations may be canceled before they
         * are run, in which case this method may not be called. {@link #onPostExecute(boolean)}
         * will only be run if this method was run. This callback is invoked on the calling thread.
         * Called before this operation is to be run. An operation may be canceled before it is run,
         * in which case this method may not be invoked. {@link #onPostExecute(boolean)} will only
         * be invoked if this method was previously invoked. This callback is invoked on the
         * calling thread.
         */
        default void onPreExecute() {}

        /**
         * Called if the operation fails while running. Will not be invoked in the event of a
         * RuntimeException, which will propagate normally. Implementations of
         * {@link ListenerExecutor} have the option to override
         * {@link ListenerExecutor#onOperationFailure(ListenerOperation, Exception)} instead to
         * intercept failures at the class level. This callback is invoked on the executor thread.
         * unchecked exception, which will propagate normally. This callback is invoked on the
         * executor thread.
         */
        default void onFailure(Exception e) {
            // implementations should handle any exceptions that may be thrown
            throw new AssertionError(e);
        }
        default void onFailure(Exception e) {}

        /**
         * Called after the operation is run. This method will always be called if
         * {@link #onPreExecute()} is called. Success implies that the operation was run to
         * completion with no failures. This callback may be invoked on the calling thread or
         * executor thread.
         * Called after the operation may have been run. Will always be invoked for every operation
         * which has previously had {@link #onPreExecute()} invoked. Success implies that the
         * operation was run to completion with no failures. If {@code success} is true, this
         * callback will always be invoked on the executor thread. If {@code success} is false, this
         * callback may be invoked on the calling thread or executor thread.
         */
        default void onPostExecute(boolean success) {}

        /**
         * Called after this operation is complete (which does not imply that it was necessarily
         * run). Will always be called once per operation, no matter if the operation was run or
         * not. Success implies that the operation was run to completion with no failures. This
         * callback may be invoked on the calling thread or executor thread.
         * Will always be called once for every operation submitted to
         * {@link #executeSafely(Executor, Supplier, ListenerOperation)}, no matter if the operation
         * was run or not. This method is always invoked last, after every other callback. Success
         * implies that the operation was run to completion with no failures. If {@code success}
         * is true, this callback will always be invoked on the executor thread. If {@code success}
         * is false, this callback may be invoked on the calling thread or executor thread.
         */
        default void onComplete(boolean success) {}
    }

    /**
     * May be override to handle operation failures at a class level. Will not be invoked in the
     * event of a RuntimeException, which will propagate normally. This callback is invoked on the
     * executor thread.
     * An callback for listener operation failure.
     *
     * @param <TListenerOperation> listener operation type
     */
    default <TListener> void onOperationFailure(ListenerOperation<TListener> operation,
            Exception exception) {
        operation.onFailure(exception);
    interface FailureCallback<TListenerOperation extends ListenerOperation<?>> {

        /**
         * Called if a listener operation fails while running with a checked exception. This
         * callback is invoked on the executor thread.
         */
        void onFailure(TListenerOperation operation, Exception exception);
    }

    /**
     * See {@link #executeSafely(Executor, Supplier, ListenerOperation, FailureCallback)}.
     */
    default <TListener> void executeSafely(Executor executor, Supplier<TListener> listenerSupplier,
            @Nullable ListenerOperation<TListener> operation) {
        executeSafely(executor, listenerSupplier, operation, null);
    }

    /**
     * Executes the given listener operation on the given executor, using the provided listener
     * supplier. If the supplier returns a null value, or a value during the operation that does not
     * match the value prior to the operation, then the operation is considered canceled. If a null
     * operation is supplied, nothing happens.
     * operation is supplied, nothing happens. If a failure callback is supplied, this will be
     * invoked on the executor thread in the event a checked exception is thrown from the listener
     * operation.
     */
    default <TListener> void executeSafely(Executor executor, Supplier<TListener> listenerSupplier,
            @Nullable ListenerOperation<TListener> operation) {
    default <TListener, TListenerOperation extends ListenerOperation<TListener>> void executeSafely(
            Executor executor, Supplier<TListener> listenerSupplier,
            @Nullable TListenerOperation operation,
            @Nullable FailureCallback<TListenerOperation> failureCallback) {
        if (operation == null) {
            return;
        }

        boolean executing = false;
        boolean preexecute = false;
        try {
        TListener listener = listenerSupplier.get();
        if (listener == null) {
            return;
        }

        boolean executing = false;
        boolean preexecute = false;
        try {
            operation.onPreExecute();
            preexecute = true;
            executor.execute(() -> {
@@ -116,7 +131,10 @@ public interface ListenerExecutor {
                    if (e instanceof RuntimeException) {
                        throw (RuntimeException) e;
                    } else {
                        onOperationFailure(operation, e);
                        operation.onFailure(e);
                        if (failureCallback != null) {
                            failureCallback.onFailure(operation, e);
                        }
                    }
                } finally {
                    operation.onPostExecute(success);
+7 −7
Original line number Diff line number Diff line
@@ -475,7 +475,7 @@ public final class LocationRequest implements Parcelable {

    /**
     * Returns the minimum update interval. If location updates are available faster than the
     * request interval then locations will only be delivered if the minimum update interval has
     * request interval then locations will only be updated if the minimum update interval has
     * expired since the last location update.
     *
     * <p class=note><strong>Note:</strong> Some allowance for jitter is already built into the
@@ -951,9 +951,9 @@ public final class LocationRequest implements Parcelable {

        /**
         * Sets an explicit minimum update interval. If location updates are available faster than
         * the request interval then locations will only be delivered if the minimum update interval
         * has expired since the last location update. Defaults to no explicit minimum update
         * interval set, which means the minimum update interval is the same as the interval.
         * the request interval then an update will only occur if the minimum update interval has
         * expired since the last location update. Defaults to no explicit minimum update interval
         * set, which means the minimum update interval is the same as the interval.
         *
         * <p class=note><strong>Note:</strong> Some allowance for jitter is already built into the
         * minimum update interval, so you need not worry about updates blocked simply because they
@@ -972,7 +972,7 @@ public final class LocationRequest implements Parcelable {

        /**
         * Clears an explicitly set minimum update interval and reverts to an implicit minimum
         * update interval (ie, the minimum update interval is same value as the interval).
         * update interval (ie, the minimum update interval is the same value as the interval).
         */
        public @NonNull Builder clearMinUpdateIntervalMillis() {
            mMinUpdateIntervalMillis = IMPLICIT_MIN_UPDATE_INTERVAL;
@@ -980,8 +980,8 @@ public final class LocationRequest implements Parcelable {
        }

        /**
         * Sets the minimum update distance between delivered locations. If a potential location
         * update is closer to the last delivered location than the minimum update distance, then
         * Sets the minimum update distance between location updates. If a potential location
         * update is closer to the last location update than the minimum update distance, then
         * the potential location update will not occur. Defaults to 0, which represents no minimum
         * update distance.
         */
+2 −11
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.server.location;

import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;

import android.annotation.Nullable;
import android.location.Location;
import android.location.util.identity.CallerIdentity;
@@ -342,8 +340,7 @@ public abstract class AbstractLocationProvider {
     */
    public final void setRequest(ProviderRequest request) {
        // all calls into the provider must be moved onto the provider thread to prevent deadlock
        mExecutor.execute(obtainRunnable(AbstractLocationProvider::onSetRequest, this, request)
                .recycleOnUse());
        mExecutor.execute(() -> onSetRequest(request));
    }

    /**
@@ -356,13 +353,7 @@ public abstract class AbstractLocationProvider {
     */
    public final void sendExtraCommand(int uid, int pid, String command, Bundle extras) {
        // all calls into the provider must be moved onto the provider thread to prevent deadlock

        // the integer boxing done here likely cancels out any gains from removing lambda
        // allocation, but since this an infrequently used api with no real performance needs, we
        // we use pooled lambdas anyways for consistency.
        mExecutor.execute(
                obtainRunnable(AbstractLocationProvider::onExtraCommand, this, uid, pid, command,
                        extras).recycleOnUse());
        mExecutor.execute(() -> onExtraCommand(uid, pid, command, extras));
    }

    /**
+162 −59

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ class PassiveLocationProviderManager extends LocationProviderManager {
    }

    @Override
    protected ProviderRequest mergeRequests(Collection<Registration> registrations) {
    protected ProviderRequest mergeRegistrations(Collection<Registration> registrations) {
        ProviderRequest.Builder providerRequest = new ProviderRequest.Builder()
                .setIntervalMillis(0);

Loading