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.app.people; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.graphics.drawable.Icon; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 public final class ConversationStatus implements Parcelable { 31 private static final String TAG = "ConversationStatus"; 32 33 /** @hide */ 34 @IntDef(prefix = { "ACTIVITY_" }, value = { 35 ACTIVITY_OTHER, 36 ACTIVITY_BIRTHDAY, 37 ACTIVITY_ANNIVERSARY, 38 ACTIVITY_NEW_STORY, 39 ACTIVITY_AUDIO, 40 ACTIVITY_VIDEO, 41 ACTIVITY_GAME, 42 ACTIVITY_LOCATION, 43 ACTIVITY_UPCOMING_BIRTHDAY 44 }) 45 @Retention(RetentionPolicy.SOURCE) 46 public @interface ActivityType {} 47 48 /** 49 * Constant representing that the conversation user is engaged in an activity that cannot be 50 * more specifically represented by another type. 51 */ 52 public static final int ACTIVITY_OTHER = 0; 53 /** 54 * Constant representing that today is the conversation user's birthday. 55 */ 56 public static final int ACTIVITY_BIRTHDAY = 1; 57 /** 58 * Constant representing that the conversation user and the device user are celebrating 59 * and anniversary today. 60 */ 61 public static final int ACTIVITY_ANNIVERSARY = 2; 62 /** 63 * Constant representing that the conversation user has posted a new story. 64 */ 65 public static final int ACTIVITY_NEW_STORY = 3; 66 /** 67 * Constant representing that the conversation user is listening to music or other audio 68 * like a podcast. 69 */ 70 public static final int ACTIVITY_AUDIO = 4; 71 /** 72 * Constant representing that the conversation user is watching video content. 73 */ 74 public static final int ACTIVITY_VIDEO = 5; 75 /** 76 * Constant representing that the conversation user is playing a game. 77 */ 78 public static final int ACTIVITY_GAME = 6; 79 /** 80 * Constant representing that the conversation user is sharing status with the device user. 81 * Use this to represent a general 'this person is sharing their location with you' status or 82 * a more specific 'this is the current location of this person' status. 83 */ 84 public static final int ACTIVITY_LOCATION = 7; 85 /** 86 * Constant representing that the conversation user's birthday is approaching soon. 87 */ 88 public static final int ACTIVITY_UPCOMING_BIRTHDAY = 8; 89 90 /** @hide */ 91 @IntDef(prefix = { "AVAILABILITY_" }, value = { 92 AVAILABILITY_UNKNOWN, 93 AVAILABILITY_AVAILABLE, 94 AVAILABILITY_BUSY, 95 AVAILABILITY_OFFLINE 96 }) 97 @Retention(RetentionPolicy.SOURCE) 98 public @interface Availability {} 99 100 public static final int AVAILABILITY_UNKNOWN = -1; 101 public static final int AVAILABILITY_AVAILABLE = 0; 102 public static final int AVAILABILITY_BUSY = 1; 103 public static final int AVAILABILITY_OFFLINE = 2; 104 105 private final String mId; 106 private final int mActivity; 107 108 private int mAvailability; 109 private CharSequence mDescription; 110 private Icon mIcon; 111 private long mStartTimeMs; 112 private long mEndTimeMs; 113 ConversationStatus(Builder b)114 private ConversationStatus(Builder b) { 115 mId = b.mId; 116 mActivity = b.mActivity; 117 mAvailability = b.mAvailability; 118 mDescription = b.mDescription; 119 mIcon = b.mIcon; 120 mStartTimeMs = b.mStartTimeMs; 121 mEndTimeMs = b.mEndTimeMs; 122 } 123 ConversationStatus(Parcel p)124 private ConversationStatus(Parcel p) { 125 mId = p.readString(); 126 mActivity = p.readInt(); 127 mAvailability = p.readInt(); 128 mDescription = p.readCharSequence(); 129 mIcon = p.readParcelable(Icon.class.getClassLoader(), android.graphics.drawable.Icon.class); 130 mStartTimeMs = p.readLong(); 131 mEndTimeMs = p.readLong(); 132 } 133 134 @Override writeToParcel(@onNull Parcel dest, int flags)135 public void writeToParcel(@NonNull Parcel dest, int flags) { 136 dest.writeString(mId); 137 dest.writeInt(mActivity); 138 dest.writeInt(mAvailability); 139 dest.writeCharSequence(mDescription); 140 dest.writeParcelable(mIcon, flags); 141 dest.writeLong(mStartTimeMs); 142 dest.writeLong(mEndTimeMs); 143 } 144 145 /** 146 * Returns the unique identifier for the status. 147 */ getId()148 public @NonNull String getId() { 149 return mId; 150 } 151 152 /** 153 * Returns the type of activity represented by this status 154 */ getActivity()155 public @ActivityType int getActivity() { 156 return mActivity; 157 } 158 159 /** 160 * Returns the availability of the people behind this conversation while this activity is 161 * happening. 162 */ getAvailability()163 public @Availability int getAvailability() { 164 return mAvailability; 165 } 166 167 /** 168 * Returns the description for this activity. 169 */ getDescription()170 public @Nullable CharSequence getDescription() { 171 return mDescription; 172 } 173 174 /** 175 * Returns the image for this activity. 176 */ getIcon()177 public @Nullable Icon getIcon() { 178 return mIcon; 179 } 180 181 /** 182 * Returns the time at which this status started 183 */ getStartTimeMillis()184 public long getStartTimeMillis() { 185 return mStartTimeMs; 186 } 187 188 /** 189 * Returns the time at which this status should be expired. 190 */ getEndTimeMillis()191 public long getEndTimeMillis() { 192 return mEndTimeMs; 193 } 194 195 @Override equals(Object o)196 public boolean equals(Object o) { 197 if (this == o) return true; 198 if (o == null || getClass() != o.getClass()) return false; 199 ConversationStatus that = (ConversationStatus) o; 200 return mActivity == that.mActivity && 201 mAvailability == that.mAvailability && 202 mStartTimeMs == that.mStartTimeMs && 203 mEndTimeMs == that.mEndTimeMs && 204 mId.equals(that.mId) && 205 Objects.equals(mDescription, that.mDescription) && 206 Objects.equals(mIcon, that.mIcon); 207 } 208 209 @Override hashCode()210 public int hashCode() { 211 return Objects.hash(mId, mActivity, mAvailability, mDescription, mIcon, mStartTimeMs, 212 mEndTimeMs); 213 } 214 215 @Override toString()216 public String toString() { 217 return "ConversationStatus{" + 218 "mId='" + mId + '\'' + 219 ", mActivity=" + mActivity + 220 ", mAvailability=" + mAvailability + 221 ", mDescription=" + mDescription + 222 ", mIcon=" + mIcon + 223 ", mStartTimeMs=" + mStartTimeMs + 224 ", mEndTimeMs=" + mEndTimeMs + 225 '}'; 226 } 227 228 @Override describeContents()229 public int describeContents() { 230 return 0; 231 } 232 233 public static final @NonNull Creator<ConversationStatus> CREATOR 234 = new Creator<ConversationStatus>() { 235 public ConversationStatus createFromParcel(Parcel source) { 236 return new ConversationStatus(source); 237 } 238 239 public ConversationStatus[] newArray(int size) { 240 return new ConversationStatus[size]; 241 } 242 }; 243 244 public static final class Builder { 245 final String mId; 246 final int mActivity; 247 int mAvailability = AVAILABILITY_UNKNOWN; 248 CharSequence mDescription; 249 Icon mIcon; 250 long mStartTimeMs = -1; 251 long mEndTimeMs = -1; 252 253 /** 254 * Creates a new builder. 255 * 256 * @param id The unique id for this status 257 * @param activity The type of status 258 */ Builder(@onNull String id, @ActivityType @NonNull int activity)259 public Builder(@NonNull String id, @ActivityType @NonNull int activity) { 260 mId = id; 261 mActivity = activity; 262 } 263 264 265 /** 266 * Sets the availability of the conversation to provide a hint about how likely 267 * it is that the user would receive a timely response if they sent a message. 268 */ setAvailability(@vailability int availability)269 public @NonNull Builder setAvailability(@Availability int availability) { 270 mAvailability = availability; 271 return this; 272 } 273 274 /** 275 * Sets a user visible description expanding on the conversation user(s)'s activity. 276 * 277 * <p>Examples include: what media someone is watching or listening to, their approximate 278 * location, or what type of anniversary they are celebrating.</p> 279 */ setDescription(@ullable CharSequence description)280 public @NonNull Builder setDescription(@Nullable CharSequence description) { 281 mDescription = description; 282 return this; 283 } 284 285 /** 286 * Sets an image representing the conversation user(s)'s activity. 287 * 288 * <p>Examples include: A still from a new story update, album art, or a map showing 289 * approximate location.</p> 290 */ setIcon(@ullable Icon icon)291 public @NonNull Builder setIcon(@Nullable Icon icon) { 292 mIcon = icon; 293 return this; 294 } 295 296 /** 297 * Sets the time at which this status became valid. 298 */ setStartTimeMillis(long startTimeMs)299 public @NonNull Builder setStartTimeMillis(long startTimeMs) { 300 mStartTimeMs = startTimeMs; 301 return this; 302 } 303 304 /** 305 * Sets an expiration time for this status. 306 * 307 * <p>The system will remove the status at this time if it hasn't already been withdrawn. 308 * </p> 309 */ setEndTimeMillis(long endTimeMs)310 public @NonNull Builder setEndTimeMillis(long endTimeMs) { 311 mEndTimeMs = endTimeMs; 312 return this; 313 } 314 build()315 public @NonNull ConversationStatus build() { 316 return new ConversationStatus(this); 317 } 318 } 319 } 320