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