Add charging metrics

Change-Id: Icef477c99cb9e53faff852cf6003f912ab8b10c3
Fixes: 78463707
Test: manual
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 7c05b2b..95dc3ab 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5828,6 +5828,30 @@
     // OS: P
     DIALOG_SWITCH_HFP_DEVICES = 1416;
 
+    // ACTION: User has started or ended charging
+    // Type TYPE_DISMISS: Charging has ended
+    // Type TYPE_ACTION: Charging has started, contains fields: battery level
+    // Tag FIELD_BATTERY_LEVEL_START: Battery level at the start
+    // Tag FIELD_BATTERY_LEVEL_END: Battery level at the end
+    // Tag FIELD_CHARGING_DURATION: Time in ms phone was charging
+    // Tag FIELD_PLUG_TYPE: Charging plug type
+    ACTION_CHARGE = 1417;
+
+    // Tag used to determine battery level when device started charging
+    FIELD_BATTERY_LEVEL_START = 1418;
+
+    // Tag used to determine battery level when device ended charging
+    FIELD_BATTERY_LEVEL_END = 1419;
+
+    // Tag used to determine length of charging
+    FIELD_CHARGING_DURATION_MILLIS = 1420;
+
+    // Tag used to determine what type of charging was started/ended
+    // 1 = Plugged AC
+    // 2 = Plugged USB
+    // 3 = Wireless
+    FIELD_PLUG_TYPE = 1421;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d31a605..87647ca 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,36 +16,27 @@
 
 package com.android.server;
 
-import android.app.ActivityManagerInternal;
-import android.database.ContentObserver;
-import android.os.BatteryStats;
-
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.os.ShellCommand;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.DumpUtils;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.Light;
-import com.android.server.lights.LightsManager;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
+import android.hardware.health.V1_0.HealthInfo;
+import android.hardware.health.V2_0.IHealth;
+import android.hardware.health.V2_0.IHealthInfoCallback;
+import android.hardware.health.V2_0.Result;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
-import android.hardware.health.V1_0.HealthInfo;
-import android.hardware.health.V2_0.IHealthInfoCallback;
-import android.hardware.health.V2_0.IHealth;
-import android.hardware.health.V2_0.Result;
+import android.metrics.LogMaker;
 import android.os.BatteryManager;
 import android.os.BatteryManagerInternal;
 import android.os.BatteryProperty;
+import android.os.BatteryStats;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.DropBoxManager;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -54,8 +45,12 @@
 import android.os.IBatteryPropertiesRegistrar;
 import android.os.IBinder;
 import android.os.OsProtoEnums;
+import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UEventObserver;
@@ -67,12 +62,19 @@
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
+import com.android.server.am.BatteryStatsService;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
-
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -171,6 +173,9 @@
     private long mDischargeStartTime;
     private int mDischargeStartLevel;
 
+    private long mChargeStartTime;
+    private int mChargeStartLevel;
+
     private boolean mUpdatesStopped;
 
     private Led mLed;
@@ -185,6 +190,8 @@
     private ArrayDeque<Bundle> mBatteryLevelsEventQueue;
     private long mLastBatteryLevelChangedSentMs;
 
+    private MetricsLogger mMetricsLogger;
+
     public BatteryService(Context context) {
         super(context);
 
@@ -204,6 +211,7 @@
                 com.android.internal.R.integer.config_shutdownBatteryTemperature);
 
         mBatteryLevelsEventQueue = new ArrayDeque<>();
+        mMetricsLogger = new MetricsLogger();
 
         // watch for invalid charger messages if the invalid_charger switch exists
         if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
@@ -476,6 +484,15 @@
             if (mPlugType != mLastPlugType) {
                 if (mLastPlugType == BATTERY_PLUGGED_NONE) {
                     // discharging -> charging
+                    mChargeStartLevel = mHealthInfo.batteryLevel;
+                    mChargeStartTime = SystemClock.elapsedRealtime();
+
+                    final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);
+                    builder.setType(MetricsEvent.TYPE_ACTION);
+                    builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mPlugType);
+                    builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,
+                            mHealthInfo.batteryLevel);
+                    mMetricsLogger.write(builder);
 
                     // There's no value in this data unless we've discharged at least once and the
                     // battery level has changed; so don't log until it does.
@@ -491,6 +508,21 @@
                     // charging -> discharging or we just powered up
                     mDischargeStartTime = SystemClock.elapsedRealtime();
                     mDischargeStartLevel = mHealthInfo.batteryLevel;
+
+                    long chargeDuration = SystemClock.elapsedRealtime() - mChargeStartTime;
+                    if (mChargeStartTime != 0 && chargeDuration != 0) {
+                        final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);
+                        builder.setType(MetricsEvent.TYPE_DISMISS);
+                        builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType);
+                        builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILLIS,
+                                chargeDuration);
+                        builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,
+                                mChargeStartLevel);
+                        builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_END,
+                                mHealthInfo.batteryLevel);
+                        mMetricsLogger.write(builder);
+                    }
+                    mChargeStartTime = 0;
                 }
             }
             if (mHealthInfo.batteryStatus != mLastBatteryStatus ||