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

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

Merge "Change VibratorInfo reload logic in VibratorManagerService"

parents 88ba7c8f 39b2dab1
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ public class SystemVibrator extends Vibrator {
            mRegisteredListeners = new ArrayMap<>();

    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private AllVibratorsInfo mVibratorInfo;

    @UnsupportedAppUsage
@@ -73,7 +74,15 @@ public class SystemVibrator extends Vibrator {
            int[] vibratorIds = mVibratorManager.getVibratorIds();
            VibratorInfo[] vibratorInfos = new VibratorInfo[vibratorIds.length];
            for (int i = 0; i < vibratorIds.length; i++) {
                vibratorInfos[i] = mVibratorManager.getVibrator(vibratorIds[i]).getInfo();
                Vibrator vibrator = mVibratorManager.getVibrator(vibratorIds[i]);
                if (vibrator instanceof NullVibrator) {
                    Log.w(TAG, "Vibrator manager service not ready; "
                            + "Info not yet available for vibrator: " + vibratorIds[i]);
                    // This should never happen after the vibrator manager service is ready.
                    // Skip caching this vibrator until then.
                    return VibratorInfo.EMPTY_VIBRATOR_INFO;
                }
                vibratorInfos[i] = vibrator.getInfo();
            }
            return mVibratorInfo = new AllVibratorsInfo(vibratorInfos);
        }
+5 −1
Original line number Diff line number Diff line
@@ -165,7 +165,11 @@ public abstract class Vibrator {
        return ctx != null ? ctx.getResources().getFloat(resId) : defaultValue;
    }

    /** @hide */
    /**
     * Get the info describing this vibrator.
     *
     * @hide
     */
    protected VibratorInfo getInfo() {
        return VibratorInfo.EMPTY_VIBRATOR_INFO;
    }
+2 −1
Original line number Diff line number Diff line
@@ -461,7 +461,8 @@ public class VibratorInfo implements Parcelable {
        int supportedPrimitivesCount = mSupportedPrimitives.size();
        String[] names = new String[supportedPrimitivesCount];
        for (int i = 0; i < supportedPrimitivesCount; i++) {
            names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i));
            names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i))
                    + "(" + mSupportedPrimitives.valueAt(i) + "ms)";
        }
        return names;
    }
+56 −25
Original line number Diff line number Diff line
@@ -41,12 +41,11 @@ final class VibratorController {

    private final Object mLock = new Object();
    private final NativeWrapper mNativeWrapper;
    private final VibratorInfo.Builder mVibratorInfoBuilder;

    @GuardedBy("mLock")
    private VibratorInfo mVibratorInfo;
    @GuardedBy("mLock")
    private boolean mVibratorInfoLoaded;
    private boolean mVibratorInfoLoadSuccessful;
    @GuardedBy("mLock")
    private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners =
            new RemoteCallbackList<>();
@@ -73,10 +72,16 @@ final class VibratorController {
            NativeWrapper nativeWrapper) {
        mNativeWrapper = nativeWrapper;
        mNativeWrapper.init(vibratorId, listener);
        mVibratorInfoBuilder = new VibratorInfo.Builder(vibratorId);
        mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
                mVibratorInfoBuilder);
        mVibratorInfo = mVibratorInfoBuilder.build();
        VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId);
        mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
                vibratorInfoBuilder);
        mVibratorInfo = vibratorInfoBuilder.build();

        if (!mVibratorInfoLoadSuccessful) {
            Slog.e(TAG,
                    "Vibrator controller initialization failed to load some HAL info for vibrator "
                            + vibratorId);
        }
    }

    /** Register state listener for this vibrator. */
@@ -108,15 +113,33 @@ final class VibratorController {
        }
    }

    /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */
    public void reloadVibratorInfoIfNeeded() {
        synchronized (mLock) {
            if (mVibratorInfoLoadSuccessful) {
                return;
            }
            int vibratorId = mVibratorInfo.getId();
            VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId);
            mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
                    vibratorInfoBuilder);
            mVibratorInfo = vibratorInfoBuilder.build();
            if (!mVibratorInfoLoadSuccessful) {
                Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId);
            }
        }
    }

    /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */
    boolean isVibratorInfoLoadSuccessful() {
        synchronized (mLock) {
            return mVibratorInfoLoadSuccessful;
        }
    }

    /** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */
    public VibratorInfo getVibratorInfo() {
        synchronized (mLock) {
            if (!mVibratorInfoLoaded) {
                // Try to load the vibrator metadata that has failed in the last attempt.
                mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
                        mVibratorInfoBuilder);
                mVibratorInfo = mVibratorInfoBuilder.build();
            }
            return mVibratorInfo;
        }
    }
