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