log service stats similar to batterystats

service launches
service start/stops

Bug: 113352978
Test: atest
CtsStatsdHostTestCases:android.cts.statsd.validation.BatteryStatsValidationTests#testServiceStartCount
atest
CtsStatsdHostTestCases:android.cts.statsd.validation.BatteryStatsValidationTests#testServiceLaunchCount
Change-Id: I5b213070f8917fb381e3a130b2f8272b4a05978e
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 53d9673..dca47f7 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -148,6 +148,11 @@
         UserRestrictionChanged user_restriction_changed = 96;
         SettingsUIChanged settings_ui_changed = 97;
         ConnectivityStateChanged connectivity_state_changed = 98;
+        // TODO: service state change is very noisy shortly after boot, as well
+        // as at other transitions - coming out of doze, device plugged in, etc.
+        // Consider removing this if it becomes a problem
+        ServiceStateChanged service_state_changed = 99;
+        ServiceLaunchReported service_launch_reported = 100;
     }
 
     // Pulled events will start at field 10000.
@@ -2135,16 +2140,51 @@
  * Logged in StatsCompanionService.java
  */
 message ConnectivityStateChanged {
-    // Id of the network.
-    optional int32 net_id = 1;
+  // Id of the network.
+  optional int32 net_id = 1;
+
+  enum State {
+    UNKNOWN = 0;
+    CONNECTED = 1;
+    DISCONNECTED = 2;
+  }
+  // Connected state of a network.
+  optional State state = 2;
+}
+
+/**
+ * Logs when a service starts and stops.
+ * Logged from:
+ *   services/core/java/com/android/server/am/ActiveServices.java
+ */
+message ServiceStateChanged {
+
+    optional int32 uid = 1 [(is_uid) = true];
+
+    optional string package_name = 2;
+
+    optional string service_name = 3;
 
     enum State {
-        UNKNOWN = 0;
-        CONNECTED = 1;
-        DISCONNECTED = 2;
+        START = 1;
+        STOP = 2;
     }
-    // Connected state of a network.
-    optional State state = 2;
+
+    optional State state = 4;
+}
+
+/**
+ * Logs when a service is launched.
+ * Logged from:
+ *   services/core/java/com/android/server/am/ActiveServices.java
+ */
+message ServiceLaunchReported {
+
+    optional int32 uid = 1 [(is_uid) = true];
+
+    optional string package_name = 2;
+
+    optional string service_name = 3;
 }
 
 //////////////////////////////////////////////////////////////////////
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b5217ad..c660cc6 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -677,6 +677,8 @@
             stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
         }
         r.callStart = false;
+        StatsLog.write(StatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(),
+                r.name.getClassName(), StatsLog.SERVICE_STATE_CHANGED__STATE__START);
         synchronized (r.stats.getBatteryStats()) {
             r.stats.startRunningLocked();
         }
@@ -715,6 +717,9 @@
             service.delayedStop = true;
             return;
         }
+        StatsLog.write(StatsLog.SERVICE_STATE_CHANGED, service.appInfo.uid,
+                service.name.getPackageName(), service.name.getClassName(),
+                StatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
         synchronized (service.stats.getBatteryStats()) {
             service.stats.stopRunningLocked();
         }
@@ -856,6 +861,8 @@
                 }
             }
 
+            StatsLog.write(StatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(),
+                    r.name.getClassName(), StatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.stopRunningLocked();
             }
@@ -2517,6 +2524,8 @@
                 EventLogTags.writeAmCreateService(
                         r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
             }
+            StatsLog.write(StatsLog.SERVICE_LAUNCH_REPORTED, r.appInfo.uid, r.name.getPackageName(),
+                    r.name.getClassName());
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.startLaunchedLocked();
             }