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

Commit 46f27a9c authored by Ahmad Khalil's avatar Ahmad Khalil Committed by Android (Google) Code Review
Browse files

Merge "Add input validation on VibrationParam[] to prohibit null items" into main

parents d9338163 c8fb6099
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -101,7 +101,9 @@ final class VibratorControlService extends IVibratorControlService.Stub {
    }

    @Override
    public void registerVibratorController(IVibratorController controller) {
    public void registerVibratorController(@NonNull IVibratorController controller) {
        Objects.requireNonNull(controller);

        synchronized (mLock) {
            mVibratorControllerHolder.setVibratorController(controller);
        }
@@ -134,6 +136,7 @@ final class VibratorControlService extends IVibratorControlService.Stub {
    public void setVibrationParams(@SuppressLint("ArrayReturn") VibrationParam[] params,
            @NonNull IVibratorController token) {
        Objects.requireNonNull(token);
        requireContainsNoNullElement(params);

        synchronized (mLock) {
            if (mVibratorControllerHolder.getVibratorController() == null) {
@@ -148,6 +151,13 @@ final class VibratorControlService extends IVibratorControlService.Stub {
                        + "controller doesn't match the registered one. " + this);
                return;
            }
            if (params == null) {
                // Adaptive haptics scales cannot be set to null. Ignoring request.
                Slog.d(TAG,
                        "New vibration params received but are null. New vibration "
                                + "params ignored.");
                return;
            }

            updateAdaptiveHapticsScales(params);
            recordUpdateVibrationParams(params, /* fromRequest= */ false);
@@ -181,6 +191,7 @@ final class VibratorControlService extends IVibratorControlService.Stub {
    public void onRequestVibrationParamsComplete(
            @NonNull IBinder requestToken, @SuppressLint("ArrayReturn") VibrationParam[] result) {
        Objects.requireNonNull(requestToken);
        requireContainsNoNullElement(result);

        synchronized (mLock) {
            if (mVibrationParamRequest == null) {
@@ -202,6 +213,13 @@ final class VibratorControlService extends IVibratorControlService.Stub {
            long latencyMs = SystemClock.uptimeMillis() - mVibrationParamRequest.uptimeMs;
            mStatsLogger.logVibrationParamRequestLatency(mVibrationParamRequest.uid, latencyMs);

            if (result == null) {
                Slog.d(TAG,
                        "New vibration params received but are null. New vibration "
                                + "params ignored.");
                return;
            }

            updateAdaptiveHapticsScales(result);
            endOngoingRequestVibrationParamsLocked(/* wasCancelled= */ false);
            recordUpdateVibrationParams(result, /* fromRequest= */ true);
@@ -401,10 +419,9 @@ final class VibratorControlService extends IVibratorControlService.Stub {
     *
     * @param params the new vibration params.
     */
    private void updateAdaptiveHapticsScales(@Nullable VibrationParam[] params) {
        if (params == null) {
            return;
        }
    private void updateAdaptiveHapticsScales(@NonNull VibrationParam[] params) {
        Objects.requireNonNull(params);

        for (VibrationParam param : params) {
            if (param.getTag() != VibrationParam.scale) {
                Slog.e(TAG, "Unsupported vibration param: " + param);
@@ -448,11 +465,10 @@ final class VibratorControlService extends IVibratorControlService.Stub {
        mVibrationScaler.updateAdaptiveHapticsScale(usageHint, scale);
    }

    private void recordUpdateVibrationParams(@Nullable VibrationParam[] params,
    private void recordUpdateVibrationParams(@NonNull VibrationParam[] params,
            boolean fromRequest) {
        if (params == null) {
            return;
        }
        Objects.requireNonNull(params);

        VibrationParamsRecords.Operation operation =
                fromRequest ? VibrationParamsRecords.Operation.PULL
                        : VibrationParamsRecords.Operation.PUSH;
@@ -474,6 +490,13 @@ final class VibratorControlService extends IVibratorControlService.Stub {
                VibrationParamsRecords.Operation.CLEAR, createTime, typesMask, NO_SCALE));
    }

    private void requireContainsNoNullElement(VibrationParam[] params) {
        if (ArrayUtils.contains(params, null)) {
            throw new IllegalArgumentException(
                    "Invalid vibration params received: null values are not permitted.");
        }
    }

    /**
     * Keep records of {@link VibrationParam} values received by this service from a registered
     * {@link VibratorController} and provide debug information for this service.
+34 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.pm.PackageManagerInternal;
import android.frameworks.vibrator.ScaleParam;
import android.frameworks.vibrator.VibrationParam;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -59,6 +60,8 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@@ -177,6 +180,24 @@ public class VibratorControlServiceTest {
        verifyZeroInteractions(mMockVibrationScaler);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testOnRequestVibrationParamsComplete_withNullVibrationParams_throwsException() {
        mVibratorControlService.registerVibratorController(mFakeVibratorController);
        int timeoutInMillis = 10;
        CompletableFuture<Void> unusedFuture =
                mVibratorControlService.triggerVibrationParamsRequest(UID, USAGE_RINGTONE,
                        timeoutInMillis);
        IBinder token = mVibratorControlService.getRequestVibrationParamsToken();

        List<VibrationParam> vibrationParamList = Arrays.asList(
                VibrationParamGenerator.generateVibrationParam(ScaleParam.TYPE_ALARM, 0.7f),
                null,
                VibrationParamGenerator.generateVibrationParam(ScaleParam.TYPE_NOTIFICATION, 0.4f));

        mVibratorControlService.onRequestVibrationParamsComplete(token,
                vibrationParamList.toArray(new VibrationParam[0]));
    }

    @Test
    public void testSetVibrationParams_cachesAdaptiveHapticsScalesCorrectly() {
        mVibratorControlService.registerVibratorController(mFakeVibratorController);
@@ -214,6 +235,19 @@ public class VibratorControlServiceTest {
        verifyZeroInteractions(mMockVibrationScaler);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetVibrationParams_withNullVibrationParams_throwsException() {
        mVibratorControlService.registerVibratorController(mFakeVibratorController);
        List<VibrationParam> vibrationParamList = Arrays.asList(
                VibrationParamGenerator.generateVibrationParam(ScaleParam.TYPE_ALARM, 0.7f),
                null,
                VibrationParamGenerator.generateVibrationParam(ScaleParam.TYPE_NOTIFICATION, 0.4f));

        mVibratorControlService.setVibrationParams(
                vibrationParamList.toArray(new VibrationParam[0]),
                mFakeVibratorController);
    }

    @Test
    public void testClearVibrationParams_clearsCachedAdaptiveHapticsScales() {
        mVibratorControlService.registerVibratorController(mFakeVibratorController);
+4 −1
Original line number Diff line number Diff line
@@ -42,7 +42,10 @@ public final class VibrationParamGenerator {
        return vibrationParamList.toArray(new VibrationParam[0]);
    }

    private static VibrationParam generateVibrationParam(int type, float scale) {
    /**
     * Generates a {@link VibrationParam} with the specified type and scale.
     */
    public static VibrationParam generateVibrationParam(int type, float scale) {
        ScaleParam scaleParam = new ScaleParam();
        scaleParam.typesMask = type;
        scaleParam.scale = scale;