Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab2a4aac authored by Li Junfei's avatar Li Junfei Committed by Gerrit - the friendly Code Review server
Browse files

Add a new feature for recording data usage of video call

Provide framework API for Dialer, which used for recording the total
data usage of a video call.

Change-Id: Icef46c725286655c42050ca4fa4ac45889284b82
CRs-Fixed: 1039373
parent dd4b9521
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -67,4 +67,6 @@ interface INetworkStatsService {
    /** Unregisters a callback on data usage. */
    void unregisterUsageRequest(in DataUsageRequest request);

    /** record video call data usage. */
    void recordVideoCallData(String iface, int ifaceType, long rxBytes, long txBytes);
}
+5 −1
Original line number Diff line number Diff line
@@ -182,7 +182,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
            roaming = state.networkInfo.isRoaming();

            metered = !state.networkCapabilities.hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
                    || (context.getResources().getBoolean(
                    com.android.internal.R.bool.config_video_call_datausage_enable)
                    && state.networkCapabilities.hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_IMS));

        } else if (type == TYPE_WIFI) {
            if (state.networkId != null) {
+2 −0
Original line number Diff line number Diff line
@@ -2636,6 +2636,8 @@
        <item>-44</item>
    </integer-array>

    <!--  Enable framework to record video call data usage -->
    <bool name="config_video_call_datausage_enable">false</bool>
    <!-- Enables the feature that can show/hide the operator name in statusbar.
        When true, the user can select to show/hide operator name through a
        checkbox in Settings. When false, there is no option to show operator
+1 −0
Original line number Diff line number Diff line
@@ -2729,6 +2729,7 @@
  <java-symbol type="bool" name="config_regional_hotspot_show_broadcast_ssid_checkbox" />
  <java-symbol type="bool" name="config_regional_hotspot_show_notification_when_turn_on" />

  <java-symbol type="bool" name="config_video_call_datausage_enable" />
  <java-symbol type="bool" name="config_showOperatorNameInStatusBar" />
  <java-symbol type="bool" name="config_passpoint_setting_on" />
  <java-symbol type="integer" name="wifi_hotspot_security_type" />
+82 −1
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.DataUsageRequest;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
@@ -152,6 +153,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    private static final int FLAG_PERSIST_FORCE = 0x100;

    private static final String TAG_NETSTATS_ERROR = "netstats_error";
    private static final String DIALER_PACKEAGE_NAME = "com.android.dialer";

    private final Context mContext;
    private final INetworkManagementService mNetworkManager;
@@ -232,6 +234,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    private NetworkStatsRecorder mUidRecorder;
    private NetworkStatsRecorder mUidTagRecorder;

    private NetworkStats.Entry mVideoCallMobileDataEntry;
    private NetworkStats.Entry mVideoCallWifiDataEntry;
    private boolean mConfigEnableDataUsage = false;

    /** Cached {@link #mXtRecorder} stats. */
    private NetworkStatsCollection mXtStatsCached;

@@ -304,6 +310,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        ContentResolver contentResolver = context.getContentResolver();
        contentResolver.registerContentObserver(Settings.Global.getUriFor(
               NETSTATS_GLOBAL_ALERT_BYTES), false, mGlobalAlertBytesObserver);

        mConfigEnableDataUsage = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_video_call_datausage_enable);
    }

    @VisibleForTesting
@@ -986,7 +995,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
                        || !state.networkCapabilities.hasTransport(
                                    NetworkCapabilities.TRANSPORT_CELLULAR)
                        || state.networkCapabilities.hasCapability(
                                    NetworkCapabilities.NET_CAPABILITY_INTERNET))) {
                                    NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        || hasImsNetworkCapability(state))) {
                final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
                final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);

@@ -1040,6 +1050,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {

        NetPluginDelegate.getTetherStats(uidSnapshot, xtSnapshot, devSnapshot);

        if (mConfigEnableDataUsage) {
            combineVideoCallEntryValues(uidSnapshot);
        }

        // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
        // can't be reattributed to responsible apps.
        mDevRecorder.recordSnapshotLocked(
@@ -1497,4 +1511,71 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
        }
    }

    public void recordVideoCallData(String iface, int ifaceType, long rxBytes, long txBytes) {
        Log.d(TAG, "recordVideoCallData  service ifaceType = " + ifaceType
                + " iface = "+ iface + " rxBytes = " +rxBytes + "txBytes = "+ txBytes);
        if (ifaceType == ConnectivityManager.TYPE_MOBILE) {
            if (mVideoCallMobileDataEntry == null) {
                mVideoCallMobileDataEntry = createVideoCallDataEntry(iface);
            }
            synchronized(mVideoCallMobileDataEntry) {
                mVideoCallMobileDataEntry.rxBytes += rxBytes;
                mVideoCallMobileDataEntry.txBytes += txBytes;
            }
        } else if (ifaceType == ConnectivityManager.TYPE_WIFI) {
            if (mVideoCallWifiDataEntry == null) {
                mVideoCallWifiDataEntry = createVideoCallDataEntry(iface);
            }
            synchronized(mVideoCallWifiDataEntry) {
                mVideoCallWifiDataEntry.rxBytes += rxBytes;
                mVideoCallWifiDataEntry.txBytes += txBytes;
            }
        } else {
            return;
        }

        synchronized (mStatsLock) {
            performPollLocked(FLAG_PERSIST_ALL);
        }
    }


    private NetworkStats.Entry createVideoCallDataEntry(String iface) {
        NetworkStats.Entry dataEntry = new NetworkStats.Entry();
        PackageManager pm = mContext.getPackageManager();
        ApplicationInfo ai = null;
        try {
            ai = pm.getApplicationInfo(DIALER_PACKEAGE_NAME, PackageManager.GET_ACTIVITIES);
        } catch(Exception e) {
            Log.d(TAG, "get dialer getApplicationInfo failed ");
        }
        if (ai != null){
            dataEntry.uid = ai.uid;
        }
        dataEntry.iface = iface;
        return dataEntry;
    }

    private void combineVideoCallEntryValues(NetworkStats uidSnapshot) {
        if (mVideoCallMobileDataEntry != null) {
            synchronized(mVideoCallMobileDataEntry) {
                uidSnapshot.combineValues(mVideoCallMobileDataEntry);
            }
        }
        if (mVideoCallWifiDataEntry != null) {
            synchronized(mVideoCallWifiDataEntry) {
                uidSnapshot.combineValues(mVideoCallWifiDataEntry);
            }
        }
    }

    private boolean hasImsNetworkCapability(NetworkState state) {
        if (mConfigEnableDataUsage && state.networkCapabilities.hasCapability(
                NetworkCapabilities.NET_CAPABILITY_IMS)) {
            return true;
        }
        return false;
    }

}