1bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock/* 2bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * Copyright (C) 2013 The Android Open Source Project 3bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * 4bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * you may not use this file except in compliance with the License. 6bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * You may obtain a copy of the License at 7bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * 8bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * 10bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * Unless required by applicable law or agreed to in writing, software 11bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * See the License for the specific language governing permissions and 14bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock * limitations under the License. 15bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock */ 16bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 17bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockpackage com.android.server.connectivity; 18bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 19bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.content.BroadcastReceiver; 20bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.content.Context; 21bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.content.Intent; 22bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.content.IntentFilter; 23bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.net.ConnectivityManager; 24bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.os.RemoteException; 25bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.telephony.PhoneStateListener; 26bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.telephony.ServiceState; 27bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.telephony.SignalStrength; 28bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.telephony.TelephonyManager; 29bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport android.util.Log; 30bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 31bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport com.android.internal.app.IBatteryStats; 32bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport com.android.internal.telephony.IccCardConstants; 33bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport com.android.internal.telephony.TelephonyIntents; 34bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockimport com.android.server.am.BatteryStatsService; 35bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 36bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlockpublic class DataConnectionStats extends BroadcastReceiver { 37bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private static final String TAG = "DataConnectionStats"; 38bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private static final boolean DEBUG = false; 39bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 40bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private final Context mContext; 41bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private final IBatteryStats mBatteryStats; 42bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 43bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private IccCardConstants.State mSimState = IccCardConstants.State.READY; 44bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private SignalStrength mSignalStrength; 45bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private ServiceState mServiceState; 46bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private int mDataState = TelephonyManager.DATA_DISCONNECTED; 47bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 48bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public DataConnectionStats(Context context) { 49bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mContext = context; 50bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mBatteryStats = BatteryStatsService.getService(); 51bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 52bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 53bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void startMonitoring() { 54bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock TelephonyManager phone = 55bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 56bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock phone.listen(mPhoneStateListener, 57bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock PhoneStateListener.LISTEN_SERVICE_STATE 58bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 59bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 60bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock | PhoneStateListener.LISTEN_DATA_ACTIVITY); 61bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 62bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock IntentFilter filter = new IntentFilter(); 63bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 64bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 65bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); 66bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mContext.registerReceiver(this, filter); 67bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 68bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 69bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock @Override 70bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void onReceive(Context context, Intent intent) { 71bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock final String action = intent.getAction(); 72bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { 73bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock updateSimState(intent); 74bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock notePhoneDataConnectionState(); 75bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || 76bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock action.equals(ConnectivityManager.INET_CONDITION_ACTION)) { 77bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock notePhoneDataConnectionState(); 78bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 79bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 80bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 81bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private void notePhoneDataConnectionState() { 82bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock if (mServiceState == null) { 83bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock return; 84bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 85bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock boolean simReadyOrUnknown = mSimState == IccCardConstants.State.READY 86bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock || mSimState == IccCardConstants.State.UNKNOWN; 87bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock boolean visible = (simReadyOrUnknown || isCdma()) // we only check the sim state for GSM 88bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock && hasService() 89bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock && mDataState == TelephonyManager.DATA_CONNECTED; 90bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock int networkType = mServiceState.getDataNetworkType(); 91bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible", 92bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock networkType, visible ? "" : "not ")); 93bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock try { 94bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mBatteryStats.notePhoneDataConnectionState(networkType, visible); 95bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } catch (RemoteException e) { 96bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock Log.w(TAG, "Error noting data connection state", e); 97bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 98bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 99bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 100bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private final void updateSimState(Intent intent) { 101bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 102bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 103bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.ABSENT; 104bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 105bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.READY; 106bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 107bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock final String lockedReason = 108bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); 109bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 110bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.PIN_REQUIRED; 111bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 112bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.PUK_REQUIRED; 113bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else { 114bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.NETWORK_LOCKED; 115bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 116bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } else { 117bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSimState = IccCardConstants.State.UNKNOWN; 118bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 119bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 120bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 121bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private boolean isCdma() { 122bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock return mSignalStrength != null && !mSignalStrength.isGsm(); 123bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 124bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 125bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private boolean hasService() { 126bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock return mServiceState != null 127bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock && mServiceState.getState() != ServiceState.STATE_OUT_OF_SERVICE 128bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock && mServiceState.getState() != ServiceState.STATE_POWER_OFF; 129bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 130bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 131bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 132bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock @Override 133bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void onSignalStrengthsChanged(SignalStrength signalStrength) { 134bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mSignalStrength = signalStrength; 135bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 136bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 137bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock @Override 138bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void onServiceStateChanged(ServiceState state) { 139bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mServiceState = state; 140bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock notePhoneDataConnectionState(); 141bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 142bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 143bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock @Override 144bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void onDataConnectionStateChanged(int state, int networkType) { 145bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock mDataState = state; 146bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock notePhoneDataConnectionState(); 147bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 148bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock 149bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock @Override 150bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock public void onDataActivity(int direction) { 151bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock notePhoneDataConnectionState(); 152bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock } 153bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock }; 154bf991a8f426921c26e21e54e493781e1d5eb39ffJohn Spurlock} 155