add radio stats to link layer

Bug:15563188

Change-Id: I3d2a230b0362520b9f1b2bc3792260116971e106
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 71b6bee..397d700 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -25,6 +25,7 @@
 import android.net.wifi.WifiChannel;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConnectionStatistics;
+import android.net.wifi.WifiActivityEnergyInfo;
 
 import android.net.DhcpInfo;
 
@@ -41,6 +42,8 @@
 {
     List<WifiAdapter> getAdaptors();
 
+    WifiActivityEnergyInfo reportActivityInfo(in WifiAdapter adapter);
+
     List<WifiConfiguration> getConfiguredNetworks();
 
     List<WifiConfiguration> getPrivilegedConfiguredNetworks();
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
new file mode 100644
index 0000000..007ec94
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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 android.net.wifi;
+
+parcelable WifiActivityEnergyInfo;
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
new file mode 100644
index 0000000..533b8bc
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 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 android.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Record of energy and activity information from controller and
+ * underlying wifi stack state.Timestamp the record with system
+ * time
+ * @hide
+ */
+public final class WifiActivityEnergyInfo implements Parcelable {
+    private final int mStackState;
+    private final int mControllerTxTimeMs;
+    private final int mControllerRxTimeMs;
+    private final int mControllerIdleTimeMs;
+    private final int mControllerEnergyUsed;
+    private final long timestamp;
+
+    public static final int STACK_STATE_INVALID = 0;
+    public static final int STACK_STATE_STATE_ACTIVE = 1;
+    public static final int STACK_STATE_STATE_SCANNING = 2;
+    public static final int STACK_STATE_STATE_IDLE = 3;
+
+    public WifiActivityEnergyInfo(int stackState, int txTime, int rxTime,
+                                  int idleTime, int energyUsed) {
+        mStackState = stackState;
+        mControllerTxTimeMs = txTime;
+        mControllerRxTimeMs = rxTime;
+        mControllerIdleTimeMs = idleTime;
+        mControllerEnergyUsed = energyUsed;
+        timestamp = System.currentTimeMillis();
+    }
+
+    @Override
+    public String toString() {
+        return "WifiActivityEnergyInfo{"
+            + " timestamp=" + timestamp
+            + " mStackState=" + mStackState
+            + " mControllerTxTimeMs=" + mControllerTxTimeMs
+            + " mControllerRxTimeMs=" + mControllerRxTimeMs
+            + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+            + " mControllerEnergyUsed=" + mControllerEnergyUsed
+            + " }";
+    }
+
+    public static final Parcelable.Creator<WifiActivityEnergyInfo> CREATOR =
+            new Parcelable.Creator<WifiActivityEnergyInfo>() {
+        public WifiActivityEnergyInfo createFromParcel(Parcel in) {
+            int stackState = in.readInt();
+            int txTime = in.readInt();
+            int rxTime = in.readInt();
+            int idleTime = in.readInt();
+            int energyUsed = in.readInt();
+            return new WifiActivityEnergyInfo(stackState, txTime, rxTime,
+                    idleTime, energyUsed);
+        }
+        public WifiActivityEnergyInfo[] newArray(int size) {
+            return new WifiActivityEnergyInfo[size];
+        }
+    };
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mStackState);
+        out.writeInt(mControllerTxTimeMs);
+        out.writeInt(mControllerRxTimeMs);
+        out.writeInt(mControllerIdleTimeMs);
+        out.writeInt(mControllerEnergyUsed);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @return bt stack reported state
+     */
+    public int getStackState() {
+        return mStackState;
+    }
+
+    /**
+     * @return tx time in ms
+     */
+    public int getControllerTxTimeMillis() {
+        return (int)mControllerTxTimeMs;
+    }
+
+    /**
+     * @return rx time in ms
+     */
+    public int getControllerRxTimeMillis() {
+        return (int)mControllerRxTimeMs;
+    }
+
+    /**
+     * @return idle time in ms
+     */
+    public int getControllerIdleTimeMillis() {
+        return (int)mControllerIdleTimeMs;
+    }
+
+    /**
+     * product of current(mA), voltage(V) and time(ms)
+     * @return energy used
+     */
+    public int getControllerEnergyUsed() {
+        return mControllerEnergyUsed;
+    }
+    /**
+     * @return timestamp(wall clock) of record creation
+     */
+    public long getTimeStamp() {
+        return timestamp;
+    }
+
+    /**
+     * @return if the record is valid
+     */
+    public boolean isValid() {
+        return ((getControllerTxTimeMillis() !=0) ||
+                (getControllerRxTimeMillis() !=0) ||
+                (getControllerIdleTimeMillis() !=0));
+    }
+}
diff --git a/wifi/java/android/net/wifi/WifiAdapter.aidl b/wifi/java/android/net/wifi/WifiAdapter.aidl
index 931da92..0bb5dd7 100644
--- a/wifi/java/android/net/wifi/WifiAdapter.aidl
+++ b/wifi/java/android/net/wifi/WifiAdapter.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2008, The Android Open Source Project
+ * Copyright (c) 2014, 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.
diff --git a/wifi/java/android/net/wifi/WifiAdapter.java b/wifi/java/android/net/wifi/WifiAdapter.java
index c0211f3..0b12dea 100644
--- a/wifi/java/android/net/wifi/WifiAdapter.java
+++ b/wifi/java/android/net/wifi/WifiAdapter.java
@@ -18,6 +18,8 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
 
 /**
  * Represents local wifi adapter. Different devices have different kinds of
@@ -25,6 +27,7 @@
  * which capabilites are supported by the wifi adapter on the device.
  */
 public class WifiAdapter implements Parcelable {
+    private static final String TAG = "WifiAdapter";
 
     /* Keep this list in sync with wifi_hal.h */
     /** @hide */
@@ -58,9 +61,20 @@
     /** @hide */
     public static final int WIFI_FEATURE_EPR              = 0x4000;  // Enhanced power reporting
 
+    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
+    /** @hide */
+    public static final int ACTIVITY_ENERGY_INFO_CACHED = 0;
+    /** @hide */
+    public static final int ACTIVITY_ENERGY_INFO_REFRESHED = 1;
+
     private String name;
     private int    supportedFeatures;
 
+    // Make the API consistent with BlueTooth Adaptor, allowing WifiService to be accessed
+    // Directly from the adapter
+    /** @hide */
+    public IWifiManager mService = null;
+
     /** @hide */
     public WifiAdapter(String name, int supportedFeatures) {
         this.name = name;
@@ -175,6 +189,38 @@
         return isFeatureSupported(WIFI_FEATURE_EPR);
     }
 
+
+    /**
+     * Return the record of {@link WifiActivityEnergyInfo} object that
+     * has the activity and energy info. This can be used to ascertain what
+     * the controller has been up to, since the last sample.
+     * @param updateType Type of info, cached vs refreshed.
+     *
+     * @return a record with {@link WifiActivityEnergyInfo} or null if
+     * report is unavailable or unsupported
+     * @hide
+     */
+    public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
+        if (mService == null) return null;
+        try {
+            WifiActivityEnergyInfo record;
+            if (!isEnhancedPowerReportingSupported()) {
+                return null;
+            }
+            synchronized(this) {
+                record = mService.reportActivityInfo(this);
+                if (record.isValid()) {
+                    return record;
+                } else {
+                    return null;
+                }
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
+        }
+        return null;
+    }
+
     /* Parcelable implementation */
     /**
      * Implement the Parcelable interface
diff --git a/wifi/java/android/net/wifi/WifiLinkLayerStats.java b/wifi/java/android/net/wifi/WifiLinkLayerStats.java
index ae2fa98..7fac7cf 100644
--- a/wifi/java/android/net/wifi/WifiLinkLayerStats.java
+++ b/wifi/java/android/net/wifi/WifiLinkLayerStats.java
@@ -102,6 +102,14 @@
     /** {@hide} */
     public long retries_vo;
 
+    /** {@hide} */
+    public int on_time;
+    /** {@hide} */
+    public int tx_time;
+    /** {@hide} */
+    public int rx_time;
+    /** {@hide} */
+    public int on_time_scan;
 
     /** {@hide} */
     public WifiLinkLayerStats() {
@@ -138,7 +146,10 @@
                 .append(" tx=").append(Long.toString(this.txmpdu_vo))
                 .append(" lost=").append(Long.toString(this.lostmpdu_vo))
                 .append(" retries=").append(Long.toString(this.retries_vo)).append('\n');
-
+        sbuf.append(" on_time : ").append(Integer.toString(this.on_time))
+                .append(" tx_time=").append(Integer.toString(this.tx_time))
+                .append(" rx_time=").append(Integer.toString(this.rx_time))
+                .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n');
         return sbuf.toString();
     }
 
@@ -172,6 +183,10 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(SSID);
         dest.writeString(BSSID);
+        dest.writeInt(on_time);
+        dest.writeInt(tx_time);
+        dest.writeInt(rx_time);
+        dest.writeInt(on_time_scan);
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -181,6 +196,10 @@
                 WifiLinkLayerStats stats = new WifiLinkLayerStats();
                 stats.SSID = in.readString();
                 stats.BSSID = in.readString();
+                stats.on_time = in.readInt();
+                stats.tx_time = in.readInt();
+                stats.rx_time = in.readInt();
+                stats.on_time_scan = in.readInt();
                 return stats;
             };
             public WifiLinkLayerStats[] newArray(int size) {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e27bd7e..4a4da22 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -581,7 +581,11 @@
      */
     public List<WifiAdapter> getAdapters() {
         try {
-            return mService.getAdaptors();
+            List<WifiAdapter> adapterList = mService.getAdaptors();
+            for (WifiAdapter a : adapterList) {
+                a.mService = mService;
+            }
+            return adapterList;
         } catch (RemoteException e) {
             return null;
         }