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

Commit d293e382 authored by Lais Andrade's avatar Lais Andrade
Browse files

Introduce getter for managed IVibrator

Introduce HalVibratorManager.getVibrator method to allow managed
vibrators to be loaded based on the IVibratorManager service.

Bug: 422944962
Flag: android.os.vibrator.remove_hidl_support
Test: FrameworksVibratorServicesTests
Change-Id: I68db734bd6a4567e9b63e8d54541039fa13b5e94
parent b8d0ac29
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -424,8 +424,7 @@ public class VibratorInfo implements Parcelable {
     * @return The duration in milliseconds estimated for the primitive, or zero if primitive not
     * @return The duration in milliseconds estimated for the primitive, or zero if primitive not
     * supported.
     * supported.
     */
     */
    public int getPrimitiveDuration(
    public int getPrimitiveDuration(int primitiveId) {
            @VibrationEffect.Composition.PrimitiveType int primitiveId) {
        return mSupportedPrimitives.get(primitiveId);
        return mSupportedPrimitives.get(primitiveId);
    }
    }


+5 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.vibrator;
package com.android.server.vibrator;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.IndentingPrintWriter;
import android.util.IndentingPrintWriter;


/** Handles interactions with a vibrator manager HAL. */
/** Handles interactions with a vibrator manager HAL. */
@@ -48,6 +49,10 @@ interface HalVibratorManager {
    /** Return the IDs of the vibrators controlled by this manager. */
    /** Return the IDs of the vibrators controlled by this manager. */
    @NonNull int[] getVibratorIds();
    @NonNull int[] getVibratorIds();


    /** Return the vibrator with given ID controlled by this manager. */
    @Nullable
    HalVibrator getVibrator(int id);

    /** Prepare vibrators for triggering vibrations in sync. */
    /** Prepare vibrators for triggering vibrations in sync. */
    boolean prepareSynced(@NonNull int[] vibratorIds);
    boolean prepareSynced(@NonNull int[] vibratorIds);


+71 −40
Original line number Original line Diff line number Diff line
@@ -162,7 +162,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    private final AppOpsManager mAppOps;
    private final AppOpsManager mAppOps;
    private final HalVibratorManager mVibratorManager;
    private final HalVibratorManager mVibratorManager;
    private final VibratorManagerRecords mVibratorManagerRecords;
    private final VibratorManagerRecords mVibratorManagerRecords;
    private final SparseArray<HalVibrator> mVibrators;
    private final VibrationThreadCallbacks mVibrationThreadCallbacks =
    private final VibrationThreadCallbacks mVibrationThreadCallbacks =
            new VibrationThreadCallbacks();
            new VibrationThreadCallbacks();
    private final ExternalVibrationCallbacks mExternalVibrationCallbacks =
    private final ExternalVibrationCallbacks mExternalVibrationCallbacks =
@@ -297,15 +296,17 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        mVibrationThread.start();
        mVibrationThread.start();


        int[] vibratorIds = mVibratorManager.getVibratorIds();
        int[] vibratorIds = mVibratorManager.getVibratorIds();
        mVibrators = new SparseArray<>(vibratorIds.length);
        SparseArray<HalVibrator> availableVibrators = new SparseArray<>(vibratorIds.length);
        for (int vibratorId : vibratorIds) {
        for (int vibratorId : vibratorIds) {
            HalVibrator vibrator = injector.createHalVibrator(vibratorId);
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null) {
                availableVibrators.put(vibratorId, vibrator);
                vibrator.init(halListener);
                vibrator.init(halListener);
            mVibrators.put(vibratorId, vibrator);
            }
        }
        }


        // Load vibrator adapter, that depends on hardware info.
        // Load vibrator adapter, that depends on hardware info.
        mDeviceAdapter = new DeviceAdapter(mVibrationSettings, mVibrators);
        mDeviceAdapter = new DeviceAdapter(mVibrationSettings, availableVibrators);


        IntentFilter filter = new IntentFilter();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -328,8 +329,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        Trace.traceBegin(TRACE_TAG_VIBRATOR, "systemReady");
        Trace.traceBegin(TRACE_TAG_VIBRATOR, "systemReady");
        try {
        try {
            mVibratorManager.onSystemReady();
            mVibratorManager.onSystemReady();
            for (int i = 0; i < mVibrators.size(); i++) {
            for (int vibratorId : mVibratorManager.getVibratorIds()) {
                mVibrators.valueAt(i).onSystemReady();
                HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
                if (vibrator != null) {
                    vibrator.onSystemReady();
                }
            }
            }


            synchronized (mLock) {
            synchronized (mLock) {
@@ -371,7 +375,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    @Override // Binder call
    @Override // Binder call
    @Nullable
    @Nullable
    public VibratorInfo getVibratorInfo(int vibratorId) {
    public VibratorInfo getVibratorInfo(int vibratorId) {
        final HalVibrator vibrator = mVibrators.get(vibratorId);
        final HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
        if (vibrator == null) {
        if (vibrator == null) {
            return null;
            return null;
        }
        }
@@ -403,7 +407,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    @Override // Binder call
    @Override // Binder call
    public boolean isVibrating(int vibratorId) {
    public boolean isVibrating(int vibratorId) {
        isVibrating_enforcePermission();
        isVibrating_enforcePermission();
        HalVibrator vibrator = mVibrators.get(vibratorId);
        HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
        return vibrator != null && vibrator.isVibrating();
        return vibrator != null && vibrator.isVibrating();
    }
    }


@@ -411,7 +415,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    @Override // Binder call
    @Override // Binder call
    public boolean registerVibratorStateListener(int vibratorId, IVibratorStateListener listener) {
    public boolean registerVibratorStateListener(int vibratorId, IVibratorStateListener listener) {
        registerVibratorStateListener_enforcePermission();
        registerVibratorStateListener_enforcePermission();
        HalVibrator vibrator = mVibrators.get(vibratorId);
        HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
        if (vibrator == null || listener == null) {
        if (vibrator == null || listener == null) {
            return false;
            return false;
        }
        }
@@ -423,7 +427,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    public boolean unregisterVibratorStateListener(int vibratorId,
    public boolean unregisterVibratorStateListener(int vibratorId,
            IVibratorStateListener listener) {
            IVibratorStateListener listener) {
        unregisterVibratorStateListener_enforcePermission();
        unregisterVibratorStateListener_enforcePermission();
        HalVibrator vibrator = mVibrators.get(vibratorId);
        HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
        if (vibrator == null || listener == null) {
        if (vibrator == null || listener == null) {
            return false;
            return false;
        }
        }
@@ -767,7 +771,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        // Create session with adapter that only uses the session vibrators.
        // Create session with adapter that only uses the session vibrators.
        SparseArray<HalVibrator> sessionVibrators = new SparseArray<>(vibratorIds.length);
        SparseArray<HalVibrator> sessionVibrators = new SparseArray<>(vibratorIds.length);
        for (int vibratorId : vibratorIds) {
        for (int vibratorId : vibratorIds) {
            HalVibrator vibrator = mVibrators.get(vibratorId);
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null) {
            if (vibrator != null) {
                sessionVibrators.put(vibratorId, vibrator);
                sessionVibrators.put(vibratorId, vibrator);
            }
            }
@@ -937,14 +941,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            mVibratorManager.dump(pw);
            mVibratorManager.dump(pw);
            pw.println();
            pw.println();


            pw.println("Vibrators:");
            pw.increaseIndent();
            for (int i = 0; i < mVibrators.size(); i++) {
                mVibrators.valueAt(i).dump(pw);
            }
            pw.decreaseIndent();
            pw.println();

            pw.println("CurrentVibration:");
            pw.println("CurrentVibration:");
            pw.increaseIndent();
            pw.increaseIndent();
            if (mCurrentSession != null) {
            if (mCurrentSession != null) {
@@ -986,8 +982,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                mCurrentSession.getDebugInfo().dump(proto,
                mCurrentSession.getDebugInfo().dump(proto,
                        VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
                        VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
            }
            }
            for (int i = 0; i < mVibrators.size(); i++) {
            for (int vibratorId : mVibratorManager.getVibratorIds()) {
                proto.write(VibratorManagerServiceDumpProto.VIBRATOR_IDS, mVibrators.keyAt(i));
                proto.write(VibratorManagerServiceDumpProto.VIBRATOR_IDS, vibratorId);
            }
            }
        }
        }
        mVibratorManagerRecords.dump(proto);
        mVibratorManagerRecords.dump(proto);
@@ -1031,16 +1027,19 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    }
    }


    private void setExternalControl(boolean externalControl, VibrationStats vibrationStats) {
    private void setExternalControl(boolean externalControl, VibrationStats vibrationStats) {
        for (int i = 0; i < mVibrators.size(); i++) {
        for (int vibratorId : mVibratorManager.getVibratorIds()) {
            mVibrators.valueAt(i).setExternalControl(externalControl);
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null) {
                vibrator.setExternalControl(externalControl);
                vibrationStats.reportSetExternalControl();
                vibrationStats.reportSetExternalControl();
            }
            }
        }
        }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void updateAlwaysOnLocked(AlwaysOnVibration vib) {
    private void updateAlwaysOnLocked(AlwaysOnVibration vib) {
        for (int i = 0; i < vib.effects.size(); i++) {
        for (int i = 0; i < vib.effects.size(); i++) {
            HalVibrator vibrator = mVibrators.get(vib.effects.keyAt(i));
            HalVibrator vibrator = mVibratorManager.getVibrator(vib.effects.keyAt(i));
            PrebakedSegment effect = vib.effects.valueAt(i);
            PrebakedSegment effect = vib.effects.valueAt(i);
            if (vibrator == null) {
            if (vibrator == null) {
                continue;
                continue;
@@ -1642,7 +1641,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                return null;
                return null;
            }
            }
            int vibratorId = effects.keyAt(i);
            int vibratorId = effects.keyAt(i);
            HalVibrator vibrator = mVibrators.get(vibratorId);
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null
            if (vibrator != null
                    && vibrator.getInfo().hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
                    && vibrator.getInfo().hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
                result.put(vibratorId, prebaked);
                result.put(vibratorId, prebaked);
@@ -1711,16 +1710,23 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void runOnAllVibratorsLocked(Consumer<HalVibrator> consumer) {
    private void runOnAllVibratorsLocked(Consumer<HalVibrator> consumer) {
        for (int i = 0; i < mVibrators.size(); i++) {
        for (int vibratorId : mVibratorManager.getVibratorIds()) {
            consumer.accept(mVibrators.valueAt(i));
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null) {
                consumer.accept(vibrator);
            }
        }
        }
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private <T> SparseArray<T> applyToAllVibratorsLocked(Function<HalVibrator, T> fn) {
    private <T> SparseArray<T> applyToAllVibratorsLocked(Function<HalVibrator, T> fn) {
        SparseArray<T> ret = new SparseArray<>(mVibrators.size());
        int[] vibratorIds = mVibratorManager.getVibratorIds();
        for (int i = 0; i < mVibrators.size(); i++) {
        SparseArray<T> ret = new SparseArray<>(vibratorIds.length);
            ret.put(mVibrators.keyAt(i), fn.apply(mVibrators.valueAt(i)));
        for (int vibratorId : vibratorIds) {
            HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
            if (vibrator != null) {
                ret.put(vibratorId, fn.apply(vibrator));
            }
        }
        }
        return ret;
        return ret;
    }
    }
@@ -1750,10 +1756,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            return new NativeHalVibratorManager(new NativeWrapper());
            return new NativeHalVibratorManager(new NativeWrapper());
        }
        }


        HalVibrator createHalVibrator(int vibratorId) {
            return new VibratorController(vibratorId);
        }

        HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider(
        HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider(
                Resources resources, VibratorInfo vibratorInfo) {
                Resources resources, VibratorInfo vibratorInfo) {
            return new HapticFeedbackVibrationProvider(resources, vibratorInfo);
            return new HapticFeedbackVibrationProvider(resources, vibratorInfo);
@@ -2061,7 +2063,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                    // Make sure all controllers in session are reset after session ended.
                    // Make sure all controllers in session are reset after session ended.
                    // This will update the vibrator state to isVibrating = false for listeners.
                    // This will update the vibrator state to isVibrating = false for listeners.
                    for (int vibratorId : session.getVibratorIds()) {
                    for (int vibratorId : session.getVibratorIds()) {
                        mVibrators.get(vibratorId).off();
                        HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
                        if (vibrator != null) {
                            vibrator.off();
                        }
                    }
                    }
                    finishAppOpModeLocked(mCurrentSession.getCallerInfo());
                    finishAppOpModeLocked(mCurrentSession.getCallerInfo());
                    clearCurrentSessionLocked();
                    clearCurrentSessionLocked();
@@ -2131,6 +2136,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    // TODO(b/409002423): remove this class once remove_hidl_support flag removed
    // TODO(b/409002423): remove this class once remove_hidl_support flag removed
    public static class NativeHalVibratorManager implements HalVibratorManager {
    public static class NativeHalVibratorManager implements HalVibratorManager {
        private final NativeWrapper mNativeWrapper;
        private final NativeWrapper mNativeWrapper;
        private final SparseArray<HalVibrator> mVibrators = new SparseArray<>();


        // Variables that are updated from synchronized blocks but can be read anytime
        // Variables that are updated from synchronized blocks but can be read anytime
        // for a snippet of the current known vibrator manager info.
        // for a snippet of the current known vibrator manager info.
@@ -2153,6 +2159,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            int[] vibratorIds = mNativeWrapper.getVibratorIds();
            int[] vibratorIds = mNativeWrapper.getVibratorIds();
            if (vibratorIds != null) {
            if (vibratorIds != null) {
                mVibratorIds = vibratorIds;
                mVibratorIds = vibratorIds;
                for (int id : vibratorIds) {
                    mVibrators.put(id, mNativeWrapper.createVibrator(id));
                }
            }
            }


            // Reset the hardware to a default state.
            // Reset the hardware to a default state.
@@ -2178,6 +2187,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            return mVibratorIds;
            return mVibratorIds;
        }
        }


        @Nullable
        @Override
        public HalVibrator getVibrator(int id) {
            return mVibrators.get(id);
        }

        @Override
        @Override
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
            return mNativeWrapper.prepareSynced(vibratorIds);
            return mNativeWrapper.prepareSynced(vibratorIds);
@@ -2209,9 +2224,18 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        public void dump(IndentingPrintWriter pw) {
        public void dump(IndentingPrintWriter pw) {
            pw.println("Native HAL VibratorManager:");
            pw.println("Native HAL VibratorManager:");
            pw.increaseIndent();
            pw.increaseIndent();

            pw.println("capabilitiesFlags = " + Long.toBinaryString(mCapabilities));
            pw.println("capabilitiesFlags = " + Long.toBinaryString(mCapabilities));
            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("Vibrators:");
            pw.increaseIndent();
            for (int i = 0; i < mVibrators.size(); i++) {
                mVibrators.valueAt(i).dump(pw);
            }
            pw.decreaseIndent();

            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.println();
        }
        }


        @Override
        @Override
@@ -2229,6 +2253,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {


        private long mNativeServicePtr = 0;
        private long mNativeServicePtr = 0;


        /** Create the {@link HalVibrator} instance for given vibrator ID. */
        public HalVibrator createVibrator(int vibratorId) {
            return new VibratorController(vibratorId);
        }

        /** Returns native pointer to newly created controller and connects with HAL service. */
        /** Returns native pointer to newly created controller and connects with HAL service. */
        public void init(HalVibratorManager.Callbacks callback) {
        public void init(HalVibratorManager.Callbacks callback) {
            mNativeServicePtr = nativeInit(callback);
            mNativeServicePtr = nativeInit(callback);
@@ -2641,8 +2670,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        }
        }


        private boolean hasExternalControlCapability() {
        private boolean hasExternalControlCapability() {
            for (int i = 0; i < mVibrators.size(); i++) {
            for (int vibratorId : mVibratorManager.getVibratorIds()) {
                if (mVibrators.valueAt(i).getInfo().hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                HalVibrator vibrator = mVibratorManager.getVibrator(vibratorId);
                if (vibrator != null
                        && vibrator.getInfo().hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                    return true;
                    return true;
                }
                }
            }
            }
+56 −8
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.vibrator;
package com.android.server.vibrator;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.vibrator.IVibrationSession;
import android.hardware.vibrator.IVibrationSession;
import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.IVibratorCallback;
import android.hardware.vibrator.IVibratorCallback;
@@ -30,9 +32,7 @@ import android.os.vibrator.Flags;
import android.util.IndentingPrintWriter;
import android.util.IndentingPrintWriter;
import android.util.LongSparseArray;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.Slog;

import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.server.vibrator.VintfUtils.VintfSupplier;
import com.android.server.vibrator.VintfUtils.VintfSupplier;
@@ -42,6 +42,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import java.util.Optional;
import java.util.Optional;
import java.util.function.IntFunction;


/** Implementations for {@link HalVibratorManager} backed by VINTF objects. */
/** Implementations for {@link HalVibratorManager} backed by VINTF objects. */
class VintfHalVibratorManager {
class VintfHalVibratorManager {
@@ -50,17 +51,21 @@ class VintfHalVibratorManager {


    /** Create {@link HalVibratorManager} based on declared services on device. */
    /** Create {@link HalVibratorManager} based on declared services on device. */
    static HalVibratorManager createHalVibratorManager() {
    static HalVibratorManager createHalVibratorManager() {
        // TODO(b/422944962): Replace this with Vintf HalVibrator
        IntFunction<HalVibrator> vibratorFactory = VibratorController::new;

        if (ServiceManager.isDeclared(IVibratorManager.DESCRIPTOR + "/default")) {
        if (ServiceManager.isDeclared(IVibratorManager.DESCRIPTOR + "/default")) {
            Slog.v(TAG, "Loading default IVibratorManager service.");
            Slog.v(TAG, "Loading default IVibratorManager service.");
            return new DefaultHalVibratorManager(new DefaultVibratorManagerSupplier());
            return new DefaultHalVibratorManager(
                    new DefaultVibratorManagerSupplier(), vibratorFactory);
        }
        }
        if (ServiceManager.isDeclared(IVibrator.DESCRIPTOR + "/default")) {
        if (ServiceManager.isDeclared(IVibrator.DESCRIPTOR + "/default")) {
            Slog.v(TAG, "Loading default IVibrator service.");
            Slog.v(TAG, "Loading default IVibrator service.");
            return new LegacyHalVibratorManager(new int[] { DEFAULT_VIBRATOR_ID });
            return new LegacyHalVibratorManager(new int[] { DEFAULT_VIBRATOR_ID }, vibratorFactory);
        }
        }
        Slog.v(TAG, "No default services declared for IVibratorManager or IVibrator."
        Slog.v(TAG, "No default services declared for IVibratorManager or IVibrator."
                + " Vibrator manager service will proceed without vibrator hardware.");
                + " Vibrator manager service will proceed without vibrator hardware.");
        return new LegacyHalVibratorManager(new int[0]);
        return new LegacyHalVibratorManager(new int[0], vibratorFactory);
    }
    }


    /** {@link VintfSupplier} for default {@link IVibratorManager} service. */
    /** {@link VintfSupplier} for default {@link IVibratorManager} service. */
@@ -87,14 +92,18 @@ class VintfHalVibratorManager {
        @GuardedBy("mLock")
        @GuardedBy("mLock")
        private final LongSparseArray<IVibrationSession> mOngoingSessions = new LongSparseArray<>();
        private final LongSparseArray<IVibrationSession> mOngoingSessions = new LongSparseArray<>();
        private final VintfSupplier<IVibratorManager> mHalSupplier;
        private final VintfSupplier<IVibratorManager> mHalSupplier;
        private final IntFunction<HalVibrator> mVibratorFactory;
        private final SparseArray<HalVibrator> mVibrators = new SparseArray<>();


        private Callbacks mCallbacks;
        private Callbacks mCallbacks;


        private volatile long mCapabilities = 0;
        private volatile long mCapabilities = 0;
        private volatile int[] mVibratorIds = new int[0];
        private volatile int[] mVibratorIds = new int[0];


        DefaultHalVibratorManager(VintfSupplier<IVibratorManager> supplier) {
        DefaultHalVibratorManager(VintfSupplier<IVibratorManager> supplier,
                IntFunction<HalVibrator> vibratorFactory) {
            mHalSupplier = supplier;
            mHalSupplier = supplier;
            mVibratorFactory = vibratorFactory;
        }
        }


        @Override
        @Override
@@ -112,6 +121,9 @@ class VintfHalVibratorManager {
                    e -> Slog.e(TAG, "Error getting vibrator ids", e));
                    e -> Slog.e(TAG, "Error getting vibrator ids", e));
            mCapabilities = capabilities.orElse(0).longValue();
            mCapabilities = capabilities.orElse(0).longValue();
            mVibratorIds = vibratorIds.orElseGet(() -> new int[0]);
            mVibratorIds = vibratorIds.orElseGet(() -> new int[0]);
            for (int id : mVibratorIds) {
                mVibrators.put(id, mVibratorFactory.apply(id));
            }


            // Reset the hardware to a default state.
            // Reset the hardware to a default state.
            // In case this is a runtime restart instead of a fresh boot.
            // In case this is a runtime restart instead of a fresh boot.
@@ -136,6 +148,12 @@ class VintfHalVibratorManager {
            return mVibratorIds;
            return mVibratorIds;
        }
        }


        @Nullable
        @Override
        public HalVibrator getVibrator(int id) {
            return mVibrators.get(id);
        }

        @Override
        @Override
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
            if (!hasCapability(IVibratorManager.CAP_SYNC)) {
            if (!hasCapability(IVibratorManager.CAP_SYNC)) {
@@ -229,11 +247,20 @@ class VintfHalVibratorManager {
        public void dump(IndentingPrintWriter pw) {
        public void dump(IndentingPrintWriter pw) {
            pw.println("Default Hal VibratorManager:");
            pw.println("Default Hal VibratorManager:");
            pw.increaseIndent();
            pw.increaseIndent();

            pw.println("capabilities = " + Arrays.toString(getCapabilitiesNames()));
            pw.println("capabilities = " + Arrays.toString(getCapabilitiesNames()));
            pw.println("capabilitiesFlags = " + Long.toBinaryString(mCapabilities));
            pw.println("capabilitiesFlags = " + Long.toBinaryString(mCapabilities));
            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("ongoingSessionsCount = " + mOngoingSessions.size());
            pw.println("ongoingSessionsCount = " + mOngoingSessions.size());
            pw.println("Vibrators:");
            pw.increaseIndent();
            for (int i = 0; i < mVibrators.size(); i++) {
                mVibrators.valueAt(i).dump(pw);
            }
            pw.decreaseIndent();

            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.println();
        }
        }


        @Override
        @Override
@@ -365,9 +392,15 @@ class VintfHalVibratorManager {
    /** Legacy implementation for devices without a declared {@link IVibratorManager} service. */
    /** Legacy implementation for devices without a declared {@link IVibratorManager} service. */
    static final class LegacyHalVibratorManager implements HalVibratorManager {
    static final class LegacyHalVibratorManager implements HalVibratorManager {
        private final int[] mVibratorIds;
        private final int[] mVibratorIds;
        private final SparseArray<HalVibrator> mVibrators;


        LegacyHalVibratorManager(@NonNull int[] vibratorIds) {
        LegacyHalVibratorManager(@NonNull int[] vibratorIds,
                IntFunction<HalVibrator> vibratorFactory) {
            mVibratorIds = vibratorIds;
            mVibratorIds = vibratorIds;
            mVibrators = new SparseArray<>(vibratorIds.length);
            for (int id : vibratorIds) {
                mVibrators.put(id, vibratorFactory.apply(id));
            }
        }
        }


        @Override
        @Override
@@ -389,6 +422,12 @@ class VintfHalVibratorManager {
            return mVibratorIds;
            return mVibratorIds;
        }
        }


        @Nullable
        @Override
        public HalVibrator getVibrator(int id) {
            return mVibrators.get(id);
        }

        @Override
        @Override
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
        public boolean prepareSynced(@NonNull int[] vibratorIds) {
            return false;
            return false;
@@ -418,8 +457,17 @@ class VintfHalVibratorManager {
        public void dump(IndentingPrintWriter pw) {
        public void dump(IndentingPrintWriter pw) {
            pw.println("Legacy HAL VibratorManager:");
            pw.println("Legacy HAL VibratorManager:");
            pw.increaseIndent();
            pw.increaseIndent();

            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("vibratorIds = " + Arrays.toString(mVibratorIds));
            pw.println("Vibrators:");
            pw.increaseIndent();
            for (int i = 0; i < mVibrators.size(); i++) {
                mVibrators.valueAt(i).dump(pw);
            }
            pw.decreaseIndent();

            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.println();
        }
        }


        @Override
        @Override
+29 −3
Original line number Original line Diff line number Diff line
@@ -67,7 +67,7 @@ public abstract class HalVibratorManagerTestCase {
    @Test
    @Test
    @EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
    @EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
    public void init_initializesHalAndClearSyncedAndSessions() {
    public void init_initializesHalAndClearSyncedAndSessions() {
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC | IVibratorManager.CAP_START_SESSIONS);
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_START_SESSIONS);
        mHelper.setVibratorIds(new int[] {1, 2});
        mHelper.setVibratorIds(new int[] {1, 2});
        HalVibratorManager manager = newVibratorManager();
        HalVibratorManager manager = newVibratorManager();
        manager.init(mHalCallbackMock);
        manager.init(mHalCallbackMock);
@@ -87,7 +87,7 @@ public abstract class HalVibratorManagerTestCase {


    @Test
    @Test
    public void hasCapability_checksAllFlagBits() {
    public void hasCapability_checksAllFlagBits() {
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC | IVibratorManager.CAP_START_SESSIONS);
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_START_SESSIONS);
        HalVibratorManager manager = newInitializedVibratorManager();
        HalVibratorManager manager = newInitializedVibratorManager();


        assertThat(manager.hasCapability(IVibratorManager.CAP_SYNC)).isTrue();
        assertThat(manager.hasCapability(IVibratorManager.CAP_SYNC)).isTrue();
@@ -98,6 +98,32 @@ public abstract class HalVibratorManagerTestCase {
        assertThat(manager.hasCapability(IVibratorManager.CAP_TRIGGER_CALLBACK)).isFalse();
        assertThat(manager.hasCapability(IVibratorManager.CAP_TRIGGER_CALLBACK)).isFalse();
    }
    }


    @Test
    public void getVibrator_validVibratorId_returnsValidVibrators() {
        mHelper.setVibratorIds(new int[] {1, 2});
        HalVibratorManager manager = newInitializedVibratorManager();
        assertThat(manager.getVibrator(1)).isNotNull();
        assertThat(manager.getVibrator(1).getInfo().getId()).isEqualTo(1);
        assertThat(manager.getVibrator(2)).isNotNull();
        assertThat(manager.getVibrator(2).getInfo().getId()).isEqualTo(2);
    }

    @Test
    public void getVibrator_beforeInit_returnsNull() {
        mHelper.setVibratorIds(new int[] {1, 2});
        HalVibratorManager manager = newVibratorManager();
        assertThat(manager.getVibrator(1)).isNull();
        assertThat(manager.getVibrator(2)).isNull();
    }

    @Test
    public void getVibrator_badVibratorId_returnsNull() {
        mHelper.setVibratorIds(new int[] {1, 2});
        HalVibratorManager manager = newInitializedVibratorManager();
        assertThat(manager.getVibrator(3)).isNull();
        assertThat(manager.getVibrator(-1)).isNull();
    }

    @Test
    @Test
    public void prepareSynced_withCapabilityAndValidVibrators_returnsTrue() {
    public void prepareSynced_withCapabilityAndValidVibrators_returnsTrue() {
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC);
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC);
@@ -170,7 +196,7 @@ public abstract class HalVibratorManagerTestCase {


    @Test
    @Test
    public void triggerSynced_triggerCallback_returnsVibrationId() {
    public void triggerSynced_triggerCallback_returnsVibrationId() {
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC | IVibratorManager.CAP_TRIGGER_CALLBACK);
        mHelper.setCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_TRIGGER_CALLBACK);
        mHelper.setVibratorIds(new int[] {1, 2});
        mHelper.setVibratorIds(new int[] {1, 2});
        HalVibratorManager manager = newInitializedVibratorManager();
        HalVibratorManager manager = newInitializedVibratorManager();


Loading