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.brs.cts;
18 
19 import static android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS;
20 import static android.Manifest.permission.INTERNET;
21 import static android.Manifest.permission.PACKAGE_USAGE_STATS;
22 import static android.Manifest.permission.USE_EXACT_ALARM;
23 import static android.app.role.RoleManager.ROLE_ASSISTANT;
24 import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
25 import static android.provider.DeviceConfig.NAMESPACE_APP_STANDBY;
26 
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertThrows;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.fail;
31 
32 import android.app.ActivityManager;
33 import android.app.AppOpsManager;
34 import android.app.BroadcastOptions;
35 import android.app.Notification;
36 import android.app.PendingIntent;
37 import android.app.UiAutomation;
38 import android.app.role.OnRoleHoldersChangedListener;
39 import android.app.role.RoleManager;
40 import android.app.usage.BroadcastResponseStats;
41 import android.app.usage.UsageStatsManager;
42 import android.app.usage.cts.ITestReceiver;
43 import android.app.usage.cts.UsageStatsTestRunner;
44 import android.content.ComponentName;
45 import android.content.Context;
46 import android.content.Intent;
47 import android.content.ServiceConnection;
48 import android.graphics.drawable.Icon;
49 import android.media.session.MediaSession;
50 import android.os.Bundle;
51 import android.os.IBinder;
52 import android.os.Process;
53 import android.os.RemoteCallback;
54 import android.os.SystemClock;
55 import android.os.UserHandle;
56 import android.util.ArrayMap;
57 import android.util.Log;
58 
59 import androidx.test.InstrumentationRegistry;
60 import androidx.test.filters.FlakyTest;
61 import androidx.test.filters.MediumTest;
62 import androidx.test.uiautomator.UiDevice;
63 
64 import com.android.compatibility.common.util.AppOpsUtils;
65 import com.android.compatibility.common.util.DeviceConfigStateHelper;
66 import com.android.compatibility.common.util.PollingCheck;
67 import com.android.compatibility.common.util.SystemUtil;
68 import com.android.compatibility.common.util.TestUtils;
69 
70 import org.junit.After;
71 import org.junit.AfterClass;
72 import org.junit.Before;
73 import org.junit.BeforeClass;
74 import org.junit.Test;
75 import org.junit.runner.RunWith;
76 
77 import java.util.Arrays;
78 import java.util.Comparator;
79 import java.util.List;
80 import java.util.concurrent.BlockingQueue;
81 import java.util.concurrent.CompletableFuture;
82 import java.util.concurrent.CountDownLatch;
83 import java.util.concurrent.LinkedBlockingQueue;
84 import java.util.concurrent.TimeUnit;
85 
86 @RunWith(UsageStatsTestRunner.class)
87 public class BroadcastResponseStatsTest {
88     private static final String TAG = "BroadcastResponseStatsTest";
89 
90     private static final String TEST_APP_PKG = "android.app.usage.cts.test1";
91     private static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
92     private static final String TEST_APP_CLASS_SERVICE =
93             "android.app.usage.cts.test1.TestService";
94     private static final String TEST_APP_CLASS_BROADCAST_RECEIVER =
95             "android.app.usage.cts.test1.TestBroadcastReceiver";
96 
97     private static final String TEST_APP3_PKG = "android.app.usage.cts.test3";
98     private static final String TEST_APP4_PKG = "android.app.usage.cts.test4";
99     private static final String TEST_ASSIST_APP_PKG = "android.app.usage.cts.test.assist";
100     private static final String TEST_EXACT_ALARM_APP_PKG = "android.app.usage.cts.test.exactalarm";
101 
102     private static final long TEST_RESPONSE_STATS_ID_1 = 11;
103     private static final long TEST_RESPONSE_STATS_ID_2 = 22;
104 
105     private static final String TEST_NOTIFICATION_CHANNEL_ID = "test-channel-id";
106     private static final String TEST_NOTIFICATION_CHANNEL_NAME = "test-channel-name";
107     private static final String TEST_NOTIFICATION_CHANNEL_DESC = "test-channel-description";
108 
109     private static final int TEST_NOTIFICATION_ID_1 = 10;
110     private static final int TEST_NOTIFICATION_ID_2 = 20;
111     private static final String TEST_NOTIFICATION_TITLE_FMT = "Test title; id=%s";
112     private static final String TEST_NOTIFICATION_TEXT_1 = "Test content 1";
113     private static final String TEST_NOTIFICATION_TEXT_2 = "Test content 2";
114 
115     private static final int DEFAULT_TIMEOUT_MS = 10_000;
116     // For tests that are verifying a certain event doesn't occur, wait for some time
117     // to ensure the event doesn't really occur. Otherwise, we cannot be sure if the event didn't
118     // occur or the verification was done too early before the event occurred.
119     private static final int WAIT_TIME_FOR_NEGATIVE_TESTS_MS = 500;
120 
121     private static final long TIMEOUT_BINDER_SERVICE_SEC = 2;
122 
123     private static final long BROADCAST_SESSIONS_DURATION_MS = 2_000;
124     private static final long BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS = 2_000;
125     private static final long BROADCAST_RESPONSE_WINDOW_DURATION_MS = 8_000;
126 
127     // TODO: Define these constants in UsageStatsManager as @TestApis to avoid hardcoding here.
128     private static final String KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS =
129             "broadcast_response_window_timeout_ms";
130     private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
131             "broadcast_response_fg_threshold_state";
132     private static final String KEY_BROADCAST_SESSIONS_DURATION_MS =
133             "broadcast_sessions_duration_ms";
134     private static final String KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS =
135             "broadcast_sessions_with_response_duration_ms";
136     private static final String KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS =
137             "note_response_event_for_all_broadcast_sessions";
138     private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES =
139             "brodacast_response_exempted_roles";
140     private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS =
141             "brodacast_response_exempted_permissions";
142 
143     private static Context sContext;
144     private static String sTargetPackage;
145     private UsageStatsManager mUsageStatsManager;
146     private RoleManager mRoleManager;
147     private UiDevice mUiDevice;
148     private UiAutomation mUiAutomation;
149 
150     private static int sInitialAppOpMode;
151 
152     @BeforeClass
setUpClass()153     public static void setUpClass() throws Exception {
154         sContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
155         sTargetPackage = sContext.getPackageName();
156         sInitialAppOpMode = AppOpsUtils.getOpMode(sTargetPackage,
157                 AppOpsManager.OPSTR_GET_USAGE_STATS);
158         AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
159                 AppOpsManager.MODE_IGNORED);
160         SystemUtil.runShellCommand("am wait-for-broadcast-barrier");
161     }
162 
163     @AfterClass
tearDownClass()164     public static void tearDownClass() throws Exception {
165         AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
166                 sInitialAppOpMode);
167     }
168 
169     @Before
setUp()170     public void setUp() throws Exception {
171         mUsageStatsManager = sContext.getSystemService(UsageStatsManager.class);
172         mRoleManager = sContext.getSystemService(RoleManager.class);
173         mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
174         mUiAutomation = InstrumentationRegistry.getInstrumentation()
175                 .getUiAutomation();
176         mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
177 
178         // Make sure all procstats are reset by killing test apps
179         SystemUtil.runShellCommand("am force-stop " + TEST_APP_PKG);
180         SystemUtil.runShellCommand("am force-stop " + TEST_APP3_PKG);
181         SystemUtil.runShellCommand("am force-stop " + TEST_APP4_PKG);
182     }
183 
184     @After
tearDown()185     public void tearDown() throws Exception {
186         mUiDevice.pressHome();
187 
188         // Clear broadcast response stats
189         mUsageStatsManager.clearBroadcastEvents();
190         mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
191         mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
192     }
193 
194     @Test
testBroadcastOptions_noPermission()195     public void testBroadcastOptions_noPermission() throws Exception {
196         final BroadcastOptions options = BroadcastOptions.makeBasic();
197         options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
198         final Intent intent = new Intent().setComponent(new ComponentName(
199                 TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
200         sendBroadcastAndWaitForReceipt(intent, options.toBundle());
201 
202         mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
203         try {
204             assertThrows(SecurityException.class, () -> {
205                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
206             });
207         } finally {
208             mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
209         }
210     }
211 
212     @Test
testQueryBroadcastResponseStats_noPermission()213     public void testQueryBroadcastResponseStats_noPermission() throws Exception {
214         mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
215 
216         mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
217         try {
218             assertThrows(SecurityException.class, () -> {
219                 mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG,
220                         TEST_RESPONSE_STATS_ID_1);
221             });
222         } finally {
223             mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
224         }
225     }
226 
227     @Test
testClearBroadcastResponseStats_noPermission()228     public void testClearBroadcastResponseStats_noPermission() throws Exception {
229         mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
230 
231         mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
232         try {
233             assertThrows(SecurityException.class, () -> {
234                 mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
235                         TEST_RESPONSE_STATS_ID_1);
236             });
237         } finally {
238             mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
239         }
240     }
241 
242     @FlakyTest(bugId = 288339565)
243     @Test
testBroadcastResponseStats_broadcastDispatchedCount()244     public void testBroadcastResponseStats_broadcastDispatchedCount() throws Exception {
245         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
246                 0 /* broadcastCount */,
247                 0 /* notificationPostedCount */,
248                 0 /* notificationUpdatedCount */,
249                 0 /* notificationCancelledCount */);
250         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
251                 0 /* broadcastCount */,
252                 0 /* notificationPostedCount */,
253                 0 /* notificationUpdatedCount */,
254                 0 /* notificationCancelledCount */);
255 
256         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
257         try {
258             ITestReceiver testReceiver = connection.getITestReceiver();
259             testReceiver.cancelAll();
260 
261             // Send a normal broadcast.
262             final Intent intent = new Intent().setComponent(new ComponentName(
263                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
264             sendBroadcastAndWaitForReceipt(intent, null);
265 
266             // Trigger a notification from test app and verify none of the counts get
267             // incremented.
268             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
269                     TEST_NOTIFICATION_CHANNEL_NAME,
270                     TEST_NOTIFICATION_CHANNEL_DESC);
271             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
272                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
273                             TEST_NOTIFICATION_TEXT_1));
274 
275             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
276                     0 /* broadcastCount */,
277                     0 /* notificationPostedCount */,
278                     0 /* notificationUpdatedCount */,
279                     0 /* notificationCancelledCount */);
280             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
281                     0 /* broadcastCount */,
282                     0 /* notificationPostedCount */,
283                     0 /* notificationUpdatedCount */,
284                     0 /* notificationCancelledCount */);
285 
286             // Send a broadcast with a request to record response.
287             final BroadcastOptions options = BroadcastOptions.makeBasic();
288             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
289             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
290 
291             // Trigger a notification from test app and verify notification-posted count gets
292             // incremented.
293             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
294                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
295                             TEST_NOTIFICATION_TEXT_2));
296 
297             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
298                     1 /* broadcastCount */,
299                     0 /* notificationPostedCount */,
300                     1 /* notificationUpdatedCount */,
301                     0 /* notificationCancelledCount */);
302             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
303                     0 /* broadcastCount */,
304                     0 /* notificationPostedCount */,
305                     0 /* notificationUpdatedCount */,
306                     0 /* notificationCancelledCount */);
307 
308             testReceiver.cancelAll();
309         } finally {
310             connection.unbind();
311         }
312     }
313 
314     @Test
testBroadcastResponseStats_notificationPostedCount()315     public void testBroadcastResponseStats_notificationPostedCount() throws Exception {
316         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
317                 0 /* broadcastCount */,
318                 0 /* notificationPostedCount */,
319                 0 /* notificationUpdatedCount */,
320                 0 /* notificationCancelledCount */);
321         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
322                 0 /* broadcastCount */,
323                 0 /* notificationPostedCount */,
324                 0 /* notificationUpdatedCount */,
325                 0 /* notificationCancelledCount */);
326 
327         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
328         try {
329             ITestReceiver testReceiver = connection.getITestReceiver();
330             testReceiver.cancelAll();
331 
332             // Send a normal broadcast and verify none of the counts get incremented.
333             final Intent intent = new Intent().setComponent(new ComponentName(
334                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
335             sendBroadcastAndWaitForReceipt(intent, null);
336 
337             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
338                     0 /* broadcastCount */,
339                     0 /* notificationPostedCount */,
340                     0 /* notificationUpdatedCount */,
341                     0 /* notificationCancelledCount */);
342             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
343                     0 /* broadcastCount */,
344                     0 /* notificationPostedCount */,
345                     0 /* notificationUpdatedCount */,
346                     0 /* notificationCancelledCount */);
347 
348             // Send a broadcast with a request to record response and verify broadcast-sent
349             // count gets incremented.
350             final BroadcastOptions options = BroadcastOptions.makeBasic();
351             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
352             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
353 
354             // Trigger a notification from test app and verify notification-posted count gets
355             // incremented.
356             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
357                     TEST_NOTIFICATION_CHANNEL_NAME,
358                     TEST_NOTIFICATION_CHANNEL_DESC);
359             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
360                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
361                             TEST_NOTIFICATION_TEXT_1));
362 
363             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
364                     1 /* broadcastCount */,
365                     1 /* notificationPostedCount */,
366                     0 /* notificationUpdatedCount */,
367                     0 /* notificationCancelledCount */);
368             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
369                     0 /* broadcastCount */,
370                     0 /* notificationPostedCount */,
371                     0 /* notificationUpdatedCount */,
372                     0 /* notificationCancelledCount */);
373 
374             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
375             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
376                     0 /* broadcastCount */,
377                     0 /* notificationPostedCount */,
378                     0 /* notificationUpdatedCount */,
379                     0 /* notificationCancelledCount */);
380             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
381                     0 /* broadcastCount */,
382                     0 /* notificationPostedCount */,
383                     0 /* notificationUpdatedCount */,
384                     0 /* notificationCancelledCount */);
385 
386             testReceiver.cancelAll();
387         } finally {
388             connection.unbind();
389         }
390     }
391 
392     @Test
testBroadcastResponseStats_notificationUpdatedCount()393     public void testBroadcastResponseStats_notificationUpdatedCount() throws Exception {
394         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
395                 0 /* broadcastCount */,
396                 0 /* notificationPostedCount */,
397                 0 /* notificationUpdatedCount */,
398                 0 /* notificationCancelledCount */);
399         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
400                 0 /* broadcastCount */,
401                 0 /* notificationPostedCount */,
402                 0 /* notificationUpdatedCount */,
403                 0 /* notificationCancelledCount */);
404 
405         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
406         try {
407             ITestReceiver testReceiver = connection.getITestReceiver();
408             testReceiver.cancelAll();
409 
410             // Post a notification (before sending any broadcast) and verify none of the counts
411             // get incremented.
412             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
413                     TEST_NOTIFICATION_CHANNEL_NAME,
414                     TEST_NOTIFICATION_CHANNEL_DESC);
415             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
416                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
417                             TEST_NOTIFICATION_TEXT_1));
418 
419             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
420                     0 /* broadcastCount */,
421                     0 /* notificationPostedCount */,
422                     0 /* notificationUpdatedCount */,
423                     0 /* notificationCancelledCount */);
424             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
425                     0 /* broadcastCount */,
426                     0 /* notificationPostedCount */,
427                     0 /* notificationUpdatedCount */,
428                     0 /* notificationCancelledCount */);
429 
430             // Send a broadcast with a request to record response and verify broadcast-sent
431             // count gets incremented.
432             final Intent intent = new Intent().setComponent(new ComponentName(
433                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
434             final BroadcastOptions options = BroadcastOptions.makeBasic();
435             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
436             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
437 
438             // Update a previously posted notification (change content text) and verify
439             // notification-updated count gets incremented.
440             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
441                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
442                             TEST_NOTIFICATION_TEXT_2));
443 
444             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
445                     1 /* broadcastCount */,
446                     0 /* notificationPostedCount */,
447                     1 /* notificationUpdatedCount */,
448                     0 /* notificationCancelledCount */);
449             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
450                     0 /* broadcastCount */,
451                     0 /* notificationPostedCount */,
452                     0 /* notificationUpdatedCount */,
453                     0 /* notificationCancelledCount */);
454 
455             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
456             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
457                     0 /* broadcastCount */,
458                     0 /* notificationPostedCount */,
459                     0 /* notificationUpdatedCount */,
460                     0 /* notificationCancelledCount */);
461             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
462                     0 /* broadcastCount */,
463                     0 /* notificationPostedCount */,
464                     0 /* notificationUpdatedCount */,
465                     0 /* notificationCancelledCount */);
466 
467             testReceiver.cancelAll();
468         } finally {
469             connection.unbind();
470         }
471     }
472 
473     @Test
testBroadcastResponseStats_notificationCancelledCount()474     public void testBroadcastResponseStats_notificationCancelledCount() throws Exception {
475         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
476                 0 /* broadcastCount */,
477                 0 /* notificationPostedCount */,
478                 0 /* notificationUpdatedCount */,
479                 0 /* notificationCancelledCount */);
480         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
481                 0 /* broadcastCount */,
482                 0 /* notificationPostedCount */,
483                 0 /* notificationUpdatedCount */,
484                 0 /* notificationCancelledCount */);
485 
486         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
487         try {
488             ITestReceiver testReceiver = connection.getITestReceiver();
489             testReceiver.cancelAll();
490 
491             // Post a notification (before sending any broadcast) and verify none of the counts
492             // get incremented.
493             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
494                     TEST_NOTIFICATION_CHANNEL_NAME,
495                     TEST_NOTIFICATION_CHANNEL_DESC);
496             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
497                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
498                             TEST_NOTIFICATION_TEXT_1));
499 
500             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
501                     0 /* broadcastCount */,
502                     0 /* notificationPostedCount */,
503                     0 /* notificationUpdatedCount */,
504                     0 /* notificationCancelledCount */);
505             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
506                     0 /* broadcastCount */,
507                     0 /* notificationPostedCount */,
508                     0 /* notificationUpdatedCount */,
509                     0 /* notificationCancelledCount */);
510 
511             // Send a broadcast with a request to record response and verify broadcast-sent
512             // count gets incremented.
513             final Intent intent = new Intent().setComponent(new ComponentName(
514                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
515             sendBroadcastAndWaitForReceipt(intent, null);
516             final BroadcastOptions options = BroadcastOptions.makeBasic();
517             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
518             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
519 
520             // Cancel a previously posted notification (change content text) and verify
521             // notification-cancelled count gets incremented.
522             testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
523 
524             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
525                     1 /* broadcastCount */,
526                     0 /* notificationPostedCount */,
527                     0 /* notificationUpdatedCount */,
528                     1 /* notificationCancelledCount */);
529             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
530                     0 /* broadcastCount */,
531                     0 /* notificationPostedCount */,
532                     0 /* notificationUpdatedCount */,
533                     0 /* notificationCancelledCount */);
534 
535             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
536             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
537                     0 /* broadcastCount */,
538                     0 /* notificationPostedCount */,
539                     0 /* notificationUpdatedCount */,
540                     0 /* notificationCancelledCount */);
541             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
542                     0 /* broadcastCount */,
543                     0 /* notificationPostedCount */,
544                     0 /* notificationUpdatedCount */,
545                     0 /* notificationCancelledCount */);
546 
547             testReceiver.cancelAll();
548         } finally {
549             connection.unbind();
550         }
551     }
552 
553     @Test
testBroadcastResponseStats_multipleEvents()554     public void testBroadcastResponseStats_multipleEvents() throws Exception {
555         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
556                 0 /* broadcastCount */,
557                 0 /* notificationPostedCount */,
558                 0 /* notificationUpdatedCount */,
559                 0 /* notificationCancelledCount */);
560         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
561                 0 /* broadcastCount */,
562                 0 /* notificationPostedCount */,
563                 0 /* notificationUpdatedCount */,
564                 0 /* notificationCancelledCount */);
565 
566         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
567         try {
568             ITestReceiver testReceiver = connection.getITestReceiver();
569             testReceiver.cancelAll();
570 
571             // Send a normal broadcast and verify none of the counts get incremented.
572             final Intent intent = new Intent().setComponent(new ComponentName(
573                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
574             sendBroadcastAndWaitForReceipt(intent, null);
575 
576             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
577                     0 /* broadcastCount */,
578                     0 /* notificationPostedCount */,
579                     0 /* notificationUpdatedCount */,
580                     0 /* notificationCancelledCount */);
581             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
582                     0 /* broadcastCount */,
583                     0 /* notificationPostedCount */,
584                     0 /* notificationUpdatedCount */,
585                     0 /* notificationCancelledCount */);
586 
587             // Send a broadcast with a request to record response and verify broadcast-sent
588             // count gets incremented.
589             final BroadcastOptions options = BroadcastOptions.makeBasic();
590             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
591             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
592 
593             // Trigger a notification from test app and verify notification-posted count gets
594             // incremented.
595             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
596                     TEST_NOTIFICATION_CHANNEL_NAME,
597                     TEST_NOTIFICATION_CHANNEL_DESC);
598             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
599                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
600                             TEST_NOTIFICATION_TEXT_1));
601 
602             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
603                     1 /* broadcastCount */,
604                     1 /* notificationPostedCount */,
605                     0 /* notificationUpdatedCount */,
606                     0 /* notificationCancelledCount */);
607             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
608                     0 /* broadcastCount */,
609                     0 /* notificationPostedCount */,
610                     0 /* notificationUpdatedCount */,
611                     0 /* notificationCancelledCount */);
612 
613             // Send another broadcast and trigger another notification.
614             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
615             testReceiver.postNotification(TEST_NOTIFICATION_ID_2,
616                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_2,
617                             TEST_NOTIFICATION_TEXT_2));
618             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
619                     2 /* broadcastCount */,
620                     2 /* notificationPostedCount */,
621                     0 /* notificationUpdatedCount */,
622                     0 /* notificationCancelledCount */);
623             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
624                     0 /* broadcastCount */,
625                     0 /* notificationPostedCount */,
626                     0 /* notificationUpdatedCount */,
627                     0 /* notificationCancelledCount */);
628 
629             // Send another broadcast with a different ID and update a previously posted
630             // notification.
631             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
632             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
633             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
634                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
635                             TEST_NOTIFICATION_TEXT_2));
636             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
637                     2 /* broadcastCount */,
638                     2 /* notificationPostedCount */,
639                     0 /* notificationUpdatedCount */,
640                     0 /* notificationCancelledCount */);
641             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
642                     1 /* broadcastCount */,
643                     0 /* notificationPostedCount */,
644                     1 /* notificationUpdatedCount */,
645                     0 /* notificationCancelledCount */);
646 
647             // Update/cancel a previously posted notifications and verify there is
648             // no change in counts.
649             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
650                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
651                             TEST_NOTIFICATION_TEXT_1));
652             testReceiver.cancelNotification(TEST_NOTIFICATION_ID_2);
653             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
654                     2 /* broadcastCount */,
655                     2 /* notificationPostedCount */,
656                     0 /* notificationUpdatedCount */,
657                     0 /* notificationCancelledCount */);
658             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
659                     1 /* broadcastCount */,
660                     0 /* notificationPostedCount */,
661                     1 /* notificationUpdatedCount */,
662                     0 /* notificationCancelledCount */);
663 
664             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
665             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
666                     0 /* broadcastCount */,
667                     0 /* notificationPostedCount */,
668                     0 /* notificationUpdatedCount */,
669                     0 /* notificationCancelledCount */);
670             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
671                     1 /* broadcastCount */,
672                     0 /* notificationPostedCount */,
673                     1 /* notificationUpdatedCount */,
674                     0 /* notificationCancelledCount */);
675 
676             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2);
677             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
678                     0 /* broadcastCount */,
679                     0 /* notificationPostedCount */,
680                     0 /* notificationUpdatedCount */,
681                     0 /* notificationCancelledCount */);
682             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
683                     0 /* broadcastCount */,
684                     0 /* notificationPostedCount */,
685                     0 /* notificationUpdatedCount */,
686                     0 /* notificationCancelledCount */);
687 
688             testReceiver.cancelAll();
689         } finally {
690             connection.unbind();
691         }
692     }
693 
694     @Test
testBroadcastResponseStats_clearCounts()695     public void testBroadcastResponseStats_clearCounts() throws Exception {
696         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
697                 0 /* broadcastCount */,
698                 0 /* notificationPostedCount */,
699                 0 /* notificationUpdatedCount */,
700                 0 /* notificationCancelledCount */);
701         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
702                 0 /* broadcastCount */,
703                 0 /* notificationPostedCount */,
704                 0 /* notificationUpdatedCount */,
705                 0 /* notificationCancelledCount */);
706 
707         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
708         try {
709             ITestReceiver testReceiver = connection.getITestReceiver();
710             testReceiver.cancelAll();
711 
712             // Send a broadcast with a request to record response and verify broadcast-sent
713             // count gets incremented.
714             final Intent intent = new Intent().setComponent(new ComponentName(
715                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
716             final BroadcastOptions options = BroadcastOptions.makeBasic();
717             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
718             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
719 
720             // Trigger a notification from test app and verify notification-posted count gets
721             // incremented.
722             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
723                     TEST_NOTIFICATION_CHANNEL_NAME,
724                     TEST_NOTIFICATION_CHANNEL_DESC);
725             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
726                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
727                             TEST_NOTIFICATION_TEXT_1));
728 
729             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
730                     1 /* broadcastCount */,
731                     1 /* notificationPostedCount */,
732                     0 /* notificationUpdatedCount */,
733                     0 /* notificationCancelledCount */);
734             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
735                     0 /* broadcastCount */,
736                     0 /* notificationPostedCount */,
737                     0 /* notificationUpdatedCount */,
738                     0 /* notificationCancelledCount */);
739 
740             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
741             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
742                     0 /* broadcastCount */,
743                     0 /* notificationPostedCount */,
744                     0 /* notificationUpdatedCount */,
745                     0 /* notificationCancelledCount */);
746             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
747                     0 /* broadcastCount */,
748                     0 /* notificationPostedCount */,
749                     0 /* notificationUpdatedCount */,
750                     0 /* notificationCancelledCount */);
751 
752             // Send the broadcast again after clearing counts and verify counts get incremented
753             // as expected.
754             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
755             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
756                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
757                             TEST_NOTIFICATION_TEXT_2));
758 
759             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
760                     1 /* broadcastCount */,
761                     0 /* notificationPostedCount */,
762                     1 /* notificationUpdatedCount */,
763                     0 /* notificationCancelledCount */);
764             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
765                     0 /* broadcastCount */,
766                     0 /* notificationPostedCount */,
767                     0 /* notificationUpdatedCount */,
768                     0 /* notificationCancelledCount */);
769 
770             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
771             testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
772 
773             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
774                     2 /* broadcastCount */,
775                     0 /* notificationPostedCount */,
776                     1 /* notificationUpdatedCount */,
777                     1 /* notificationCancelledCount */);
778             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
779                     0 /* broadcastCount */,
780                     0 /* notificationPostedCount */,
781                     0 /* notificationUpdatedCount */,
782                     0 /* notificationCancelledCount */);
783 
784             testReceiver.cancelAll();
785         } finally {
786             connection.unbind();
787         }
788     }
789 
790     @MediumTest
791     @Test
testBroadcastResponseStats_changeResponseWindowDuration()792     public void testBroadcastResponseStats_changeResponseWindowDuration() throws Exception {
793         try (DeviceConfigStateHelper deviceConfigStateHelper =
794                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
795             updateFlagsWithDefaultDelays(deviceConfigStateHelper);
796 
797             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
798                     0 /* broadcastCount */,
799                     0 /* notificationPostedCount */,
800                     0 /* notificationUpdatedCount */,
801                     0 /* notificationCancelledCount */);
802             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
803                     0 /* broadcastCount */,
804                     0 /* notificationPostedCount */,
805                     0 /* notificationUpdatedCount */,
806                     0 /* notificationCancelledCount */);
807 
808             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
809             try {
810                 ITestReceiver testReceiver = connection.getITestReceiver();
811                 testReceiver.cancelAll();
812 
813                 // Send a broadcast with a request to record response and verify broadcast-sent
814                 // count gets incremented.
815                 final Intent intent = new Intent().setComponent(new ComponentName(
816                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
817                 final BroadcastOptions options = BroadcastOptions.makeBasic();
818                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
819                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
820 
821                 // Trigger a notification from test app and verify notification-posted count gets
822                 // incremented.
823                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
824                         TEST_NOTIFICATION_CHANNEL_NAME,
825                         TEST_NOTIFICATION_CHANNEL_DESC);
826                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
827                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
828                                 TEST_NOTIFICATION_TEXT_1));
829 
830                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
831                         1 /* broadcastCount */,
832                         1 /* notificationPostedCount */,
833                         0 /* notificationUpdatedCount */,
834                         0 /* notificationCancelledCount */);
835                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
836                         0 /* broadcastCount */,
837                         0 /* notificationPostedCount */,
838                         0 /* notificationUpdatedCount */,
839                         0 /* notificationCancelledCount */);
840 
841                 testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
842                 mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
843                         TEST_RESPONSE_STATS_ID_1);
844                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
845                         0 /* broadcastCount */,
846                         0 /* notificationPostedCount */,
847                         0 /* notificationUpdatedCount */,
848                         0 /* notificationCancelledCount */);
849                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
850                         0 /* broadcastCount */,
851                         0 /* notificationPostedCount */,
852                         0 /* notificationUpdatedCount */,
853                         0 /* notificationCancelledCount */);
854 
855                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
856 
857                 SystemClock.sleep(BROADCAST_RESPONSE_WINDOW_DURATION_MS);
858 
859                 // Trigger a notification from test app but verify counts do not get
860                 // incremented as the notification is posted after the window durations is expired.
861                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
862                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
863                                 TEST_NOTIFICATION_TEXT_1));
864 
865                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
866                         1 /* broadcastCount */,
867                         0 /* notificationPostedCount */,
868                         0 /* notificationUpdatedCount */,
869                         0 /* notificationCancelledCount */);
870                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
871                         0 /* broadcastCount */,
872                         0 /* notificationPostedCount */,
873                         0 /* notificationUpdatedCount */,
874                         0 /* notificationCancelledCount */);
875 
876                 testReceiver.cancelAll();
877             } finally {
878                 connection.unbind();
879             }
880         }
881     }
882 
883     @Test
testBroadcastResponseStats_appNotInForeground()884     public void testBroadcastResponseStats_appNotInForeground() throws Exception {
885         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
886                 0 /* broadcastCount */,
887                 0 /* notificationPostedCount */,
888                 0 /* notificationUpdatedCount */,
889                 0 /* notificationCancelledCount */);
890         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
891                 0 /* broadcastCount */,
892                 0 /* notificationPostedCount */,
893                 0 /* notificationUpdatedCount */,
894                 0 /* notificationCancelledCount */);
895 
896         try (DeviceConfigStateHelper deviceConfigStateHelper =
897                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
898             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
899             try {
900                 updateFlagWithDelay(deviceConfigStateHelper,
901                         KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
902                         String.valueOf(ActivityManager.PROCESS_STATE_TOP));
903 
904                 ITestReceiver testReceiver = connection.getITestReceiver();
905                 testReceiver.cancelAll();
906 
907                 // Send a broadcast with a request to record response.
908                 final Intent intent = new Intent().setComponent(new ComponentName(
909                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
910                 final BroadcastOptions options = BroadcastOptions.makeBasic();
911                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
912                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
913                 // Trigger a notification from test app and verify notification-posted count gets
914                 // incremented.
915                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
916                         TEST_NOTIFICATION_CHANNEL_NAME,
917                         TEST_NOTIFICATION_CHANNEL_DESC);
918                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
919                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
920                                 TEST_NOTIFICATION_TEXT_1));
921                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
922                         1 /* broadcastCount */,
923                         1 /* notificationPostedCount */,
924                         0 /* notificationUpdatedCount */,
925                         0 /* notificationCancelledCount */);
926                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
927                         0 /* broadcastCount */,
928                         0 /* notificationPostedCount */,
929                         0 /* notificationUpdatedCount */,
930                         0 /* notificationCancelledCount */);
931 
932                 // Bring the test app to the foreground, send the broadcast again and verify that
933                 // counts do not change.
934                 launchTestActivityAndWaitToBeResumed(TEST_APP_PKG, TEST_APP_CLASS);
935                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
936                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
937                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
938                                 TEST_NOTIFICATION_TEXT_2));
939 
940                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
941                         1 /* broadcastCount */,
942                         1 /* notificationPostedCount */,
943                         0 /* notificationUpdatedCount */,
944                         0 /* notificationCancelledCount */);
945                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
946                         0 /* broadcastCount */,
947                         0 /* notificationPostedCount */,
948                         0 /* notificationUpdatedCount */,
949                         0 /* notificationCancelledCount */);
950 
951                 // Change the threshold to something lower than TOP, send the broadcast again
952                 // and verify that counts get incremented.
953                 updateFlagWithDelay(deviceConfigStateHelper,
954                         KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
955                         String.valueOf(ActivityManager.PROCESS_STATE_PERSISTENT));
956                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
957                 testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
958 
959                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
960                         2 /* broadcastCount */,
961                         1 /* notificationPostedCount */,
962                         0 /* notificationUpdatedCount */,
963                         1 /* notificationCancelledCount */);
964                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
965                         0 /* broadcastCount */,
966                         0 /* notificationPostedCount */,
967                         0 /* notificationUpdatedCount */,
968                         0 /* notificationCancelledCount */);
969 
970                 mUiDevice.pressHome();
971                 // Change the threshold to a process state higher than RECEIVER, send the
972                 // broadcast again and verify that counts do not change.
973                 updateFlagWithDelay(deviceConfigStateHelper,
974                         KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
975                         String.valueOf(ActivityManager.PROCESS_STATE_HOME));
976                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
977                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
978                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
979                                 TEST_NOTIFICATION_TEXT_1));
980 
981                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
982                         2 /* broadcastCount */,
983                         1 /* notificationPostedCount */,
984                         0 /* notificationUpdatedCount */,
985                         1 /* notificationCancelledCount */);
986                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
987                         0 /* broadcastCount */,
988                         0 /* notificationPostedCount */,
989                         0 /* notificationUpdatedCount */,
990                         0 /* notificationCancelledCount */);
991 
992                 testReceiver.cancelAll();
993             } finally {
994                 connection.unbind();
995             }
996         }
997     }
998 
999     @Test
testBroadcastResponseStats_multiplePackages()1000     public void testBroadcastResponseStats_multiplePackages() throws Exception {
1001         final ArrayMap<String, BroadcastResponseStats> expectedStats = new ArrayMap<>();
1002         // Initially all the counts should be empty
1003         assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1004 
1005         final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
1006         final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
1007         final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
1008         try {
1009             ITestReceiver testReceiver1 = connection1.getITestReceiver();
1010             ITestReceiver testReceiver3 = connection3.getITestReceiver();
1011             ITestReceiver testReceiver4 = connection4.getITestReceiver();
1012 
1013             testReceiver1.cancelAll();
1014             testReceiver3.cancelAll();
1015             testReceiver4.cancelAll();
1016 
1017             final Intent intent = new Intent().setComponent(new ComponentName(
1018                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1019             final Intent intent3 = new Intent().setComponent(new ComponentName(
1020                     TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1021             final Intent intent4 = new Intent().setComponent(new ComponentName(
1022                     TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1023 
1024             // Send a broadcast to test-pkg1 with a request to record response and verify
1025             // broadcast-sent count gets incremented.
1026             final BroadcastOptions options = BroadcastOptions.makeBasic();
1027             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1028             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1029 
1030             expectedStats.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
1031                     TEST_RESPONSE_STATS_ID_1));
1032             expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1033 
1034             // Send a broadcast to test-pkg3 with a request to record response and verify
1035             // broadcast-sent count gets incremented.
1036             sendBroadcastAndWaitForReceipt(intent3, options.toBundle());
1037             expectedStats.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1038                     TEST_RESPONSE_STATS_ID_1));
1039             expectedStats.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1040 
1041             // Trigger a notification from test-pkg1 and verify notification-posted count gets
1042             // incremented.
1043             testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1044                     TEST_NOTIFICATION_CHANNEL_NAME,
1045                     TEST_NOTIFICATION_CHANNEL_DESC);
1046             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1047                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1048                             TEST_NOTIFICATION_TEXT_1));
1049 
1050             expectedStats.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
1051 
1052             // Trigger a notification from test-pkg3 and verify notification-posted count gets
1053             // incremented.
1054             testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1055                     TEST_NOTIFICATION_CHANNEL_NAME,
1056                     TEST_NOTIFICATION_CHANNEL_DESC);
1057             testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
1058                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1059                             TEST_NOTIFICATION_TEXT_1));
1060 
1061             expectedStats.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
1062             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1063 
1064             // Send a broadcast to test-pkg1 with a request to record response and verify
1065             // broadcast-sent count gets incremented.
1066             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1067             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1068                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1069                             TEST_NOTIFICATION_TEXT_2));
1070             expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1071             expectedStats.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
1072             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1073 
1074             // Trigger a notification from test-pkg3 and verify stats remain the same
1075             testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1076                     TEST_NOTIFICATION_CHANNEL_NAME,
1077                     TEST_NOTIFICATION_CHANNEL_DESC);
1078             testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
1079                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1080                             TEST_NOTIFICATION_TEXT_1));
1081             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1082 
1083             // Send a broadcast to test-pkg4 with a request to record response and verify
1084             // broadcast-send count gets incremented.
1085             sendBroadcastAndWaitForReceipt(intent4, options.toBundle());
1086             testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
1087             expectedStats.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
1088                     TEST_RESPONSE_STATS_ID_1));
1089             expectedStats.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
1090             expectedStats.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
1091             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1092 
1093             mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
1094             expectedStats.clear();
1095             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
1096 
1097             testReceiver1.cancelAll();
1098             testReceiver3.cancelAll();
1099             testReceiver4.cancelAll();
1100         } finally {
1101             connection1.unbind();
1102             connection3.unbind();
1103             connection4.unbind();
1104         }
1105     }
1106 
1107     @Test
testBroadcastResponseStats_multiplePackages_multipleIds()1108     public void testBroadcastResponseStats_multiplePackages_multipleIds() throws Exception {
1109         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
1110         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
1111         // Initially all the counts should be empty
1112         assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1113         assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1114 
1115         final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
1116         final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
1117         final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
1118         try {
1119             ITestReceiver testReceiver1 = connection1.getITestReceiver();
1120             ITestReceiver testReceiver3 = connection3.getITestReceiver();
1121             ITestReceiver testReceiver4 = connection4.getITestReceiver();
1122 
1123             testReceiver1.cancelAll();
1124             testReceiver3.cancelAll();
1125             testReceiver4.cancelAll();
1126 
1127             final Intent intent = new Intent().setComponent(new ComponentName(
1128                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1129             final Intent intent3 = new Intent().setComponent(new ComponentName(
1130                     TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1131             final Intent intent4 = new Intent().setComponent(new ComponentName(
1132                     TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1133 
1134             final BroadcastOptions options1 = BroadcastOptions.makeBasic();
1135             options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1136             final BroadcastOptions options2 = BroadcastOptions.makeBasic();
1137             options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
1138 
1139             // Send a broadcast to test-pkg1 with a request to record response and verify
1140             // broadcast-sent count gets incremented.
1141             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1142             sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
1143 
1144             // Trigger a notification from test-pkg1 and verify notification-posted count gets
1145             // incremented.
1146             testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1147                     TEST_NOTIFICATION_CHANNEL_NAME,
1148                     TEST_NOTIFICATION_CHANNEL_DESC);
1149             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1150                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1151                             TEST_NOTIFICATION_TEXT_1));
1152 
1153             expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
1154                     TEST_RESPONSE_STATS_ID_1));
1155             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1156             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
1157             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1158             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1159 
1160             mUsageStatsManager.clearBroadcastEvents();
1161             // Trigger a notification from test-pkg4 and verify notification-posted count gets
1162             // incremented.
1163             testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1164                     TEST_NOTIFICATION_CHANNEL_NAME,
1165                     TEST_NOTIFICATION_CHANNEL_DESC);
1166             testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
1167                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1168                             TEST_NOTIFICATION_TEXT_1));
1169 
1170             sendBroadcastAndWaitForReceipt(intent4, options2.toBundle());
1171             expectedStatsForId2.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
1172                     TEST_RESPONSE_STATS_ID_2));
1173             expectedStatsForId2.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
1174 
1175             testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1176                     TEST_NOTIFICATION_CHANNEL_NAME,
1177                     TEST_NOTIFICATION_CHANNEL_DESC);
1178             testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
1179                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1180                             TEST_NOTIFICATION_TEXT_1));
1181             testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
1182             expectedStatsForId2.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
1183             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1184             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1185 
1186             mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
1187             expectedStatsForId1.clear();
1188             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1189             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1190 
1191             testReceiver1.cancelAll();
1192             testReceiver3.cancelAll();
1193             testReceiver4.cancelAll();
1194         } finally {
1195             connection1.unbind();
1196             connection3.unbind();
1197             connection4.unbind();
1198         }
1199     }
1200 
1201     @Test
testBroadcastResponseStats_clearCounts_multiplePackages()1202     public void testBroadcastResponseStats_clearCounts_multiplePackages() throws Exception {
1203         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
1204         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
1205         // Initially all the counts should be empty
1206         assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1207         assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1208 
1209         final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
1210         final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
1211         try {
1212             ITestReceiver testReceiver1 = connection1.getITestReceiver();
1213             ITestReceiver testReceiver3 = connection3.getITestReceiver();
1214 
1215             testReceiver1.cancelAll();
1216             testReceiver3.cancelAll();
1217 
1218             final Intent intent = new Intent().setComponent(new ComponentName(
1219                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1220             final Intent intent3 = new Intent().setComponent(new ComponentName(
1221                     TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1222             final BroadcastOptions options1 = BroadcastOptions.makeBasic();
1223             options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1224             final BroadcastOptions options2 = BroadcastOptions.makeBasic();
1225             options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
1226 
1227             testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1228                     TEST_NOTIFICATION_CHANNEL_NAME,
1229                     TEST_NOTIFICATION_CHANNEL_DESC);
1230             testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1231                     TEST_NOTIFICATION_CHANNEL_NAME,
1232                     TEST_NOTIFICATION_CHANNEL_DESC);
1233 
1234             // Send a broadcast to test-pkg1 with a request to record response and verify
1235             // broadcast-sent count gets incremented.
1236             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1237             sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
1238 
1239             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1240                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1241                             TEST_NOTIFICATION_TEXT_1));
1242             testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
1243                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1244                             TEST_NOTIFICATION_TEXT_1));
1245 
1246             expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
1247                     TEST_RESPONSE_STATS_ID_1));
1248             expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1249                     TEST_RESPONSE_STATS_ID_1));
1250             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1251             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
1252             expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1253             expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
1254             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1255             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1256 
1257             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1258             sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
1259 
1260             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1261                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1262                             TEST_NOTIFICATION_TEXT_2));
1263             testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
1264 
1265             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1266             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
1267             expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1268                     TEST_RESPONSE_STATS_ID_2));
1269             expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1270             expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
1271 
1272             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1273             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1274 
1275             mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
1276                     TEST_RESPONSE_STATS_ID_1);
1277             expectedStatsForId1.clear();
1278             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1279             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1280 
1281             mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
1282                     TEST_RESPONSE_STATS_ID_2);
1283             expectedStatsForId2.clear();
1284             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1285             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1286 
1287             testReceiver1.cancelAll();
1288             testReceiver3.cancelAll();
1289         } finally {
1290             connection1.unbind();
1291             connection3.unbind();
1292         }
1293     }
1294 
1295     @Test
testBroadcastResponseStats_clearCounts_multipleIds()1296     public void testBroadcastResponseStats_clearCounts_multipleIds() throws Exception {
1297         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
1298         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
1299         // Initially all the counts should be empty
1300         assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1301         assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1302 
1303         final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
1304         final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
1305         try {
1306             ITestReceiver testReceiver1 = connection1.getITestReceiver();
1307             ITestReceiver testReceiver3 = connection3.getITestReceiver();
1308 
1309             testReceiver1.cancelAll();
1310             testReceiver3.cancelAll();
1311 
1312             final Intent intent = new Intent().setComponent(new ComponentName(
1313                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1314             final Intent intent3 = new Intent().setComponent(new ComponentName(
1315                     TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1316             final BroadcastOptions options1 = BroadcastOptions.makeBasic();
1317             options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1318             final BroadcastOptions options2 = BroadcastOptions.makeBasic();
1319             options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
1320 
1321             testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1322                     TEST_NOTIFICATION_CHANNEL_NAME,
1323                     TEST_NOTIFICATION_CHANNEL_DESC);
1324             testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1325                     TEST_NOTIFICATION_CHANNEL_NAME,
1326                     TEST_NOTIFICATION_CHANNEL_DESC);
1327 
1328             // Send a broadcast to test-pkg1 with a request to record response and verify
1329             // broadcast-sent count gets incremented.
1330             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1331             sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
1332 
1333             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1334                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1335                             TEST_NOTIFICATION_TEXT_1));
1336             testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
1337                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1338                             TEST_NOTIFICATION_TEXT_1));
1339 
1340             expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
1341                     TEST_RESPONSE_STATS_ID_1));
1342             expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1343                     TEST_RESPONSE_STATS_ID_1));
1344             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1345             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
1346             expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1347             expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
1348             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1349             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1350 
1351             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1352             sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
1353 
1354             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1355                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1356                             TEST_NOTIFICATION_TEXT_2));
1357             testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
1358 
1359             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1360             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
1361             expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1362                     TEST_RESPONSE_STATS_ID_2));
1363             expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1364             expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
1365 
1366             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1367             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1368 
1369             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, 0 /* id */);
1370             expectedStatsForId1.remove(TEST_APP_PKG);
1371             expectedStatsForId2.remove(TEST_APP_PKG);
1372             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1373             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1374 
1375             mUsageStatsManager.clearBroadcastResponseStats(TEST_APP3_PKG, 0 /* id */);
1376             expectedStatsForId1.remove(TEST_APP3_PKG);
1377             expectedStatsForId2.remove(TEST_APP3_PKG);
1378             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1379             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1380 
1381             testReceiver1.cancelAll();
1382             testReceiver3.cancelAll();
1383         } finally {
1384             connection1.unbind();
1385             connection3.unbind();
1386         }
1387     }
1388 
1389     @Test
testBroadcastResponseStats_clearAllCounts()1390     public void testBroadcastResponseStats_clearAllCounts() throws Exception {
1391         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
1392         final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
1393         // Initially all the counts should be empty
1394         assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1395         assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1396 
1397         final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
1398         final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
1399         try {
1400             ITestReceiver testReceiver1 = connection1.getITestReceiver();
1401             ITestReceiver testReceiver3 = connection3.getITestReceiver();
1402 
1403             testReceiver1.cancelAll();
1404             testReceiver3.cancelAll();
1405 
1406             final Intent intent = new Intent().setComponent(new ComponentName(
1407                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1408             final Intent intent3 = new Intent().setComponent(new ComponentName(
1409                     TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1410             final BroadcastOptions options1 = BroadcastOptions.makeBasic();
1411             options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1412             final BroadcastOptions options2 = BroadcastOptions.makeBasic();
1413             options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
1414 
1415             testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1416                     TEST_NOTIFICATION_CHANNEL_NAME,
1417                     TEST_NOTIFICATION_CHANNEL_DESC);
1418             testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1419                     TEST_NOTIFICATION_CHANNEL_NAME,
1420                     TEST_NOTIFICATION_CHANNEL_DESC);
1421 
1422             // Send a broadcast to test-pkg1 with a request to record response and verify
1423             // broadcast-sent count gets incremented.
1424             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1425             sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
1426 
1427             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1428                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1429                             TEST_NOTIFICATION_TEXT_1));
1430             testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
1431                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1432                             TEST_NOTIFICATION_TEXT_1));
1433 
1434             expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
1435                     TEST_RESPONSE_STATS_ID_1));
1436             expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1437                     TEST_RESPONSE_STATS_ID_1));
1438             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1439             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
1440             expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1441             expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
1442             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1443             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1444 
1445             sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
1446             sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
1447 
1448             testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
1449                     buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1450                             TEST_NOTIFICATION_TEXT_2));
1451             testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
1452 
1453             expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
1454             expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
1455             expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
1456                     TEST_RESPONSE_STATS_ID_2));
1457             expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
1458             expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
1459 
1460             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1461             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1462 
1463             mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
1464             expectedStatsForId1.clear();
1465             expectedStatsForId2.clear();
1466             assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
1467             assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
1468 
1469             testReceiver1.cancelAll();
1470             testReceiver3.cancelAll();
1471         } finally {
1472             connection1.unbind();
1473             connection3.unbind();
1474         }
1475     }
1476 
1477     @Test
testBroadcastResponseStats_mediaNotification()1478     public void testBroadcastResponseStats_mediaNotification() throws Exception {
1479         assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1480                 0 /* broadcastCount */,
1481                 0 /* notificationPostedCount */,
1482                 0 /* notificationUpdatedCount */,
1483                 0 /* notificationCancelledCount */);
1484 
1485         final TestServiceConnection connection = bindToTestServiceAndGetConnection();
1486         try {
1487             ITestReceiver testReceiver = connection.getITestReceiver();
1488             testReceiver.cancelAll();
1489 
1490             // Send a broadcast with a request to record response and verify broadcast-sent
1491             // count gets incremented.
1492             final BroadcastOptions options = BroadcastOptions.makeBasic();
1493             options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1494             final Intent intent = new Intent().setComponent(new ComponentName(
1495                     TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1496             sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1497 
1498             testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1499                     TEST_NOTIFICATION_CHANNEL_NAME,
1500                     TEST_NOTIFICATION_CHANNEL_DESC);
1501             testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1502                     buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1503                             TEST_NOTIFICATION_TEXT_1));
1504 
1505             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1506                     1 /* broadcastCount */,
1507                     1 /* notificationPostedCount */,
1508                     0 /* notificationUpdatedCount */,
1509                     0 /* notificationCancelledCount */);
1510 
1511             testReceiver.cancelAll();
1512         } finally {
1513             connection.unbind();
1514         }
1515     }
1516 
1517     @MediumTest
1518     @Test
testBroadcastResponseStats_broadcastSession()1519     public void testBroadcastResponseStats_broadcastSession() throws Exception {
1520         try (DeviceConfigStateHelper deviceConfigStateHelper =
1521                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1522             updateFlagsWithDefaultDelays(deviceConfigStateHelper);
1523 
1524             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1525                     0 /* broadcastCount */,
1526                     0 /* notificationPostedCount */,
1527                     0 /* notificationUpdatedCount */,
1528                     0 /* notificationCancelledCount */);
1529             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1530                     0 /* broadcastCount */,
1531                     0 /* notificationPostedCount */,
1532                     0 /* notificationUpdatedCount */,
1533                     0 /* notificationCancelledCount */);
1534 
1535             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
1536             try {
1537                 ITestReceiver testReceiver = connection.getITestReceiver();
1538                 testReceiver.cancelAll();
1539 
1540                 // Send a broadcast with a request to record response and verify broadcast-sent
1541                 // count gets incremented.
1542                 final Intent intent = new Intent().setComponent(new ComponentName(
1543                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1544                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1545                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1546                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1547 
1548                 // Send the broadcast again multiple times
1549                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1550                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1551 
1552                 // Now wait for a while and send the broadcast again.
1553                 SystemClock.sleep(BROADCAST_SESSIONS_DURATION_MS);
1554                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1555 
1556                 // Now wait until the broadcast response duration is elapsed and send the
1557                 // broadcast again.
1558                 SystemClock.sleep(BROADCAST_RESPONSE_WINDOW_DURATION_MS);
1559                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1560 
1561                 // Verify that total broadcasts are considered as only 2 even though they
1562                 // are dispatched multiple times.
1563                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1564                         2 /* broadcastCount */,
1565                         0 /* notificationPostedCount */,
1566                         0 /* notificationUpdatedCount */,
1567                         0 /* notificationCancelledCount */);
1568                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1569                         0 /* broadcastCount */,
1570                         0 /* notificationPostedCount */,
1571                         0 /* notificationUpdatedCount */,
1572                         0 /* notificationCancelledCount */);
1573             } finally {
1574                 connection.unbind();
1575             }
1576         }
1577     }
1578 
1579     @MediumTest
1580     @Test
testBroadcastResponseStats_broadcastSession_withLateNotification()1581     public void testBroadcastResponseStats_broadcastSession_withLateNotification()
1582             throws Exception {
1583         try (DeviceConfigStateHelper deviceConfigStateHelper =
1584                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1585             updateFlagsWithDefaultDelays(deviceConfigStateHelper);
1586 
1587             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1588                     0 /* broadcastCount */,
1589                     0 /* notificationPostedCount */,
1590                     0 /* notificationUpdatedCount */,
1591                     0 /* notificationCancelledCount */);
1592             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1593                     0 /* broadcastCount */,
1594                     0 /* notificationPostedCount */,
1595                     0 /* notificationUpdatedCount */,
1596                     0 /* notificationCancelledCount */);
1597 
1598             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
1599             try {
1600                 ITestReceiver testReceiver = connection.getITestReceiver();
1601                 testReceiver.cancelAll();
1602 
1603                 // Send a broadcast with a request to record response and verify broadcast-sent
1604                 // count gets incremented.
1605                 final Intent intent = new Intent().setComponent(new ComponentName(
1606                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1607                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1608                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1609                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1610 
1611                 // Send the broadcast again multiple times
1612                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1613                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1614 
1615                 // Now wait for a while and send the broadcast again.
1616                 SystemClock.sleep(BROADCAST_SESSIONS_DURATION_MS);
1617                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1618 
1619                 // Now wait until the broadcast response duration is elapsed and post a
1620                 // notification.
1621                 SystemClock.sleep(BROADCAST_RESPONSE_WINDOW_DURATION_MS);
1622                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1623                         TEST_NOTIFICATION_CHANNEL_NAME,
1624                         TEST_NOTIFICATION_CHANNEL_DESC);
1625                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1626                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1627                                 TEST_NOTIFICATION_TEXT_1));
1628 
1629                 // Verify that total broadcasts are considered as only 2 even though they
1630                 // are dispatched multiple times and the posted notification doesn't get counted.
1631                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1632                         2 /* broadcastCount */,
1633                         0 /* notificationPostedCount */,
1634                         0 /* notificationUpdatedCount */,
1635                         0 /* notificationCancelledCount */);
1636                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1637                         0 /* broadcastCount */,
1638                         0 /* notificationPostedCount */,
1639                         0 /* notificationUpdatedCount */,
1640                         0 /* notificationCancelledCount */);
1641             } finally {
1642                 connection.unbind();
1643             }
1644         }
1645     }
1646 
1647     @MediumTest
1648     @Test
testBroadcastResponseStats_broadcastSessionWithResponse()1649     public void testBroadcastResponseStats_broadcastSessionWithResponse() throws Exception {
1650         try (DeviceConfigStateHelper deviceConfigStateHelper =
1651                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1652             updateFlagsWithDefaultDelays(deviceConfigStateHelper);
1653 
1654             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1655                     0 /* broadcastCount */,
1656                     0 /* notificationPostedCount */,
1657                     0 /* notificationUpdatedCount */,
1658                     0 /* notificationCancelledCount */);
1659             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1660                     0 /* broadcastCount */,
1661                     0 /* notificationPostedCount */,
1662                     0 /* notificationUpdatedCount */,
1663                     0 /* notificationCancelledCount */);
1664 
1665             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
1666             try {
1667                 ITestReceiver testReceiver = connection.getITestReceiver();
1668                 testReceiver.cancelAll();
1669 
1670                 // Send a broadcast with a request to record response and verify broadcast-sent
1671                 // count gets incremented.
1672                 final Intent intent = new Intent().setComponent(new ComponentName(
1673                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1674                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1675                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1676                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1677 
1678                 // Send the broadcast again multiple times
1679                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1680                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1681 
1682                 // Now wait for a while and send the broadcast again.
1683                 SystemClock.sleep(BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS);
1684                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1685 
1686                 // Repeat the previous step - wait for a while and send the broadcast again.
1687                 SystemClock.sleep(BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS);
1688                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1689 
1690                 // Trigger a notification from test app and verify notification-posted count gets
1691                 // incremented.
1692                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1693                         TEST_NOTIFICATION_CHANNEL_NAME,
1694                         TEST_NOTIFICATION_CHANNEL_DESC);
1695                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1696                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1697                                 TEST_NOTIFICATION_TEXT_1));
1698 
1699                 // Verify that total broadcasts are considered as only 2 even though they
1700                 // are dispatched multiple times.
1701                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1702                         3 /* broadcastCount */,
1703                         3 /* notificationPostedCount */,
1704                         0 /* notificationUpdatedCount */,
1705                         0 /* notificationCancelledCount */);
1706                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1707                         0 /* broadcastCount */,
1708                         0 /* notificationPostedCount */,
1709                         0 /* notificationUpdatedCount */,
1710                         0 /* notificationCancelledCount */);
1711             } finally {
1712                 connection.unbind();
1713             }
1714         }
1715     }
1716 
1717     @MediumTest
1718     @Test
testBroadcastResponseStats_broadcastSessionWithResponse_recordOnlyOne()1719     public void testBroadcastResponseStats_broadcastSessionWithResponse_recordOnlyOne()
1720             throws Exception {
1721         try (DeviceConfigStateHelper deviceConfigStateHelper =
1722                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1723             updateFlagsWithDefaultDelays(deviceConfigStateHelper);
1724             updateFlagWithDelay(deviceConfigStateHelper,
1725                     KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS,
1726                     String.valueOf(false));
1727 
1728             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1729                     0 /* broadcastCount */,
1730                     0 /* notificationPostedCount */,
1731                     0 /* notificationUpdatedCount */,
1732                     0 /* notificationCancelledCount */);
1733             assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1734                     0 /* broadcastCount */,
1735                     0 /* notificationPostedCount */,
1736                     0 /* notificationUpdatedCount */,
1737                     0 /* notificationCancelledCount */);
1738 
1739             final TestServiceConnection connection = bindToTestServiceAndGetConnection();
1740             try {
1741                 ITestReceiver testReceiver = connection.getITestReceiver();
1742                 testReceiver.cancelAll();
1743 
1744                 // Send a broadcast with a request to record response and verify broadcast-sent
1745                 // count gets incremented.
1746                 final Intent intent = new Intent().setComponent(new ComponentName(
1747                         TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1748                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1749                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1750                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1751 
1752                 // Send the broadcast again multiple times
1753                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1754                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1755 
1756                 // Now wait for a while and send the broadcast again.
1757                 SystemClock.sleep(BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS);
1758                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1759 
1760                 // Repeat the previous step - wait for a while and send the broadcast again.
1761                 SystemClock.sleep(BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS);
1762                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1763 
1764                 // Trigger a notification from test app and verify notification-posted count gets
1765                 // incremented.
1766                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1767                         TEST_NOTIFICATION_CHANNEL_NAME,
1768                         TEST_NOTIFICATION_CHANNEL_DESC);
1769                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1770                         buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1771                                 TEST_NOTIFICATION_TEXT_1));
1772 
1773                 // Verify that total broadcasts are considered as only 2 even though they
1774                 // are dispatched multiple times.
1775                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1776                         1 /* broadcastCount */,
1777                         1 /* notificationPostedCount */,
1778                         0 /* notificationUpdatedCount */,
1779                         0 /* notificationCancelledCount */);
1780                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1781                         0 /* broadcastCount */,
1782                         0 /* notificationPostedCount */,
1783                         0 /* notificationUpdatedCount */,
1784                         0 /* notificationCancelledCount */);
1785 
1786                 // Wait until the broadcast response window duration is elapsed and verify that
1787                 // previously sent broadcasts are recorded correctly.
1788                 SystemClock.sleep(BROADCAST_RESPONSE_WINDOW_DURATION_MS);
1789 
1790                 testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
1791 
1792                 // Verify that total broadcasts are considered as only 2 even though they
1793                 // are dispatched multiple times.
1794                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1795                         3 /* broadcastCount */,
1796                         1 /* notificationPostedCount */,
1797                         0 /* notificationUpdatedCount */,
1798                         0 /* notificationCancelledCount */);
1799                 assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1800                         0 /* broadcastCount */,
1801                         0 /* notificationPostedCount */,
1802                         0 /* notificationUpdatedCount */,
1803                         0 /* notificationCancelledCount */);
1804             } finally {
1805                 connection.unbind();
1806             }
1807         }
1808     }
1809 
1810     @FlakyTest(bugId = 288339565)
1811     @Test
testBroadcastResponseStats_exemptedRole()1812     public void testBroadcastResponseStats_exemptedRole() throws Exception {
1813         try (DeviceConfigStateHelper deviceConfigStateHelper =
1814                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1815             updateFlagWithDelay(deviceConfigStateHelper,
1816                     KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES,
1817                     ROLE_ASSISTANT);
1818 
1819             assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1820                     0 /* broadcastCount */,
1821                     0 /* notificationPostedCount */,
1822                     0 /* notificationUpdatedCount */,
1823                     0 /* notificationCancelledCount */);
1824             assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1825                     0 /* broadcastCount */,
1826                     0 /* notificationPostedCount */,
1827                     0 /* notificationUpdatedCount */,
1828                     0 /* notificationCancelledCount */);
1829 
1830             final TestServiceConnection connection = bindToTestServiceAndGetConnection(
1831                     TEST_ASSIST_APP_PKG);
1832             try {
1833                 ITestReceiver testReceiver = connection.getITestReceiver();
1834                 testReceiver.cancelAll();
1835 
1836                 // Send a broadcast with a request to record response and verify broadcast-sent
1837                 // count gets incremented.
1838                 final Intent intent = new Intent().setComponent(new ComponentName(
1839                         TEST_ASSIST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1840                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1841                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1842                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1843 
1844                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1845                         TEST_NOTIFICATION_CHANNEL_NAME,
1846                         TEST_NOTIFICATION_CHANNEL_DESC);
1847                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1848                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1849                                 TEST_NOTIFICATION_TEXT_1));
1850 
1851                 assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1852                         1 /* broadcastCount */,
1853                         1 /* notificationPostedCount */,
1854                         0 /* notificationUpdatedCount */,
1855                         0 /* notificationCancelledCount */);
1856 
1857                 addAssistRoleHolder(TEST_ASSIST_APP_PKG, Process.myUserHandle().getIdentifier());
1858                 // Wait until the component tracking the broadcast response stats is updated with
1859                 // the new role holder.
1860                 waitForPackageToBeExempted(TEST_ASSIST_APP_PKG);
1861 
1862                 // Since the assistant role is exempted and the test app holds assist role,
1863                 // broadcast response stats for it would not be recorded.
1864                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1865                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1866                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1867                                 TEST_NOTIFICATION_TEXT_2));
1868 
1869                 assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1870                         1 /* broadcastCount */,
1871                         1 /* notificationPostedCount */,
1872                         0 /* notificationUpdatedCount */,
1873                         0 /* notificationCancelledCount */);
1874 
1875                 // Remove the assistant role from exempted roles and verify broadcast
1876                 // response stats for the test app are recorded.
1877                 updateFlagWithDelay(deviceConfigStateHelper,
1878                         KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES,
1879                         String.join("|", RoleManager.ROLE_BROWSER, RoleManager.ROLE_EMERGENCY));
1880 
1881                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1882                 testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
1883 
1884                 assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1885                         2 /* broadcastCount */,
1886                         1 /* notificationPostedCount */,
1887                         0 /* notificationUpdatedCount */,
1888                         1 /* notificationCancelledCount */);
1889 
1890                 // Add the assistant role to the list of exempted roles and verify broadcast
1891                 // response stats for the test app are not recorded.
1892                 updateFlagWithDelay(deviceConfigStateHelper,
1893                         KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES,
1894                         String.join("|", RoleManager.ROLE_BROWSER, RoleManager.ROLE_EMERGENCY,
1895                                 ROLE_ASSISTANT));
1896 
1897                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1898                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1899                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1900                                 TEST_NOTIFICATION_TEXT_1));
1901 
1902                 assertResponseStats(TEST_ASSIST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1903                         2 /* broadcastCount */,
1904                         1 /* notificationPostedCount */,
1905                         0 /* notificationUpdatedCount */,
1906                         1 /* notificationCancelledCount */);
1907             } finally {
1908                 removeAssistRoleHolder(TEST_ASSIST_APP_PKG, Process.myUserHandle().getIdentifier());
1909                 connection.unbind();
1910             }
1911         }
1912     }
1913 
1914     @Test
testBroadcastResponseStats_exemptedPermission()1915     public void testBroadcastResponseStats_exemptedPermission() throws Exception {
1916         try (DeviceConfigStateHelper deviceConfigStateHelper =
1917                      new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
1918 
1919             assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1920                     0 /* broadcastCount */,
1921                     0 /* notificationPostedCount */,
1922                     0 /* notificationUpdatedCount */,
1923                     0 /* notificationCancelledCount */);
1924             assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_2,
1925                     0 /* broadcastCount */,
1926                     0 /* notificationPostedCount */,
1927                     0 /* notificationUpdatedCount */,
1928                     0 /* notificationCancelledCount */);
1929 
1930             final TestServiceConnection connection = bindToTestServiceAndGetConnection(
1931                     TEST_EXACT_ALARM_APP_PKG);
1932             try {
1933                 ITestReceiver testReceiver = connection.getITestReceiver();
1934                 testReceiver.cancelAll();
1935 
1936                 // Send a broadcast with a request to record response and verify broadcast-sent
1937                 // count gets incremented.
1938                 final Intent intent = new Intent().setComponent(new ComponentName(
1939                         TEST_EXACT_ALARM_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
1940                 final BroadcastOptions options = BroadcastOptions.makeBasic();
1941                 options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
1942                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1943 
1944                 testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
1945                         TEST_NOTIFICATION_CHANNEL_NAME,
1946                         TEST_NOTIFICATION_CHANNEL_DESC);
1947                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1948                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1949                                 TEST_NOTIFICATION_TEXT_1));
1950 
1951                 assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1952                         1 /* broadcastCount */,
1953                         1 /* notificationPostedCount */,
1954                         0 /* notificationUpdatedCount */,
1955                         0 /* notificationCancelledCount */);
1956 
1957                 // Add USE_EXACT_ALARM to the list of exempted permissions and verify
1958                 // broadcast response stats for the test app are not recorded.
1959                 updateFlagWithDelay(deviceConfigStateHelper,
1960                         KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS,
1961                         USE_EXACT_ALARM);
1962 
1963                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1964                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1965                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1966                                 TEST_NOTIFICATION_TEXT_2));
1967 
1968                 assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1969                         1 /* broadcastCount */,
1970                         1 /* notificationPostedCount */,
1971                         0 /* notificationUpdatedCount */,
1972                         0 /* notificationCancelledCount */);
1973 
1974                 // Remove USE_EXACT_ALARM from the list of exempted permissions and verify
1975                 // broadcast response stats for the test app are recorded.
1976                 updateFlagWithDelay(deviceConfigStateHelper,
1977                         KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS,
1978                         String.join("|", PACKAGE_USAGE_STATS, INTERNET));
1979 
1980                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1981                 testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
1982 
1983                 assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_1,
1984                         2 /* broadcastCount */,
1985                         1 /* notificationPostedCount */,
1986                         0 /* notificationUpdatedCount */,
1987                         1 /* notificationCancelledCount */);
1988 
1989                 // Add USE_EXACT_ALARM to the list of exempted permissions again and verify
1990                 // broadcast response stats for the test app are not recorded.
1991                 updateFlagWithDelay(deviceConfigStateHelper,
1992                         KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS,
1993                         String.join("|", PACKAGE_USAGE_STATS, INTERNET, USE_EXACT_ALARM));
1994 
1995                 sendBroadcastAndWaitForReceipt(intent, options.toBundle());
1996                 testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
1997                         buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
1998                                 TEST_NOTIFICATION_TEXT_1));
1999 
2000                 assertResponseStats(TEST_EXACT_ALARM_APP_PKG, TEST_RESPONSE_STATS_ID_1,
2001                         2 /* broadcastCount */,
2002                         1 /* notificationPostedCount */,
2003                         0 /* notificationUpdatedCount */,
2004                         1 /* notificationCancelledCount */);
2005             } finally {
2006                 connection.unbind();
2007             }
2008         }
2009     }
2010 
updateFlagsWithDefaultDelays(DeviceConfigStateHelper deviceConfigStateHelper)2011     private void updateFlagsWithDefaultDelays(DeviceConfigStateHelper deviceConfigStateHelper) {
2012         updateFlagWithDelay(deviceConfigStateHelper,
2013                 KEY_BROADCAST_SESSIONS_DURATION_MS,
2014                 String.valueOf(BROADCAST_SESSIONS_DURATION_MS));
2015         updateFlagWithDelay(deviceConfigStateHelper,
2016                 KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS,
2017                 String.valueOf(BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS));
2018         updateFlagWithDelay(deviceConfigStateHelper,
2019                 KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
2020                 String.valueOf(BROADCAST_RESPONSE_WINDOW_DURATION_MS));
2021     }
2022 
updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper, String key, String value)2023     private void updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper,
2024             String key, String value) {
2025         deviceConfigStateHelper.set(key, value);
2026         SystemUtil.runWithShellPermissionIdentity(() -> {
2027             final String actualValue = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
2028                     () -> mUsageStatsManager.getAppStandbyConstant(key),
2029                     result -> value.equals(result));
2030             assertEquals("Error changing the value of " + key, value, actualValue);
2031         });
2032     }
2033 
buildNotification(String channelId, int notificationId, String notificationText)2034     private Notification buildNotification(String channelId, int notificationId,
2035             String notificationText) {
2036         return new Notification.Builder(sContext, channelId)
2037                 .setSmallIcon(android.R.drawable.ic_info)
2038                 .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
2039                 .setContentText(notificationText)
2040                 .build();
2041     }
2042 
buildMediaNotification(String channelId, int notificationId, String notificationText)2043     private Notification buildMediaNotification(String channelId, int notificationId,
2044             String notificationText) {
2045         final PendingIntent pendingIntent = PendingIntent.getActivity(sContext,
2046                 0 /* requestCode */, new Intent(sContext, this.getClass()),
2047                 PendingIntent.FLAG_IMMUTABLE);
2048         final MediaSession session = new MediaSession(sContext, "test_media");
2049         return new Notification.Builder(sContext, channelId)
2050                 .setSmallIcon(android.R.drawable.ic_menu_day)
2051                 .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
2052                 .setContentText(notificationText)
2053                 .addAction(new Notification.Action.Builder(
2054                         Icon.createWithResource(sContext, android.R.drawable.ic_media_previous),
2055                         "previous", pendingIntent).build())
2056                 .addAction(new Notification.Action.Builder(
2057                         Icon.createWithResource(sContext, android.R.drawable.ic_media_play),
2058                         "play", pendingIntent).build())
2059                 .addAction(new Notification.Action.Builder(
2060                         Icon.createWithResource(sContext, android.R.drawable.ic_media_next),
2061                         "next", pendingIntent).build())
2062                 .setStyle(new Notification.MediaStyle()
2063                         .setShowActionsInCompactView(0, 1, 2)
2064                         .setMediaSession(session.getSessionToken()))
2065                 .build();
2066     }
2067 
sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)2068     private void sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)
2069             throws Exception {
2070         final CountDownLatch latch = new CountDownLatch(1);
2071         intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
2072         sContext.sendBroadcast(intent, null /* receiverPermission */, options);
2073         SystemUtil.runShellCommand("am wait-for-broadcast-barrier");
2074         if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
2075             fail("Timed out waiting for the test app to receive the broadcast");
2076         }
2077     }
2078 
assertResponseStats(String packageName, long id, int... expectedCounts)2079     private void assertResponseStats(String packageName, long id, int... expectedCounts) {
2080         final BroadcastResponseStats expectedStats = new BroadcastResponseStats(packageName, id);
2081         expectedStats.incrementBroadcastsDispatchedCount(expectedCounts[0]);
2082         expectedStats.incrementNotificationsPostedCount(expectedCounts[1]);
2083         expectedStats.incrementNotificationsUpdatedCount(expectedCounts[2]);
2084         expectedStats.incrementNotificationsCancelledCount(expectedCounts[3]);
2085         assertResponseStats(packageName, id, expectedStats);
2086     }
2087 
assertResponseStats(String packageName, long id, BroadcastResponseStats expectedStats)2088     private void assertResponseStats(String packageName, long id,
2089             BroadcastResponseStats expectedStats) {
2090         List<BroadcastResponseStats> actualStats = mUsageStatsManager
2091                 .queryBroadcastResponseStats(packageName, id);
2092         if (compareStats(expectedStats, actualStats)) {
2093             SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
2094         }
2095 
2096         actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
2097                 () -> mUsageStatsManager.queryBroadcastResponseStats(packageName, id),
2098                 result -> compareStats(expectedStats, result));
2099         actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
2100         final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
2101                 1, expectedStats,
2102                 actualStats.size(), Arrays.toString(actualStats.toArray()));
2103         assertTrue(errorMsg, compareStats(expectedStats, actualStats));
2104     }
2105 
assertResponseStats(long id, ArrayMap<String, BroadcastResponseStats> expectedStats)2106     private void assertResponseStats(long id,
2107             ArrayMap<String, BroadcastResponseStats> expectedStats) {
2108         // TODO: Call into the above assertResponseStats() method instead of duplicating
2109         // the logic.
2110         List<BroadcastResponseStats> actualStats = mUsageStatsManager
2111                 .queryBroadcastResponseStats(null /* packageName */, id);
2112         if (compareStats(expectedStats, actualStats)) {
2113             SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
2114         }
2115 
2116         actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
2117                 () -> mUsageStatsManager.queryBroadcastResponseStats(null /* packageName */, id),
2118                 result -> compareStats(expectedStats, result));
2119         actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
2120         final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
2121                 expectedStats.size(), expectedStats,
2122                 actualStats.size(), Arrays.toString(actualStats.toArray()));
2123         assertTrue(errorMsg, compareStats(expectedStats, actualStats));
2124     }
2125 
compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats, List<BroadcastResponseStats> actualStats)2126     private boolean compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats,
2127             List<BroadcastResponseStats> actualStats) {
2128         if (expectedStats.size() != actualStats.size()) {
2129             return false;
2130         }
2131         for (int i = 0; i < actualStats.size(); ++i) {
2132             final BroadcastResponseStats actualPackageStats = actualStats.get(i);
2133             final String packageName = actualPackageStats.getPackageName();
2134             if (!actualPackageStats.equals(expectedStats.get(packageName))) {
2135                 return false;
2136             }
2137         }
2138         return true;
2139     }
2140 
compareStats(BroadcastResponseStats expectedStats, List<BroadcastResponseStats> actualStats)2141     private boolean compareStats(BroadcastResponseStats expectedStats,
2142             List<BroadcastResponseStats> actualStats) {
2143         if (actualStats.size() > 1) {
2144             return false;
2145         }
2146         final BroadcastResponseStats stats = (actualStats == null || actualStats.isEmpty())
2147                 ? new BroadcastResponseStats(expectedStats.getPackageName(), expectedStats.getId())
2148                 : actualStats.get(0);
2149         return expectedStats.equals(stats);
2150     }
2151 
bindToTestServiceAndGetConnection(String packageName)2152     private TestServiceConnection bindToTestServiceAndGetConnection(String packageName) {
2153         final TestServiceConnection
2154                 connection = new TestServiceConnection(sContext);
2155         final Intent intent = new Intent().setComponent(
2156                 new ComponentName(packageName, TEST_APP_CLASS_SERVICE));
2157         sContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
2158         return connection;
2159     }
2160 
bindToTestServiceAndGetConnection()2161     private TestServiceConnection bindToTestServiceAndGetConnection() throws Exception {
2162         return bindToTestServiceAndGetConnection(TEST_APP_PKG);
2163     }
2164 
launchTestActivityAndWaitToBeResumed(String pkgName, String className)2165     private void launchTestActivityAndWaitToBeResumed(String pkgName, String className)
2166             throws Exception {
2167         // Make sure the screen is awake and unlocked. Otherwise, the app activity won't be resumed.
2168         wakeUpAndDismissKeyguard();
2169 
2170         final Intent intent = createTestActivityIntent(pkgName, className);
2171         final CountDownLatch latch = new CountDownLatch(1);
2172         intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
2173         sContext.startActivity(intent);
2174         if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
2175             fail("Timed out waiting for the test app activity to be resumed");
2176         }
2177     }
2178 
addAssistRoleHolder(String pkgName, int userId)2179     protected void addAssistRoleHolder(String pkgName, int userId) {
2180         SystemUtil.runWithShellPermissionIdentity(() -> {
2181             if (isAssistantRoleHolder(pkgName, userId)) {
2182                 Log.d(TAG, pkgName + " already holds the assist role on u" + userId);
2183                 return;
2184             }
2185             final CountDownLatch latch = new CountDownLatch(1);
2186             final OnRoleHoldersChangedListener listener = (roleName, user) -> {
2187                 Log.d(TAG, "Received role changed callback for role=" + roleName
2188                         + " in u" + user.getIdentifier());
2189                 if (latch.getCount() > 0
2190                         && ROLE_ASSISTANT.equals(roleName) && user.getIdentifier() == userId
2191                         && isAssistantRoleHolder(pkgName, userId)) {
2192                     latch.countDown();
2193                 }
2194             };
2195             mRoleManager.addOnRoleHoldersChangedListenerAsUser(sContext.getMainExecutor(),
2196                     listener, UserHandle.of(userId));
2197             addRoleHolderAsUser(ROLE_ASSISTANT, pkgName, userId);
2198             if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
2199                 fail("Timed out waiting for role holder to be added");
2200             }
2201             mRoleManager.removeOnRoleHoldersChangedListenerAsUser(listener, UserHandle.of(userId));
2202         });
2203     }
2204 
addRoleHolderAsUser(String roleName, String pkgName, int userId)2205     private void addRoleHolderAsUser(String roleName, String pkgName, int userId)
2206             throws Exception {
2207         final CompletableFuture<Boolean> callback = new CompletableFuture<>();
2208         Log.d(TAG, "Adding assist role holder; pkg=" + pkgName + ", userId=" + userId);
2209         mRoleManager.addRoleHolderAsUser(roleName, pkgName, 0,
2210                 UserHandle.of(userId), sContext.getMainExecutor(), callback::complete);
2211         assertTrue(callback.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
2212     }
2213 
removeAssistRoleHolder(String pkgName, int userId)2214     protected void removeAssistRoleHolder(String pkgName, int userId) {
2215         SystemUtil.runWithShellPermissionIdentity(() -> {
2216             if (!isAssistantRoleHolder(pkgName, userId)) {
2217                 Log.d(TAG, pkgName + " doesn't hold the assist role on u" + userId);
2218                 return;
2219             }
2220             final CountDownLatch latch = new CountDownLatch(1);
2221             final OnRoleHoldersChangedListener listener = (roleName, user) -> {
2222                 Log.d(TAG, "Received role changed callback for role=" + roleName
2223                         + " in u" + user.getIdentifier());
2224                 if (latch.getCount() > 0
2225                         && ROLE_ASSISTANT.equals(roleName) && user.getIdentifier() == userId
2226                         && !isAssistantRoleHolder(pkgName, userId)) {
2227                     latch.countDown();
2228                 }
2229             };
2230             mRoleManager.addOnRoleHoldersChangedListenerAsUser(sContext.getMainExecutor(),
2231                     listener, UserHandle.of(userId));
2232             removeRoleHolderAsUser(ROLE_ASSISTANT, pkgName, userId);
2233             if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
2234                 fail("Timed out waiting for role holder to be removed");
2235             }
2236             mRoleManager.removeOnRoleHoldersChangedListenerAsUser(listener, UserHandle.of(userId));
2237         });
2238     }
2239 
removeRoleHolderAsUser(String roleName, String pkgName, int userId)2240     private void removeRoleHolderAsUser(String roleName, String pkgName, int userId)
2241             throws Exception {
2242         final CompletableFuture<Boolean> callback = new CompletableFuture<>();
2243         Log.d(TAG, "Removing assist role holder; pkg=" + pkgName + ", userId=" + userId);
2244         mRoleManager.removeRoleHolderAsUser(roleName, pkgName, 0,
2245                 UserHandle.of(userId), sContext.getMainExecutor(), callback::complete);
2246         assertTrue(callback.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
2247     }
2248 
isAssistantRoleHolder(String pkgName, int userId)2249     protected boolean isAssistantRoleHolder(String pkgName, int userId) {
2250         final List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(
2251                 ROLE_ASSISTANT, UserHandle.of(userId));
2252         return roleHolders.contains(pkgName);
2253     }
2254 
waitForPackageToBeExempted(String pkgName)2255     private void waitForPackageToBeExempted(String pkgName) {
2256         SystemUtil.runWithShellPermissionIdentity(() ->
2257                 TestUtils.waitUntil(
2258                         "Timed out waiting for " + pkgName + " to be exempted",
2259                         DEFAULT_TIMEOUT_MS,
2260                         () -> mUsageStatsManager.isPackageExemptedFromBroadcastResponseStats(
2261                                 TEST_ASSIST_APP_PKG)));
2262     }
2263 
wakeUpAndDismissKeyguard()2264     private void wakeUpAndDismissKeyguard() throws Exception {
2265         mUiDevice.wakeUp();
2266         SystemUtil.runShellCommand("wm dismiss-keyguard");
2267     }
2268 
createTestActivityIntent(String pkgName, String className)2269     private Intent createTestActivityIntent(String pkgName, String className) {
2270         final Intent intent = new Intent();
2271         intent.setClassName(pkgName, className);
2272         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2273         return intent;
2274     }
2275 
2276     private static class TestServiceConnection implements ServiceConnection {
2277         private BlockingQueue<IBinder> mBlockingQueue = new LinkedBlockingQueue<>();
2278         private Context mContext;
2279 
TestServiceConnection(Context context)2280         TestServiceConnection(Context context) {
2281             mContext = context;
2282         }
2283 
onServiceConnected(ComponentName componentName, IBinder service)2284         public void onServiceConnected(ComponentName componentName, IBinder service) {
2285             mBlockingQueue.offer(service);
2286         }
2287 
onServiceDisconnected(ComponentName componentName)2288         public void onServiceDisconnected(ComponentName componentName) {
2289         }
2290 
getService()2291         public IBinder getService() throws Exception {
2292             final IBinder service = mBlockingQueue.poll(TIMEOUT_BINDER_SERVICE_SEC,
2293                     TimeUnit.SECONDS);
2294             return service;
2295         }
2296 
getITestReceiver()2297         public ITestReceiver getITestReceiver() throws Exception {
2298             return ITestReceiver.Stub.asInterface(getService());
2299         }
2300 
unbind()2301         public void unbind() {
2302             mContext.unbindService(this);
2303         }
2304     }
2305 }
2306