Add subsystem name field to Channel

Bug: 178115561
Test: atest FrameworksServicesTests:PowerStatsServiceTest
Change-Id: I864d9ff729534d81a1f7a89c860a78d659ccc1b2
diff --git a/core/proto/android/server/powerstatsservice.proto b/core/proto/android/server/powerstatsservice.proto
index ec9bc11..0c5a360 100644
--- a/core/proto/android/server/powerstatsservice.proto
+++ b/core/proto/android/server/powerstatsservice.proto
@@ -220,6 +220,9 @@
 
     /** Name of the energy meter channel */
     optional string name = 2;
+
+    /** Name of the subsystem associated with this Channel. Opaque to framework */
+    optional string subsystem = 3;
 }
 
 /**
diff --git a/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java b/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java
index e71b962..766cf9c 100644
--- a/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java
+++ b/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java
@@ -266,6 +266,7 @@
                 long token = pos.start(PowerStatsServiceMeterProto.CHANNEL);
                 pos.write(ChannelProto.ID, channel[i].id);
                 pos.write(ChannelProto.NAME, channel[i].name);
+                pos.write(ChannelProto.SUBSYSTEM, channel[i].subsystem);
                 pos.end(token);
             }
         }
@@ -275,7 +276,8 @@
 
             for (int i = 0; i < channel.length; i++) {
                 Slog.d(TAG, "ChannelId: " + channel[i].id
-                        + ", ChannelName: " + channel[i].name);
+                        + ", ChannelName: " + channel[i].name
+                        + ", ChannelSubsystem: " + channel[i].subsystem);
             }
         }
 
@@ -284,7 +286,8 @@
 
             for (int i = 0; i < channel.length; i++) {
                 pw.println("ChannelId: " + channel[i].id
-                        + ", ChannelName: " + channel[i].name);
+                        + ", ChannelName: " + channel[i].name
+                        + ", ChannelSubsystem: " + channel[i].subsystem);
             }
         }
     }
diff --git a/services/core/jni/com_android_server_powerstats_PowerStatsService.cpp b/services/core/jni/com_android_server_powerstats_PowerStatsService.cpp
index ec2549c..1208354 100644
--- a/services/core/jni/com_android_server_powerstats_PowerStatsService.cpp
+++ b/services/core/jni/com_android_server_powerstats_PowerStatsService.cpp
@@ -33,6 +33,7 @@
 static jmethodID method_C_init;
 static jfieldID field_C_id;
 static jfieldID field_C_name;
+static jfieldID field_C_subsystem;
 
 // EnergyMeasurement
 static jclass class_EM;
@@ -277,11 +278,14 @@
                     channelArray = env->NewObjectArray(railInfo.size(), class_C, nullptr);
                     for (int i = 0; i < railInfo.size(); i++) {
                         jstring name = env->NewStringUTF(railInfo[i].railName.c_str());
+                        jstring subsystem = env->NewStringUTF(railInfo[i].subsysName.c_str());
                         jobject channel = env->NewObject(class_C, method_C_init);
                         env->SetIntField(channel, field_C_id, railInfo[i].index);
                         env->SetObjectField(channel, field_C_name, name);
+                        env->SetObjectField(channel, field_C_subsystem, subsystem);
                         env->SetObjectArrayElement(channelArray, i, channel);
                         env->DeleteLocalRef(name);
+                        env->DeleteLocalRef(subsystem);
                         env->DeleteLocalRef(channel);
                     }
                 }
@@ -359,6 +363,7 @@
     method_C_init = env->GetMethodID(class_C, "<init>", "()V");
     field_C_id = env->GetFieldID(class_C, "id", "I");
     field_C_name = env->GetFieldID(class_C, "name", "Ljava/lang/String;");
+    field_C_subsystem = env->GetFieldID(class_C, "subsystem", "Ljava/lang/String;");
 
     // EnergyMeasurement
     temp = env->FindClass("android/hardware/power/stats/EnergyMeasurement");
diff --git a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java
index b6ae855..84b690f 100644
--- a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java
@@ -67,6 +67,7 @@
     private static final String RESIDENCY_FILENAME = "residencytest";
     private static final String PROTO_OUTPUT_FILENAME = "powerstats.proto";
     private static final String CHANNEL_NAME = "channelname";
+    private static final String CHANNEL_SUBSYSTEM = "channelsubsystem";
     private static final String POWER_ENTITY_NAME = "powerentityinfo";
     private static final String STATE_NAME = "stateinfo";
     private static final String ENERGY_CONSUMER_NAME = "energyconsumer";
@@ -214,6 +215,7 @@
                 energyMeterList[i] = new Channel();
                 energyMeterList[i].id = i;
                 energyMeterList[i].name = new String(CHANNEL_NAME + i);
+                energyMeterList[i].subsystem = new String(CHANNEL_SUBSYSTEM + i);
             }
             return energyMeterList;
         }
@@ -272,6 +274,7 @@
         for (int i = 0; i < pssProto.channel.length; i++) {
             assertTrue(pssProto.channel[i].id == i);
             assertTrue(pssProto.channel[i].name.equals(CHANNEL_NAME + i));
+            assertTrue(pssProto.channel[i].subsystem.equals(CHANNEL_SUBSYSTEM + i));
         }
 
         // Validate the energyMeasurement array matches what was written to on-device storage.
@@ -414,6 +417,7 @@
         for (int i = 0; i < pssProto.channel.length; i++) {
             assertTrue(pssProto.channel[i].id == i);
             assertTrue(pssProto.channel[i].name.equals(CHANNEL_NAME + i));
+            assertTrue(pssProto.channel[i].subsystem.equals(CHANNEL_SUBSYSTEM + i));
         }
 
         // No energyMeasurements should be written to the incident report since it
@@ -547,6 +551,7 @@
         for (int i = 0; i < pssProto.channel.length; i++) {
             assertTrue(pssProto.channel[i].id == i);
             assertTrue(pssProto.channel[i].name.equals(CHANNEL_NAME + i));
+            assertTrue(pssProto.channel[i].subsystem.equals(CHANNEL_SUBSYSTEM + i));
         }
 
         // No energyMeasurements should be written to the incident report since the
diff --git a/tools/powerstats/PowerStatsServiceProtoParser.java b/tools/powerstats/PowerStatsServiceProtoParser.java
index e4135b5..2140954 100644
--- a/tools/powerstats/PowerStatsServiceProtoParser.java
+++ b/tools/powerstats/PowerStatsServiceProtoParser.java
@@ -30,7 +30,7 @@
         for (int i = 0; i < proto.getChannelCount(); i++) {
             ChannelProto energyMeterInfo = proto.getChannel(i);
             csvHeader += "Index,Timestamp,Duration," + energyMeterInfo.getId()
-                + "/" + energyMeterInfo.getName() + ",";
+                + "/" + energyMeterInfo.getName() + "/" + energyMeterInfo.getSubsystem() + ",";
         }
         System.out.println(csvHeader);
     }