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 android.os.vibrator; 18 19 import android.annotation.NonNull; 20 import android.annotation.TestApi; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.VibrationEffect; 24 25 import com.android.internal.util.Preconditions; 26 27 import java.util.Objects; 28 29 /** 30 * Representation of {@link VibrationEffectSegment} that holds a fixed vibration amplitude and 31 * frequency for a specified duration. 32 * 33 * @hide 34 */ 35 @TestApi 36 public final class StepSegment extends VibrationEffectSegment { 37 private final float mAmplitude; 38 private final float mFrequency; 39 private final int mDuration; 40 StepSegment(@onNull Parcel in)41 StepSegment(@NonNull Parcel in) { 42 this(in.readFloat(), in.readFloat(), in.readInt()); 43 } 44 45 /** @hide */ StepSegment(float amplitude, float frequency, int duration)46 public StepSegment(float amplitude, float frequency, int duration) { 47 mAmplitude = amplitude; 48 mFrequency = frequency; 49 mDuration = duration; 50 } 51 52 @Override equals(Object o)53 public boolean equals(Object o) { 54 if (!(o instanceof StepSegment)) { 55 return false; 56 } 57 StepSegment other = (StepSegment) o; 58 return Float.compare(mAmplitude, other.mAmplitude) == 0 59 && Float.compare(mFrequency, other.mFrequency) == 0 60 && mDuration == other.mDuration; 61 } 62 getAmplitude()63 public float getAmplitude() { 64 return mAmplitude; 65 } 66 getFrequency()67 public float getFrequency() { 68 return mFrequency; 69 } 70 71 @Override getDuration()72 public long getDuration() { 73 return mDuration; 74 } 75 76 @Override hasNonZeroAmplitude()77 public boolean hasNonZeroAmplitude() { 78 // DEFAULT_AMPLITUDE == -1 is still a non-zero amplitude that will be resolved later. 79 return Float.compare(mAmplitude, 0) != 0; 80 } 81 82 @Override validate()83 public void validate() { 84 Preconditions.checkArgumentNonnegative(mDuration, 85 "Durations must all be >= 0, got " + mDuration); 86 if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) { 87 Preconditions.checkArgumentInRange(mAmplitude, 0f, 1f, "amplitude"); 88 } 89 } 90 91 @NonNull 92 @Override resolve(int defaultAmplitude)93 public StepSegment resolve(int defaultAmplitude) { 94 if (defaultAmplitude > VibrationEffect.MAX_AMPLITUDE || defaultAmplitude <= 0) { 95 throw new IllegalArgumentException( 96 "amplitude must be between 1 and 255 inclusive (amplitude=" 97 + defaultAmplitude + ")"); 98 } 99 if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) { 100 return this; 101 } 102 return new StepSegment((float) defaultAmplitude / VibrationEffect.MAX_AMPLITUDE, mFrequency, 103 mDuration); 104 } 105 106 @NonNull 107 @Override scale(float scaleFactor)108 public StepSegment scale(float scaleFactor) { 109 if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) == 0) { 110 return this; 111 } 112 return new StepSegment(VibrationEffect.scale(mAmplitude, scaleFactor), mFrequency, 113 mDuration); 114 } 115 116 @NonNull 117 @Override applyEffectStrength(int effectStrength)118 public StepSegment applyEffectStrength(int effectStrength) { 119 return this; 120 } 121 122 @Override hashCode()123 public int hashCode() { 124 return Objects.hash(mAmplitude, mFrequency, mDuration); 125 } 126 127 @Override toString()128 public String toString() { 129 return "Step{amplitude=" + mAmplitude 130 + ", frequency=" + mFrequency 131 + ", duration=" + mDuration 132 + "}"; 133 } 134 135 @Override describeContents()136 public int describeContents() { 137 return 0; 138 } 139 140 @Override writeToParcel(@onNull Parcel out, int flags)141 public void writeToParcel(@NonNull Parcel out, int flags) { 142 out.writeInt(PARCEL_TOKEN_STEP); 143 out.writeFloat(mAmplitude); 144 out.writeFloat(mFrequency); 145 out.writeInt(mDuration); 146 } 147 148 @NonNull 149 public static final Parcelable.Creator<StepSegment> CREATOR = 150 new Parcelable.Creator<StepSegment>() { 151 @Override 152 public StepSegment createFromParcel(Parcel in) { 153 // Skip the type token 154 in.readInt(); 155 return new StepSegment(in); 156 } 157 158 @Override 159 public StepSegment[] newArray(int size) { 160 return new StepSegment[size]; 161 } 162 }; 163 } 164