CTS tests for Statsd AppOps puller.
New version of test also test correctness of
logging operation ids.
Bug:143519689
Test: atest android.cts.statsd.atom.UidAtomTests#testAppOps
Test: atest android.cts.statsd.atom.UidAtomTests#testForegroundServiceAccessAppOp
Exempt-From-Owner-Approval: approved in rvc-dev
Change-Id: I20120e7e8556ef16ddee4b46b9ebd7825ef39988
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 7458be5..fa74b7f 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -60,6 +60,7 @@
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.util.ArrayMap;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -70,6 +71,7 @@
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -78,6 +80,108 @@
private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd";
+ private static final Map<String, Integer> APP_OPS_ENUM_MAP = new ArrayMap<>();
+ static {
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_COARSE_LOCATION, 0);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_FINE_LOCATION, 1);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GPS, 2);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_VIBRATE, 3);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CONTACTS, 4);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CONTACTS, 5);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALL_LOG, 6);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALL_LOG, 7);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALENDAR, 8);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALENDAR, 9);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WIFI_SCAN, 10);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_POST_NOTIFICATION, 11);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NEIGHBORING_CELLS, 12);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CALL_PHONE, 13);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_SMS, 14);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SMS, 15);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_SMS, 16);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_EMERGENCY_BROADCAST, 17);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_MMS, 18);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_WAP_PUSH, 19);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SEND_SMS, 20);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_ICC_SMS, 21);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_ICC_SMS, 22);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SETTINGS, 23);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, 24);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS, 25);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CAMERA, 26);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECORD_AUDIO, 27);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PLAY_AUDIO, 28);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CLIPBOARD, 29);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CLIPBOARD, 30);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_MEDIA_BUTTONS, 31);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_AUDIO_FOCUS, 32);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MASTER_VOLUME, 33);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_VOICE_VOLUME, 34);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_RING_VOLUME, 35);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MEDIA_VOLUME, 36);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ALARM_VOLUME, 37);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_NOTIFICATION_VOLUME, 38);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_BLUETOOTH_VOLUME, 39);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WAKE_LOCK, 40);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_LOCATION, 41);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION, 42);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_USAGE_STATS, 43);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MUTE_MICROPHONE, 44);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TOAST_WINDOW, 45);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROJECT_MEDIA, 46);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_VPN, 47);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_WALLPAPER, 48);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_STRUCTURE, 49);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_SCREENSHOT, 50);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_STATE, 51);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ADD_VOICEMAIL, 52);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_SIP, 53);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROCESS_OUTGOING_CALLS, 54);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_FINGERPRINT, 55);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BODY_SENSORS, 56);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 57);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MOCK_LOCATION, 58);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, 59);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE, 60);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TURN_SCREEN_ON, 61);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_ACCOUNTS, 62);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_IN_BACKGROUND, 63);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 64);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, 65);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES, 66);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, 67);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INSTANT_APP_START_FOREGROUND, 68);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ANSWER_PHONE_CALLS, 69);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, 70);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, 71);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, 72);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE, 73);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCEPT_HANDOVER, 74);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, 75);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_START_FOREGROUND, 76);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BLUETOOTH_SCAN, 77);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_BIOMETRIC, 78);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVITY_RECOGNITION, 79);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS, 80);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_AUDIO, 81);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_AUDIO, 82);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_VIDEO, 83);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO, 84);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_IMAGES, 85);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES, 86);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LEGACY_STORAGE, 87);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, 88);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, 89);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_MEDIA_LOCATION, 90);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_QUERY_ALL_PACKAGES, 91);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE, 92);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INTERACT_ACROSS_PROFILES, 93);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, 94);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LOADER_USAGE_STATS, 95);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_CALL_AUDIO, 96);
+ APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 97);
+ }
+
@Test
public void testAudioState() {
// TODO: This should surely be getTargetContext(), here and everywhere, but test first.
@@ -244,6 +348,7 @@
// No foreground service session
noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+ sleep(500);
// Foreground service session 1
context.startService(fgsIntent);
@@ -255,14 +360,34 @@
noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA, true);
noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, false);
noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, true);
+ sleep(500);
context.stopService(fgsIntent);
// No foreground service session
noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+ sleep(500);
// TODO(b/149098800): Start fgs a second time and log OPSTR_CAMERA again
}
+ @Test
+ public void testAppOps() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+
+ String[] opsList = appOpsManager.getOpStrs();
+
+ for (int i = 0; i < opsList.length; i++) {
+ String op = opsList[i];
+ int noteCount = APP_OPS_ENUM_MAP.getOrDefault(op, opsList.length) + 1;
+ for (int j = 0; j < noteCount; j++) {
+ try {
+ noteAppOp(appOpsManager, opsList[i], true);
+ } catch (SecurityException e) {}
+ }
+ }
+ }
+
/** @param doNote true if should use noteOp; false if should use startOp. */
private void noteAppOp(AppOpsManager appOpsManager, String opStr, boolean doNote) {
if (doNote) {
@@ -274,7 +399,6 @@
(aom) -> aom.startOp(opStr, android.os.Process.myUid(),
MY_PACKAGE_NAME, null, "statsdTest"));
}
- sleep(500);
}
/** Check if service is running. */
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 039068c..10c4f7c 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.app.AppOpEnum;
import android.net.wifi.WifiModeEnum;
import android.os.WakeLockLevelEnum;
import android.server.ErrorSource;
@@ -30,6 +31,7 @@
import com.android.os.AtomsProto.AppOps;
import com.android.os.AtomsProto.AppStartOccurred;
import com.android.os.AtomsProto.Atom;
+import com.android.os.AtomsProto.AttributedAppOps;
import com.android.os.AtomsProto.AttributionNode;
import com.android.os.AtomsProto.AudioStateChanged;
import com.android.os.AtomsProto.BinderCalls;
@@ -85,8 +87,13 @@
private static final String TAG = "Statsd.UidAtomTests";
+ private static final String TEST_PACKAGE_NAME = "com.android.server.cts.device.statsd";
+
private static final boolean DAVEY_ENABLED = false;
+ private static final int NUM_APP_OPS = AttributedAppOps.getDefaultInstance().getOp().
+ getDescriptorForType().getValues().size() - 1;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -171,7 +178,7 @@
.isEqualTo(AppCrashOccurred.InstantApp.FALSE_VALUE);
assertThat(atom.getForegroundState().getNumber())
.isEqualTo(AppCrashOccurred.ForegroundState.FOREGROUND_VALUE);
- assertThat(atom.getPackageName()).isEqualTo("com.android.server.cts.device.statsd");
+ assertThat(atom.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
}
public void testAppStartOccurred() throws Exception {
@@ -189,7 +196,7 @@
List<EventMetricData> data = getEventMetricDataList();
AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred();
- assertThat(atom.getPkgName()).isEqualTo("com.android.server.cts.device.statsd");
+ assertThat(atom.getPkgName()).isEqualTo(TEST_PACKAGE_NAME);
assertThat(atom.getActivityName())
.isEqualTo("com.android.server.cts.device.statsd.StatsdCtsForegroundActivity");
assertThat(atom.getIsInstantApp()).isFalse();
@@ -570,22 +577,21 @@
final int count = acceptances + rejections;
int expectedCount = 0;
switch (opName) {
- case ForegroundServiceAppOpSessionEnded.AppOpName.OP_CAMERA_VALUE:
+ case AppOpEnum.APP_OP_CAMERA_VALUE:
expectedCount = 2;
break;
- case ForegroundServiceAppOpSessionEnded.AppOpName.OP_FINE_LOCATION_VALUE:
+ case AppOpEnum.APP_OP_FINE_LOCATION_VALUE:
expectedCount = 1;
break;
- case ForegroundServiceAppOpSessionEnded.AppOpName.OP_RECORD_AUDIO_VALUE:
+ case AppOpEnum.APP_OP_RECORD_AUDIO_VALUE:
expectedCount = 2;
break;
- case ForegroundServiceAppOpSessionEnded.AppOpName.OP_COARSE_LOCATION_VALUE:
+ case AppOpEnum.APP_OP_COARSE_LOCATION_VALUE:
// fall-through
default:
fail("Unexpected opName " + opName);
}
assertWithMessage("Wrong count for " + opName).that(count).isEqualTo(expectedCount);
-
}
}
@@ -1560,20 +1566,38 @@
StatsdConfig.Builder config = getPulledConfig();
addGaugeAtomWithDimensions(config, Atom.APP_OPS_FIELD_NUMBER, null);
uploadConfig(config);
+
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testAppOps");
Thread.sleep(WAIT_TIME_SHORT);
// Pull a report
setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_SHORT);
- long accessInstancesRecorded = 0;
-
- for (Atom atom : getGaugeMetricDataList()) {
- AppOps appOps = atom.getAppOps();
- accessInstancesRecorded += appOps.getTrustedForegroundGrantedCount();
+ ArrayList<Integer> expectedOps = new ArrayList<>();
+ for (int i = 0; i < NUM_APP_OPS; i++) {
+ expectedOps.add(i);
}
- assertThat(accessInstancesRecorded).isAtLeast(1l);
+ for (Atom atom : getGaugeMetricDataList()) {
+
+ AppOps appOps = atom.getAppOps();
+ if (appOps.getPackageName().equals(TEST_PACKAGE_NAME)) {
+ if (appOps.getOpId().getNumber() == -1) {
+ continue;
+ }
+ long totalNoted = appOps.getTrustedForegroundGrantedCount()
+ + appOps.getTrustedBackgroundGrantedCount()
+ + appOps.getTrustedForegroundRejectedCount()
+ + appOps.getTrustedBackgroundRejectedCount();
+ assertWithMessage("Operation in APP_OPS_ENUM_MAP: " + appOps.getOpId().getNumber())
+ .that(totalNoted - 1).isEqualTo(appOps.getOpId().getNumber());
+ assertWithMessage("Unexpected Op reported").that(expectedOps).contains(
+ appOps.getOpId().getNumber());
+ expectedOps.remove(expectedOps.indexOf(appOps.getOpId().getNumber()));
+ }
+ }
+ assertWithMessage("Logging app op ids are missing in report.").that(expectedOps).isEmpty();
}
public void testANROccurred() throws Exception {