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.Nullable;
21 import android.annotation.TestApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.VibrationEffect;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.util.Objects;
29 
30 /**
31  * Representation of {@link VibrationEffectSegment} that plays a primitive vibration effect after a
32  * specified delay and applying a given scale.
33  *
34  * @hide
35  */
36 @TestApi
37 public final class PrimitiveSegment extends VibrationEffectSegment {
38     private final int mPrimitiveId;
39     private final float mScale;
40     private final int mDelay;
41 
PrimitiveSegment(@onNull Parcel in)42     PrimitiveSegment(@NonNull Parcel in) {
43         this(in.readInt(), in.readFloat(), in.readInt());
44     }
45 
46     /** @hide */
PrimitiveSegment(int id, float scale, int delay)47     public PrimitiveSegment(int id, float scale, int delay) {
48         mPrimitiveId = id;
49         mScale = scale;
50         mDelay = delay;
51     }
52 
getPrimitiveId()53     public int getPrimitiveId() {
54         return mPrimitiveId;
55     }
56 
getScale()57     public float getScale() {
58         return mScale;
59     }
60 
getDelay()61     public int getDelay() {
62         return mDelay;
63     }
64 
65     @Override
getDuration()66     public long getDuration() {
67         return -1;
68     }
69 
70     @Override
hasNonZeroAmplitude()71     public boolean hasNonZeroAmplitude() {
72         // Every primitive plays a vibration with a non-zero amplitude, even at scale == 0.
73         return true;
74     }
75 
76     @NonNull
77     @Override
resolve(int defaultAmplitude)78     public PrimitiveSegment resolve(int defaultAmplitude) {
79         return this;
80     }
81 
82     @NonNull
83     @Override
scale(float scaleFactor)84     public PrimitiveSegment scale(float scaleFactor) {
85         return new PrimitiveSegment(mPrimitiveId, VibrationEffect.scale(mScale, scaleFactor),
86                 mDelay);
87     }
88 
89     @NonNull
90     @Override
applyEffectStrength(int effectStrength)91     public PrimitiveSegment applyEffectStrength(int effectStrength) {
92         return this;
93     }
94 
95     @Override
validate()96     public void validate() {
97         Preconditions.checkArgumentInRange(mPrimitiveId, VibrationEffect.Composition.PRIMITIVE_NOOP,
98                 VibrationEffect.Composition.PRIMITIVE_LOW_TICK, "primitiveId");
99         Preconditions.checkArgumentInRange(mScale, 0f, 1f, "scale");
100         Preconditions.checkArgumentNonnegative(mDelay, "primitive delay should be >= 0");
101     }
102 
103     @Override
writeToParcel(@onNull Parcel dest, int flags)104     public void writeToParcel(@NonNull Parcel dest, int flags) {
105         dest.writeInt(PARCEL_TOKEN_PRIMITIVE);
106         dest.writeInt(mPrimitiveId);
107         dest.writeFloat(mScale);
108         dest.writeInt(mDelay);
109     }
110 
111     @Override
describeContents()112     public int describeContents() {
113         return 0;
114     }
115 
116     @Override
toString()117     public String toString() {
118         return "Primitive{"
119                 + "primitive=" + VibrationEffect.Composition.primitiveToString(mPrimitiveId)
120                 + ", scale=" + mScale
121                 + ", delay=" + mDelay
122                 + '}';
123     }
124 
125     @Override
equals(@ullable Object o)126     public boolean equals(@Nullable Object o) {
127         if (this == o) return true;
128         if (o == null || getClass() != o.getClass()) return false;
129         PrimitiveSegment that = (PrimitiveSegment) o;
130         return mPrimitiveId == that.mPrimitiveId
131                 && Float.compare(that.mScale, mScale) == 0
132                 && mDelay == that.mDelay;
133     }
134 
135     @Override
hashCode()136     public int hashCode() {
137         return Objects.hash(mPrimitiveId, mScale, mDelay);
138     }
139 
140     @NonNull
141     public static final Parcelable.Creator<PrimitiveSegment> CREATOR =
142             new Parcelable.Creator<PrimitiveSegment>() {
143                 @Override
144                 public PrimitiveSegment createFromParcel(Parcel in) {
145                     // Skip the type token
146                     in.readInt();
147                     return new PrimitiveSegment(in);
148                 }
149 
150                 @Override
151                 public PrimitiveSegment[] newArray(int size) {
152                     return new PrimitiveSegment[size];
153                 }
154             };
155 }
156