summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/connectivity/DataConnectionStats.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/connectivity/DataConnectionStats.java')
-rw-r--r--services/core/java/com/android/server/connectivity/DataConnectionStats.java154
1 files changed, 154 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
new file mode 100644
index 0000000..227ab23
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2013 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 com.android.server.connectivity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.os.RemoteException;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.server.am.BatteryStatsService;
+
+public class DataConnectionStats extends BroadcastReceiver {
+ private static final String TAG = "DataConnectionStats";
+ private static final boolean DEBUG = false;
+
+ private final Context mContext;
+ private final IBatteryStats mBatteryStats;
+
+ private IccCardConstants.State mSimState = IccCardConstants.State.READY;
+ private SignalStrength mSignalStrength;
+ private ServiceState mServiceState;
+ private int mDataState = TelephonyManager.DATA_DISCONNECTED;
+
+ public DataConnectionStats(Context context) {
+ mContext = context;
+ mBatteryStats = BatteryStatsService.getService();
+ }
+
+ public void startMonitoring() {
+ TelephonyManager phone =
+ (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ phone.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_SERVICE_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+ | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
+ mContext.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+ updateSimState(intent);
+ notePhoneDataConnectionState();
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
+ action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
+ notePhoneDataConnectionState();
+ }
+ }
+
+ private void notePhoneDataConnectionState() {
+ if (mServiceState == null) {
+ return;
+ }
+ boolean simReadyOrUnknown = mSimState == IccCardConstants.State.READY
+ || mSimState == IccCardConstants.State.UNKNOWN;
+ boolean visible = (simReadyOrUnknown || isCdma()) // we only check the sim state for GSM
+ && hasService()
+ && mDataState == TelephonyManager.DATA_CONNECTED;
+ int networkType = mServiceState.getDataNetworkType();
+ if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
+ networkType, visible ? "" : "not "));
+ try {
+ mBatteryStats.notePhoneDataConnectionState(networkType, visible);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error noting data connection state", e);
+ }
+ }
+
+ private final void updateSimState(Intent intent) {
+ String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.ABSENT;
+ } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.READY;
+ } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ final String lockedReason =
+ intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PIN_REQUIRED;
+ } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PUK_REQUIRED;
+ } else {
+ mSimState = IccCardConstants.State.NETWORK_LOCKED;
+ }
+ } else {
+ mSimState = IccCardConstants.State.UNKNOWN;
+ }
+ }
+
+ private boolean isCdma() {
+ return mSignalStrength != null && !mSignalStrength.isGsm();
+ }
+
+ private boolean hasService() {
+ return mServiceState != null
+ && mServiceState.getState() != ServiceState.STATE_OUT_OF_SERVICE
+ && mServiceState.getState() != ServiceState.STATE_POWER_OFF;
+ }
+
+ private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ mSignalStrength = signalStrength;
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState state) {
+ mServiceState = state;
+ notePhoneDataConnectionState();
+ }
+
+ @Override
+ public void onDataConnectionStateChanged(int state, int networkType) {
+ mDataState = state;
+ notePhoneDataConnectionState();
+ }
+
+ @Override
+ public void onDataActivity(int direction) {
+ notePhoneDataConnectionState();
+ }
+ };
+}