• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * <p>The amplitude is expressed by a float value in the range [0, 1], representing the relative
34  * output acceleration for the vibrator. The frequency is expressed in hertz by a positive finite
35  * float value. The special value zero is used here for an unspecified frequency, and will be
36  * automatically mapped to the device's default vibration frequency (usually the resonant
37  * frequency).
38  *
39  * @hide
40  */
41 @TestApi
42 public final class StepSegment extends VibrationEffectSegment {
43     private final float mAmplitude;
44     private final float mFrequencyHz;
45     private final int mDuration;
46 
StepSegment(@onNull Parcel in)47     StepSegment(@NonNull Parcel in) {
48         this(in.readFloat(), in.readFloat(), in.readInt());
49     }
50 
51     /** @hide */
StepSegment(float amplitude, float frequencyHz, int duration)52     public StepSegment(float amplitude, float frequencyHz, int duration) {
53         mAmplitude = amplitude;
54         mFrequencyHz = frequencyHz;
55         mDuration = duration;
56     }
57 
58     @Override
equals(Object o)59     public boolean equals(Object o) {
60         if (!(o instanceof StepSegment)) {
61             return false;
62         }
63         StepSegment other = (StepSegment) o;
64         return Float.compare(mAmplitude, other.mAmplitude) == 0
65                 && Float.compare(mFrequencyHz, other.mFrequencyHz) == 0
66                 && mDuration == other.mDuration;
67     }
68 
getAmplitude()69     public float getAmplitude() {
70         return mAmplitude;
71     }
72 
getFrequencyHz()73     public float getFrequencyHz() {
74         return mFrequencyHz;
75     }
76 
77     @Override
getDuration()78     public long getDuration() {
79         return mDuration;
80     }
81 
82     /** @hide */
83     @Override
isHapticFeedbackCandidate()84     public boolean isHapticFeedbackCandidate() {
85         return true;
86     }
87 
88     /** @hide */
89     @Override
hasNonZeroAmplitude()90     public boolean hasNonZeroAmplitude() {
91         // DEFAULT_AMPLITUDE == -1 is still a non-zero amplitude that will be resolved later.
92         return Float.compare(mAmplitude, 0) != 0;
93     }
94 
95     /** @hide */
96     @Override
validate()97     public void validate() {
98         VibrationEffectSegment.checkFrequencyArgument(mFrequencyHz, "frequencyHz");
99         VibrationEffectSegment.checkDurationArgument(mDuration, "duration");
100         if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) {
101             Preconditions.checkArgumentInRange(mAmplitude, 0f, 1f, "amplitude");
102         }
103     }
104 
105     /** @hide */
106     @NonNull
107     @Override
resolve(int defaultAmplitude)108     public StepSegment resolve(int defaultAmplitude) {
109         if (defaultAmplitude > VibrationEffect.MAX_AMPLITUDE || defaultAmplitude <= 0) {
110             throw new IllegalArgumentException(
111                     "amplitude must be between 1 and 255 inclusive (amplitude="
112                             + defaultAmplitude + ")");
113         }
114         if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) {
115             return this;
116         }
117         return new StepSegment((float) defaultAmplitude / VibrationEffect.MAX_AMPLITUDE,
118                 mFrequencyHz,
119                 mDuration);
120     }
121 
122     /** @hide */
123     @NonNull
124     @Override
scale(float scaleFactor)125     public StepSegment scale(float scaleFactor) {
126         if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) == 0) {
127             return this;
128         }
129         return new StepSegment(VibrationEffect.scale(mAmplitude, scaleFactor), mFrequencyHz,
130                 mDuration);
131     }
132 
133     /** @hide */
134     @NonNull
135     @Override
applyEffectStrength(int effectStrength)136     public StepSegment applyEffectStrength(int effectStrength) {
137         return this;
138     }
139 
140     @Override
hashCode()141     public int hashCode() {
142         return Objects.hash(mAmplitude, mFrequencyHz, mDuration);
143     }
144 
145     @Override
toString()146     public String toString() {
147         return "Step{amplitude=" + mAmplitude
148                 + ", frequencyHz=" + mFrequencyHz
149                 + ", duration=" + mDuration
150                 + "}";
151     }
152 
153     @Override
describeContents()154     public int describeContents() {
155         return 0;
156     }
157 
158     @Override
writeToParcel(@onNull Parcel out, int flags)159     public void writeToParcel(@NonNull Parcel out, int flags) {
160         out.writeInt(PARCEL_TOKEN_STEP);
161         out.writeFloat(mAmplitude);
162         out.writeFloat(mFrequencyHz);
163         out.writeInt(mDuration);
164     }
165 
166     @NonNull
167     public static final Parcelable.Creator<StepSegment> CREATOR =
168             new Parcelable.Creator<StepSegment>() {
169                 @Override
170                 public StepSegment createFromParcel(Parcel in) {
171                     // Skip the type token
172                     in.readInt();
173                     return new StepSegment(in);
174                 }
175 
176                 @Override
177                 public StepSegment[] newArray(int size) {
178                     return new StepSegment[size];
179                 }
180             };
181 }
182