diff options
3 files changed, 70 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/vibrator/VibratorControlService.java b/services/core/java/com/android/server/vibrator/VibratorControlService.java index b33fa6f56a23..f82ff673d74e 100644 --- a/services/core/java/com/android/server/vibrator/VibratorControlService.java +++ b/services/core/java/com/android/server/vibrator/VibratorControlService.java @@ -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. diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java index 3f5217c371de..8ca862390a65 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java @@ -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); diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/VibrationParamGenerator.java b/services/tests/vibrator/utils/com/android/server/vibrator/VibrationParamGenerator.java index a606388da190..c17d11e51497 100644 --- a/services/tests/vibrator/utils/com/android/server/vibrator/VibrationParamGenerator.java +++ b/services/tests/vibrator/utils/com/android/server/vibrator/VibrationParamGenerator.java @@ -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; |