1 /*
2  * Copyright (C) 2022 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.usage;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.SystemApi;
22 import android.app.BroadcastOptions;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.util.Objects;
27 
28 /**
29  * Class containing a collection of stats related to response events started from an app
30  * after receiving a broadcast.
31  *
32  * @see UsageStatsManager#queryBroadcastResponseStats(String, long)
33  * @see UsageStatsManager#clearBroadcastResponseStats(String, long)
34  * @hide
35  */
36 @SystemApi
37 public final class BroadcastResponseStats implements Parcelable {
38     private final String mPackageName;
39     private final long mId;
40     private int mBroadcastsDispatchedCount;
41     private int mNotificationsPostedCount;
42     private int mNotificationsUpdatedCount;
43     private int mNotificationsCancelledCount;
44 
45     /**
46      * Creates a new {@link BroadcastResponseStats} object that contain the stats for broadcasts
47      * with {@code id} (specified using
48      * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)} by the sender) that
49      * were sent to {@code packageName}.
50      *
51      * @param packageName the name of the package that broadcasts were sent to.
52      * @param id the ID specified by the sender using
53      *           {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
54      */
BroadcastResponseStats(@onNull String packageName, @IntRange(from = 1) long id)55     public BroadcastResponseStats(@NonNull String packageName, @IntRange(from = 1) long id) {
56         mPackageName = packageName;
57         mId = id;
58     }
59 
BroadcastResponseStats(@onNull Parcel in)60     private BroadcastResponseStats(@NonNull Parcel in) {
61         mPackageName = in.readString8();
62         mId = in.readLong();
63         mBroadcastsDispatchedCount = in.readInt();
64         mNotificationsPostedCount = in.readInt();
65         mNotificationsUpdatedCount = in.readInt();
66         mNotificationsCancelledCount = in.readInt();
67     }
68 
69     /**
70      * @return the name of the package that the stats in this object correspond to.
71      */
72     @NonNull
getPackageName()73     public String getPackageName() {
74         return mPackageName;
75     }
76 
77     /**
78      * @return the ID of the broadcasts that the stats in this object correspond to.
79      */
80     @IntRange(from = 1)
getId()81     public long getId() {
82         return mId;
83     }
84 
85     /**
86      * Returns the total number of broadcasts that were dispatched to the app by the caller.
87      *
88      * <b> Note that the returned count will only include the broadcasts that the caller explicitly
89      * requested to record using
90      * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
91      *
92      * @return the total number of broadcasts that were dispatched to the app.
93      */
94     @IntRange(from = 0)
getBroadcastsDispatchedCount()95     public int getBroadcastsDispatchedCount() {
96         return mBroadcastsDispatchedCount;
97     }
98 
99     /**
100      * Returns the total number of notifications posted by the app soon after receiving a
101      * broadcast.
102      *
103      * <b> Note that the returned count will only include the notifications that correspond to the
104      * broadcasts that the caller explicitly requested to record using
105      * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
106      *
107      * @return the total number of notifications posted by the app soon after receiving
108      *         a broadcast.
109      */
110     @IntRange(from = 0)
getNotificationsPostedCount()111     public int getNotificationsPostedCount() {
112         return mNotificationsPostedCount;
113     }
114 
115     /**
116      * Returns the total number of notifications updated by the app soon after receiving a
117      * broadcast.
118      *
119      * <b> Note that the returned count will only include the notifications that correspond to the
120      * broadcasts that the caller explicitly requested to record using
121      * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
122      *
123      * @return the total number of notifications updated by the app soon after receiving
124      *         a broadcast.
125      */
126     @IntRange(from = 0)
getNotificationsUpdatedCount()127     public int getNotificationsUpdatedCount() {
128         return mNotificationsUpdatedCount;
129     }
130 
131     /**
132      * Returns the total number of notifications cancelled by the app soon after receiving a
133      * broadcast.
134      *
135      * <b> Note that the returned count will only include the notifications that correspond to the
136      * broadcasts that the caller explicitly requested to record using
137      * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}.
138      *
139      * @return the total number of notifications cancelled by the app soon after receiving
140      *         a broadcast.
141      */
142     @IntRange(from = 0)
getNotificationsCancelledCount()143     public int getNotificationsCancelledCount() {
144         return mNotificationsCancelledCount;
145     }
146 
147     /** @hide */
incrementBroadcastsDispatchedCount(@ntRangefrom = 0) int count)148     public void incrementBroadcastsDispatchedCount(@IntRange(from = 0) int count) {
149         mBroadcastsDispatchedCount += count;
150     }
151 
152     /** @hide */
incrementNotificationsPostedCount(@ntRangefrom = 0) int count)153     public void incrementNotificationsPostedCount(@IntRange(from = 0) int count) {
154         mNotificationsPostedCount += count;
155     }
156 
157     /** @hide */
incrementNotificationsUpdatedCount(@ntRangefrom = 0) int count)158     public void incrementNotificationsUpdatedCount(@IntRange(from = 0) int count) {
159         mNotificationsUpdatedCount += count;
160     }
161 
162     /** @hide */
incrementNotificationsCancelledCount(@ntRangefrom = 0) int count)163     public void incrementNotificationsCancelledCount(@IntRange(from = 0) int count) {
164         mNotificationsCancelledCount += count;
165     }
166 
167     /** @hide */
addCounts(@onNull BroadcastResponseStats stats)168     public void addCounts(@NonNull BroadcastResponseStats stats) {
169         incrementBroadcastsDispatchedCount(stats.getBroadcastsDispatchedCount());
170         incrementNotificationsPostedCount(stats.getNotificationsPostedCount());
171         incrementNotificationsUpdatedCount(stats.getNotificationsUpdatedCount());
172         incrementNotificationsCancelledCount(stats.getNotificationsCancelledCount());
173     }
174 
175     @Override
equals(Object obj)176     public boolean equals(Object obj) {
177         if (this == obj) {
178             return true;
179         }
180         if (obj == null || !(obj instanceof BroadcastResponseStats)) {
181             return false;
182         }
183         final BroadcastResponseStats other = (BroadcastResponseStats) obj;
184         return this.mBroadcastsDispatchedCount == other.mBroadcastsDispatchedCount
185                 && this.mNotificationsPostedCount == other.mNotificationsPostedCount
186                 && this.mNotificationsUpdatedCount == other.mNotificationsUpdatedCount
187                 && this.mNotificationsCancelledCount == other.mNotificationsCancelledCount
188                 && this.mId == other.mId
189                 && this.mPackageName.equals(other.mPackageName);
190     }
191 
192     @Override
hashCode()193     public int hashCode() {
194         return Objects.hash(mPackageName, mId, mBroadcastsDispatchedCount,
195                 mNotificationsPostedCount, mNotificationsUpdatedCount,
196                 mNotificationsCancelledCount);
197     }
198 
199     @Override
toString()200     public @NonNull String toString() {
201         return "stats {"
202                 + "package=" + mPackageName
203                 + ",id=" + mId
204                 + ",broadcastsSent=" + mBroadcastsDispatchedCount
205                 + ",notificationsPosted=" + mNotificationsPostedCount
206                 + ",notificationsUpdated=" + mNotificationsUpdatedCount
207                 + ",notificationsCancelled=" + mNotificationsCancelledCount
208                 + "}";
209     }
210 
211     @Override
describeContents()212     public @ContentsFlags int describeContents() {
213         return 0;
214     }
215 
216     @Override
writeToParcel(@onNull Parcel dest, @WriteFlags int flags)217     public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
218         dest.writeString8(mPackageName);
219         dest.writeLong(mId);
220         dest.writeInt(mBroadcastsDispatchedCount);
221         dest.writeInt(mNotificationsPostedCount);
222         dest.writeInt(mNotificationsUpdatedCount);
223         dest.writeInt(mNotificationsCancelledCount);
224     }
225 
226     public static final @NonNull Creator<BroadcastResponseStats> CREATOR =
227             new Creator<BroadcastResponseStats>() {
228                 @Override
229                 public @NonNull BroadcastResponseStats createFromParcel(@NonNull Parcel source) {
230                     return new BroadcastResponseStats(source);
231                 }
232 
233                 @Override
234                 public @NonNull BroadcastResponseStats[] newArray(int size) {
235                     return new BroadcastResponseStats[size];
236                 }
237             };
238 }
239