1 /*
2  * Copyright (C) 2022 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.annotation.NonNull;
20 import android.os.CombinedVibration;
21 import android.os.SystemClock;
22 import android.os.VibrationEffect;
23 
24 import java.util.List;
25 
26 /**
27  * Represent a single step for playing a vibration.
28  *
29  * <p>Every step has a start time, which can be used to apply delays between steps while
30  * executing them in sequence.
31  */
32 abstract class Step implements Comparable<Step> {
33     public final VibrationStepConductor conductor;
34     public final long startTime;
35 
Step(VibrationStepConductor conductor, long startTime)36     Step(VibrationStepConductor conductor, long startTime) {
37         this.conductor = conductor;
38         this.startTime = startTime;
39     }
40 
getVibration()41     protected HalVibration getVibration() {
42         return conductor.getVibration();
43     }
44 
45     /**
46      * Returns true if this step is a clean up step and not part of a {@link VibrationEffect} or
47      * {@link CombinedVibration}.
48      */
isCleanUp()49     public boolean isCleanUp() {
50         return false;
51     }
52 
53     /** Play this step, returning a (possibly empty) list of next steps. */
54     @NonNull
play()55     public abstract List<Step> play();
56 
57     /**
58      * Cancel this pending step and return a (possibly empty) list of clean-up steps that should
59      * be played to gracefully cancel this step.
60      */
61     @NonNull
cancel()62     public abstract List<Step> cancel();
63 
64     /** Cancel this pending step immediately, skipping any clean-up. */
cancelImmediately()65     public abstract void cancelImmediately();
66 
67     /**
68      * Return the duration the vibrator was turned on when this step was played.
69      *
70      * @return A positive duration that the vibrator was turned on for by this step;
71      * Zero if the segment is not supported, the step was not played yet or vibrator was never
72      * turned on by this step; A negative value if the vibrator call has failed.
73      */
getVibratorOnDuration()74     public long getVibratorOnDuration() {
75         return 0;
76     }
77 
78     /**
79      * Return true to run this step right after a vibrator has notified vibration completed,
80      * used to resume steps waiting on vibrator callbacks with a timeout.
81      */
acceptVibratorCompleteCallback(int vibratorId)82     public boolean acceptVibratorCompleteCallback(int vibratorId) {
83         return false;
84     }
85 
86     /**
87      * Returns the time in millis to wait before playing this step. This is performed
88      * while holding the queue lock, so should not rely on potentially slow operations.
89      */
calculateWaitTime()90     public long calculateWaitTime() {
91         if (startTime == Long.MAX_VALUE) {
92             // This step don't have a predefined start time, it's just marked to be executed
93             // after all other steps have finished.
94             return 0;
95         }
96         return Math.max(0, startTime - SystemClock.uptimeMillis());
97     }
98 
99     @Override
compareTo(Step o)100     public int compareTo(Step o) {
101         return Long.compare(startTime, o.startTime);
102     }
103 }
104