Dialer: Recording data usage for video call
Add a new feature for recording video call data usage.
Call NetworkstatsService API to record the total video
call data usage at the end of a video call.
Change-Id: If569e5e62b2c9926a29add655610347aa72fc4ab
CRs-Fixed: 1039373
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 70493df..b87e31f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -61,6 +61,8 @@
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<!-- This tells the activity manager to not delay any of our activity
start requests, even if they happen immediately after the user
presses home. -->
diff --git a/InCallUI/src/com/android/incallui/InCallMessageController.java b/InCallUI/src/com/android/incallui/InCallMessageController.java
index d019f6b..aa5a57e 100644
--- a/InCallUI/src/com/android/incallui/InCallMessageController.java
+++ b/InCallUI/src/com/android/incallui/InCallMessageController.java
@@ -30,7 +30,16 @@
import android.content.Context;
import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
+import android.net.INetworkStatsService;
+import android.net.LinkProperties;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkState;
import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import com.android.incallui.InCallPresenter.InCallDetailsListener;
import com.android.incallui.InCallVideoCallCallbackNotifier.VideoEventListener;
@@ -51,6 +60,11 @@
CallList.Listener, SessionModificationListener, InCallSessionModificationCauseListener,
InCallDetailsListener {
+ private INetworkStatsService mStatsService;
+ private IConnectivityManager mConnManager;
+ private long previousLteUsage;
+ private long previousWlanUsage;
+
private static InCallMessageController sInCallMessageController;
private PrimaryCallTracker mPrimaryCallTracker;
@@ -78,6 +92,10 @@
InCallPresenter.getInstance().addListener(mPrimaryCallTracker);
InCallVideoCallCallbackNotifier.getInstance().addSessionModificationListener(this);
InCallPresenter.getInstance().addDetailsListener(this);
+ mStatsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+ mConnManager = IConnectivityManager.Stub.asInterface(
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
}
/**
@@ -95,6 +113,10 @@
InCallVideoCallCallbackNotifier.getInstance().removeSessionModificationListener(this);
InCallPresenter.getInstance().removeDetailsListener(this);
mPrimaryCallTracker = null;
+ mStatsService = null;
+ mConnManager = null;
+ previousLteUsage = 0;
+ previousWlanUsage = 0;
}
/**
@@ -223,6 +245,12 @@
Log.i(this, "onDetailsChanged LTE data value = " + lteUsage + " WiFi data value = " +
wlanUsage);
+ if (mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_video_call_datausage_enable)) {
+ recordDataUsage(lteUsage, wlanUsage);
+ }
+
+
if (QtiImsExtUtils.isCarrierConfigEnabled(mContext,
QtiCarrierConfigs.SHOW_DATA_USAGE_TOAST)) {
final String dataUsageChangedText = mContext.getResources().getString(
@@ -397,4 +425,97 @@
break;
}
}
+
+ /**
+ * This method is used to ignore the repeatly calling onDetailsChanged
+ */
+ private boolean hasDataUsageChanged(long lteUsage, long wlanUsage) {
+ boolean hasChanged = false;
+ if (previousLteUsage != lteUsage) {
+ hasChanged = true;
+ previousLteUsage = lteUsage;
+ }
+ if (previousWlanUsage != wlanUsage) {
+ hasChanged = true;
+ previousWlanUsage = wlanUsage;
+ }
+ return hasChanged;
+ }
+
+ private void recordDataUsage(long lteUsage, long wlanUsage) {
+ String wifiIface;
+ String imsIface;
+ if(!hasDataUsageChanged(lteUsage, wlanUsage)) {
+ return;
+ }
+
+ if (wlanUsage != 0) {
+ wifiIface = getWifiIface();
+ if (wifiIface != null)
+ recordUsage(wifiIface, ConnectivityManager.TYPE_WIFI, wlanUsage, 0);
+ }
+
+ if (lteUsage != 0 ) {
+ imsIface = getImsIface();
+ if (imsIface != null)
+ recordUsage(imsIface, ConnectivityManager.TYPE_MOBILE, lteUsage, 0);
+ }
+ }
+
+ private void recordUsage(String ifaces, int ifaceType, long rx, long tx) {
+ if (ifaces == null) {
+ Log.d(this, "recordDataUseage ifaces is null");
+ return;
+ }
+ Log.d(this,"recordDataUseage ifaces ="+ ifaces + " ifaceType=" + ifaceType +
+ "rx = " + rx + " tx =" + tx);
+
+ try {
+ mStatsService.recordVideoCallData(ifaces, ifaceType, rx, tx);
+ } catch (RuntimeException e) {
+ Log.e(this, "recordDataUseage RuntimeException" + e);
+ } catch (RemoteException e) {
+ Log.e(this, "recordDataUseage RemoteException" + e);
+ }
+ }
+
+ private String getImsIface() {
+ final NetworkState[] states;
+ try {
+ states = mConnManager.getAllNetworkState();
+ } catch (RemoteException e) {
+ Log.e(this, "getVoiceCallIfaces RemoteException" + e);
+ return null;
+ }
+
+ if (states != null) {
+ for (NetworkState state : states) {
+ if (state.networkInfo.isConnected() && state.networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_IMS)) {
+ final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(
+ state.networkInfo.getType());
+ final String baseIface = state.linkProperties.getInterfaceName();
+ if (isMobile)
+ return baseIface;
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getWifiIface() {
+ final LinkProperties wifiLinkProperties;
+ try {
+ wifiLinkProperties =
+ mConnManager.getLinkPropertiesForType(ConnectivityManager.TYPE_WIFI);
+ if (wifiLinkProperties != null) {
+ return wifiLinkProperties.getInterfaceName();
+ }
+ } catch (RemoteException e) {
+ Log.e(this, "get wifi Iface RemoteException" + e);
+ }
+ return null;
+ }
+
+
}