Move BroadcastResponseStats related tests to separate class.
We want to make sure we are testing the new broadcast response
stats related APIs without holding the PACKAGE_USAGE_STATS
permisison.
Bug: 225039700
Test: atest tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
Change-Id: Ic5612cff155a746939002f28c190bfade3b45031
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java
new file mode 100644
index 0000000..977d45a
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java
@@ -0,0 +1,1731 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.usage.cts;
+
+import static android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS_BROADCAST_RECEIVER;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS_SERVICE;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_PKG;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+import static android.provider.DeviceConfig.NAMESPACE_APP_STANDBY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.UiAutomation;
+import android.app.usage.BroadcastResponseStats;
+import android.app.usage.UsageStatsManager;
+import android.app.usage.cts.UsageStatsTest.TestServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.media.session.MediaSession;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.uiautomator.UiDevice;
+import android.util.ArrayMap;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+
+import com.android.compatibility.common.util.AppOpsUtils;
+import com.android.compatibility.common.util.DeviceConfigStateHelper;
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(UsageStatsTestRunner.class)
+public class BroadcastResponseStatsTest {
+
+ private static final String TEST_APP3_PKG = "android.app.usage.cts.test3";
+ private static final String TEST_APP4_PKG = "android.app.usage.cts.test4";
+
+ private static final long TEST_RESPONSE_STATS_ID_1 = 11;
+ private static final long TEST_RESPONSE_STATS_ID_2 = 22;
+
+ private static final String TEST_NOTIFICATION_CHANNEL_ID = "test-channel-id";
+ private static final String TEST_NOTIFICATION_CHANNEL_NAME = "test-channel-name";
+ private static final String TEST_NOTIFICATION_CHANNEL_DESC = "test-channel-description";
+
+ private static final int TEST_NOTIFICATION_ID_1 = 10;
+ private static final int TEST_NOTIFICATION_ID_2 = 20;
+ private static final String TEST_NOTIFICATION_TITLE_FMT = "Test title; id=%s";
+ private static final String TEST_NOTIFICATION_TEXT_1 = "Test content 1";
+ private static final String TEST_NOTIFICATION_TEXT_2 = "Test content 2";
+
+ private static final int DEFAULT_TIMEOUT_MS = 10_000;
+ // For tests that are verifying a certain event doesn't occur, wait for some time
+ // to ensure the event doesn't really occur. Otherwise, we cannot be sure if the event didn't
+ // occur or the verification was done too early before the event occurred.
+ private static final int WAIT_TIME_FOR_NEGATIVE_TESTS_MS = 500;
+
+ // TODO: Define these constants in UsageStatsManager as @TestApis to avoid hardcoding here.
+ private static final String KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS =
+ "broadcast_response_window_timeout_ms";
+ private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
+ "broadcast_response_fg_threshold_state";
+
+ private static Context sContext;
+ private static String sTargetPackage;
+ private UsageStatsManager mUsageStatsManager;
+ private UiDevice mUiDevice;
+ private UiAutomation mUiAutomation;
+
+ private static int sInitialAppOpMode;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ sContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ sTargetPackage = sContext.getPackageName();
+ sInitialAppOpMode = AppOpsUtils.getOpMode(sTargetPackage,
+ AppOpsManager.OPSTR_GET_USAGE_STATS);
+ AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
+ AppOpsManager.MODE_IGNORED);
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
+ sInitialAppOpMode);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mUsageStatsManager = sContext.getSystemService(UsageStatsManager.class);
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mUiAutomation = InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation();
+ mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUiDevice.pressHome();
+
+ // Clear broadcast response stats
+ mUsageStatsManager.clearBroadcastEvents();
+ mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
+ mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastOptions_noPermission() throws Exception {
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ try {
+ assertThrows(SecurityException.class, () -> {
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ });
+ } finally {
+ mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testQueryBroadcastResponseStats_noPermission() throws Exception {
+ mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+
+ mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ try {
+ assertThrows(SecurityException.class, () -> {
+ mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1);
+ });
+ } finally {
+ mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testClearBroadcastResponseStats_noPermission() throws Exception {
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+
+ mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ try {
+ assertThrows(SecurityException.class, () -> {
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1);
+ });
+ } finally {
+ mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_broadcastDispatchedCount() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a normal broadcast and verify none of the counts get incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, null);
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Trigger a notification from test app and verify notification-posted count gets
+ // incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_notificationPostedCount() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a normal broadcast and verify none of the counts get incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, null);
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Trigger a notification from test app and verify notification-posted count gets
+ // incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_notificationUpdatedCount() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Post a notification (before sending any broadcast) and verify none of the counts
+ // get incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Update a previously posted notification (change content text) and verify
+ // notification-updated count gets incremented.
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_notificationCancelledCount() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Post a notification (before sending any broadcast) and verify none of the counts
+ // get incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Cancel a previously posted notification (change content text) and verify
+ // notification-cancelled count gets incremented.
+ testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 1 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_multipleEvents() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a normal broadcast and verify none of the counts get incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, null);
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Trigger a notification from test app and verify notification-posted count gets
+ // incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send another broadcast and trigger another notification.
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_2,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_2,
+ TEST_NOTIFICATION_TEXT_2));
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 2 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send another broadcast with a different ID and update a previously posted
+ // notification.
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 2 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Update/cancel a previously posted notifications and verify there is
+ // no change in counts.
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ testReceiver.cancelNotification(TEST_NOTIFICATION_ID_2);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 2 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_clearCounts() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Trigger a notification from test app and verify notification-posted count gets
+ // incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Send the broadcast again after clearing counts and verify counts get incremented
+ // as expected.
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 1 /* notificationUpdatedCount */,
+ 1 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @MediumTest
+ @Test
+ public void testBroadcastResponseStats_changeResponseWindowDuration() throws Exception {
+ final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(2);
+ try (DeviceConfigStateHelper deviceConfigStateHelper =
+ new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+ updateFlagWithDelay(deviceConfigStateHelper,
+ KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+ String.valueOf(broadcastResponseWindowDurationMs));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Trigger a notification from test app and verify notification-posted count gets
+ // incremented.
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ SystemClock.sleep(broadcastResponseWindowDurationMs);
+ // Trigger a notification from test app but verify counts do not get
+ // incremented as the notification is posted after the window durations is expired.
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_appNotInForeground() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ try (DeviceConfigStateHelper deviceConfigStateHelper =
+ new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ updateFlagWithDelay(deviceConfigStateHelper,
+ KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+ String.valueOf(ActivityManager.PROCESS_STATE_TOP));
+
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Bring the test app to the foreground, send the broadcast again and verify that
+ // counts do not change.
+ launchTestActivityAndWaitToBeResumed(TEST_APP_PKG, TEST_APP_CLASS);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ // Change the threshold to something lower than TOP, send the broadcast again
+ // and verify that counts get incremented.
+ updateFlagWithDelay(deviceConfigStateHelper,
+ KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+ String.valueOf(ActivityManager.PROCESS_STATE_PERSISTENT));
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ mUiDevice.pressHome();
+ // Change the threshold to a process state higher than RECEIVER, send the
+ // broadcast again and verify that counts do not change.
+ updateFlagWithDelay(deviceConfigStateHelper,
+ KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+ String.valueOf(ActivityManager.PROCESS_STATE_HOME));
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 2 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_multiplePackages() throws Exception {
+ final ArrayMap<String, BroadcastResponseStats> expectedStats = new ArrayMap<>();
+ // Initially all the counts should be empty
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+ final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
+ try {
+ ITestReceiver testReceiver1 = connection1.getITestReceiver();
+ ITestReceiver testReceiver3 = connection3.getITestReceiver();
+ ITestReceiver testReceiver4 = connection4.getITestReceiver();
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ testReceiver4.cancelAll();
+
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent3 = new Intent().setComponent(new ComponentName(
+ TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent4 = new Intent().setComponent(new ComponentName(
+ TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ expectedStats.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Send a broadcast to test-pkg3 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent3, options.toBundle());
+ expectedStats.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStats.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Trigger a notification from test-pkg1 and verify notification-posted count gets
+ // incremented.
+ testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStats.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Trigger a notification from test-pkg3 and verify notification-posted count gets
+ // incremented.
+ testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStats.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+ expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStats.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Trigger a notification from test-pkg3 and verify stats remain the same
+ testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ // Send a broadcast to test-pkg4 with a request to record response and verify
+ // broadcast-send count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent4, options.toBundle());
+ testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
+ expectedStats.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStats.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStats.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
+ expectedStats.clear();
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ testReceiver4.cancelAll();
+ } finally {
+ connection1.unbind();
+ connection3.unbind();
+ connection4.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_multiplePackages_multipleIds() throws Exception {
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+ // Initially all the counts should be empty
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+ final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
+ try {
+ ITestReceiver testReceiver1 = connection1.getITestReceiver();
+ ITestReceiver testReceiver3 = connection3.getITestReceiver();
+ ITestReceiver testReceiver4 = connection4.getITestReceiver();
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ testReceiver4.cancelAll();
+
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent3 = new Intent().setComponent(new ComponentName(
+ TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent4 = new Intent().setComponent(new ComponentName(
+ TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+ // Trigger a notification from test-pkg1 and verify notification-posted count gets
+ // incremented.
+ testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+ expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_2));
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastEvents();
+ // Trigger a notification from test-pkg4 and verify notification-posted count gets
+ // incremented.
+ testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ sendBroadcastAndWaitForReceipt(intent4, options2.toBundle());
+ expectedStatsForId2.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
+ TEST_RESPONSE_STATS_ID_2));
+ expectedStatsForId2.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
+
+ testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
+ expectedStatsForId2.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
+ expectedStatsForId1.clear();
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ testReceiver4.cancelAll();
+ } finally {
+ connection1.unbind();
+ connection3.unbind();
+ connection4.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_clearCounts_multiplePackages() throws Exception {
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+ // Initially all the counts should be empty
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+ try {
+ ITestReceiver testReceiver1 = connection1.getITestReceiver();
+ ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent3 = new Intent().setComponent(new ComponentName(
+ TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+ testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+ testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+ expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_2));
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
+ TEST_RESPONSE_STATS_ID_1);
+ expectedStatsForId1.clear();
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
+ TEST_RESPONSE_STATS_ID_2);
+ expectedStatsForId2.clear();
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ } finally {
+ connection1.unbind();
+ connection3.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_clearCounts_multipleIds() throws Exception {
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+ // Initially all the counts should be empty
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+ try {
+ ITestReceiver testReceiver1 = connection1.getITestReceiver();
+ ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent3 = new Intent().setComponent(new ComponentName(
+ TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+ testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+ testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+ expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_2));
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, 0 /* id */);
+ expectedStatsForId1.remove(TEST_APP_PKG);
+ expectedStatsForId2.remove(TEST_APP_PKG);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(TEST_APP3_PKG, 0 /* id */);
+ expectedStatsForId1.remove(TEST_APP3_PKG);
+ expectedStatsForId2.remove(TEST_APP3_PKG);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ } finally {
+ connection1.unbind();
+ connection3.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_clearAllCounts() throws Exception {
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+ final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+ // Initially all the counts should be empty
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+ try {
+ ITestReceiver testReceiver1 = connection1.getITestReceiver();
+ ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final Intent intent3 = new Intent().setComponent(new ComponentName(
+ TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+ testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+
+ // Send a broadcast to test-pkg1 with a request to record response and verify
+ // broadcast-sent count gets incremented.
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+ testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_1));
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+ sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+ testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+ buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_2));
+ testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+ expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+ expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+ TEST_RESPONSE_STATS_ID_2));
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+ expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
+ expectedStatsForId1.clear();
+ expectedStatsForId2.clear();
+ assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+ assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+ testReceiver1.cancelAll();
+ testReceiver3.cancelAll();
+ } finally {
+ connection1.unbind();
+ connection3.unbind();
+ }
+ }
+
+ @AppModeFull(reason = "No broadcast message response stats in instant apps")
+ @Test
+ public void testBroadcastResponseStats_mediaNotification() throws Exception {
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 0 /* broadcastCount */,
+ 0 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+ try {
+ ITestReceiver testReceiver = connection.getITestReceiver();
+ testReceiver.cancelAll();
+
+ // Send a broadcast with a request to record response and verify broadcast-sent
+ // count gets incremented.
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+ final Intent intent = new Intent().setComponent(new ComponentName(
+ TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+ sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+ testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+ TEST_NOTIFICATION_CHANNEL_NAME,
+ TEST_NOTIFICATION_CHANNEL_DESC);
+ testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+ buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+ TEST_NOTIFICATION_TEXT_1));
+
+ assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+ 1 /* broadcastCount */,
+ 1 /* notificationPostedCount */,
+ 0 /* notificationUpdatedCount */,
+ 0 /* notificationCancelledCount */);
+
+ testReceiver.cancelAll();
+ } finally {
+ connection.unbind();
+ }
+ }
+
+ private void updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper,
+ String key, String value) {
+ deviceConfigStateHelper.set(key, value);
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ final String actualValue = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+ () -> mUsageStatsManager.getAppStandbyConstant(key),
+ result -> value.equals(result));
+ assertEquals("Error changing the value of " + key, value, actualValue);
+ });
+ }
+
+ private Notification buildNotification(String channelId, int notificationId,
+ String notificationText) {
+ return new Notification.Builder(sContext, channelId)
+ .setSmallIcon(android.R.drawable.ic_info)
+ .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
+ .setContentText(notificationText)
+ .build();
+ }
+
+ private Notification buildMediaNotification(String channelId, int notificationId,
+ String notificationText) {
+ final PendingIntent pendingIntent = PendingIntent.getActivity(sContext,
+ 0 /* requestCode */, new Intent(sContext, this.getClass()),
+ PendingIntent.FLAG_IMMUTABLE);
+ final MediaSession session = new MediaSession(sContext, "test_media");
+ return new Notification.Builder(sContext, channelId)
+ .setSmallIcon(android.R.drawable.ic_menu_day)
+ .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
+ .setContentText(notificationText)
+ .addAction(new Notification.Action.Builder(
+ Icon.createWithResource(sContext, android.R.drawable.ic_media_previous),
+ "previous", pendingIntent).build())
+ .addAction(new Notification.Action.Builder(
+ Icon.createWithResource(sContext, android.R.drawable.ic_media_play),
+ "play", pendingIntent).build())
+ .addAction(new Notification.Action.Builder(
+ Icon.createWithResource(sContext, android.R.drawable.ic_media_next),
+ "next", pendingIntent).build())
+ .setStyle(new Notification.MediaStyle()
+ .setShowActionsInCompactView(0, 1, 2)
+ .setMediaSession(session.getSessionToken()))
+ .build();
+ }
+
+ private void sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)
+ throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
+ sContext.sendBroadcast(intent, null /* receiverPermission */, options);
+ if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for the test app to receive the broadcast");
+ }
+ }
+
+ private void assertResponseStats(String packageName, long id, int... expectedCounts) {
+ final BroadcastResponseStats expectedStats = new BroadcastResponseStats(packageName, id);
+ expectedStats.incrementBroadcastsDispatchedCount(expectedCounts[0]);
+ expectedStats.incrementNotificationsPostedCount(expectedCounts[1]);
+ expectedStats.incrementNotificationsUpdatedCount(expectedCounts[2]);
+ expectedStats.incrementNotificationsCancelledCount(expectedCounts[3]);
+ assertResponseStats(packageName, id, expectedStats);
+ }
+
+ private void assertResponseStats(String packageName, long id,
+ BroadcastResponseStats expectedStats) {
+ List<BroadcastResponseStats> actualStats = mUsageStatsManager
+ .queryBroadcastResponseStats(packageName, id);
+ if (compareStats(expectedStats, actualStats)) {
+ SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
+ }
+
+ actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+ () -> mUsageStatsManager.queryBroadcastResponseStats(packageName, id),
+ result -> compareStats(expectedStats, result));
+ actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
+ final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
+ 1, expectedStats,
+ actualStats.size(), Arrays.toString(actualStats.toArray()));
+ assertTrue(errorMsg, compareStats(expectedStats, actualStats));
+ }
+
+ private void assertResponseStats(long id,
+ ArrayMap<String, BroadcastResponseStats> expectedStats) {
+ // TODO: Call into the above assertResponseStats() method instead of duplicating
+ // the logic.
+ List<BroadcastResponseStats> actualStats = mUsageStatsManager
+ .queryBroadcastResponseStats(null /* packageName */, id);
+ if (compareStats(expectedStats, actualStats)) {
+ SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
+ }
+
+ actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+ () -> mUsageStatsManager.queryBroadcastResponseStats(null /* packageName */, id),
+ result -> compareStats(expectedStats, result));
+ actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
+ final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
+ expectedStats.size(), expectedStats,
+ actualStats.size(), Arrays.toString(actualStats.toArray()));
+ assertTrue(errorMsg, compareStats(expectedStats, actualStats));
+ }
+
+ private boolean compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats,
+ List<BroadcastResponseStats> actualStats) {
+ if (expectedStats.size() != actualStats.size()) {
+ return false;
+ }
+ for (int i = 0; i < actualStats.size(); ++i) {
+ final BroadcastResponseStats actualPackageStats = actualStats.get(i);
+ final String packageName = actualPackageStats.getPackageName();
+ if (!actualPackageStats.equals(expectedStats.get(packageName))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean compareStats(BroadcastResponseStats expectedStats,
+ List<BroadcastResponseStats> actualStats) {
+ if (actualStats.size() > 1) {
+ return false;
+ }
+ final BroadcastResponseStats stats = (actualStats == null || actualStats.isEmpty())
+ ? new BroadcastResponseStats(expectedStats.getPackageName(), expectedStats.getId())
+ : actualStats.get(0);
+ return expectedStats.equals(stats);
+ }
+
+ private TestServiceConnection bindToTestServiceAndGetConnection(String packageName) {
+ final TestServiceConnection
+ connection = new TestServiceConnection(sContext);
+ final Intent intent = new Intent().setComponent(
+ new ComponentName(packageName, TEST_APP_CLASS_SERVICE));
+ sContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+ return connection;
+ }
+
+ private TestServiceConnection bindToTestServiceAndGetConnection() throws Exception {
+ return bindToTestServiceAndGetConnection(TEST_APP_PKG);
+ }
+
+ private void launchTestActivityAndWaitToBeResumed(String pkgName, String className)
+ throws Exception {
+ // Make sure the screen is awake and unlocked. Otherwise, the app activity won't be resumed.
+ wakeUpAndDismissKeyguard();
+
+ final Intent intent = createTestActivityIntent(pkgName, className);
+ final CountDownLatch latch = new CountDownLatch(1);
+ intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
+ sContext.startActivity(intent);
+ if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for the test app activity to be resumed");
+ }
+ }
+
+ private void wakeUpAndDismissKeyguard() throws Exception {
+ mUiDevice.wakeUp();
+ SystemUtil.runShellCommand("wm dismiss-keyguard");
+ }
+
+ private Intent createTestActivityIntent(String pkgName, String className) {
+ final Intent intent = new Intent();
+ intent.setClassName(pkgName, className);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return intent;
+ }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 7497bb7..3cba63c 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -16,20 +16,17 @@
package android.app.usage.cts;
-import static android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS;
import static android.Manifest.permission.POST_NOTIFICATIONS;
import static android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL;
import static android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
-import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
import static android.provider.DeviceConfig.NAMESPACE_APP_STANDBY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
@@ -39,14 +36,11 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.UiAutomation;
-import android.app.usage.BroadcastResponseStats;
import android.app.usage.EventStats;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents.Event;
@@ -60,14 +54,10 @@
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.database.Cursor;
-import android.graphics.drawable.Icon;
-import android.media.session.MediaSession;
import android.net.Uri;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
-import android.os.RemoteCallback;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
@@ -108,7 +98,6 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -150,14 +139,14 @@
private static final String JOBSCHEDULER_RUN_SHELL_COMMAND = "cmd jobscheduler run";
- private static final String TEST_APP_PKG = "android.app.usage.cts.test1";
+ static final String TEST_APP_PKG = "android.app.usage.cts.test1";
- private static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
+ static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
private static final String TEST_APP_CLASS_LOCUS
= "android.app.usage.cts.test1.SomeActivityWithLocus";
- private static final String TEST_APP_CLASS_SERVICE
+ static final String TEST_APP_CLASS_SERVICE
= "android.app.usage.cts.test1.TestService";
- private static final String TEST_APP_CLASS_BROADCAST_RECEIVER
+ static final String TEST_APP_CLASS_BROADCAST_RECEIVER
= "android.app.usage.cts.test1.TestBroadcastReceiver";
private static final String TEST_AUTHORITY = "android.app.usage.cts.test1.provider";
private static final String TEST_APP_CONTENT_URI_STRING = "content://" + TEST_AUTHORITY;
@@ -177,16 +166,8 @@
"notification_seen_duration";
private static final String KEY_NOTIFICATION_SEEN_PROMOTED_BUCKET =
"notification_seen_promoted_bucket";
- private static final String KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS =
- "broadcast_response_window_timeout_ms";
- private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
- "broadcast_response_fg_threshold_state";
private static final int DEFAULT_TIMEOUT_MS = 10_000;
- // For tests that are verifying a certain event doesn't occur, wait for some time
- // to ensure the event doesn't really occur. Otherwise, we cannot be sure if the event didn't
- // occur or the verification was done too early before the event occurred.
- private static final int WAIT_TIME_FOR_NEGATIVE_TESTS_MS = 500;
private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final long MINUTE = TimeUnit.MINUTES.toMillis(1);
@@ -199,9 +180,6 @@
private static final long TIMEOUT_BINDER_SERVICE_SEC = 2;
- private static final long TEST_RESPONSE_STATS_ID_1 = 11;
- private static final long TEST_RESPONSE_STATS_ID_2 = 22;
-
private static final String TEST_NOTIFICATION_CHANNEL_ID = "test-channel-id";
private static final String TEST_NOTIFICATION_CHANNEL_NAME = "test-channel-name";
private static final String TEST_NOTIFICATION_CHANNEL_DESC = "test-channel-description";
@@ -336,21 +314,6 @@
mUiDevice.wait(Until.hasObject(By.clazz(pkgName, className)), TIMEOUT);
}
- private void launchTestActivityAndWaitToBeResumed(String pkgName, String className)
- throws Exception {
- // Make sure the screen is awake and unlocked. Otherwise, the app activity won't be resumed.
- mUiDevice.wakeUp();
- dismissKeyguard();
-
- final Intent intent = createTestActivityIntent(pkgName, className);
- final CountDownLatch latch = new CountDownLatch(1);
- intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
- mContext.startActivity(intent);
- if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
- fail("Timed out waiting for the test app activity to be resumed");
- }
- }
-
private void launchSubActivities(Class<? extends Activity>[] activityClasses) {
for (Class<? extends Activity> clazz : activityClasses) {
launchSubActivity(clazz);
@@ -964,1446 +927,6 @@
}
}
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastOptions_noPermission() throws Exception {
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
- .getUiAutomation();
- uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- setAppOpsMode("ignore");
- try {
- assertThrows(SecurityException.class, () -> {
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- });
- } finally {
- resetAppOpsMode();
- uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testQueryBroadcastResponseStats_noPermission() throws Exception {
- mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-
- final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
- .getUiAutomation();
- uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- setAppOpsMode("ignore");
- try {
- assertThrows(SecurityException.class, () -> {
- mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1);
- });
- } finally {
- resetAppOpsMode();
- uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testClearBroadcastResponseStats_noPermission() throws Exception {
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-
- final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
- .getUiAutomation();
- uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- setAppOpsMode("ignore");
- try {
- assertThrows(SecurityException.class, () -> {
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1);
- });
- } finally {
- resetAppOpsMode();
- uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_broadcastDispatchedCount() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a normal broadcast and verify none of the counts get incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, null);
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Trigger a notification from test app and verify notification-posted count gets
- // incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_notificationPostedCount() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a normal broadcast and verify none of the counts get incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, null);
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Trigger a notification from test app and verify notification-posted count gets
- // incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_notificationUpdatedCount() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Post a notification (before sending any broadcast) and verify none of the counts
- // get incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Update a previously posted notification (change content text) and verify
- // notification-updated count gets incremented.
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_notificationCancelledCount() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Post a notification (before sending any broadcast) and verify none of the counts
- // get incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, null);
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Cancel a previously posted notification (change content text) and verify
- // notification-cancelled count gets incremented.
- testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 1 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_multipleEvents() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a normal broadcast and verify none of the counts get incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, null);
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Trigger a notification from test app and verify notification-posted count gets
- // incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send another broadcast and trigger another notification.
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- testReceiver.postNotification(TEST_NOTIFICATION_ID_2,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_2,
- TEST_NOTIFICATION_TEXT_2));
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 2 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send another broadcast with a different ID and update a previously posted
- // notification.
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 2 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Update/cancel a previously posted notifications and verify there is
- // no change in counts.
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- testReceiver.cancelNotification(TEST_NOTIFICATION_ID_2);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 2 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_clearCounts() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Trigger a notification from test app and verify notification-posted count gets
- // incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Send the broadcast again after clearing counts and verify counts get incremented
- // as expected.
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 1 /* notificationUpdatedCount */,
- 1 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @MediumTest
- @Test
- public void testBroadcastResponseStats_changeResponseWindowDuration() throws Exception {
- final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(2);
- try (DeviceConfigStateHelper deviceConfigStateHelper =
- new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
- updateFlagWithDelay(deviceConfigStateHelper,
- KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
- String.valueOf(broadcastResponseWindowDurationMs));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Trigger a notification from test app and verify notification-posted count gets
- // incremented.
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- SystemClock.sleep(broadcastResponseWindowDurationMs);
- // Trigger a notification from test app but verify counts do not get
- // incremented as the notification is posted after the window durations is expired.
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_appNotInForeground() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- try (DeviceConfigStateHelper deviceConfigStateHelper =
- new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- updateFlagWithDelay(deviceConfigStateHelper,
- KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
- String.valueOf(ActivityManager.PROCESS_STATE_TOP));
-
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Bring the test app to the foreground, send the broadcast again and verify that
- // counts do not change.
- launchTestActivityAndWaitToBeResumed(TEST_APP_PKG, TEST_APP_CLASS);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- // Change the threshold to something lower than TOP, send the broadcast again
- // and verify that counts get incremented.
- updateFlagWithDelay(deviceConfigStateHelper,
- KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
- String.valueOf(ActivityManager.PROCESS_STATE_PERSISTENT));
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- mUiDevice.pressHome();
- // Change the threshold to a process state higher than RECEIVER, send the
- // broadcast again and verify that counts do not change.
- updateFlagWithDelay(deviceConfigStateHelper,
- KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
- String.valueOf(ActivityManager.PROCESS_STATE_HOME));
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 2 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_multiplePackages() throws Exception {
- final ArrayMap<String, BroadcastResponseStats> expectedStats = new ArrayMap<>();
- // Initially all the counts should be empty
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
- final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
- final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
- try {
- ITestReceiver testReceiver1 = connection1.getITestReceiver();
- ITestReceiver testReceiver3 = connection3.getITestReceiver();
- ITestReceiver testReceiver4 = connection4.getITestReceiver();
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- testReceiver4.cancelAll();
-
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent3 = new Intent().setComponent(new ComponentName(
- TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent4 = new Intent().setComponent(new ComponentName(
- TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- expectedStats.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Send a broadcast to test-pkg3 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent3, options.toBundle());
- expectedStats.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStats.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Trigger a notification from test-pkg1 and verify notification-posted count gets
- // incremented.
- testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStats.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Trigger a notification from test-pkg3 and verify notification-posted count gets
- // incremented.
- testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStats.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
- expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStats.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Trigger a notification from test-pkg3 and verify stats remain the same
- testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- // Send a broadcast to test-pkg4 with a request to record response and verify
- // broadcast-send count gets incremented.
- sendBroadcastAndWaitForReceipt(intent4, options.toBundle());
- testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
- expectedStats.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStats.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStats.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
- expectedStats.clear();
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- testReceiver4.cancelAll();
- } finally {
- connection1.unbind();
- connection3.unbind();
- connection4.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_multiplePackages_multipleIds() throws Exception {
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
- // Initially all the counts should be empty
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
- final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
- final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
- try {
- ITestReceiver testReceiver1 = connection1.getITestReceiver();
- ITestReceiver testReceiver3 = connection3.getITestReceiver();
- ITestReceiver testReceiver4 = connection4.getITestReceiver();
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- testReceiver4.cancelAll();
-
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent3 = new Intent().setComponent(new ComponentName(
- TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent4 = new Intent().setComponent(new ComponentName(
- TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-
- final BroadcastOptions options1 = BroadcastOptions.makeBasic();
- options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final BroadcastOptions options2 = BroadcastOptions.makeBasic();
- options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
- // Trigger a notification from test-pkg1 and verify notification-posted count gets
- // incremented.
- testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
- expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_2));
- expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastEvents();
- // Trigger a notification from test-pkg4 and verify notification-posted count gets
- // incremented.
- testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- sendBroadcastAndWaitForReceipt(intent4, options2.toBundle());
- expectedStatsForId2.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
- TEST_RESPONSE_STATS_ID_2));
- expectedStatsForId2.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
-
- testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
- expectedStatsForId2.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
- expectedStatsForId1.clear();
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- testReceiver4.cancelAll();
- } finally {
- connection1.unbind();
- connection3.unbind();
- connection4.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_clearCounts_multiplePackages() throws Exception {
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
- // Initially all the counts should be empty
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
- final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
- try {
- ITestReceiver testReceiver1 = connection1.getITestReceiver();
- ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
-
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent3 = new Intent().setComponent(new ComponentName(
- TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options1 = BroadcastOptions.makeBasic();
- options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final BroadcastOptions options2 = BroadcastOptions.makeBasic();
- options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
- testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
- testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
- expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_2));
- expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
- TEST_RESPONSE_STATS_ID_1);
- expectedStatsForId1.clear();
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
- TEST_RESPONSE_STATS_ID_2);
- expectedStatsForId2.clear();
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- } finally {
- connection1.unbind();
- connection3.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_clearCounts_multipleIds() throws Exception {
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
- // Initially all the counts should be empty
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
- final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
- try {
- ITestReceiver testReceiver1 = connection1.getITestReceiver();
- ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
-
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent3 = new Intent().setComponent(new ComponentName(
- TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options1 = BroadcastOptions.makeBasic();
- options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final BroadcastOptions options2 = BroadcastOptions.makeBasic();
- options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
- testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
- testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
- expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_2));
- expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, 0 /* id */);
- expectedStatsForId1.remove(TEST_APP_PKG);
- expectedStatsForId2.remove(TEST_APP_PKG);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(TEST_APP3_PKG, 0 /* id */);
- expectedStatsForId1.remove(TEST_APP3_PKG);
- expectedStatsForId2.remove(TEST_APP3_PKG);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- } finally {
- connection1.unbind();
- connection3.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_clearAllCounts() throws Exception {
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
- final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
- // Initially all the counts should be empty
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
- final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
- try {
- ITestReceiver testReceiver1 = connection1.getITestReceiver();
- ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
-
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final Intent intent3 = new Intent().setComponent(new ComponentName(
- TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- final BroadcastOptions options1 = BroadcastOptions.makeBasic();
- options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final BroadcastOptions options2 = BroadcastOptions.makeBasic();
- options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
- testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
-
- // Send a broadcast to test-pkg1 with a request to record response and verify
- // broadcast-sent count gets incremented.
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
- testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_1));
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
- sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
- testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
- buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_2));
- testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
- expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
- expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
- TEST_RESPONSE_STATS_ID_2));
- expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
- expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
- expectedStatsForId1.clear();
- expectedStatsForId2.clear();
- assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
- assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
- testReceiver1.cancelAll();
- testReceiver3.cancelAll();
- } finally {
- connection1.unbind();
- connection3.unbind();
- }
- }
-
- @AppModeFull(reason = "No broadcast message response stats in instant apps")
- @Test
- public void testBroadcastResponseStats_mediaNotification() throws Exception {
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 0 /* broadcastCount */,
- 0 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- final TestServiceConnection connection = bindToTestServiceAndGetConnection();
- try {
- ITestReceiver testReceiver = connection.getITestReceiver();
- testReceiver.cancelAll();
-
- // Send a broadcast with a request to record response and verify broadcast-sent
- // count gets incremented.
- final BroadcastOptions options = BroadcastOptions.makeBasic();
- options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
- final Intent intent = new Intent().setComponent(new ComponentName(
- TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
- sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
- testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
- TEST_NOTIFICATION_CHANNEL_NAME,
- TEST_NOTIFICATION_CHANNEL_DESC);
- testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
- buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
- TEST_NOTIFICATION_TEXT_1));
-
- assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
- 1 /* broadcastCount */,
- 1 /* notificationPostedCount */,
- 0 /* notificationUpdatedCount */,
- 0 /* notificationCancelledCount */);
-
- testReceiver.cancelAll();
- } finally {
- connection.unbind();
- }
- }
-
- private void updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper,
- String key, String value) {
- deviceConfigStateHelper.set(key, value);
- SystemUtil.runWithShellPermissionIdentity(() -> {
- final String actualValue = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
- () -> mUsageStatsManager.getAppStandbyConstant(key),
- result -> value.equals(result));
- assertEquals("Error changing the value of " + key, value, actualValue);
- });
- }
-
private Notification buildNotification(String channelId, int notificationId,
String notificationText) {
return new Notification.Builder(mContext, channelId)
@@ -2413,114 +936,6 @@
.build();
}
- private Notification buildMediaNotification(String channelId, int notificationId,
- String notificationText) {
- final PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
- 0 /* requestCode */, new Intent(mContext, this.getClass()),
- PendingIntent.FLAG_IMMUTABLE);
- final MediaSession session = new MediaSession(mContext, "test_media");
- return new Notification.Builder(mContext, channelId)
- .setSmallIcon(android.R.drawable.ic_menu_day)
- .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
- .setContentText(notificationText)
- .addAction(new Notification.Action.Builder(
- Icon.createWithResource(mContext, android.R.drawable.ic_media_previous),
- "previous", pendingIntent).build())
- .addAction(new Notification.Action.Builder(
- Icon.createWithResource(mContext, android.R.drawable.ic_media_play),
- "play", pendingIntent).build())
- .addAction(new Notification.Action.Builder(
- Icon.createWithResource(mContext, android.R.drawable.ic_media_next),
- "next", pendingIntent).build())
- .setStyle(new Notification.MediaStyle()
- .setShowActionsInCompactView(0, 1, 2)
- .setMediaSession(session.getSessionToken()))
- .build();
- }
-
- private void sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)
- throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
- mContext.sendBroadcast(intent, null /* receiverPermission */, options);
- if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
- fail("Timed out waiting for the test app to receive the broadcast");
- }
- }
-
- private void assertResponseStats(String packageName, long id, int... expectedCounts) {
- final BroadcastResponseStats expectedStats = new BroadcastResponseStats(packageName, id);
- expectedStats.incrementBroadcastsDispatchedCount(expectedCounts[0]);
- expectedStats.incrementNotificationsPostedCount(expectedCounts[1]);
- expectedStats.incrementNotificationsUpdatedCount(expectedCounts[2]);
- expectedStats.incrementNotificationsCancelledCount(expectedCounts[3]);
- assertResponseStats(packageName, id, expectedStats);
- }
-
- private void assertResponseStats(String packageName, long id,
- BroadcastResponseStats expectedStats) {
- List<BroadcastResponseStats> actualStats = mUsageStatsManager
- .queryBroadcastResponseStats(packageName, id);
- if (compareStats(expectedStats, actualStats)) {
- SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
- }
-
- actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
- () -> mUsageStatsManager.queryBroadcastResponseStats(packageName, id),
- result -> compareStats(expectedStats, result));
- actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
- final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
- 1, expectedStats,
- actualStats.size(), Arrays.toString(actualStats.toArray()));
- assertTrue(errorMsg, compareStats(expectedStats, actualStats));
- }
-
- private void assertResponseStats(long id,
- ArrayMap<String, BroadcastResponseStats> expectedStats) {
- // TODO: Call into the above assertResponseStats() method instead of duplicating
- // the logic.
- List<BroadcastResponseStats> actualStats = mUsageStatsManager
- .queryBroadcastResponseStats(null /* packageName */, id);
- if (compareStats(expectedStats, actualStats)) {
- SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
- }
-
- actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
- () -> mUsageStatsManager.queryBroadcastResponseStats(null /* packageName */, id),
- result -> compareStats(expectedStats, result));
- actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
- final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
- expectedStats.size(), expectedStats,
- actualStats.size(), Arrays.toString(actualStats.toArray()));
- assertTrue(errorMsg, compareStats(expectedStats, actualStats));
- }
-
- private boolean compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats,
- List<BroadcastResponseStats> actualStats) {
- if (expectedStats.size() != actualStats.size()) {
- return false;
- }
- for (int i = 0; i < actualStats.size(); ++i) {
- final BroadcastResponseStats actualPackageStats = actualStats.get(i);
- final String packageName = actualPackageStats.getPackageName();
- if (!actualPackageStats.equals(expectedStats.get(packageName))) {
- return false;
- }
- }
- return true;
- }
-
- private boolean compareStats(BroadcastResponseStats expectedStats,
- List<BroadcastResponseStats> actualStats) {
- if (actualStats.size() > 1) {
- return false;
- }
- final BroadcastResponseStats stats = (actualStats == null || actualStats.isEmpty())
- ? new BroadcastResponseStats(expectedStats.getPackageName(), expectedStats.getId())
- : actualStats.get(0);
- return expectedStats.equals(stats);
- }
-
@AppModeFull(reason = "No usage events access in instant apps")
@Test
public void testNotificationInterruptionEventsObfuscation() throws Exception {
@@ -3606,7 +2021,7 @@
private TestServiceConnection bindToTestServiceAndGetConnection(String packageName)
throws Exception {
- final TestServiceConnection connection = new TestServiceConnection();
+ final TestServiceConnection connection = new TestServiceConnection(mContext);
final Intent intent = new Intent().setComponent(
new ComponentName(packageName, TEST_APP_CLASS_SERVICE));
mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
@@ -3663,8 +2078,13 @@
}
}
- private class TestServiceConnection implements ServiceConnection {
+ static class TestServiceConnection implements ServiceConnection {
private BlockingQueue<IBinder> mBlockingQueue = new LinkedBlockingQueue<>();
+ private Context mContext;
+
+ TestServiceConnection(Context context) {
+ mContext = context;
+ }
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBlockingQueue.offer(service);