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

Commit 687268b5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove the use of Optional from vibrator HAL helpers" into main

parents fe613649 b5883518
Loading
Loading
Loading
Loading
+60 −54
Original line number Diff line number Diff line
@@ -54,9 +54,7 @@ import com.android.server.vibrator.VintfUtils.VintfGetter;
import com.android.server.vibrator.VintfUtils.VintfSupplier;

import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

/** Implementations for {@link HalVibrator} backed by VINTF objects. */
class VintfHalVibrator {
@@ -154,8 +152,8 @@ class VintfHalVibrator {
            Trace.traceBegin(TRACE_TAG_VIBRATOR, "HalVibrator.init");
            try {
                mCallbacks = callbacks;
                int capabilities = getValue(IVibrator::getCapabilities,
                        "Error loading capabilities during init").orElse(0);
                int capabilities = getValueOrDefault(IVibrator::getCapabilities, 0,
                        "Error loading capabilities during init");

                // Reset the hardware to a default state.
                // In case this is a runtime restart instead of a fresh boot.
@@ -590,11 +588,16 @@ class VintfHalVibrator {

        private int vibrateNoThrow(VintfUtils.VintfRunnable<IVibrator> fn, int successResult,
                Consumer<Throwable> errorHandler) {
            return vibrateNoThrow(
                    hal -> {
                        fn.run(hal);
            try {
                VintfUtils.run(mHalSupplier, fn);
                return successResult;
                    }, errorHandler);
            } catch (RuntimeException e) {
                errorHandler.accept(e);
                if (e instanceof UnsupportedOperationException) {
                    return 0;
                }
                return -1;
            }
        }

        private int vibrateNoThrow(VintfUtils.VintfGetter<IVibrator, Integer> fn,
@@ -616,14 +619,13 @@ class VintfHalVibrator {

        private VibratorInfo loadVibratorInfo(int vibratorId) {
            VibratorInfo.Builder builder = new VibratorInfo.Builder(vibratorId);
            int capabilities = getValue(IVibrator::getCapabilities, "Error loading capabilities")
                    .orElse(0);
            int capabilities = getValueOrDefault(IVibrator::getCapabilities, 0,
                    "Error loading capabilities");
            builder.setCapabilities(capabilities);
            getValue(IVibrator::getSupportedEffects, "Error loading supported effects")
                    .ifPresent(builder::setSupportedEffects);
            getValue(IVibrator::getSupportedEffects, builder::setSupportedEffects,
                    "Error loading supported effects");
            if ((capabilities & IVibrator.CAP_GET_Q_FACTOR) != 0) {
                getValue(IVibrator::getQFactor, "Error loading q-factor")
                        .ifPresent(builder::setQFactor);
                getValue(IVibrator::getQFactor, builder::setQFactor, "Error loading q-factor");
            }

            loadInfoForPrimitives(builder, capabilities);
@@ -632,8 +634,8 @@ class VintfHalVibrator {

            float resonantFrequency;
            if ((capabilities & IVibrator.CAP_GET_RESONANT_FREQUENCY) != 0) {
                resonantFrequency = getValue(IVibrator::getResonantFrequency,
                        "Error loading resonant frequency").orElse(Float.NaN);
                resonantFrequency = getValueOrDefault(IVibrator::getResonantFrequency, Float.NaN,
                        "Error loading resonant frequency");
            } else {
                resonantFrequency = Float.NaN;
            }
@@ -650,21 +652,19 @@ class VintfHalVibrator {
            if ((capabilities & IVibrator.CAP_COMPOSE_EFFECTS) == 0) {
                return;
            }
            getValue(IVibrator::getCompositionSizeMax, "Error loading composition size max")
                    .ifPresent(builder::setCompositionSizeMax);
            getValue(IVibrator::getCompositionDelayMax, "Error loading composition delay max")
                    .ifPresent(builder::setPrimitiveDelayMax);
            int[] supportedPrimitives = getValue(IVibrator::getSupportedPrimitives,
                    "Error loading supported primitives").orElse(null);
            getValue(IVibrator::getCompositionSizeMax, builder::setCompositionSizeMax,
                    "Error loading composition size max");
            getValue(IVibrator::getCompositionDelayMax, builder::setPrimitiveDelayMax,
                    "Error loading composition delay max");
            int[] supportedPrimitives = getValueOrDefault(IVibrator::getSupportedPrimitives, null,
                    "Error loading supported primitives");

            if (supportedPrimitives != null) {
                for (int primitive : supportedPrimitives) {
                    Optional<Integer> primitiveDuration = getValue(
                            hal -> hal.getPrimitiveDuration(primitive),
                    getValue(hal -> hal.getPrimitiveDuration(primitive),
                            duration -> builder.setSupportedPrimitive(primitive, duration),
                            // Only concatenate the strings if logging error.
                            () -> "Error loading duration for primitive " + primitive);
                    primitiveDuration.ifPresent(
                            duration -> builder.setSupportedPrimitive(primitive, duration));
                            e -> logError("Error loading duration for primitive " + primitive, e));
                }
            }
        }
@@ -674,26 +674,26 @@ class VintfHalVibrator {
            if ((capabilities & IVibrator.CAP_COMPOSE_PWLE_EFFECTS) == 0) {
                return;
            }
            getValue(IVibrator::getPwleCompositionSizeMax, "Error loading PWLE V1 size max")
                    .ifPresent(builder::setPwleSizeMax);
            getValue(IVibrator::getPwlePrimitiveDurationMax, "Error loading PWLE V1 duration max")
                    .ifPresent(builder::setPwlePrimitiveDurationMax);
            getValue(IVibrator::getSupportedBraking, "Error loading PWLE V1 supported braking")
                    .ifPresent(builder::setSupportedBraking);
            getValue(IVibrator::getPwleCompositionSizeMax, builder::setPwleSizeMax,
                    "Error loading PWLE V1 size max");
            getValue(IVibrator::getPwlePrimitiveDurationMax, builder::setPwlePrimitiveDurationMax,
                    "Error loading PWLE V1 duration max");
            getValue(IVibrator::getSupportedBraking, builder::setSupportedBraking,
                    "Error loading PWLE V1 supported braking");
        }

        private void loadInfoForPwleV2(VibratorInfo.Builder builder, int capabilities) {
            if ((capabilities & IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2) == 0) {
                return;
            }
            getValue(IVibrator::getPwleV2CompositionSizeMax, "Error loading PWLE V2 size max")
                    .ifPresent(builder::setMaxEnvelopeEffectSize);
            getValue(IVibrator::getPwleV2CompositionSizeMax, builder::setMaxEnvelopeEffectSize,
                    "Error loading PWLE V2 size max");
            getValue(IVibrator::getPwleV2PrimitiveDurationMinMillis,
                    "Error loading PWLE V2 duration min")
                    .ifPresent(builder::setMinEnvelopeEffectControlPointDurationMillis);
                    builder::setMinEnvelopeEffectControlPointDurationMillis,
                    "Error loading PWLE V2 duration min");
            getValue(IVibrator::getPwleV2PrimitiveDurationMaxMillis,
                    "Error loading PWLE V2 duration max")
                    .ifPresent(builder::setMaxEnvelopeEffectControlPointDurationMillis);
                    builder::setMaxEnvelopeEffectControlPointDurationMillis,
                    "Error loading PWLE V2 duration max");
        }

        @SuppressWarnings("deprecation") // Loading deprecated values for compatibility
@@ -703,12 +703,12 @@ class VintfHalVibrator {
                return new VibratorInfo.FrequencyProfileLegacy(
                        resonantFrequency, Float.NaN, Float.NaN, null);
            }
            float minFrequency = getValue(IVibrator::getFrequencyMinimum,
                    "Error loading frequency min").orElse(Float.NaN);
            float frequencyResolution = getValue(IVibrator::getFrequencyResolution,
                    "Error loading frequency resolution").orElse(Float.NaN);
            float[] bandwidthMap = getValue(IVibrator::getBandwidthAmplitudeMap,
                    "Error loading bandwidth map").orElse(null);
            float minFrequency = getValueOrDefault(IVibrator::getFrequencyMinimum, Float.NaN,
                    "Error loading frequency min");
            float frequencyResolution = getValueOrDefault(IVibrator::getFrequencyResolution,
                    Float.NaN, "Error loading frequency resolution");
            float[] bandwidthMap = getValueOrDefault(IVibrator::getBandwidthAmplitudeMap, null,
                    "Error loading bandwidth map");
            return new VibratorInfo.FrequencyProfileLegacy(resonantFrequency, minFrequency,
                    frequencyResolution, bandwidthMap);
        }
@@ -721,8 +721,8 @@ class VintfHalVibrator {
            float[] frequencies = null;
            float[] outputs = null;
            List<FrequencyAccelerationMapEntry> map =
                    getValue(IVibrator::getFrequencyToOutputAccelerationMap,
                            "Error loading frequency acceleration map").orElse(null);
                    getValueOrDefault(IVibrator::getFrequencyToOutputAccelerationMap, null,
                            "Error loading frequency acceleration map");
            if (map != null) {
                int entryCount = map.size();
                frequencies = new float[entryCount];
@@ -736,14 +736,20 @@ class VintfHalVibrator {
            return new VibratorInfo.FrequencyProfile(resonantFrequency, frequencies, outputs);
        }

        private <T> Optional<T> getValue(VintfGetter<IVibrator, T> getter, String errorMessage) {
            return VintfUtils.getNoThrow(mHalSupplier, getter, e -> logError(errorMessage, e));
        private <T> void getValue(VintfGetter<IVibrator, T> getter, Consumer<T> resultHandler,
                String errorMessage) {
            getValue(getter, resultHandler, e -> logError(errorMessage, e));
        }

        private <T> void getValue(VintfGetter<IVibrator, T> getter, Consumer<T> resultHandler,
                Consumer<Throwable> errorHandler) {
            VintfUtils.getNoThrow(mHalSupplier, getter, resultHandler, errorHandler);
        }

        private <T> Optional<T> getValue(VintfGetter<IVibrator, T> getter,
                Supplier<String> errorMessage) {
            return VintfUtils.getNoThrow(mHalSupplier, getter,
                    e -> logError(errorMessage.get(), e));
        private <T> T getValueOrDefault(VintfGetter<IVibrator, T> getter, T defaultValue,
                String errorMessage) {
            return VintfUtils.getOrDefault(mHalSupplier, getter, defaultValue,
                    e -> logError(errorMessage, e));
        }

        private void logError(String message, Throwable error) {
+6 −7
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ import com.android.server.vibrator.VintfUtils.VintfSupplier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.IntFunction;

/** Implementations for {@link HalVibratorManager} backed by VINTF objects. */
@@ -145,14 +144,14 @@ class VintfHalVibratorManager {
            // Load vibrator hardware info. The vibrator ids and manager capabilities are loaded
            // once and assumed unchanged for the lifecycle of this service. Each vibrator can still
            // retry loading each individual vibrator hardware spec once more at systemReady.
            Optional<Integer> capabilities = VintfUtils.getNoThrow(mHalSupplier,
                    IVibratorManager::getCapabilities,
            mCapabilities = VintfUtils.getOrDefault(mHalSupplier,
                    IVibratorManager::getCapabilities, 0,
                    e -> Slog.e(TAG, "Error getting capabilities", e));
            Optional<int[]> vibratorIds = VintfUtils.getNoThrow(mHalSupplier,
                    IVibratorManager::getVibratorIds,
            int[] vibratorIds = VintfUtils.getOrDefault(mHalSupplier,
                    IVibratorManager::getVibratorIds, /* defaultValue= */ null,
                    e -> Slog.e(TAG, "Error getting vibrator ids", e));
            mCapabilities = capabilities.orElse(0).longValue();
            mVibratorIds = vibratorIds.orElseGet(() -> new int[0]);
            // Make sure IDs are never null.
            mVibratorIds = vibratorIds == null ? new int[0] : vibratorIds;
            for (int id : mVibratorIds) {
                HalVibrator vibrator = mVibratorFactory.apply(id);
                vibrator.init(vibratorCallbacks);
+50 −11
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.util.Slog;

import com.android.internal.annotations.GuardedBy;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

@@ -111,26 +110,66 @@ class VintfUtils {
        }
    }

    /**
     * Same as {@link #get(VintfSupplier, VintfGetter)}, but throws no exception and
     * returns default on error.
     */
    @Nullable
    static <I, T> T getOrDefault(VintfSupplier<I> supplier, VintfGetter<I, T> getter,
            @Nullable T defaultValue, Consumer<Throwable> errorHandler) {
        try {
            return get(supplier, getter);
        } catch (RuntimeException e) {
            errorHandler.accept(e);
        }
        return defaultValue;
    }

    /** Same as {@link #get(VintfSupplier, VintfGetter)}, but throws no exception. */
    @NonNull
    static <I, T> Optional<T> getNoThrow(VintfSupplier<I> supplier, VintfGetter<I, T> getter,
            Consumer<Throwable> errorHandler) {
    static <I, T> void getNoThrow(VintfSupplier<I> supplier, VintfGetter<I, T> getter,
            Consumer<T> resultHandler, Consumer<Throwable> errorHandler) {
        try {
            return Optional.ofNullable(get(supplier, getter));
            resultHandler.accept(get(supplier, getter));
        } catch (RuntimeException e) {
            errorHandler.accept(e);
        }
        return Optional.empty();
    }

    /** Same as {@link #getNoThrow}, but returns {@code true} when successful. */
    /**
     * Runs runnable on VINTF object provided by supplier, if any.
     *
     * <p>This automatically clears the cached object in given {@code supplier} if a
     * {@link DeadObjectException} is thrown by the remote method call, so future interactions can
     * load a new instance.
     *
     * @throws RuntimeException if supplier returns null or there is a {@link RemoteException} or
     * {@link RuntimeException} from the remote method call.
     */
    static <I> void run(VintfSupplier<I> supplier, VintfRunnable<I> runnable) {
        I hal = supplier.get();
        if (hal == null) {
            throw new RuntimeException("Missing HAL service");
        }
        try {
            runnable.run(hal);
        } catch (RemoteException e) {
            if (e instanceof DeadObjectException) {
                supplier.clear();
            }
            throw e.rethrowAsRuntimeException();
        }
    }

    /** Same as {@link #run(VintfSupplier, VintfRunnable)}, but throws no exception. */
    static <I> boolean runNoThrow(VintfSupplier<I> supplier, VintfRunnable<I> runnable,
            Consumer<Throwable> errorHandler) {
        VintfGetter<I, Boolean> getter = hal -> {
            runnable.run(hal);
        try {
            run(supplier, runnable);
            return true;
        };
        return getNoThrow(supplier, getter, errorHandler).orElse(false);
        } catch (RuntimeException e) {
            errorHandler.accept(e);
        }
        return false;
    }

    // Non-instantiable helper class.