CtsStatsdHostTestCases: Fix on batteryless devices.

Two changes are necessary to handle batteryless devices nicely.
  * Battery capacity may be 0.
  * 'cmd battery unplug' alone is not sufficient to put the device
    on simulated "on battery" mode. On P, changing state is by
    default set to "unknown" on batteryless devices. Unless the
    status as well is overridden, on-battery mode is not triggered.

Bug: 126763581
Test: CtsStatsdHosTestCases on Chromebase and phones

Change-Id: I55474a5084e9e069c4dc7c818916238b1221ef4d
Merged-In: I55474a5084e9e069c4dc7c818916238b1221ef4d
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 02bc735..657c0a6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -19,6 +19,7 @@
 import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE;
 
 import android.os.BatteryStatsProto;
+import android.service.battery.BatteryServiceDumpProto;
 import android.service.batterystats.BatteryStatsServiceDumpProto;
 import android.view.DisplayStateEnum;
 
@@ -70,6 +71,7 @@
 
     public static final String UPDATE_CONFIG_CMD = "cmd stats config update";
     public static final String DUMP_REPORT_CMD = "cmd stats dump-report";
+    public static final String DUMP_BATTERY_CMD = "dumpsys battery";
     public static final String DUMP_BATTERYSTATS_CMD = "dumpsys batterystats";
     public static final String REMOVE_CONFIG_CMD = "cmd stats config remove";
     public static final String CONFIG_UID = "1000";
@@ -502,6 +504,14 @@
     }
 
     protected void unplugDevice() throws Exception {
+        // On batteryless devices on Android P or above, the 'unplug' command
+        // alone does not simulate the really unplugged state.
+        //
+        // This is because charging state is left as "unknown". Unless a valid
+        // state like 3 = BatteryManager.BATTERY_STATUS_DISCHARGING is set,
+        // framework does not consider the device as running on battery.
+        setChargingState(3);
+
         getDevice().executeShellCommand("cmd battery unplug");
     }
 
@@ -590,7 +600,7 @@
     }
 
     protected void turnBatterySaverOn() throws Exception {
-        getDevice().executeShellCommand("cmd battery unplug");
+        unplugDevice();
         getDevice().executeShellCommand("settings put global low_power 1");
     }
 
@@ -655,6 +665,21 @@
     }
 
     /**
+     * Determines if the device has a battery.
+     */
+    protected boolean hasBattery() throws Exception {
+        try {
+            BatteryServiceDumpProto batteryProto = getDump(BatteryServiceDumpProto.parser(),
+                    String.join(" ", DUMP_BATTERY_CMD, "--proto"));
+            LogUtil.CLog.d("Got battery service dump:\n " + batteryProto.toString());
+            return batteryProto.getIsPresent();
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            LogUtil.CLog.e("Failed to dump batteryservice proto");
+            throw (e);
+        }
+    }
+
+    /**
      * Determines if the device has |file|.
      */
     protected boolean doesFileExist(String file) throws Exception {
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index cc3b47c..34adcd1 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -338,6 +338,7 @@
             return;
         }
         if (!hasFeature(FEATURE_WATCH, false)) return;
+        if (!hasBattery()) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
             .setField(Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER)
@@ -365,6 +366,7 @@
             return;
         }
         if (!hasFeature(FEATURE_WATCH, false)) return;
+        if (!hasBattery()) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
                 .setField(Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER)