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.hardware.input; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.os.SystemClock; 25 import android.view.InputEvent; 26 import android.view.MotionEvent; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 31 /** 32 * An event describing a mouse button click interaction originating from a remote device. 33 * 34 * @hide 35 */ 36 @SystemApi 37 public final class VirtualMouseButtonEvent implements Parcelable { 38 39 /** @hide */ 40 public static final int ACTION_UNKNOWN = -1; 41 /** Action indicating the mouse button has been pressed. */ 42 public static final int ACTION_BUTTON_PRESS = MotionEvent.ACTION_BUTTON_PRESS; 43 /** Action indicating the mouse button has been released. */ 44 public static final int ACTION_BUTTON_RELEASE = MotionEvent.ACTION_BUTTON_RELEASE; 45 /** @hide */ 46 @IntDef(prefix = {"ACTION_"}, value = { 47 ACTION_UNKNOWN, 48 ACTION_BUTTON_PRESS, 49 ACTION_BUTTON_RELEASE, 50 }) 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface Action {} 53 54 /** @hide */ 55 public static final int BUTTON_UNKNOWN = -1; 56 /** Action indicating the mouse button involved in this event is in the left position. */ 57 public static final int BUTTON_PRIMARY = MotionEvent.BUTTON_PRIMARY; 58 /** Action indicating the mouse button involved in this event is in the middle position. */ 59 public static final int BUTTON_TERTIARY = MotionEvent.BUTTON_TERTIARY; 60 /** Action indicating the mouse button involved in this event is in the right position. */ 61 public static final int BUTTON_SECONDARY = MotionEvent.BUTTON_SECONDARY; 62 /** 63 * Action indicating the mouse button involved in this event is intended to go back to the 64 * previous. 65 */ 66 public static final int BUTTON_BACK = MotionEvent.BUTTON_BACK; 67 /** 68 * Action indicating the mouse button involved in this event is intended to move forward to the 69 * next. 70 */ 71 public static final int BUTTON_FORWARD = MotionEvent.BUTTON_FORWARD; 72 /** @hide */ 73 @IntDef(prefix = {"BUTTON_"}, value = { 74 BUTTON_UNKNOWN, 75 BUTTON_PRIMARY, 76 BUTTON_TERTIARY, 77 BUTTON_SECONDARY, 78 BUTTON_BACK, 79 BUTTON_FORWARD, 80 }) 81 @Retention(RetentionPolicy.SOURCE) 82 public @interface Button {} 83 84 private final @Action int mAction; 85 private final @Button int mButtonCode; 86 private final long mEventTimeNanos; 87 VirtualMouseButtonEvent(@ction int action, @Button int buttonCode, long eventTimeNanos)88 private VirtualMouseButtonEvent(@Action int action, @Button int buttonCode, 89 long eventTimeNanos) { 90 mAction = action; 91 mButtonCode = buttonCode; 92 mEventTimeNanos = eventTimeNanos; 93 } 94 VirtualMouseButtonEvent(@onNull Parcel parcel)95 private VirtualMouseButtonEvent(@NonNull Parcel parcel) { 96 mAction = parcel.readInt(); 97 mButtonCode = parcel.readInt(); 98 mEventTimeNanos = parcel.readLong(); 99 } 100 101 @Override writeToParcel(@onNull Parcel parcel, int parcelableFlags)102 public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) { 103 parcel.writeInt(mAction); 104 parcel.writeInt(mButtonCode); 105 parcel.writeLong(mEventTimeNanos); 106 } 107 108 @Override describeContents()109 public int describeContents() { 110 return 0; 111 } 112 113 /** 114 * Returns the button code associated with this event. 115 */ getButtonCode()116 public @Button int getButtonCode() { 117 return mButtonCode; 118 } 119 120 /** 121 * Returns the action associated with this event. 122 */ getAction()123 public @Action int getAction() { 124 return mAction; 125 } 126 127 /** 128 * Returns the time this event occurred, in the {@link SystemClock#uptimeMillis()} time base but 129 * with nanosecond (instead of millisecond) precision. 130 * 131 * @see InputEvent#getEventTime() 132 */ getEventTimeNanos()133 public long getEventTimeNanos() { 134 return mEventTimeNanos; 135 } 136 137 /** 138 * Builder for {@link VirtualMouseButtonEvent}. 139 */ 140 public static final class Builder { 141 142 private @Action int mAction = ACTION_UNKNOWN; 143 private @Button int mButtonCode = -1; 144 private long mEventTimeNanos = 0L; 145 146 /** 147 * Creates a {@link VirtualMouseButtonEvent} object with the current builder configuration. 148 */ build()149 public @NonNull VirtualMouseButtonEvent build() { 150 if (mAction == ACTION_UNKNOWN || mButtonCode == -1) { 151 throw new IllegalArgumentException( 152 "Cannot build virtual mouse button event with unset fields"); 153 } 154 return new VirtualMouseButtonEvent(mAction, mButtonCode, mEventTimeNanos); 155 } 156 157 /** 158 * Sets the button code of the event. 159 * 160 * @return this builder, to allow for chaining of calls 161 */ setButtonCode(int buttonCode)162 public @NonNull Builder setButtonCode(int buttonCode) { 163 if (buttonCode != BUTTON_PRIMARY 164 && buttonCode != BUTTON_TERTIARY 165 && buttonCode != BUTTON_SECONDARY 166 && buttonCode != BUTTON_BACK 167 && buttonCode != BUTTON_FORWARD) { 168 throw new IllegalArgumentException("Unsupported mouse button code"); 169 } 170 mButtonCode = buttonCode; 171 return this; 172 } 173 174 /** 175 * Sets the action of the event. 176 * 177 * @return this builder, to allow for chaining of calls 178 */ setAction(@ction int action)179 public @NonNull Builder setAction(@Action int action) { 180 if (action != ACTION_BUTTON_PRESS && action != ACTION_BUTTON_RELEASE) { 181 throw new IllegalArgumentException("Unsupported mouse button action type"); 182 } 183 mAction = action; 184 return this; 185 } 186 187 /** 188 * Sets the time (in nanoseconds) when this specific event was generated. This may be 189 * obtained from {@link SystemClock#uptimeMillis()} (with nanosecond precision instead of 190 * millisecond), but can be different depending on the use case. 191 * This field is optional and can be omitted. 192 * 193 * @return this builder, to allow for chaining of calls 194 * @see InputEvent#getEventTime() 195 */ setEventTimeNanos(long eventTimeNanos)196 public @NonNull Builder setEventTimeNanos(long eventTimeNanos) { 197 if (eventTimeNanos < 0L) { 198 throw new IllegalArgumentException("Event time cannot be negative"); 199 } 200 this.mEventTimeNanos = eventTimeNanos; 201 return this; 202 } 203 } 204 205 public static final @NonNull Parcelable.Creator<VirtualMouseButtonEvent> CREATOR = 206 new Parcelable.Creator<VirtualMouseButtonEvent>() { 207 public VirtualMouseButtonEvent createFromParcel(Parcel source) { 208 return new VirtualMouseButtonEvent(source); 209 } 210 211 public VirtualMouseButtonEvent[] newArray(int size) { 212 return new VirtualMouseButtonEvent[size]; 213 } 214 }; 215 } 216