Atom for when fgs accesses appop

statsd logs when an sensitive appop is accessed while a foreground
service is held. These appops include
OP_FINE_LOCATION
OP_COARSE_LOCATION
OP_RECORD_AUDIO
OP_CAMERA

It logs the number of times each of these appops is requested per session
during which the uid holds any foreground service.
Appops requested while the app's process state is TOP are ignored.

Also, the pre-existing ForegroundServiceStateChanged atom has an
additional field that logs whether the fgs is considered 'in-use' in the
context of being allowed while-in-use permissions.

Bug: 149497535
Test: atest UidAtomTests#testForegroundServiceState UidAtomTests#testForegroundServiceAccessAppOp
Test: manually monitor: adb shell cmd stats print-logs && adb logcat -v uid -s statsd | grep "statsd  : {" | egrep '\((60|256)\)'

Change-Id: I991a427dc2ab00399188b10b266ab2d9aa92696d
diff --git a/atoms.proto b/atoms.proto
index 43d0fce..9d3973e 100644
--- a/atoms.proto
+++ b/atoms.proto
@@ -393,6 +393,8 @@
         WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"];
         AppFreezeChanged app_freeze_changed = 254 [(module) = "framework"];
         SnapshotMergeReported snapshot_merge_reported = 255;
+        ForegroundServiceAppOpSessionEnded foreground_service_app_op_session_ended =
+            256  [(module) = "framework"];
         SdkExtensionStatus sdk_extension_status = 354;
     }
 
@@ -3283,12 +3285,12 @@
     ];
 }
 
-/*
+/**
  * Logs foreground service starts and stops.
  * Note that this is not when a service starts or stops, but when it is
  * considered foreground.
  * Logged from
- *     //frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
+ *     frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
  */
 message ForegroundServiceStateChanged {
     optional int32 uid = 1 [(is_uid) = true];
@@ -3300,6 +3302,49 @@
         EXIT = 2;
     }
     optional State state = 3;
+
+    // Whether the fgs is allowed while-in-use permissions, i.e. is considered 'in-use' to the user.
+    // (If the fgs was started while the app wasn't TOP it usually will be denied these permissions)
+    optional bool allow_while_in_use_permission = 4;
+}
+
+/**
+ * Logs the number of times a uid accesses a sensitive AppOp during a foreground service session.
+ * A foreground service session is any continuous period during which the uid holds at least one
+ * foreground service; the atom will be pushed when the uid no longer holds any foreground services.
+ * Accesses initiated while the uid is in the TOP state are ignored.
+ * Sessions with no attempted accesses are not logged.
+ * Logged from
+ *     frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
+ */
+message ForegroundServiceAppOpSessionEnded {
+    optional int32 uid = 1 [(is_uid) = true];
+
+    // The operation's name.
+    // To the extent possible, preserve the mapping from AppOpsManager.OP_ constants.
+    // Only these named ops are actually logged.
+    enum AppOpName {
+        OP_NONE = -1; // Also represents UNKNOWN.
+        OP_COARSE_LOCATION = 0;
+        OP_FINE_LOCATION = 1;
+        OP_CAMERA = 26;
+        OP_RECORD_AUDIO = 27;
+    }
+    optional AppOpName app_op_name = 2 [default = OP_NONE];
+
+    // The uid's permission mode for accessing the AppOp during this fgs session.
+    enum Mode {
+        MODE_UNKNOWN = 0;
+        MODE_ALLOWED = 1; // Always allowed
+        MODE_IGNORED = 2; // Denied
+        MODE_FOREGROUND = 3; // Allow-while-in-use (or allowed-one-time)
+    }
+    optional Mode app_op_mode = 3;
+
+    // Number of times this AppOp was requested and allowed.
+    optional int32 count_ops_accepted = 4;
+    // Number of times this AppOp was requested but denied.
+    optional int32 count_ops_rejected = 5;
 }
 
 /**