1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.vibrator;
18 
19 import android.os.VibrationEffect;
20 import android.os.vibrator.VibrationEffectSegment;
21 
22 import java.util.ArrayList;
23 import java.util.List;
24 
25 /**
26  * Helpers to adapt a {@link VibrationEffect} to generic modifiers (e.g. device capabilities,
27  * user settings, etc).
28  */
29 public final class VibrationEffectAdapters {
30 
31     /**
32      * Function that applies a generic modifier to a sequence of {@link VibrationEffectSegment}.
33      *
34      * @param <T> The type of modifiers this adapter accepts.
35      */
36     public interface SegmentsAdapter<T> {
37 
38         /**
39          * Add and/or remove segments to the given {@link VibrationEffectSegment} list based on the
40          * given modifier.
41          *
42          * <p>This returns the new {@code repeatIndex} to be used together with the updated list to
43          * specify an equivalent {@link VibrationEffect}.
44          *
45          * @param segments    List of {@link VibrationEffectSegment} to be modified.
46          * @param repeatIndex Repeat index on the current segment list.
47          * @param modifier    The modifier to be applied to the sequence of segments.
48          * @return The new repeat index on the modifies list.
49          */
apply(List<VibrationEffectSegment> segments, int repeatIndex, T modifier)50         int apply(List<VibrationEffectSegment> segments, int repeatIndex, T modifier);
51     }
52 
53     /**
54      * Function that applies a generic modifier to a {@link VibrationEffect}.
55      *
56      * @param <T> The type of modifiers this adapter accepts.
57      */
58     public interface EffectAdapter<T> {
59 
60         /** Applies the modifier to given {@link VibrationEffect}, returning the new effect. */
apply(VibrationEffect effect, T modifier)61         VibrationEffect apply(VibrationEffect effect, T modifier);
62     }
63 
64     /**
65      * Applies a sequence of {@link SegmentsAdapter} to the segments of a given
66      * {@link VibrationEffect}, in order.
67      *
68      * @param effect   The effect to be adapted to given modifier.
69      * @param adapters The sequence of adapters to be applied to given {@link VibrationEffect}.
70      * @param modifier The modifier to be passed to each adapter that describes the conditions the
71      *                 {@link VibrationEffect} needs to be adapted to (e.g. device capabilities,
72      *                 user settings, etc).
73      */
apply(VibrationEffect effect, List<SegmentsAdapter<T>> adapters, T modifier)74     public static <T> VibrationEffect apply(VibrationEffect effect,
75             List<SegmentsAdapter<T>> adapters, T modifier) {
76         if (!(effect instanceof VibrationEffect.Composed)) {
77             // Segments adapters can only be applied to Composed effects.
78             return effect;
79         }
80 
81         VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
82         List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments());
83         int newRepeatIndex = composed.getRepeatIndex();
84 
85         int adapterCount = adapters.size();
86         for (int i = 0; i < adapterCount; i++) {
87             newRepeatIndex = adapters.get(i).apply(newSegments, newRepeatIndex, modifier);
88         }
89 
90         return new VibrationEffect.Composed(newSegments, newRepeatIndex);
91     }
92 }
93