diff options
7 files changed, 343 insertions, 237 deletions
diff --git a/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java new file mode 100644 index 000000000000..0690d3be3db1 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.os.VibratorInfo; +import android.os.vibrator.RampSegment; +import android.os.vibrator.StepSegment; +import android.os.vibrator.VibrationEffectSegment; +import android.util.MathUtils; + +import java.util.List; + +/** + * Adapter that clips frequency values to {@link VibratorInfo#getFrequencyRange()} and + * amplitude values to respective {@link VibratorInfo#getMaxAmplitude}. + * + * <p>Devices with no frequency control will collapse all frequencies to zero and leave + * amplitudes unchanged. + * + * <p>The frequency value returned in segments will be absolute, converted with + * {@link VibratorInfo#getAbsoluteFrequency(float)}. + */ +final class ClippingAmplitudeAndFrequencyAdapter + implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> { + + @Override + public int apply(List<VibrationEffectSegment> segments, int repeatIndex, VibratorInfo info) { + int segmentCount = segments.size(); + for (int i = 0; i < segmentCount; i++) { + VibrationEffectSegment segment = segments.get(i); + if (segment instanceof StepSegment) { + segments.set(i, apply((StepSegment) segment, info)); + } else if (segment instanceof RampSegment) { + segments.set(i, apply((RampSegment) segment, info)); + } + } + return repeatIndex; + } + + private StepSegment apply(StepSegment segment, VibratorInfo info) { + float clampedFrequency = clampFrequency(info, segment.getFrequency()); + return new StepSegment( + clampAmplitude(info, clampedFrequency, segment.getAmplitude()), + info.getAbsoluteFrequency(clampedFrequency), + (int) segment.getDuration()); + } + + private RampSegment apply(RampSegment segment, VibratorInfo info) { + float clampedStartFrequency = clampFrequency(info, segment.getStartFrequency()); + float clampedEndFrequency = clampFrequency(info, segment.getEndFrequency()); + return new RampSegment( + clampAmplitude(info, clampedStartFrequency, segment.getStartAmplitude()), + clampAmplitude(info, clampedEndFrequency, segment.getEndAmplitude()), + info.getAbsoluteFrequency(clampedStartFrequency), + info.getAbsoluteFrequency(clampedEndFrequency), + (int) segment.getDuration()); + } + + private float clampFrequency(VibratorInfo info, float frequency) { + return info.getFrequencyRange().clamp(frequency); + } + + private float clampAmplitude(VibratorInfo info, float frequency, float amplitude) { + return MathUtils.min(amplitude, info.getMaxAmplitude(frequency)); + } +} diff --git a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java index 8eff2b9aab9e..b695150d9ba3 100644 --- a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java +++ b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java @@ -16,231 +16,33 @@ package com.android.server.vibrator; -import android.hardware.vibrator.IVibrator; import android.os.VibrationEffect; import android.os.VibratorInfo; -import android.os.vibrator.RampSegment; -import android.os.vibrator.StepSegment; -import android.os.vibrator.VibrationEffectSegment; -import android.util.MathUtils; -import android.util.Range; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Adapts a {@link VibrationEffect} to a specific device, taking into account its capabilities. */ -final class DeviceVibrationEffectAdapter implements VibrationEffectModifier<VibratorInfo> { +final class DeviceVibrationEffectAdapter + implements VibrationEffectAdapters.EffectAdapter<VibratorInfo> { + /** Duration of each step created to simulate a ramp segment. */ private static final int RAMP_STEP_DURATION_MILLIS = 5; - /** Adapts a sequence of {@link VibrationEffectSegment} to device's capabilities. */ - interface SegmentsAdapter { - - /** - * Modifies the given segments list by adding/removing segments to it based on the - * device capabilities specified by given {@link VibratorInfo}. - * - * @param segments List of {@link VibrationEffectSegment} to be modified. - * @param repeatIndex Repeat index of the vibration with given segment list. - * @param info The device vibrator info that the segments must be adapted to. - * @return The new repeat index to be used for the modified list. - */ - int apply(List<VibrationEffectSegment> segments, int repeatIndex, VibratorInfo info); - } - - private final SegmentsAdapter mAmplitudeFrequencyAdapter; - private final SegmentsAdapter mStepToRampAdapter; - private final SegmentsAdapter mRampToStepsAdapter; + private final List<VibrationEffectAdapters.SegmentsAdapter<VibratorInfo>> mSegmentAdapters; DeviceVibrationEffectAdapter() { - this(new ClippingAmplitudeFrequencyAdapter()); - } - - DeviceVibrationEffectAdapter(SegmentsAdapter amplitudeFrequencyAdapter) { - mAmplitudeFrequencyAdapter = amplitudeFrequencyAdapter; - mStepToRampAdapter = new StepToRampAdapter(); - mRampToStepsAdapter = new RampToStepsAdapter(RAMP_STEP_DURATION_MILLIS); + mSegmentAdapters = Arrays.asList( + // TODO(b/167947076): add filter that removes unsupported primitives + // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback + new RampToStepAdapter(RAMP_STEP_DURATION_MILLIS), + new StepToRampAdapter(), + new ClippingAmplitudeAndFrequencyAdapter() + ); } @Override public VibrationEffect apply(VibrationEffect effect, VibratorInfo info) { - if (!(effect instanceof VibrationEffect.Composed)) { - return effect; - } - - VibrationEffect.Composed composed = (VibrationEffect.Composed) effect; - List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments()); - int newRepeatIndex = composed.getRepeatIndex(); - - // Replace ramps with a sequence of fixed steps, or no-op if PWLE capability present. - newRepeatIndex = mRampToStepsAdapter.apply(newSegments, newRepeatIndex, info); - - // Replace steps that should be handled by PWLE to ramps, or no-op if capability missing. - // This should be done before frequency is converted from relative to absolute values. - newRepeatIndex = mStepToRampAdapter.apply(newSegments, newRepeatIndex, info); - - // Adapt amplitude and frequency values to device supported ones, converting frequency - // to absolute values in Hertz. - newRepeatIndex = mAmplitudeFrequencyAdapter.apply(newSegments, newRepeatIndex, info); - - // TODO(b/167947076): add filter that removes unsupported primitives - // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback - - return new VibrationEffect.Composed(newSegments, newRepeatIndex); - } - - /** - * Adapter that converts step segments that should be handled as PWLEs to ramp segments. - * - * <p>This leaves the list unchanged if the device do not have compose PWLE capability. - */ - private static final class StepToRampAdapter implements SegmentsAdapter { - @Override - public int apply(List<VibrationEffectSegment> segments, int repeatIndex, - VibratorInfo info) { - if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { - // The vibrator do not have PWLE capability, so keep the segments unchanged. - return repeatIndex; - } - int segmentCount = segments.size(); - // Convert steps that require frequency control to ramps. - for (int i = 0; i < segmentCount; i++) { - VibrationEffectSegment segment = segments.get(i); - if ((segment instanceof StepSegment) - && ((StepSegment) segment).getFrequency() != 0) { - segments.set(i, apply((StepSegment) segment)); - } - } - // Convert steps that are next to ramps to also become ramps, so they can be composed - // together in the same PWLE waveform. - for (int i = 1; i < segmentCount; i++) { - if (segments.get(i) instanceof RampSegment) { - for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) { - segments.set(j, apply((StepSegment) segments.get(j))); - } - } - } - return repeatIndex; - } - - private RampSegment apply(StepSegment segment) { - return new RampSegment(segment.getAmplitude(), segment.getAmplitude(), - segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration()); - } - } - - /** - * Adapter that converts ramp segments that to a sequence of fixed step segments. - * - * <p>This leaves the list unchanged if the device have compose PWLE capability. - */ - private static final class RampToStepsAdapter implements SegmentsAdapter { - private final int mStepDuration; - - RampToStepsAdapter(int stepDuration) { - mStepDuration = stepDuration; - } - - @Override - public int apply(List<VibrationEffectSegment> segments, int repeatIndex, - VibratorInfo info) { - if (info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { - // The vibrator have PWLE capability, so keep the segments unchanged. - return repeatIndex; - } - int segmentCount = segments.size(); - for (int i = 0; i < segmentCount; i++) { - VibrationEffectSegment segment = segments.get(i); - if (!(segment instanceof RampSegment)) { - continue; - } - List<StepSegment> steps = apply((RampSegment) segment); - segments.remove(i); - segments.addAll(i, steps); - int addedSegments = steps.size() - 1; - if (repeatIndex > i) { - repeatIndex += addedSegments; - } - i += addedSegments; - segmentCount += addedSegments; - } - return repeatIndex; - } - - private List<StepSegment> apply(RampSegment ramp) { - if (Float.compare(ramp.getStartAmplitude(), ramp.getEndAmplitude()) == 0) { - // Amplitude is the same, so return a single step to simulate this ramp. - return Arrays.asList( - new StepSegment(ramp.getStartAmplitude(), ramp.getStartFrequency(), - (int) ramp.getDuration())); - } - - List<StepSegment> steps = new ArrayList<>(); - int stepCount = (int) (ramp.getDuration() + mStepDuration - 1) / mStepDuration; - for (int i = 0; i < stepCount - 1; i++) { - float pos = (float) i / stepCount; - steps.add(new StepSegment( - interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), pos), - interpolate(ramp.getStartFrequency(), ramp.getEndFrequency(), pos), - mStepDuration)); - } - int duration = (int) ramp.getDuration() - mStepDuration * (stepCount - 1); - steps.add(new StepSegment(ramp.getEndAmplitude(), ramp.getEndFrequency(), duration)); - return steps; - } - - private static float interpolate(float start, float end, float position) { - return start + position * (end - start); - } - } - - /** - * Adapter that clips frequency values to {@link VibratorInfo#getFrequencyRange()} and - * amplitude values to respective {@link VibratorInfo#getMaxAmplitude}. - * - * <p>Devices with no frequency control will collapse all frequencies to zero and leave - * amplitudes unchanged. - * - * <p>The frequency value returned in segments will be absolute, conveted with - * {@link VibratorInfo#getAbsoluteFrequency(float)}. - */ - private static final class ClippingAmplitudeFrequencyAdapter implements SegmentsAdapter { - @Override - public int apply(List<VibrationEffectSegment> segments, int repeatIndex, - VibratorInfo info) { - int segmentCount = segments.size(); - for (int i = 0; i < segmentCount; i++) { - VibrationEffectSegment segment = segments.get(i); - if (segment instanceof StepSegment) { - segments.set(i, apply((StepSegment) segment, info)); - } else if (segment instanceof RampSegment) { - segments.set(i, apply((RampSegment) segment, info)); - } - } - return repeatIndex; - } - - private StepSegment apply(StepSegment segment, VibratorInfo info) { - float clampedFrequency = info.getFrequencyRange().clamp(segment.getFrequency()); - return new StepSegment( - MathUtils.min(segment.getAmplitude(), info.getMaxAmplitude(clampedFrequency)), - info.getAbsoluteFrequency(clampedFrequency), - (int) segment.getDuration()); - } - - private RampSegment apply(RampSegment segment, VibratorInfo info) { - Range<Float> frequencyRange = info.getFrequencyRange(); - float clampedStartFrequency = frequencyRange.clamp(segment.getStartFrequency()); - float clampedEndFrequency = frequencyRange.clamp(segment.getEndFrequency()); - return new RampSegment( - MathUtils.min(segment.getStartAmplitude(), - info.getMaxAmplitude(clampedStartFrequency)), - MathUtils.min(segment.getEndAmplitude(), - info.getMaxAmplitude(clampedEndFrequency)), - info.getAbsoluteFrequency(clampedStartFrequency), - info.getAbsoluteFrequency(clampedEndFrequency), - (int) segment.getDuration()); - } + return VibrationEffectAdapters.apply(effect, mSegmentAdapters, info); } } diff --git a/services/core/java/com/android/server/vibrator/RampToStepAdapter.java b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java new file mode 100644 index 000000000000..1e05bdbdf082 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.hardware.vibrator.IVibrator; +import android.os.VibratorInfo; +import android.os.vibrator.RampSegment; +import android.os.vibrator.StepSegment; +import android.os.vibrator.VibrationEffectSegment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Adapter that converts ramp segments that to a sequence of fixed step segments. + * + * <p>This leaves the list unchanged if the device have compose PWLE capability. + */ +final class RampToStepAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> { + + private final int mStepDuration; + + RampToStepAdapter(int stepDuration) { + mStepDuration = stepDuration; + } + + @Override + public int apply(List<VibrationEffectSegment> segments, int repeatIndex, + VibratorInfo info) { + if (info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { + // The vibrator have PWLE capability, so keep the segments unchanged. + return repeatIndex; + } + int segmentCount = segments.size(); + for (int i = 0; i < segmentCount; i++) { + VibrationEffectSegment segment = segments.get(i); + if (!(segment instanceof RampSegment)) { + continue; + } + List<StepSegment> steps = apply((RampSegment) segment); + segments.remove(i); + segments.addAll(i, steps); + int addedSegments = steps.size() - 1; + if (repeatIndex > i) { + repeatIndex += addedSegments; + } + i += addedSegments; + segmentCount += addedSegments; + } + return repeatIndex; + } + + private List<StepSegment> apply(RampSegment ramp) { + if (Float.compare(ramp.getStartAmplitude(), ramp.getEndAmplitude()) == 0) { + // Amplitude is the same, so return a single step to simulate this ramp. + return Arrays.asList( + new StepSegment(ramp.getStartAmplitude(), ramp.getStartFrequency(), + (int) ramp.getDuration())); + } + + List<StepSegment> steps = new ArrayList<>(); + int stepCount = (int) (ramp.getDuration() + mStepDuration - 1) / mStepDuration; + for (int i = 0; i < stepCount - 1; i++) { + float pos = (float) i / stepCount; + steps.add(new StepSegment( + interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), pos), + interpolate(ramp.getStartFrequency(), ramp.getEndFrequency(), pos), + mStepDuration)); + } + int duration = (int) ramp.getDuration() - mStepDuration * (stepCount - 1); + steps.add(new StepSegment(ramp.getEndAmplitude(), ramp.getEndFrequency(), duration)); + return steps; + } + + private static float interpolate(float start, float end, float position) { + return start + position * (end - start); + } +} diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java new file mode 100644 index 000000000000..f78df9208fbd --- /dev/null +++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.hardware.vibrator.IVibrator; +import android.os.VibratorInfo; +import android.os.vibrator.RampSegment; +import android.os.vibrator.StepSegment; +import android.os.vibrator.VibrationEffectSegment; + +import java.util.List; + +/** + * Adapter that converts step segments that should be handled as PWLEs to ramp segments. + * + * <p>This leaves the list unchanged if the device do not have compose PWLE capability. + */ +final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> { + @Override + public int apply(List<VibrationEffectSegment> segments, int repeatIndex, + VibratorInfo info) { + if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { + // The vibrator do not have PWLE capability, so keep the segments unchanged. + return repeatIndex; + } + int segmentCount = segments.size(); + // Convert steps that require frequency control to ramps. + for (int i = 0; i < segmentCount; i++) { + VibrationEffectSegment segment = segments.get(i); + if ((segment instanceof StepSegment) + && ((StepSegment) segment).getFrequency() != 0) { + segments.set(i, apply((StepSegment) segment)); + } + } + // Convert steps that are next to ramps to also become ramps, so they can be composed + // together in the same PWLE waveform. + for (int i = 1; i < segmentCount; i++) { + if (segments.get(i) instanceof RampSegment) { + for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) { + segments.set(j, apply((StepSegment) segments.get(j))); + } + } + } + return repeatIndex; + } + + private RampSegment apply(StepSegment segment) { + return new RampSegment(segment.getAmplitude(), segment.getAmplitude(), + segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration()); + } +} diff --git a/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java b/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java new file mode 100644 index 000000000000..446d9810ff19 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.os.VibrationEffect; +import android.os.vibrator.VibrationEffectSegment; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helpers to adapt a {@link VibrationEffect} to generic modifiers (e.g. device capabilities, + * user settings, etc). + */ +public final class VibrationEffectAdapters { + + /** + * Function that applies a generic modifier to a sequence of {@link VibrationEffectSegment}. + * + * @param <T> The type of modifiers this adapter accepts. + */ + public interface SegmentsAdapter<T> { + + /** + * Add and/or remove segments to the given {@link VibrationEffectSegment} list based on the + * given modifier. + * + * <p>This returns the new {@code repeatIndex} to be used together with the updated list to + * specify an equivalent {@link VibrationEffect}. + * + * @param segments List of {@link VibrationEffectSegment} to be modified. + * @param repeatIndex Repeat index on the current segment list. + * @param modifier The modifier to be applied to the sequence of segments. + * @return The new repeat index on the modifies list. + */ + int apply(List<VibrationEffectSegment> segments, int repeatIndex, T modifier); + } + + /** + * Function that applies a generic modifier to a {@link VibrationEffect}. + * + * @param <T> The type of modifiers this adapter accepts. + */ + public interface EffectAdapter<T> { + + /** Applies the modifier to given {@link VibrationEffect}, returning the new effect. */ + VibrationEffect apply(VibrationEffect effect, T modifier); + } + + /** + * Applies a sequence of {@link SegmentsAdapter} to the segments of a given + * {@link VibrationEffect}, in order. + * + * @param effect The effect to be adapted to given modifier. + * @param adapters The sequence of adapters to be applied to given {@link VibrationEffect}. + * @param modifier The modifier to be passed to each adapter that describes the conditions the + * {@link VibrationEffect} needs to be adapted to (e.g. device capabilities, + * user settings, etc). + */ + public static <T> VibrationEffect apply(VibrationEffect effect, + List<SegmentsAdapter<T>> adapters, T modifier) { + if (!(effect instanceof VibrationEffect.Composed)) { + // Segments adapters can only be applied to Composed effects. + return effect; + } + + VibrationEffect.Composed composed = (VibrationEffect.Composed) effect; + List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments()); + int newRepeatIndex = composed.getRepeatIndex(); + + int adapterCount = adapters.size(); + for (int i = 0; i < adapterCount; i++) { + newRepeatIndex = adapters.get(i).apply(newSegments, newRepeatIndex, modifier); + } + + return new VibrationEffect.Composed(newSegments, newRepeatIndex); + } +} diff --git a/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java b/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java deleted file mode 100644 index d287c8faa34d..000000000000 --- a/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.vibrator; - -import android.os.VibrationEffect; - -/** Function that applies a generic modifier to a {@link VibrationEffect}. */ -interface VibrationEffectModifier<T> { - - /** Applies the modifier to given {@link VibrationEffect}. */ - VibrationEffect apply(VibrationEffect effect, T modifier); -} diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java index bc61478ec1b5..a33c546c866a 100644 --- a/services/core/java/com/android/server/vibrator/VibrationThread.java +++ b/services/core/java/com/android/server/vibrator/VibrationThread.java @@ -93,7 +93,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient { private final WorkSource mWorkSource = new WorkSource(); private final PowerManager.WakeLock mWakeLock; private final IBatteryStats mBatteryStatsService; - private final VibrationEffectModifier<VibratorInfo> mDeviceEffectAdapter = + private final DeviceVibrationEffectAdapter mDeviceEffectAdapter = new DeviceVibrationEffectAdapter(); private final Vibration mVibration; private final VibrationCallbacks mCallbacks; |