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