1 /* 2 * Copyright (C) 2020 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 package android.app.search; 17 18 import android.annotation.IntDef; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Objects; 30 31 /** 32 * A representation of an search target event. 33 * 34 * There are two types of events. First type of event correspends to the user interaction 35 * that happens on the search surface. (e.g., {@link #ACTION_TAP}. Second type of events 36 * correspends to the lifecycle event of the search surface {@link #ACTION_SURFACE_VISIBLE}. 37 * 38 * @hide 39 */ 40 @SystemApi 41 public final class SearchTargetEvent implements Parcelable { 42 43 /** 44 * @hide 45 */ 46 @IntDef(prefix = {"ACTION_"}, value = { 47 ACTION_SURFACE_VISIBLE, 48 ACTION_TAP, 49 ACTION_LONGPRESS, 50 ACTION_LAUNCH_TOUCH, 51 ACTION_LAUNCH_KEYBOARD_FOCUS, 52 ACTION_DRAGNDROP, 53 ACTION_SURFACE_INVISIBLE, 54 ACTION_DELETE, 55 ACTION_DISMISS 56 }) 57 @Retention(RetentionPolicy.SOURCE) 58 public @interface ActionType {} 59 60 /** 61 * @hide 62 */ 63 @IntDef(prefix = {"FLAG_"}, value = { 64 FLAG_IME_SHOWN 65 }) 66 @Retention(RetentionPolicy.SOURCE) 67 public @interface FlagType {} 68 69 @NonNull 70 private final List<String> mTargetIds; 71 @Nullable 72 private final String mLocation; 73 @ActionType 74 private final int mAction; 75 @FlagType 76 private int mFlags; 77 78 /** 79 * IME was shown when event happened. 80 */ 81 public static final int FLAG_IME_SHOWN = 1 << 0; 82 83 84 /** 85 * Search container was opened. 86 */ 87 public static final int ACTION_SURFACE_VISIBLE = 1; 88 89 /** 90 * Constants that define tapping without closing the search surface. 91 */ 92 public static final int ACTION_TAP = 3; 93 94 /** 95 * Constants that define long pressing without closing the search surface. 96 */ 97 public static final int ACTION_LONGPRESS = 4; 98 99 /** 100 * Constants that define tapping on the touch target to launch. 101 */ 102 public static final int ACTION_LAUNCH_TOUCH = 5; 103 104 /** 105 * Constants that define tapping on the soft keyboard confirm or search to launch. 106 */ 107 public static final int ACTION_LAUNCH_KEYBOARD_FOCUS = 6; 108 109 /** 110 * Searcheable item was draged and dropped to another surface. 111 */ 112 public static final int ACTION_DRAGNDROP = 7; 113 114 /** 115 * Search container was closed. 116 */ 117 public static final int ACTION_SURFACE_INVISIBLE = 8; 118 119 /** 120 * Constant that defines user deleted a target. 121 */ 122 public static final int ACTION_DELETE = 9; 123 124 /** 125 * Constant that defines user dismissed a target. 126 */ 127 public static final int ACTION_DISMISS = 10; 128 SearchTargetEvent(@onNull List<String> targetIds, @Nullable String location, @ActionType int actionType, @FlagType int flags)129 private SearchTargetEvent(@NonNull List<String> targetIds, 130 @Nullable String location, 131 @ActionType int actionType, 132 @FlagType int flags) { 133 mTargetIds = Objects.requireNonNull(targetIds); 134 mLocation = location; 135 mAction = actionType; 136 mFlags = flags; 137 } 138 SearchTargetEvent(Parcel parcel)139 private SearchTargetEvent(Parcel parcel) { 140 mTargetIds = new ArrayList<>(); 141 parcel.readStringList(mTargetIds); 142 mLocation = parcel.readString(); 143 mAction = parcel.readInt(); 144 mFlags = parcel.readInt(); 145 } 146 147 /** 148 * Returns the primary search target with interaction. 149 */ 150 @NonNull getTargetId()151 public String getTargetId() { 152 return mTargetIds.get(0); 153 } 154 155 /** 156 * Returns the list of search targets with visualization change. 157 */ 158 @NonNull getTargetIds()159 public List<String> getTargetIds() { 160 return mTargetIds; 161 } 162 163 /** 164 * Returns the launch location. 165 */ 166 @Nullable getLaunchLocation()167 public String getLaunchLocation() { 168 return mLocation; 169 } 170 171 /** 172 * Returns the action type. 173 */ 174 @ActionType getAction()175 public int getAction() { 176 return mAction; 177 } 178 getFlags()179 public int getFlags() { 180 return mFlags; 181 } 182 183 @Override hashCode()184 public int hashCode() { 185 return mTargetIds.get(0).hashCode() + mAction; 186 } 187 188 @Override equals(@ullable Object o)189 public boolean equals(@Nullable Object o) { 190 if (!getClass().equals(o != null ? o.getClass() : null)) return false; 191 192 SearchTargetEvent other = (SearchTargetEvent) o; 193 return mTargetIds.equals(other.mTargetIds) 194 && mAction == other.mAction 195 && mFlags == other.mFlags 196 && mLocation == null ? other.mLocation == null : mLocation.equals(other.mLocation); 197 } 198 199 @Override describeContents()200 public int describeContents() { 201 return 0; 202 } 203 204 @Override writeToParcel(@onNull Parcel dest, int flags)205 public void writeToParcel(@NonNull Parcel dest, int flags) { 206 dest.writeStringList(mTargetIds); 207 dest.writeString(mLocation); 208 dest.writeInt(mAction); 209 dest.writeInt(mFlags); 210 } 211 212 public static final @NonNull Creator<SearchTargetEvent> CREATOR = 213 new Creator<SearchTargetEvent>() { 214 public SearchTargetEvent createFromParcel(Parcel parcel) { 215 return new SearchTargetEvent(parcel); 216 } 217 218 public SearchTargetEvent[] newArray(int size) { 219 return new SearchTargetEvent[size]; 220 } 221 }; 222 223 /** 224 * A builder for search target events. 225 * 226 * @hide 227 */ 228 @SystemApi 229 public static final class Builder { 230 @NonNull 231 private List<String> mTargetIds; 232 @Nullable 233 private String mLocation; 234 @ActionType 235 private int mAction; 236 private int mFlags; 237 238 /** 239 * @param id The target id that is associated with this event. 240 * @param actionType The event type 241 */ Builder(@onNull String id, @ActionType int actionType)242 public Builder(@NonNull String id, @ActionType int actionType) { 243 mTargetIds = new ArrayList<>(); 244 mTargetIds.add(id); 245 mAction = actionType; 246 } 247 248 /** 249 * @param ids The target ids that is associated with this event. 250 * @param actionType The event type 251 */ Builder(@onNull List<String> ids, @ActionType int actionType)252 public Builder(@NonNull List<String> ids, @ActionType int actionType) { 253 mTargetIds = ids; 254 mAction = actionType; 255 } 256 257 /** 258 * Sets the launch location. 259 */ 260 @NonNull setLaunchLocation(@ullable String location)261 public Builder setLaunchLocation(@Nullable String location) { 262 mLocation = location; 263 return this; 264 } 265 266 /** 267 * Sets the launch location. 268 */ 269 @NonNull setFlags(int flags)270 public Builder setFlags(int flags) { 271 mFlags = flags; 272 return this; 273 } 274 275 /** 276 * Builds a new event instance. 277 */ 278 @NonNull build()279 public SearchTargetEvent build() { 280 return new SearchTargetEvent(mTargetIds, mLocation, mAction, mFlags); 281 } 282 } 283 } 284