blob: c23a1d9c10ecfbea81e44168a2bcd79d23d82b8e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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;
18
19import android.content.Context;
20import android.content.Intent;
21import android.content.pm.PackageManager;
Wink Savillef61101f2010-09-16 16:36:42 -070022import android.net.LinkCapabilities;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070023import android.net.LinkProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.Binder;
25import android.os.Bundle;
26import android.os.IBinder;
27import android.os.RemoteException;
28import android.telephony.CellLocation;
29import android.telephony.PhoneStateListener;
30import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070031import android.telephony.SignalStrength;
John Wang963db55d2012-03-30 16:04:06 -070032import android.telephony.CellInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.telephony.TelephonyManager;
34import android.text.TextUtils;
Joe Onorato8a9b2202010-02-26 18:56:32 -080035import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37import java.util.ArrayList;
38import java.io.FileDescriptor;
39import java.io.PrintWriter;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070040import java.net.NetworkInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42import com.android.internal.app.IBatteryStats;
43import com.android.internal.telephony.ITelephonyRegistry;
44import com.android.internal.telephony.IPhoneStateListener;
45import com.android.internal.telephony.DefaultPhoneNotifier;
46import com.android.internal.telephony.Phone;
Wink Savillea639b312012-07-10 12:37:54 -070047import com.android.internal.telephony.PhoneConstants;
Wink Savillec9330dd2011-01-12 13:37:38 -080048import com.android.internal.telephony.ServiceStateTracker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import com.android.internal.telephony.TelephonyIntents;
50import com.android.server.am.BatteryStatsService;
51
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052/**
Wink Savillee9b06d72009-05-18 21:47:50 -070053 * Since phone process can be restarted, this class provides a centralized place
54 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 */
56class TelephonyRegistry extends ITelephonyRegistry.Stub {
57 private static final String TAG = "TelephonyRegistry";
Wink Savillec9acde92011-09-21 11:05:43 -070058 private static final boolean DBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60 private static class Record {
61 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 int events;
68 }
69
70 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070071
Joe Onorato163d8d92010-10-21 13:21:20 -040072 // access should be inside synchronized (mRecords) for these two fields
73 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
74 private final ArrayList<Record> mRecords = new ArrayList<Record>();
Wink Savillee9b06d72009-05-18 21:47:50 -070075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 private final IBatteryStats mBatteryStats;
77
78 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -070083
84 private SignalStrength mSignalStrength = new SignalStrength();
85
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -070091
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -080092 private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070099
Robert Greenwalt02648a42010-05-18 10:52:51 -0700100 private ArrayList<String> mConnectedApns;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700101
Wink Savillef61101f2010-09-16 16:36:42 -0700102 private LinkProperties mDataConnectionLinkProperties;
103
104 private LinkCapabilities mDataConnectionLinkCapabilities;
Wink Savillee9b06d72009-05-18 21:47:50 -0700105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 private Bundle mCellLocation = new Bundle();
107
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700108 private int mDataConnectionNetworkType;
109
Wink Savillec9330dd2011-01-12 13:37:38 -0800110 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
Wink Savillefd2d0132010-10-28 14:22:26 -0700111
John Wang963db55d2012-03-30 16:04:06 -0700112 private CellInfo mCellInfo = null;
113
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700114 static final int PHONE_STATE_PERMISSION_MASK =
115 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
116 PhoneStateListener.LISTEN_CALL_STATE |
117 PhoneStateListener.LISTEN_DATA_ACTIVITY |
118 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
119 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
120
Wink Savillee9b06d72009-05-18 21:47:50 -0700121 // we keep a copy of all of the state so we can send it out when folks
122 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700124 // In these calls we call with the lock held. This is safe becasuse remote
125 // calls go through a oneway interface and local calls going through a
126 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127
128 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700129 CellLocation location = CellLocation.getEmpty();
130
131 // Note that location can be null for non-phone builds like
132 // like the generic one.
133 if (location != null) {
134 location.fillInNotifierBundle(mCellLocation);
135 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 mContext = context;
137 mBatteryStats = BatteryStatsService.getService();
Robert Greenwalt02648a42010-05-18 10:52:51 -0700138 mConnectedApns = new ArrayList<String>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 }
140
141 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
142 boolean notifyNow) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800143 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
Wink Savillee9b06d72009-05-18 21:47:50 -0700144 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700146 /* Checks permission and throws Security exception */
147 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
149 synchronized (mRecords) {
150 // register
151 Record r = null;
152 find_and_add: {
153 IBinder b = callback.asBinder();
154 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700155 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 r = mRecords.get(i);
157 if (b == r.binder) {
158 break find_and_add;
159 }
160 }
161 r = new Record();
162 r.binder = b;
163 r.callback = callback;
164 r.pkgForDebug = pkgForDebug;
165 mRecords.add(r);
166 }
167 int send = events & (events ^ r.events);
168 r.events = events;
169 if (notifyNow) {
170 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400171 try {
172 r.callback.onServiceStateChanged(new ServiceState(mServiceState));
173 } catch (RemoteException ex) {
174 remove(r.binder);
175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 }
177 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
178 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700179 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
180 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
181 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 } catch (RemoteException ex) {
183 remove(r.binder);
184 }
185 }
186 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
187 try {
188 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
189 } catch (RemoteException ex) {
190 remove(r.binder);
191 }
192 }
193 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
194 try {
195 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
196 } catch (RemoteException ex) {
197 remove(r.binder);
198 }
199 }
200 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400201 try {
202 r.callback.onCellLocationChanged(new Bundle(mCellLocation));
203 } catch (RemoteException ex) {
204 remove(r.binder);
205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 }
207 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
208 try {
209 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
210 } catch (RemoteException ex) {
211 remove(r.binder);
212 }
213 }
214 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
215 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700216 r.callback.onDataConnectionStateChanged(mDataConnectionState,
217 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 } catch (RemoteException ex) {
219 remove(r.binder);
220 }
221 }
222 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
223 try {
224 r.callback.onDataActivity(mDataActivity);
225 } catch (RemoteException ex) {
226 remove(r.binder);
227 }
228 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700229 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
230 try {
231 r.callback.onSignalStrengthsChanged(mSignalStrength);
232 } catch (RemoteException ex) {
233 remove(r.binder);
234 }
235 }
Wink Savillefd2d0132010-10-28 14:22:26 -0700236 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
237 try {
238 r.callback.onOtaspChanged(mOtaspMode);
239 } catch (RemoteException ex) {
240 remove(r.binder);
241 }
242 }
John Wang963db55d2012-03-30 16:04:06 -0700243 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
244 try {
245 r.callback.onCellInfoChanged(new CellInfo(mCellInfo));
246 } catch (RemoteException ex) {
247 remove(r.binder);
248 }
249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 }
251 }
252 } else {
253 remove(callback.asBinder());
254 }
255 }
256
257 private void remove(IBinder binder) {
258 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700259 final int recordCount = mRecords.size();
260 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 if (mRecords.get(i).binder == binder) {
262 mRecords.remove(i);
263 return;
264 }
265 }
266 }
267 }
268
269 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700270 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700271 return;
272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 synchronized (mRecords) {
274 mCallState = state;
275 mCallIncomingNumber = incomingNumber;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700276 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
278 try {
279 r.callback.onCallStateChanged(state, incomingNumber);
280 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400281 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 }
283 }
284 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400285 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 }
287 broadcastCallStateChanged(state, incomingNumber);
288 }
289
290 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700291 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700292 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 synchronized (mRecords) {
295 mServiceState = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700296 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400298 try {
299 r.callback.onServiceStateChanged(new ServiceState(state));
300 } catch (RemoteException ex) {
301 mRemoveList.add(r.binder);
302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 }
304 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400305 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 }
307 broadcastServiceStateChanged(state);
308 }
309
Wink Savillee9b06d72009-05-18 21:47:50 -0700310 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700311 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700312 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700315 mSignalStrength = signalStrength;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700316 for (Record r : mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700317 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400318 try {
319 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
320 } catch (RemoteException ex) {
321 mRemoveList.add(r.binder);
322 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
325 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700326 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
327 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
328 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400330 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332 }
333 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400334 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700336 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 }
338
John Wang963db55d2012-03-30 16:04:06 -0700339 public void notifyCellInfo(CellInfo cellInfo) {
340 if (!checkNotifyPermission("notifyCellInfo()")) {
341 return;
342 }
343
344 synchronized (mRecords) {
345 mCellInfo = cellInfo;
346 for (Record r : mRecords) {
347 if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
348 try {
349 r.callback.onCellInfoChanged(new CellInfo(cellInfo));
350 } catch (RemoteException ex) {
351 mRemoveList.add(r.binder);
352 }
353 }
354 }
355 handleRemoveListLocked();
356 }
357 }
358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700360 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700361 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 synchronized (mRecords) {
364 mMessageWaiting = mwi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700365 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
367 try {
368 r.callback.onMessageWaitingIndicatorChanged(mwi);
369 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400370 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 }
372 }
373 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400374 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 }
376 }
377
378 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700379 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700380 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 synchronized (mRecords) {
383 mCallForwarding = cfi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700384 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
386 try {
387 r.callback.onCallForwardingIndicatorChanged(cfi);
388 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400389 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391 }
392 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400393 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 }
395 }
396
397 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700398 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700399 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 synchronized (mRecords) {
402 mDataActivity = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700403 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
405 try {
406 r.callback.onDataActivity(state);
407 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400408 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
410 }
411 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400412 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 }
414 }
415
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700416 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700417 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700418 LinkCapabilities linkCapabilities, int networkType, boolean roaming) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700419 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700420 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700421 }
Wink Savillec9acde92011-09-21 11:05:43 -0700422 if (DBG) {
423 Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
Wink Saville26f5a382010-11-24 16:44:29 -0800424 + isDataConnectivityPossible + " reason='" + reason
425 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType);
Wink Savillec9acde92011-09-21 11:05:43 -0700426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 synchronized (mRecords) {
Robert Greenwalt02648a42010-05-18 10:52:51 -0700428 boolean modified = false;
429 if (state == TelephonyManager.DATA_CONNECTED) {
430 if (!mConnectedApns.contains(apnType)) {
431 mConnectedApns.add(apnType);
432 if (mDataConnectionState != state) {
433 mDataConnectionState = state;
434 modified = true;
435 }
436 }
437 } else {
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800438 if (mConnectedApns.remove(apnType)) {
439 if (mConnectedApns.isEmpty()) {
440 mDataConnectionState = state;
441 modified = true;
442 } else {
443 // leave mDataConnectionState as is and
444 // send out the new status for the APN in question.
445 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700446 }
447 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700448 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 mDataConnectionReason = reason;
Wink Savillef61101f2010-09-16 16:36:42 -0700450 mDataConnectionLinkProperties = linkProperties;
451 mDataConnectionLinkCapabilities = linkCapabilities;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700452 if (mDataConnectionNetworkType != networkType) {
453 mDataConnectionNetworkType = networkType;
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800454 // need to tell registered listeners about the new network type
Robert Greenwalt02648a42010-05-18 10:52:51 -0700455 modified = true;
456 }
457 if (modified) {
Wink Savillec9acde92011-09-21 11:05:43 -0700458 if (DBG) {
459 Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
yoonsung.name6fa1202011-08-20 21:39:12 -0700460 + ", " + mDataConnectionNetworkType + ")");
Wink Savillec9acde92011-09-21 11:05:43 -0700461 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700462 for (Record r : mRecords) {
463 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
464 try {
yoonsung.name6fa1202011-08-20 21:39:12 -0700465 r.callback.onDataConnectionStateChanged(mDataConnectionState,
466 mDataConnectionNetworkType);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700467 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400468 mRemoveList.add(r.binder);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 }
471 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400472 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 }
474 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700475 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700476 apnType, linkProperties, linkCapabilities, roaming);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 }
478
Robert Greenwalt02648a42010-05-18 10:52:51 -0700479 public void notifyDataConnectionFailed(String reason, String apnType) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700480 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700481 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 /*
Robert Greenwalt02648a42010-05-18 10:52:51 -0700484 * This is commented out because there is no onDataConnectionFailed callback
485 * in PhoneStateListener. There should be.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 synchronized (mRecords) {
487 mDataConnectionFailedReason = reason;
488 final int N = mRecords.size();
489 for (int i=N-1; i>=0; i--) {
490 Record r = mRecords.get(i);
491 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
492 // XXX
493 }
494 }
495 }
496 */
Robert Greenwalt02648a42010-05-18 10:52:51 -0700497 broadcastDataConnectionFailed(reason, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 }
499
500 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700501 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700502 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 synchronized (mRecords) {
505 mCellLocation = cellLocation;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700506 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400508 try {
509 r.callback.onCellLocationChanged(new Bundle(cellLocation));
510 } catch (RemoteException ex) {
511 mRemoveList.add(r.binder);
512 }
513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 }
515 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400516 handleRemoveListLocked();
Wink Savillee9b06d72009-05-18 21:47:50 -0700517 }
518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519
Wink Savillefd2d0132010-10-28 14:22:26 -0700520 public void notifyOtaspChanged(int otaspMode) {
521 if (!checkNotifyPermission("notifyOtaspChanged()" )) {
522 return;
523 }
524 synchronized (mRecords) {
525 mOtaspMode = otaspMode;
526 for (Record r : mRecords) {
527 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
528 try {
529 r.callback.onOtaspChanged(otaspMode);
530 } catch (RemoteException ex) {
531 mRemoveList.add(r.binder);
532 }
533 }
534 }
535 handleRemoveListLocked();
536 }
537 }
538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 @Override
540 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
541 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
542 != PackageManager.PERMISSION_GRANTED) {
543 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700544 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 return;
546 }
547 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700548 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 pw.println("last known state:");
550 pw.println(" mCallState=" + mCallState);
551 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
552 pw.println(" mServiceState=" + mServiceState);
553 pw.println(" mSignalStrength=" + mSignalStrength);
554 pw.println(" mMessageWaiting=" + mMessageWaiting);
555 pw.println(" mCallForwarding=" + mCallForwarding);
556 pw.println(" mDataActivity=" + mDataActivity);
557 pw.println(" mDataConnectionState=" + mDataConnectionState);
558 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
559 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
560 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
Wink Savillef61101f2010-09-16 16:36:42 -0700561 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
562 pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 pw.println(" mCellLocation=" + mCellLocation);
John Wang963db55d2012-03-30 16:04:06 -0700564 pw.println(" mCellInfo=" + mCellInfo);
Wink Savillee9b06d72009-05-18 21:47:50 -0700565 pw.println("registrations: count=" + recordCount);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700566 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
568 }
569 }
570 }
571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 //
573 // the legacy intent broadcasting
574 //
575
576 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700577 long ident = Binder.clearCallingIdentity();
578 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700579 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700580 } catch (RemoteException re) {
581 // Can't do much
582 } finally {
583 Binder.restoreCallingIdentity(ident);
584 }
585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
587 Bundle data = new Bundle();
588 state.fillInNotifierBundle(data);
589 intent.putExtras(data);
590 mContext.sendStickyBroadcast(intent);
591 }
592
Wink Savillee9b06d72009-05-18 21:47:50 -0700593 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700594 long ident = Binder.clearCallingIdentity();
595 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700596 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700597 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700598 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700599 } finally {
600 Binder.restoreCallingIdentity(ident);
601 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800604 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700605 Bundle data = new Bundle();
606 signalStrength.fillInNotifierBundle(data);
607 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 mContext.sendStickyBroadcast(intent);
609 }
610
611 private void broadcastCallStateChanged(int state, String incomingNumber) {
612 long ident = Binder.clearCallingIdentity();
613 try {
614 if (state == TelephonyManager.CALL_STATE_IDLE) {
615 mBatteryStats.notePhoneOff();
616 } else {
617 mBatteryStats.notePhoneOn();
618 }
619 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700620 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 } finally {
622 Binder.restoreCallingIdentity(ident);
623 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700626 intent.putExtra(PhoneConstants.STATE_KEY,
627 DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 if (!TextUtils.isEmpty(incomingNumber)) {
629 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
630 }
631 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
632 }
633
Robert Greenwalt42acef32009-08-12 16:08:25 -0700634 private void broadcastDataConnectionStateChanged(int state,
635 boolean isDataConnectivityPossible,
Wink Savillef61101f2010-09-16 16:36:42 -0700636 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700637 LinkCapabilities linkCapabilities, boolean roaming) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700638 // Note: not reporting to the battery stats service here, because the
639 // status bar takes care of that after taking into account all of the
640 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700642 intent.putExtra(PhoneConstants.STATE_KEY,
643 DefaultPhoneNotifier.convertDataState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 if (!isDataConnectivityPossible) {
Wink Savillea639b312012-07-10 12:37:54 -0700645 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 }
647 if (reason != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700648 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700650 if (linkProperties != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700651 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700652 String iface = linkProperties.getInterfaceName();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700653 if (iface != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700654 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700655 }
656 }
Wink Savillef61101f2010-09-16 16:36:42 -0700657 if (linkCapabilities != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700658 intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
Wink Savillef61101f2010-09-16 16:36:42 -0700659 }
Wink Savillea639b312012-07-10 12:37:54 -0700660 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
Robert Greenwalta6d42482011-09-02 15:19:31 -0700661
Wink Savillea639b312012-07-10 12:37:54 -0700662 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
663 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 mContext.sendStickyBroadcast(intent);
665 }
666
Robert Greenwalt02648a42010-05-18 10:52:51 -0700667 private void broadcastDataConnectionFailed(String reason, String apnType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Wink Savillea639b312012-07-10 12:37:54 -0700669 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
670 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 mContext.sendStickyBroadcast(intent);
672 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700673
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700674 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700675 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
676 == PackageManager.PERMISSION_GRANTED) {
677 return true;
678 }
679 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700680 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Wink Savillec9acde92011-09-21 11:05:43 -0700681 if (DBG) Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700682 return false;
683 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700684
685 private void checkListenerPermission(int events) {
686 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
687 mContext.enforceCallingOrSelfPermission(
688 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
689
690 }
691
John Wang963db55d2012-03-30 16:04:06 -0700692 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
693 mContext.enforceCallingOrSelfPermission(
694 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
695
696 }
697
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700698 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
699 mContext.enforceCallingOrSelfPermission(
700 android.Manifest.permission.READ_PHONE_STATE, null);
701 }
702 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400703
704 private void handleRemoveListLocked() {
705 if (mRemoveList.size() > 0) {
706 for (IBinder b: mRemoveList) {
707 remove(b);
708 }
709 mRemoveList.clear();
710 }
711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712}