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