OSDN Git Service

add atoms and pulling methods for wifi controller activity and modem
authorChenjie Yu <cjyu@google.com>
Tue, 21 Nov 2017 18:21:41 +0000 (10:21 -0800)
committerChenjie Yu <cjyu@google.com>
Thu, 30 Nov 2017 06:54:54 +0000 (06:54 +0000)
controller activity

Test: manual test on device
Change-Id: Ib4213b4bf8badaf22b5f655e0261f45a55ab6bb7

cmds/statsd/src/atoms.proto
services/core/java/com/android/server/stats/StatsCompanionService.java

index 20e7c60..e0d9ce7 100644 (file)
@@ -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;
+}
index e240ec5..00c208d 100644 (file)
@@ -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 extends Parcelable> 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<StatsLogEventWrapper> 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<StatsLogEventWrapper> 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;