blob: 5010e46a74eb15b0377c90f8693bb141d1249dba [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
Hall Liu5a95a702020-01-06 19:04:10 -080019import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
20import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
21
John Spurlockbf991a82013-06-24 14:20:23 -040022import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.net.ConnectivityManager;
Remi NGUYEN VANf9354792019-08-27 20:21:58 +090027import android.os.Handler;
28import android.os.Looper;
John Spurlockbf991a82013-06-24 14:20:23 -040029import android.os.RemoteException;
Hall Liu5a95a702020-01-06 19:04:10 -080030import android.telephony.NetworkRegistrationInfo;
John Spurlockbf991a82013-06-24 14:20:23 -040031import android.telephony.PhoneStateListener;
32import android.telephony.ServiceState;
33import android.telephony.SignalStrength;
34import android.telephony.TelephonyManager;
35import android.util.Log;
36
37import com.android.internal.app.IBatteryStats;
John Spurlockbf991a82013-06-24 14:20:23 -040038import com.android.server.am.BatteryStatsService;
39
40public class DataConnectionStats extends BroadcastReceiver {
41 private static final String TAG = "DataConnectionStats";
42 private static final boolean DEBUG = false;
43
44 private final Context mContext;
45 private final IBatteryStats mBatteryStats;
Remi NGUYEN VANf9354792019-08-27 20:21:58 +090046 private final Handler mListenerHandler;
47 private final PhoneStateListener mPhoneStateListener;
John Spurlockbf991a82013-06-24 14:20:23 -040048
Jayachandran C316302c2019-12-05 12:04:33 -080049 private int mSimState = TelephonyManager.SIM_STATE_READY;
John Spurlockbf991a82013-06-24 14:20:23 -040050 private SignalStrength mSignalStrength;
51 private ServiceState mServiceState;
52 private int mDataState = TelephonyManager.DATA_DISCONNECTED;
53
Remi NGUYEN VANf9354792019-08-27 20:21:58 +090054 public DataConnectionStats(Context context, Handler listenerHandler) {
John Spurlockbf991a82013-06-24 14:20:23 -040055 mContext = context;
56 mBatteryStats = BatteryStatsService.getService();
Remi NGUYEN VANf9354792019-08-27 20:21:58 +090057 mListenerHandler = listenerHandler;
58 mPhoneStateListener = new PhoneStateListenerImpl(listenerHandler.getLooper());
John Spurlockbf991a82013-06-24 14:20:23 -040059 }
60
61 public void startMonitoring() {
62 TelephonyManager phone =
63 (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
64 phone.listen(mPhoneStateListener,
65 PhoneStateListener.LISTEN_SERVICE_STATE
66 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
67 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
68 | PhoneStateListener.LISTEN_DATA_ACTIVITY);
69
70 IntentFilter filter = new IntentFilter();
Jayachandran C316302c2019-12-05 12:04:33 -080071 filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
John Spurlockbf991a82013-06-24 14:20:23 -040072 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
73 filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
Remi NGUYEN VANf9354792019-08-27 20:21:58 +090074 mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler);
John Spurlockbf991a82013-06-24 14:20:23 -040075 }
76
77 @Override
78 public void onReceive(Context context, Intent intent) {
79 final String action = intent.getAction();
Jayachandran C316302c2019-12-05 12:04:33 -080080 if (action.equals(Intent.ACTION_SIM_STATE_CHANGED)) {
John Spurlockbf991a82013-06-24 14:20:23 -040081 updateSimState(intent);
82 notePhoneDataConnectionState();
83 } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
84 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
85 notePhoneDataConnectionState();
86 }
87 }
88
89 private void notePhoneDataConnectionState() {
90 if (mServiceState == null) {
91 return;
92 }
Jayachandran C316302c2019-12-05 12:04:33 -080093 boolean simReadyOrUnknown = mSimState == TelephonyManager.SIM_STATE_READY
94 || mSimState == TelephonyManager.SIM_STATE_UNKNOWN;
John Spurlockbf991a82013-06-24 14:20:23 -040095 boolean visible = (simReadyOrUnknown || isCdma()) // we only check the sim state for GSM
96 && hasService()
97 && mDataState == TelephonyManager.DATA_CONNECTED;
Hall Liu5a95a702020-01-06 19:04:10 -080098 NetworkRegistrationInfo regInfo =
99 mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
100 int networkType = regInfo == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
101 : regInfo.getAccessNetworkTechnology();
John Spurlockbf991a82013-06-24 14:20:23 -0400102 if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
103 networkType, visible ? "" : "not "));
104 try {
Blake Kragtenbc75c722019-03-20 17:14:58 -0700105 mBatteryStats.notePhoneDataConnectionState(networkType, visible,
106 mServiceState.getState());
John Spurlockbf991a82013-06-24 14:20:23 -0400107 } catch (RemoteException e) {
108 Log.w(TAG, "Error noting data connection state", e);
109 }
110 }
111
112 private final void updateSimState(Intent intent) {
Jayachandran C316302c2019-12-05 12:04:33 -0800113 String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
114 if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) {
115 mSimState = TelephonyManager.SIM_STATE_ABSENT;
116 } else if (Intent.SIM_STATE_READY.equals(stateExtra)) {
117 mSimState = TelephonyManager.SIM_STATE_READY;
118 } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) {
John Spurlockbf991a82013-06-24 14:20:23 -0400119 final String lockedReason =
Jayachandran C316302c2019-12-05 12:04:33 -0800120 intent.getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
121 if (Intent.SIM_LOCKED_ON_PIN.equals(lockedReason)) {
122 mSimState = TelephonyManager.SIM_STATE_PIN_REQUIRED;
123 } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) {
124 mSimState = TelephonyManager.SIM_STATE_PUK_REQUIRED;
John Spurlockbf991a82013-06-24 14:20:23 -0400125 } else {
Jayachandran C316302c2019-12-05 12:04:33 -0800126 mSimState = TelephonyManager.SIM_STATE_NETWORK_LOCKED;
John Spurlockbf991a82013-06-24 14:20:23 -0400127 }
128 } else {
Jayachandran C316302c2019-12-05 12:04:33 -0800129 mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
John Spurlockbf991a82013-06-24 14:20:23 -0400130 }
131 }
132
133 private boolean isCdma() {
134 return mSignalStrength != null && !mSignalStrength.isGsm();
135 }
136
137 private boolean hasService() {
138 return mServiceState != null
139 && mServiceState.getState() != ServiceState.STATE_OUT_OF_SERVICE
140 && mServiceState.getState() != ServiceState.STATE_POWER_OFF;
141 }
142
Remi NGUYEN VANf9354792019-08-27 20:21:58 +0900143 private class PhoneStateListenerImpl extends PhoneStateListener {
144 PhoneStateListenerImpl(Looper looper) {
145 super(looper);
146 }
147
John Spurlockbf991a82013-06-24 14:20:23 -0400148 @Override
149 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
150 mSignalStrength = signalStrength;
151 }
152
153 @Override
154 public void onServiceStateChanged(ServiceState state) {
155 mServiceState = state;
156 notePhoneDataConnectionState();
157 }
158
159 @Override
160 public void onDataConnectionStateChanged(int state, int networkType) {
161 mDataState = state;
162 notePhoneDataConnectionState();
163 }
164
165 @Override
166 public void onDataActivity(int direction) {
167 notePhoneDataConnectionState();
168 }
169 };
170}