From 05013b377266f9e4e2651c6aa819960479dc3676 Mon Sep 17 00:00:00 2001 From: Chenjie Yu Date: Tue, 21 Nov 2017 10:21:41 -0800 Subject: [PATCH] add atoms and pulling methods for wifi controller activity and modem controller activity Test: manual test on device Change-Id: Ib4213b4bf8badaf22b5f655e0261f45a55ab6bb7 --- cmds/statsd/src/atoms.proto | 63 ++++++++++++- .../server/stats/StatsCompanionService.java | 104 +++++++++++++++++++++ 2 files changed, 163 insertions(+), 4 deletions(-) diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 20e7c600938e..e0d9ce7d8802 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -91,6 +91,8 @@ message Atom { CpuTimePerFreqPulled cpu_time_per_freq_pulled = 1008; CpuTimePerUidPulled cpu_time_per_uid_pulled = 1009; CpuTimePerUidFreqPulled cpu_time_per_uid_freq_pulled = 1010; + WifiActivityEnergyInfoPulled wifi_activity_energy_info_pulled = 1011; + ModemActivityInfoPulled modem_activity_info_pulled = 1012; } } @@ -699,7 +701,7 @@ message SettingChanged { optional int32 user = 7; } -/* +/** * Logs activity going to foreground or background * * Logged from: @@ -839,7 +841,7 @@ message KernelWakelockPulled { optional int64 time = 4; } -/* +/** * Pulls PowerStatePlatformSleepState. * * Definition here: @@ -899,7 +901,7 @@ message IsolatedUidChanged { optional int32 is_create = 3; } -/* +/** * Pulls Cpu time per frequency. * Note: this should be pulled for gauge metric only, without condition. * The puller keeps internal state of last values. It should not be pulled by @@ -916,7 +918,7 @@ message CpuTimePerFreqPulled { optional uint64 time = 3; } -/* +/** * Pulls Cpu Time Per Uid. * Note that isolated process uid time should be attributed to host uids. */ @@ -965,3 +967,56 @@ message PacketWakeupOccurred { // The destination port if this was a TCP or UDP packet. optional int32 destination_port = 9; } + +/** + * Pulls Wifi Controller Activity Energy Info + */ +message WifiActivityEnergyInfoPulled { + // timestamp(wall clock) of record creation + optional uint64 timestamp_ms = 1; + // stack reported state + // TODO: replace this with proto enum + optional int32 stack_state = 2; + // tx time in ms + optional uint64 controller_tx_time_ms = 3; + // rx time in ms + optional uint64 controller_rx_time_ms = 4; + // idle time in ms + optional uint64 controller_idle_time_ms = 5; + // product of current(mA), voltage(V) and time(ms) + optional uint64 controller_energy_used = 6; +} + +/** + * Pulls Modem Activity Energy Info + */ +message ModemActivityInfoPulled { + // timestamp(wall clock) of record creation + optional uint64 timestamp_ms = 1; + // sleep time in ms. + optional uint64 sleep_time_ms = 2; + // idle time in ms + optional uint64 controller_idle_time_ms = 3; + /** + * Tx power index + * index 0 = tx_power < 0dBm + * index 1 = 0dBm < tx_power < 5dBm + * index 2 = 5dBm < tx_power < 15dBm + * index 3 = 15dBm < tx_power < 20dBm + * index 4 = tx_power > 20dBm + */ + // tx time in ms at power level 0 + optional uint64 controller_tx_time_pl0_ms = 4; + // tx time in ms at power level 1 + optional uint64 controller_tx_time_pl1_ms = 5; + // tx time in ms at power level 2 + optional uint64 controller_tx_time_pl2_ms = 6; + // tx time in ms at power level 3 + optional uint64 controller_tx_time_pl3_ms = 7; + // tx time in ms at power level 4 + optional uint64 controller_tx_time_pl4_ms = 8; + // rx time in ms at power level 5 + optional uint64 controller_rx_time_ms = 9; + // product of current(mA), voltage(V) and time(ms) + optional uint64 energy_used = 10; +} diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index e240ec5e1701..00c208d08883 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -15,6 +15,7 @@ */ package com.android.server.stats; +import android.annotation.Nullable; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -25,16 +26,22 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.net.NetworkStats; +import android.net.wifi.IWifiManager; +import android.net.wifi.WifiActivityEnergyInfo; +import android.telephony.ModemActivityInfo; +import android.telephony.TelephonyManager; import android.os.BatteryStatsInternal; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IStatsCompanionService; import android.os.IStatsManager; +import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatsLogEventWrapper; +import android.os.SynchronousResultReceiver; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; @@ -52,6 +59,7 @@ import com.android.server.SystemService; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeoutException; /** * Helper service for statsd (the native stats management service in cmds/statsd/). @@ -60,6 +68,13 @@ import java.util.Map; * @hide */ public class StatsCompanionService extends IStatsCompanionService.Stub { + /** + * How long to wait on an individual subsystem to return its stats. + */ + private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000; + + public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity"; + static final String TAG = "StatsCompanionService"; static final boolean DEBUG = true; public static final String ACTION_TRIGGER_COLLECTION = @@ -79,6 +94,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); private final KernelCpuSpeedReader[] mKernelCpuSpeedReaders; + private IWifiManager mWifiManager = null; + private TelephonyManager mTelephony = null; public StatsCompanionService(Context context) { super(); @@ -389,6 +406,40 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return ret; } + /** + * Helper method to extract the Parcelable controller info from a + * SynchronousResultReceiver. + */ + private static T awaitControllerInfo( + @Nullable SynchronousResultReceiver receiver) { + if (receiver == null) { + return null; + } + + try { + final SynchronousResultReceiver.Result result = + receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS); + if (result.bundle != null) { + // This is the final destination for the Bundle. + result.bundle.setDefusable(true); + + final T data = result.bundle.getParcelable( + RESULT_RECEIVER_CONTROLLER_KEY); + if (data != null) { + return data; + } + } + Slog.e(TAG, "no controller energy info supplied for " + receiver.getName()); + } catch (TimeoutException e) { + Slog.w(TAG, "timeout reading " + receiver.getName() + " stats"); + } + return null; + } + + /** + * + * Pulls wifi controller activity energy info from WiFiManager + */ @Override // Binder call public StatsLogEventWrapper[] pullData(int tagId) { enforceCallingPermission(); @@ -509,6 +560,59 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } return ret.toArray(new StatsLogEventWrapper[ret.size()]); } + case StatsLog.WIFI_ACTIVITY_ENERGY_INFO_PULLED: { + List ret = new ArrayList(); + long token = Binder.clearCallingIdentity(); + if (mWifiManager == null) { + mWifiManager = IWifiManager.Stub.asInterface(ServiceManager.getService( + Context.WIFI_SERVICE)); + } + if (mWifiManager != null) { + try { + SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi"); + mWifiManager.requestActivityInfo(wifiReceiver); + final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 6); + e.writeLong(wifiInfo.getTimeStamp()); + e.writeInt(wifiInfo.getStackState()); + e.writeLong(wifiInfo.getControllerTxTimeMillis()); + e.writeLong(wifiInfo.getControllerRxTimeMillis()); + e.writeLong(wifiInfo.getControllerIdleTimeMillis()); + e.writeLong(wifiInfo.getControllerEnergyUsed()); + ret.add(e); + } catch (RemoteException e) { + Slog.e(TAG, "Pulling wifiManager for wifi controller activity energy info has error", e); + } finally { + Binder.restoreCallingIdentity(token); + } + } + break; + } + case StatsLog.MODEM_ACTIVITY_INFO_PULLED: { + List ret = new ArrayList(); + long token = Binder.clearCallingIdentity(); + if (mTelephony == null) { + mTelephony = TelephonyManager.from(mContext); + } + if (mTelephony != null) { + SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony"); + mTelephony.requestModemActivityInfo(modemReceiver); + final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 6); + e.writeLong(modemInfo.getTimestamp()); + e.writeLong(modemInfo.getSleepTimeMillis()); + e.writeLong(modemInfo.getIdleTimeMillis()); + e.writeLong(modemInfo.getTxTimeMillis()[0]); + e.writeLong(modemInfo.getTxTimeMillis()[1]); + e.writeLong(modemInfo.getTxTimeMillis()[2]); + e.writeLong(modemInfo.getTxTimeMillis()[3]); + e.writeLong(modemInfo.getTxTimeMillis()[4]); + e.writeLong(modemInfo.getRxTimeMillis()); + e.writeLong(modemInfo.getEnergyUsed()); + ret.add(e); + } + break; + } default: Slog.w(TAG, "No such tagId data as " + tagId); return null; -- 2.11.0