@@ -164,8 +187,10 @@ final class VibratorController {
     * @return true if this vibrator has this capability, false otherwise
     */
    public boolean hasCapability(long capability) {
        synchronized (mLock) {
            return mVibratorInfo.hasCapability(capability);
        }
    }

    /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */
    public boolean isAvailable() {
@@ -178,10 +203,10 @@ final class VibratorController {
     * <p>This will affect the state of {@link #isUnderExternalControl()}.
     */
    public void setExternalControl(boolean externalControl) {
        synchronized (mLock) {
            if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                return;
            }
        synchronized (mLock) {
            mIsUnderExternalControl = externalControl;
            mNativeWrapper.setExternalControl(externalControl);
        }
@@ -192,10 +217,10 @@ final class VibratorController {
     * if given {@code effect} is {@code null}.
     */
    public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) {
        synchronized (mLock) {
            if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
                return;
            }
        synchronized (mLock) {
            if (prebaked == null) {
                mNativeWrapper.alwaysOnDisable(id);
            } else {
@@ -268,10 +293,10 @@ final class VibratorController {
     * do not support the input or a negative number if the operation failed.
     */
    public long on(PrimitiveSegment[] primitives, long vibrationId) {
        synchronized (mLock) {
            if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
                return 0;
            }
        synchronized (mLock) {
            long duration = mNativeWrapper.compose(primitives, vibrationId);
            if (duration > 0) {
                mCurrentAmplitude = -1;
@@ -290,10 +315,10 @@ final class VibratorController {
     * @return The duration of the effect playing, or 0 if unsupported.
     */
    public long on(RampSegment[] primitives, long vibrationId) {
        synchronized (mLock) {
            if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
                return 0;
            }
        synchronized (mLock) {
            int braking = mVibratorInfo.getDefaultBraking();
            long duration = mNativeWrapper.composePwle(primitives, braking, vibrationId);
            if (duration > 0) {
@@ -327,6 +352,7 @@ final class VibratorController {
        synchronized (mLock) {
            return "VibratorController{"
                    + "mVibratorInfo=" + mVibratorInfo
                    + ", mVibratorInfoLoadSuccessful=" + mVibratorInfoLoadSuccessful
                    + ", mIsVibrating=" + mIsVibrating
                    + ", mCurrentAmplitude=" + mCurrentAmplitude
                    + ", mIsUnderExternalControl=" + mIsUnderExternalControl
@@ -393,10 +419,15 @@ final class VibratorController {
         * allocated and returned by {@link #nativeInit(int, OnVibrationCompleteListener)}.
         */
        private static native long getNativeFinalizer();

        private static native boolean isAvailable(long nativePtr);

        private static native long on(long nativePtr, long milliseconds, long vibrationId);

        private static native void off(long nativePtr);

        private static native void setAmplitude(long nativePtr, float amplitude);

        private static native long performEffect(long nativePtr, long effect, long strength,
                long vibrationId);

+26 −2
Original line number Diff line number Diff line
@@ -128,6 +128,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    private VibrationThread mNextVibration;
    @GuardedBy("mLock")
    private ExternalVibrationHolder mCurrentExternalVibration;
    @GuardedBy("mLock")
    private boolean mServiceReady;

    private final VibrationSettings mVibrationSettings;
    private final VibrationScaler mVibrationScaler;
@@ -201,6 +203,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
        mWakeLock.setReferenceCounted(true);

        // Load vibrator hardware info. The vibrator ids and manager capabilities are loaded only
        // once and assumed unchanged for the lifecycle of this service. Each individual vibrator
        // can still retry loading each individual vibrator hardware spec once more at systemReady.
        mCapabilities = mNativeWrapper.getCapabilities();
        int[] vibratorIds = mNativeWrapper.getVibratorIds();
        if (vibratorIds == null) {
@@ -235,6 +240,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        Slog.v(TAG, "Initializing VibratorManager service...");
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "systemReady");
        try {
            // Will retry to load each vibrator's info, if any request have failed.
            for (int i = 0; i < mVibrators.size(); i++) {
                mVibrators.valueAt(i).reloadVibratorInfoIfNeeded();
            }

            mVibrationSettings.onSystemReady();
            mInputDeviceDelegate.onSystemReady();

@@ -243,6 +253,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            // Will update settings and input devices.
            updateServiceState();
        } finally {
            synchronized (mLock) {
                mServiceReady = true;
            }
            Slog.v(TAG, "VibratorManager service initialized");
            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
        }
@@ -256,8 +269,19 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    @Override // Binder call
    @Nullable
    public VibratorInfo getVibratorInfo(int vibratorId) {
        VibratorController controller = mVibrators.get(vibratorId);
        return controller == null ? null : controller.getVibratorInfo();
        final VibratorController controller = mVibrators.get(vibratorId);
        if (controller == null) {
            return null;
        }
        final VibratorInfo info = controller.getVibratorInfo();
        synchronized (mLock) {
            if (mServiceReady) {
                return info;
            }
        }
        // If the service is not ready and the load was unsuccessful then return null while waiting
        // for the service to be ready. It will retry to load the complete info from the HAL.
        return controller.isVibratorInfoLoadSuccessful() ? info : null;
    }

    @Override // Binder call
Loading