public ThreeG(Context context, PhoneConstants phoneConstants) { this.phoneConstants = phoneConstants; telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); String interfaceName = phoneConstants.threegInterface(); ThreeGState = new ThreeGStateKeeper(); uidStates = new SparseArray<ThreeGStateKeeper>(); transPacketsFile = "/sys/devices/virtual/net/" + interfaceName + "/statistics/tx_packets"; readPacketsFile = "/sys/devices/virtual/net/" + interfaceName + "/statistics/rx_packets"; readBytesFile = "/sys/devices/virtual/net/" + interfaceName + "/statistics/rx_bytes"; transBytesFile = "/sys/devices/virtual/net/" + interfaceName + "/statistics/tx_bytes"; uidStatsFolder = new File("/proc/uid_stat"); sysInfo = SystemInfo.getInstance(); }
@Override public IterationData calculateIteration(long iteration) { IterationData result = IterationData.obtain(); int netType = telephonyManager.getNetworkType(); if ((netType != TelephonyManager.NETWORK_TYPE_UMTS && netType != 8 /* TelephonyManager.NETWORK_TYPE_HSDPA */)) { // TODO: Actually get models for the different network types. netType = TelephonyManager.NETWORK_TYPE_UMTS; } if (telephonyManager.getDataState() != TelephonyManager.DATA_CONNECTED || (netType != TelephonyManager.NETWORK_TYPE_UMTS && netType != 8 /* TelephonyManager.NETWORK_TYPE_HSDPA */)) { /* We need to allow the real iterface state keeper to reset it's state * so that the next update it knows it's coming back from an off state. * We also need to clear all the uid information. */ oper = null; ThreeGState.interfaceOff(); uidStates.clear(); ThreeGData data = ThreeGData.obtain(); data.init(); result.setSensorData(data); return result; } if (oper == null) { oper = telephonyManager.getNetworkOperatorName(); dchFachDelay = phoneConstants.threegDchFachDelay(oper); fachIdleDelay = phoneConstants.threegFachIdleDelay(oper); uplinkQueueSize = phoneConstants.threegUplinkQueue(oper); downlinkQueueSize = phoneConstants.threegDownlinkQueue(oper); } long transmitPackets = readLongFromFile(transPacketsFile); long receivePackets = readLongFromFile(readPacketsFile); long transmitBytes = readLongFromFile(transBytesFile); long receiveBytes = readLongFromFile(readBytesFile); if (transmitBytes == -1 || receiveBytes == -1) { /* Couldn't read interface data files. */ Log.w(TAG, "Failed to read packet and byte counts from wifi interface"); return result; } if (ThreeGState.isInitialized()) { ThreeGState.updateState( transmitPackets, receivePackets, transmitBytes, receiveBytes, dchFachDelay, fachIdleDelay, uplinkQueueSize, downlinkQueueSize); ThreeGData data = ThreeGData.obtain(); data.init( ThreeGState.getPackets(), ThreeGState.getUplinkBytes(), ThreeGState.getDownlinkBytes(), ThreeGState.getPowerState(), oper); result.setSensorData(data); } else { ThreeGState.updateState( transmitPackets, receivePackets, transmitBytes, receiveBytes, dchFachDelay, fachIdleDelay, uplinkQueueSize, downlinkQueueSize); } lastUids = sysInfo.getUids(lastUids); if (lastUids != null) for (int uid : lastUids) { if (uid == -1) { continue; } try { ThreeGStateKeeper uidState = uidStates.get(uid); if (uidState == null) { uidState = new ThreeGStateKeeper(); uidStates.put(uid, uidState); } if (!uidState.isStale()) { /* We use a huerstic here so that we don't poll for uids that haven't * had much activity recently. */ continue; } /* These read operations are the expensive part of polling. */ receiveBytes = readLongFromFile("/proc/uid_stat/" + uid + "/tcp_rcv"); transmitBytes = readLongFromFile("/proc/uid_stat/" + uid + "/tcp_snd"); if (receiveBytes == -1 || transmitBytes == -1) { Log.w(TAG, "Failed to read uid read/write byte counts"); } else if (uidState.isInitialized()) { uidState.updateState( -1, -1, transmitBytes, receiveBytes, dchFachDelay, fachIdleDelay, uplinkQueueSize, downlinkQueueSize); if (uidState.getUplinkBytes() + uidState.getDownlinkBytes() != 0 || uidState.getPowerState() != POWER_STATE_IDLE) { ThreeGData uidData = ThreeGData.obtain(); uidData.init( uidState.getPackets(), uidState.getUplinkBytes(), uidState.getDownlinkBytes(), uidState.getPowerState(), oper); result.addUidSensorData(uid, uidData); } } else { uidState.updateState( -1, -1, transmitBytes, receiveBytes, dchFachDelay, fachIdleDelay, uplinkQueueSize, downlinkQueueSize); } } catch (NumberFormatException e) { Log.w(TAG, "Non-uid files in /proc/uid_stat"); } } return result; }