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.VibrationEffect; 23 24 import com.android.internal.util.Preconditions; 25 26 import java.util.Objects; 27 28 /** 29 * Representation of {@link VibrationEffectSegment} that ramps vibration amplitude and/or frequency 30 * for a specified duration. 31 * 32 * <p>The amplitudes are expressed by float values in the range [0, 1], representing the relative 33 * output acceleration for the vibrator. The frequencies are expressed in hertz by positive finite 34 * float values. The special value zero is used here for an unspecified frequency, and will be 35 * automatically mapped to the device's default vibration frequency (usually the resonant 36 * frequency). 37 * 38 * @hide 39 */ 40 @TestApi 41 public final class RampSegment extends VibrationEffectSegment { 42 private final float mStartAmplitude; 43 private final float mStartFrequencyHz; 44 private final float mEndAmplitude; 45 private final float mEndFrequencyHz; 46 private final int mDuration; 47 RampSegment(@onNull Parcel in)48 RampSegment(@NonNull Parcel in) { 49 this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readInt()); 50 } 51 52 /** @hide */ RampSegment(float startAmplitude, float endAmplitude, float startFrequencyHz, float endFrequencyHz, int duration)53 public RampSegment(float startAmplitude, float endAmplitude, float startFrequencyHz, 54 float endFrequencyHz, int duration) { 55 mStartAmplitude = startAmplitude; 56 mEndAmplitude = endAmplitude; 57 mStartFrequencyHz = startFrequencyHz; 58 mEndFrequencyHz = endFrequencyHz; 59 mDuration = duration; 60 } 61 62 @Override equals(Object o)63 public boolean equals(Object o) { 64 if (!(o instanceof RampSegment)) { 65 return false; 66 } 67 RampSegment other = (RampSegment) o; 68 return Float.compare(mStartAmplitude, other.mStartAmplitude) == 0 69 && Float.compare(mEndAmplitude, other.mEndAmplitude) == 0 70 && Float.compare(mStartFrequencyHz, other.mStartFrequencyHz) == 0 71 && Float.compare(mEndFrequencyHz, other.mEndFrequencyHz) == 0 72 && mDuration == other.mDuration; 73 } 74 getStartAmplitude()75 public float getStartAmplitude() { 76 return mStartAmplitude; 77 } 78 getEndAmplitude()79 public float getEndAmplitude() { 80 return mEndAmplitude; 81 } 82 getStartFrequencyHz()83 public float getStartFrequencyHz() { 84 return mStartFrequencyHz; 85 } 86 getEndFrequencyHz()87 public float getEndFrequencyHz() { 88 return mEndFrequencyHz; 89 } 90 91 @Override getDuration()92 public long getDuration() { 93 return mDuration; 94 } 95 96 /** @hide */ 97 @Override isHapticFeedbackCandidate()98 public boolean isHapticFeedbackCandidate() { 99 return true; 100 } 101 102 /** @hide */ 103 @Override hasNonZeroAmplitude()104 public boolean hasNonZeroAmplitude() { 105 return mStartAmplitude > 0 || mEndAmplitude > 0; 106 } 107 108 /** @hide */ 109 @Override validate()110 public void validate() { 111 VibrationEffectSegment.checkFrequencyArgument(mStartFrequencyHz, "startFrequencyHz"); 112 VibrationEffectSegment.checkFrequencyArgument(mEndFrequencyHz, "endFrequencyHz"); 113 VibrationEffectSegment.checkDurationArgument(mDuration, "duration"); 114 Preconditions.checkArgumentInRange(mStartAmplitude, 0f, 1f, "startAmplitude"); 115 Preconditions.checkArgumentInRange(mEndAmplitude, 0f, 1f, "endAmplitude"); 116 } 117 118 /** @hide */ 119 @NonNull 120 @Override resolve(int defaultAmplitude)121 public RampSegment resolve(int defaultAmplitude) { 122 // Default amplitude is not supported for ramping. 123 return this; 124 } 125 126 /** @hide */ 127 @NonNull 128 @Override scale(float scaleFactor)129 public RampSegment scale(float scaleFactor) { 130 float newStartAmplitude = VibrationEffect.scale(mStartAmplitude, scaleFactor); 131 float newEndAmplitude = VibrationEffect.scale(mEndAmplitude, scaleFactor); 132 if (Float.compare(mStartAmplitude, newStartAmplitude) == 0 133 && Float.compare(mEndAmplitude, newEndAmplitude) == 0) { 134 return this; 135 } 136 return new RampSegment(newStartAmplitude, newEndAmplitude, mStartFrequencyHz, 137 mEndFrequencyHz, 138 mDuration); 139 } 140 141 /** @hide */ 142 @NonNull 143 @Override applyEffectStrength(int effectStrength)144 public RampSegment applyEffectStrength(int effectStrength) { 145 return this; 146 } 147 148 @Override hashCode()149 public int hashCode() { 150 return Objects.hash(mStartAmplitude, mEndAmplitude, mStartFrequencyHz, mEndFrequencyHz, 151 mDuration); 152 } 153 154 @Override toString()155 public String toString() { 156 return "Ramp{startAmplitude=" + mStartAmplitude 157 + ", endAmplitude=" + mEndAmplitude 158 + ", startFrequencyHz=" + mStartFrequencyHz 159 + ", endFrequencyHz=" + mEndFrequencyHz 160 + ", duration=" + mDuration 161 + "}"; 162 } 163 164 @Override describeContents()165 public int describeContents() { 166 return 0; 167 } 168 169 @Override writeToParcel(@onNull Parcel out, int flags)170 public void writeToParcel(@NonNull Parcel out, int flags) { 171 out.writeInt(PARCEL_TOKEN_RAMP); 172 out.writeFloat(mStartAmplitude); 173 out.writeFloat(mEndAmplitude); 174 out.writeFloat(mStartFrequencyHz); 175 out.writeFloat(mEndFrequencyHz); 176 out.writeInt(mDuration); 177 } 178 179 @NonNull 180 public static final Creator<RampSegment> CREATOR = 181 new Creator<RampSegment>() { 182 @Override 183 public RampSegment createFromParcel(Parcel in) { 184 // Skip the type token 185 in.readInt(); 186 return new RampSegment(in); 187 } 188 189 @Override 190 public RampSegment[] newArray(int size) { 191 return new RampSegment[size]; 192 } 193 }; 194 } 195