Loading core/java/android/content/Context.java +11 −0 Original line number Diff line number Diff line Loading @@ -3384,6 +3384,7 @@ public abstract class Context { /** @hide */ @StringDef(suffix = { "_SERVICE" }, value = { POWER_SERVICE, //@hide: POWER_STATS_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE, ACCOUNT_SERVICE, Loading Loading @@ -3724,6 +3725,16 @@ public abstract class Context { */ public static final String POWER_SERVICE = "power"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.os.PowerStatsService} for accessing power stats * service. * * @see #getSystemService(String) * @hide */ public static final String POWER_STATS_SERVICE = "power_stats"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.os.RecoverySystem} for accessing the recovery system Loading core/proto/android/os/incident.proto +6 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import "frameworks/base/core/proto/android/server/fingerprint.proto"; import "frameworks/base/core/proto/android/server/jobscheduler.proto"; import "frameworks/base/core/proto/android/server/location/context_hub.proto"; import "frameworks/base/core/proto/android/server/powermanagerservice.proto"; import "frameworks/base/core/proto/android/server/powerstatsservice.proto"; import "frameworks/base/core/proto/android/server/rolemanagerservice.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/service/appwidget.proto"; Loading Loading @@ -510,6 +511,11 @@ message IncidentProto { (section).args = "sensorservice --proto" ]; optional com.android.server.powerstats.PowerStatsServiceProto powerstats = 3054 [ (section).type = SECTION_DUMPSYS, (section).args = "power_stats --proto" ]; // Dumps in text format (on userdebug and eng builds only): 4000 ~ 4999 optional android.util.TextDumpProto textdump_wifi = 4000 [ (section).type = SECTION_TEXT_DUMPSYS, Loading core/proto/android/server/powerstatsservice.proto 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package com.android.server.powerstats; option java_multiple_files = true; message IncidentReportProto { /** Section number matches that in incident.proto */ optional PowerStatsServiceProto incident_report = 3054; } message PowerStatsServiceProto { repeated RailInfoProto rail_info = 1; repeated EnergyDataProto energy_data = 2; } /** * Rail information: * Reports information related to the rails being monitored. */ message RailInfoProto { /** Index corresponding to the rail */ optional int32 index = 1; /** Name of the rail (opaque to the framework) */ optional string rail_name = 2; /** Name of the subsystem to which this rail belongs (opaque to the framework) */ optional string subsys_name = 3; /** Hardware sampling rate */ optional int32 sampling_rate = 4; } /** * Rail level energy measurements: * Reports accumulated energy since boot on each rail. */ message EnergyDataProto { /** * Index corresponding to the rail. This index matches * the index returned in RailInfo */ optional int32 index = 1; /** Time since device boot(CLOCK_BOOTTIME) in milli-seconds */ optional int64 timestamp_ms = 2; /** Accumulated energy since device boot in microwatt-seconds (uWs) */ optional int64 energy_uws = 3; } services/core/java/com/android/server/powerstats/BatteryTrigger.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.powerstats; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.util.Log; /** * BatteryTrigger instantiates a BroadcastReceiver that listens for changes * to the battery. When the battery level drops by 1% a message is sent to * the PowerStatsLogger to log the rail energy data to on-device storage. */ public final class BatteryTrigger extends PowerStatsLogTrigger { private static final String TAG = BatteryTrigger.class.getSimpleName(); private static final boolean DEBUG = false; private int mBatteryLevel = 0; private final BroadcastReceiver mBatteryLevelReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case Intent.ACTION_BATTERY_CHANGED: int newBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); if (newBatteryLevel < mBatteryLevel) { if (DEBUG) Log.d(TAG, "Battery level dropped. Log rail data"); logPowerStatsData(); } mBatteryLevel = newBatteryLevel; break; } } }; public BatteryTrigger(Context context, PowerStatsLogger powerStatsLogger, boolean triggerEnabled) { super(context, powerStatsLogger); if (triggerEnabled) { IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryStatus = mContext.registerReceiver(mBatteryLevelReceiver, filter); mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); } } } services/core/java/com/android/server/powerstats/PowerStatsData.java 0 → 100644 +286 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.powerstats; import android.util.Log; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import android.util.proto.WireTypeMismatchException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * PowerStatsData is a class that performs two operations: * 1) Unpacks serialized protobuf byte arrays, as defined in powerstatsservice.proto, * into RailInfo or EnergyData object arrays. * * 2) Packs RailInfo or EnergyData object arrays in protobuf byte arrays as * defined in powerstatsservice.proto. * * Inside frameworks, proto source is generated with the genstream option * and therefore the getter/setter helper functions are not available. * The protos need to be packed/unpacked in a more manual way using * ProtoOutputStream/ProtoInputStream. */ public class PowerStatsData { private static final String TAG = PowerStatsData.class.getSimpleName(); private List<Data> mDataList; public PowerStatsData(ProtoInputStream pis) throws IOException { mDataList = new ArrayList<Data>(); unpackProto(pis); } public PowerStatsData(Data[] data) { mDataList = new ArrayList<Data>(Arrays.asList(data)); } private void unpackProto(ProtoInputStream pis) throws IOException { long token; while (true) { try { switch (pis.nextField()) { case (int) PowerStatsServiceProto.RAIL_INFO: token = pis.start(PowerStatsServiceProto.RAIL_INFO); mDataList.add(new RailInfo(pis)); pis.end(token); break; case (int) PowerStatsServiceProto.ENERGY_DATA: token = pis.start(PowerStatsServiceProto.ENERGY_DATA); mDataList.add(new EnergyData(pis)); pis.end(token); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in proto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in proto: " + ProtoUtils.currentFieldToString(pis)); } } } /** * Write this object to an output stream in protobuf format. * * @param pos ProtoOutputStream of file where data is to be written. Data is * written in protobuf format as defined by powerstatsservice.proto. */ public void toProto(ProtoOutputStream pos) { long token; for (Data data : mDataList) { if (data instanceof RailInfo) { token = pos.start(PowerStatsServiceProto.RAIL_INFO); } else { token = pos.start(PowerStatsServiceProto.ENERGY_DATA); } data.toProto(pos); pos.end(token); } } /** * Convert mDataList to proto format and return the serialized byte array. * * @return byte array containing a serialized protobuf of mDataList. */ public byte[] getProtoBytes() { ProtoOutputStream pos = new ProtoOutputStream(); long token; for (Data data : mDataList) { if (data instanceof RailInfo) { token = pos.start(PowerStatsServiceProto.RAIL_INFO); } else { token = pos.start(PowerStatsServiceProto.ENERGY_DATA); } data.toProto(pos); pos.end(token); } return pos.getBytes(); } /** * Print this object to logcat. */ public void print() { for (Data data : mDataList) { Log.d(TAG, data.toString()); } } /** * RailInfo is a class that stores a description for an individual ODPM * rail. It provides functionality to unpack a RailInfo object from a * serialized protobuf byte array, and to pack a RailInfo object into * a ProtoOutputStream. */ public static class RailInfo extends Data { public String mRailName; public String mSubSysName; public long mSamplingRate; public RailInfo(ProtoInputStream pis) throws IOException { unpackProto(pis); } public RailInfo(long index, String railName, String subSysName, long samplingRate) { mIndex = index; mRailName = railName; mSubSysName = subSysName; mSamplingRate = samplingRate; } @Override protected void unpackProto(ProtoInputStream pis) throws IOException { while (true) { try { switch (pis.nextField()) { case (int) RailInfoProto.INDEX: mIndex = pis.readInt(RailInfoProto.INDEX); break; case (int) RailInfoProto.RAIL_NAME: mRailName = pis.readString(RailInfoProto.RAIL_NAME); break; case (int) RailInfoProto.SUBSYS_NAME: mSubSysName = pis.readString(RailInfoProto.SUBSYS_NAME); break; case (int) RailInfoProto.SAMPLING_RATE: mSamplingRate = pis.readInt(RailInfoProto.SAMPLING_RATE); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in RailInfoProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in RailInfoProto: " + ProtoUtils.currentFieldToString(pis)); } } } @Override public void toProto(ProtoOutputStream pos) { pos.write(RailInfoProto.INDEX, mIndex); pos.write(RailInfoProto.RAIL_NAME, mRailName); pos.write(RailInfoProto.SUBSYS_NAME, mSubSysName); pos.write(RailInfoProto.SAMPLING_RATE, mSamplingRate); } @Override public String toString() { return String.format("Index = " + mIndex + ", RailName = " + mRailName + ", SubSysName = " + mSubSysName + ", SamplingRate = " + mSamplingRate); } } /** * EnergyData is a class that stores an energy (uWs) data reading for an * individual ODPM rail. It provides functionality to unpack an EnergyData * object from a serialized protobuf byte array, and to pack an EnergyData * object into a ProtoOutputStream. */ public static class EnergyData extends Data { public long mTimestampMs; public long mEnergyUWs; public EnergyData(ProtoInputStream pis) throws IOException { unpackProto(pis); } public EnergyData(long index, long timestampMs, long energyUWs) { mIndex = index; mTimestampMs = timestampMs; mEnergyUWs = energyUWs; } @Override protected void unpackProto(ProtoInputStream pis) throws IOException { while (true) { try { switch (pis.nextField()) { case (int) EnergyDataProto.INDEX: mIndex = pis.readInt(EnergyDataProto.INDEX); break; case (int) EnergyDataProto.TIMESTAMP_MS: mTimestampMs = pis.readLong(EnergyDataProto.TIMESTAMP_MS); break; case (int) EnergyDataProto.ENERGY_UWS: mEnergyUWs = pis.readLong(EnergyDataProto.ENERGY_UWS); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in EnergyDataProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in EnergyDataProto: " + ProtoUtils.currentFieldToString(pis)); } } } @Override protected void toProto(ProtoOutputStream pos) { pos.write(EnergyDataProto.INDEX, mIndex); pos.write(EnergyDataProto.TIMESTAMP_MS, mTimestampMs); pos.write(EnergyDataProto.ENERGY_UWS, mEnergyUWs); } @Override public String toString() { return String.format("Index = " + mIndex + ", Timestamp (ms) = " + mTimestampMs + ", Energy (uWs) = " + mEnergyUWs); } } private abstract static class Data { public long mIndex; protected abstract void unpackProto(ProtoInputStream pis) throws IOException; protected abstract void toProto(ProtoOutputStream pos); } } Loading
core/java/android/content/Context.java +11 −0 Original line number Diff line number Diff line Loading @@ -3384,6 +3384,7 @@ public abstract class Context { /** @hide */ @StringDef(suffix = { "_SERVICE" }, value = { POWER_SERVICE, //@hide: POWER_STATS_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE, ACCOUNT_SERVICE, Loading Loading @@ -3724,6 +3725,16 @@ public abstract class Context { */ public static final String POWER_SERVICE = "power"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.os.PowerStatsService} for accessing power stats * service. * * @see #getSystemService(String) * @hide */ public static final String POWER_STATS_SERVICE = "power_stats"; /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.os.RecoverySystem} for accessing the recovery system Loading
core/proto/android/os/incident.proto +6 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import "frameworks/base/core/proto/android/server/fingerprint.proto"; import "frameworks/base/core/proto/android/server/jobscheduler.proto"; import "frameworks/base/core/proto/android/server/location/context_hub.proto"; import "frameworks/base/core/proto/android/server/powermanagerservice.proto"; import "frameworks/base/core/proto/android/server/powerstatsservice.proto"; import "frameworks/base/core/proto/android/server/rolemanagerservice.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/service/appwidget.proto"; Loading Loading @@ -510,6 +511,11 @@ message IncidentProto { (section).args = "sensorservice --proto" ]; optional com.android.server.powerstats.PowerStatsServiceProto powerstats = 3054 [ (section).type = SECTION_DUMPSYS, (section).args = "power_stats --proto" ]; // Dumps in text format (on userdebug and eng builds only): 4000 ~ 4999 optional android.util.TextDumpProto textdump_wifi = 4000 [ (section).type = SECTION_TEXT_DUMPSYS, Loading
core/proto/android/server/powerstatsservice.proto 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package com.android.server.powerstats; option java_multiple_files = true; message IncidentReportProto { /** Section number matches that in incident.proto */ optional PowerStatsServiceProto incident_report = 3054; } message PowerStatsServiceProto { repeated RailInfoProto rail_info = 1; repeated EnergyDataProto energy_data = 2; } /** * Rail information: * Reports information related to the rails being monitored. */ message RailInfoProto { /** Index corresponding to the rail */ optional int32 index = 1; /** Name of the rail (opaque to the framework) */ optional string rail_name = 2; /** Name of the subsystem to which this rail belongs (opaque to the framework) */ optional string subsys_name = 3; /** Hardware sampling rate */ optional int32 sampling_rate = 4; } /** * Rail level energy measurements: * Reports accumulated energy since boot on each rail. */ message EnergyDataProto { /** * Index corresponding to the rail. This index matches * the index returned in RailInfo */ optional int32 index = 1; /** Time since device boot(CLOCK_BOOTTIME) in milli-seconds */ optional int64 timestamp_ms = 2; /** Accumulated energy since device boot in microwatt-seconds (uWs) */ optional int64 energy_uws = 3; }
services/core/java/com/android/server/powerstats/BatteryTrigger.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.powerstats; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.util.Log; /** * BatteryTrigger instantiates a BroadcastReceiver that listens for changes * to the battery. When the battery level drops by 1% a message is sent to * the PowerStatsLogger to log the rail energy data to on-device storage. */ public final class BatteryTrigger extends PowerStatsLogTrigger { private static final String TAG = BatteryTrigger.class.getSimpleName(); private static final boolean DEBUG = false; private int mBatteryLevel = 0; private final BroadcastReceiver mBatteryLevelReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case Intent.ACTION_BATTERY_CHANGED: int newBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); if (newBatteryLevel < mBatteryLevel) { if (DEBUG) Log.d(TAG, "Battery level dropped. Log rail data"); logPowerStatsData(); } mBatteryLevel = newBatteryLevel; break; } } }; public BatteryTrigger(Context context, PowerStatsLogger powerStatsLogger, boolean triggerEnabled) { super(context, powerStatsLogger); if (triggerEnabled) { IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryStatus = mContext.registerReceiver(mBatteryLevelReceiver, filter); mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); } } }
services/core/java/com/android/server/powerstats/PowerStatsData.java 0 → 100644 +286 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.powerstats; import android.util.Log; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import android.util.proto.WireTypeMismatchException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * PowerStatsData is a class that performs two operations: * 1) Unpacks serialized protobuf byte arrays, as defined in powerstatsservice.proto, * into RailInfo or EnergyData object arrays. * * 2) Packs RailInfo or EnergyData object arrays in protobuf byte arrays as * defined in powerstatsservice.proto. * * Inside frameworks, proto source is generated with the genstream option * and therefore the getter/setter helper functions are not available. * The protos need to be packed/unpacked in a more manual way using * ProtoOutputStream/ProtoInputStream. */ public class PowerStatsData { private static final String TAG = PowerStatsData.class.getSimpleName(); private List<Data> mDataList; public PowerStatsData(ProtoInputStream pis) throws IOException { mDataList = new ArrayList<Data>(); unpackProto(pis); } public PowerStatsData(Data[] data) { mDataList = new ArrayList<Data>(Arrays.asList(data)); } private void unpackProto(ProtoInputStream pis) throws IOException { long token; while (true) { try { switch (pis.nextField()) { case (int) PowerStatsServiceProto.RAIL_INFO: token = pis.start(PowerStatsServiceProto.RAIL_INFO); mDataList.add(new RailInfo(pis)); pis.end(token); break; case (int) PowerStatsServiceProto.ENERGY_DATA: token = pis.start(PowerStatsServiceProto.ENERGY_DATA); mDataList.add(new EnergyData(pis)); pis.end(token); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in proto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in proto: " + ProtoUtils.currentFieldToString(pis)); } } } /** * Write this object to an output stream in protobuf format. * * @param pos ProtoOutputStream of file where data is to be written. Data is * written in protobuf format as defined by powerstatsservice.proto. */ public void toProto(ProtoOutputStream pos) { long token; for (Data data : mDataList) { if (data instanceof RailInfo) { token = pos.start(PowerStatsServiceProto.RAIL_INFO); } else { token = pos.start(PowerStatsServiceProto.ENERGY_DATA); } data.toProto(pos); pos.end(token); } } /** * Convert mDataList to proto format and return the serialized byte array. * * @return byte array containing a serialized protobuf of mDataList. */ public byte[] getProtoBytes() { ProtoOutputStream pos = new ProtoOutputStream(); long token; for (Data data : mDataList) { if (data instanceof RailInfo) { token = pos.start(PowerStatsServiceProto.RAIL_INFO); } else { token = pos.start(PowerStatsServiceProto.ENERGY_DATA); } data.toProto(pos); pos.end(token); } return pos.getBytes(); } /** * Print this object to logcat. */ public void print() { for (Data data : mDataList) { Log.d(TAG, data.toString()); } } /** * RailInfo is a class that stores a description for an individual ODPM * rail. It provides functionality to unpack a RailInfo object from a * serialized protobuf byte array, and to pack a RailInfo object into * a ProtoOutputStream. */ public static class RailInfo extends Data { public String mRailName; public String mSubSysName; public long mSamplingRate; public RailInfo(ProtoInputStream pis) throws IOException { unpackProto(pis); } public RailInfo(long index, String railName, String subSysName, long samplingRate) { mIndex = index; mRailName = railName; mSubSysName = subSysName; mSamplingRate = samplingRate; } @Override protected void unpackProto(ProtoInputStream pis) throws IOException { while (true) { try { switch (pis.nextField()) { case (int) RailInfoProto.INDEX: mIndex = pis.readInt(RailInfoProto.INDEX); break; case (int) RailInfoProto.RAIL_NAME: mRailName = pis.readString(RailInfoProto.RAIL_NAME); break; case (int) RailInfoProto.SUBSYS_NAME: mSubSysName = pis.readString(RailInfoProto.SUBSYS_NAME); break; case (int) RailInfoProto.SAMPLING_RATE: mSamplingRate = pis.readInt(RailInfoProto.SAMPLING_RATE); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in RailInfoProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in RailInfoProto: " + ProtoUtils.currentFieldToString(pis)); } } } @Override public void toProto(ProtoOutputStream pos) { pos.write(RailInfoProto.INDEX, mIndex); pos.write(RailInfoProto.RAIL_NAME, mRailName); pos.write(RailInfoProto.SUBSYS_NAME, mSubSysName); pos.write(RailInfoProto.SAMPLING_RATE, mSamplingRate); } @Override public String toString() { return String.format("Index = " + mIndex + ", RailName = " + mRailName + ", SubSysName = " + mSubSysName + ", SamplingRate = " + mSamplingRate); } } /** * EnergyData is a class that stores an energy (uWs) data reading for an * individual ODPM rail. It provides functionality to unpack an EnergyData * object from a serialized protobuf byte array, and to pack an EnergyData * object into a ProtoOutputStream. */ public static class EnergyData extends Data { public long mTimestampMs; public long mEnergyUWs; public EnergyData(ProtoInputStream pis) throws IOException { unpackProto(pis); } public EnergyData(long index, long timestampMs, long energyUWs) { mIndex = index; mTimestampMs = timestampMs; mEnergyUWs = energyUWs; } @Override protected void unpackProto(ProtoInputStream pis) throws IOException { while (true) { try { switch (pis.nextField()) { case (int) EnergyDataProto.INDEX: mIndex = pis.readInt(EnergyDataProto.INDEX); break; case (int) EnergyDataProto.TIMESTAMP_MS: mTimestampMs = pis.readLong(EnergyDataProto.TIMESTAMP_MS); break; case (int) EnergyDataProto.ENERGY_UWS: mEnergyUWs = pis.readLong(EnergyDataProto.ENERGY_UWS); break; case ProtoInputStream.NO_MORE_FIELDS: return; default: Log.e(TAG, "Unhandled field in EnergyDataProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Log.e(TAG, "Wire Type mismatch in EnergyDataProto: " + ProtoUtils.currentFieldToString(pis)); } } } @Override protected void toProto(ProtoOutputStream pos) { pos.write(EnergyDataProto.INDEX, mIndex); pos.write(EnergyDataProto.TIMESTAMP_MS, mTimestampMs); pos.write(EnergyDataProto.ENERGY_UWS, mEnergyUWs); } @Override public String toString() { return String.format("Index = " + mIndex + ", Timestamp (ms) = " + mTimestampMs + ", Energy (uWs) = " + mEnergyUWs); } } private abstract static class Data { public long mIndex; protected abstract void unpackProto(ProtoInputStream pis) throws IOException; protected abstract void toProto(ProtoOutputStream pos); } }