blob: 1b1638a52e9797d2b89940d9108bdebf7d060369 [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 Savillec9330dd2011-01-12 13:37:38 -080047import com.android.internal.telephony.ServiceStateTracker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import com.android.internal.telephony.TelephonyIntents;
49import com.android.server.am.BatteryStatsService;
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051/**
Wink Savillee9b06d72009-05-18 21:47:50 -070052 * Since phone process can be restarted, this class provides a centralized place
53 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 */
55class TelephonyRegistry extends ITelephonyRegistry.Stub {
56 private static final String TAG = "TelephonyRegistry";
Wink Savillec9acde92011-09-21 11:05:43 -070057 private static final boolean DBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59 private static class Record {
60 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 int events;
67 }
68
69 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070070
Joe Onorato163d8d92010-10-21 13:21:20 -040071 // access should be inside synchronized (mRecords) for these two fields
72 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
73 private final ArrayList<Record> mRecords = new ArrayList<Record>();
Wink Savillee9b06d72009-05-18 21:47:50 -070074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 private final IBatteryStats mBatteryStats;
76
77 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -070082
83 private SignalStrength mSignalStrength = new SignalStrength();
84
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -070090
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -080091 private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070098
Robert Greenwalt02648a42010-05-18 10:52:51 -070099 private ArrayList<String> mConnectedApns;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700100
Wink Savillef61101f2010-09-16 16:36:42 -0700101 private LinkProperties mDataConnectionLinkProperties;
102
103 private LinkCapabilities mDataConnectionLinkCapabilities;
Wink Savillee9b06d72009-05-18 21:47:50 -0700104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 private Bundle mCellLocation = new Bundle();
106
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700107 private int mDataConnectionNetworkType;
108
Wink Savillec9330dd2011-01-12 13:37:38 -0800109 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
Wink Savillefd2d0132010-10-28 14:22:26 -0700110
John Wang963db55d2012-03-30 16:04:06 -0700111 private CellInfo mCellInfo = null;
112
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700113 static final int PHONE_STATE_PERMISSION_MASK =
114 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
115 PhoneStateListener.LISTEN_CALL_STATE |
116 PhoneStateListener.LISTEN_DATA_ACTIVITY |
117 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
118 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
119
Wink Savillee9b06d72009-05-18 21:47:50 -0700120 // we keep a copy of all of the state so we can send it out when folks
121 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700123 // In these calls we call with the lock held. This is safe becasuse remote
124 // calls go through a oneway interface and local calls going through a
125 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126
127 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700128 CellLocation location = CellLocation.getEmpty();
129
130 // Note that location can be null for non-phone builds like
131 // like the generic one.
132 if (location != null) {
133 location.fillInNotifierBundle(mCellLocation);
134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 mContext = context;
136 mBatteryStats = BatteryStatsService.getService();
Robert Greenwalt02648a42010-05-18 10:52:51 -0700137 mConnectedApns = new ArrayList<String>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 }
139
140 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
141 boolean notifyNow) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800142 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
Wink Savillee9b06d72009-05-18 21:47:50 -0700143 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700145 /* Checks permission and throws Security exception */
146 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
148 synchronized (mRecords) {
149 // register
150 Record r = null;
151 find_and_add: {
152 IBinder b = callback.asBinder();
153 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700154 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 r = mRecords.get(i);
156 if (b == r.binder) {
157 break find_and_add;
158 }
159 }
160 r = new Record();
161 r.binder = b;
162 r.callback = callback;
163 r.pkgForDebug = pkgForDebug;
164 mRecords.add(r);
165 }
166 int send = events & (events ^ r.events);
167 r.events = events;
168 if (notifyNow) {
169 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400170 try {
171 r.callback.onServiceStateChanged(new ServiceState(mServiceState));
172 } catch (RemoteException ex) {
173 remove(r.binder);
174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 }
176 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
177 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700178 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
179 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
180 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 } catch (RemoteException ex) {
182 remove(r.binder);
183 }
184 }
185 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
186 try {
187 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
188 } catch (RemoteException ex) {
189 remove(r.binder);
190 }
191 }
192 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
193 try {
194 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
195 } catch (RemoteException ex) {
196 remove(r.binder);
197 }
198 }
199 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400200 try {
201 r.callback.onCellLocationChanged(new Bundle(mCellLocation));
202 } catch (RemoteException ex) {
203 remove(r.binder);
204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 }
206 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
207 try {
208 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
209 } catch (RemoteException ex) {
210 remove(r.binder);
211 }
212 }
213 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
214 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700215 r.callback.onDataConnectionStateChanged(mDataConnectionState,
216 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 } catch (RemoteException ex) {
218 remove(r.binder);
219 }
220 }
221 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
222 try {
223 r.callback.onDataActivity(mDataActivity);
224 } catch (RemoteException ex) {
225 remove(r.binder);
226 }
227 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700228 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
229 try {
230 r.callback.onSignalStrengthsChanged(mSignalStrength);
231 } catch (RemoteException ex) {
232 remove(r.binder);
233 }
234 }
Wink Savillefd2d0132010-10-28 14:22:26 -0700235 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
236 try {
237 r.callback.onOtaspChanged(mOtaspMode);
238 } catch (RemoteException ex) {
239 remove(r.binder);
240 }
241 }
John Wang963db55d2012-03-30 16:04:06 -0700242 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
243 try {
244 r.callback.onCellInfoChanged(new CellInfo(mCellInfo));
245 } catch (RemoteException ex) {
246 remove(r.binder);
247 }
248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 }
250 }
251 } else {
252 remove(callback.asBinder());
253 }
254 }
255
256 private void remove(IBinder binder) {
257 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700258 final int recordCount = mRecords.size();
259 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 if (mRecords.get(i).binder == binder) {
261 mRecords.remove(i);
262 return;
263 }
264 }
265 }
266 }
267
268 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700269 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700270 return;
271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 synchronized (mRecords) {
273 mCallState = state;
274 mCallIncomingNumber = incomingNumber;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700275 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
277 try {
278 r.callback.onCallStateChanged(state, incomingNumber);
279 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400280 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 }
282 }
283 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400284 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 }
286 broadcastCallStateChanged(state, incomingNumber);
287 }
288
289 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700290 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700291 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 synchronized (mRecords) {
294 mServiceState = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700295 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400297 try {
298 r.callback.onServiceStateChanged(new ServiceState(state));
299 } catch (RemoteException ex) {
300 mRemoveList.add(r.binder);
301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 }
303 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400304 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
306 broadcastServiceStateChanged(state);
307 }
308
Wink Savillee9b06d72009-05-18 21:47:50 -0700309 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700310 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700311 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700314 mSignalStrength = signalStrength;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700315 for (Record r : mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700316 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400317 try {
318 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
319 } catch (RemoteException ex) {
320 mRemoveList.add(r.binder);
321 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
324 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700325 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
326 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
327 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400329 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 }
331 }
332 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400333 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700335 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 }
337
John Wang963db55d2012-03-30 16:04:06 -0700338 public void notifyCellInfo(CellInfo cellInfo) {
339 if (!checkNotifyPermission("notifyCellInfo()")) {
340 return;
341 }
342
343 synchronized (mRecords) {
344 mCellInfo = cellInfo;
345 for (Record r : mRecords) {
346 if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
347 try {
348 r.callback.onCellInfoChanged(new CellInfo(cellInfo));
349 } catch (RemoteException ex) {
350 mRemoveList.add(r.binder);
351 }
352 }
353 }
354 handleRemoveListLocked();
355 }
356 }
357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700359 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700360 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 synchronized (mRecords) {
363 mMessageWaiting = mwi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700364 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
366 try {
367 r.callback.onMessageWaitingIndicatorChanged(mwi);
368 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400369 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 }
371 }
372 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400373 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
375 }
376
377 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700378 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700379 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 synchronized (mRecords) {
382 mCallForwarding = cfi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700383 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
385 try {
386 r.callback.onCallForwardingIndicatorChanged(cfi);
387 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400388 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390 }
391 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400392 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394 }
395
396 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700397 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700398 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 synchronized (mRecords) {
401 mDataActivity = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700402 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
404 try {
405 r.callback.onDataActivity(state);
406 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400407 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409 }
410 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400411 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 }
413 }
414
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700415 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700416 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700417 LinkCapabilities linkCapabilities, int networkType, boolean roaming) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700418 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700419 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700420 }
Wink Savillec9acde92011-09-21 11:05:43 -0700421 if (DBG) {
422 Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
Wink Saville26f5a382010-11-24 16:44:29 -0800423 + isDataConnectivityPossible + " reason='" + reason
424 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType);
Wink Savillec9acde92011-09-21 11:05:43 -0700425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 synchronized (mRecords) {
Robert Greenwalt02648a42010-05-18 10:52:51 -0700427 boolean modified = false;
428 if (state == TelephonyManager.DATA_CONNECTED) {
429 if (!mConnectedApns.contains(apnType)) {
430 mConnectedApns.add(apnType);
431 if (mDataConnectionState != state) {
432 mDataConnectionState = state;
433 modified = true;
434 }
435 }
436 } else {
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800437 if (mConnectedApns.remove(apnType)) {
438 if (mConnectedApns.isEmpty()) {
439 mDataConnectionState = state;
440 modified = true;
441 } else {
442 // leave mDataConnectionState as is and
443 // send out the new status for the APN in question.
444 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700445 }
446 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700447 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 mDataConnectionReason = reason;
Wink Savillef61101f2010-09-16 16:36:42 -0700449 mDataConnectionLinkProperties = linkProperties;
450 mDataConnectionLinkCapabilities = linkCapabilities;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700451 if (mDataConnectionNetworkType != networkType) {
452 mDataConnectionNetworkType = networkType;
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800453 // need to tell registered listeners about the new network type
Robert Greenwalt02648a42010-05-18 10:52:51 -0700454 modified = true;
455 }
456 if (modified) {
Wink Savillec9acde92011-09-21 11:05:43 -0700457 if (DBG) {
458 Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
yoonsung.name6fa1202011-08-20 21:39:12 -0700459 + ", " + mDataConnectionNetworkType + ")");
Wink Savillec9acde92011-09-21 11:05:43 -0700460 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700461 for (Record r : mRecords) {
462 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
463 try {
yoonsung.name6fa1202011-08-20 21:39:12 -0700464 r.callback.onDataConnectionStateChanged(mDataConnectionState,
465 mDataConnectionNetworkType);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700466 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400467 mRemoveList.add(r.binder);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 }
470 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400471 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 }
473 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700474 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700475 apnType, linkProperties, linkCapabilities, roaming);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 }
477
Robert Greenwalt02648a42010-05-18 10:52:51 -0700478 public void notifyDataConnectionFailed(String reason, String apnType) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700479 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700480 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 /*
Robert Greenwalt02648a42010-05-18 10:52:51 -0700483 * This is commented out because there is no onDataConnectionFailed callback
484 * in PhoneStateListener. There should be.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 synchronized (mRecords) {
486 mDataConnectionFailedReason = reason;
487 final int N = mRecords.size();
488 for (int i=N-1; i>=0; i--) {
489 Record r = mRecords.get(i);
490 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
491 // XXX
492 }
493 }
494 }
495 */
Robert Greenwalt02648a42010-05-18 10:52:51 -0700496 broadcastDataConnectionFailed(reason, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 }
498
499 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700500 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700501 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 synchronized (mRecords) {
504 mCellLocation = cellLocation;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700505 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400507 try {
508 r.callback.onCellLocationChanged(new Bundle(cellLocation));
509 } catch (RemoteException ex) {
510 mRemoveList.add(r.binder);
511 }
512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 }
514 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400515 handleRemoveListLocked();
Wink Savillee9b06d72009-05-18 21:47:50 -0700516 }
517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518
Wink Savillefd2d0132010-10-28 14:22:26 -0700519 public void notifyOtaspChanged(int otaspMode) {
520 if (!checkNotifyPermission("notifyOtaspChanged()" )) {
521 return;
522 }
523 synchronized (mRecords) {
524 mOtaspMode = otaspMode;
525 for (Record r : mRecords) {
526 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
527 try {
528 r.callback.onOtaspChanged(otaspMode);
529 } catch (RemoteException ex) {
530 mRemoveList.add(r.binder);
531 }
532 }
533 }
534 handleRemoveListLocked();
535 }
536 }
537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 @Override
539 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
540 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
541 != PackageManager.PERMISSION_GRANTED) {
542 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700543 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 return;
545 }
546 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700547 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 pw.println("last known state:");
549 pw.println(" mCallState=" + mCallState);
550 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
551 pw.println(" mServiceState=" + mServiceState);
552 pw.println(" mSignalStrength=" + mSignalStrength);
553 pw.println(" mMessageWaiting=" + mMessageWaiting);
554 pw.println(" mCallForwarding=" + mCallForwarding);
555 pw.println(" mDataActivity=" + mDataActivity);
556 pw.println(" mDataConnectionState=" + mDataConnectionState);
557 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
558 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
559 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
Wink Savillef61101f2010-09-16 16:36:42 -0700560 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
561 pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 pw.println(" mCellLocation=" + mCellLocation);
John Wang963db55d2012-03-30 16:04:06 -0700563 pw.println(" mCellInfo=" + mCellInfo);
Wink Savillee9b06d72009-05-18 21:47:50 -0700564 pw.println("registrations: count=" + recordCount);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700565 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
567 }
568 }
569 }
570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 //
572 // the legacy intent broadcasting
573 //
574
575 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700576 long ident = Binder.clearCallingIdentity();
577 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700578 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700579 } catch (RemoteException re) {
580 // Can't do much
581 } finally {
582 Binder.restoreCallingIdentity(ident);
583 }
584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
586 Bundle data = new Bundle();
587 state.fillInNotifierBundle(data);
588 intent.putExtras(data);
589 mContext.sendStickyBroadcast(intent);
590 }
591
Wink Savillee9b06d72009-05-18 21:47:50 -0700592 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700593 long ident = Binder.clearCallingIdentity();
594 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700595 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700596 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700597 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700598 } finally {
599 Binder.restoreCallingIdentity(ident);
600 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800603 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700604 Bundle data = new Bundle();
605 signalStrength.fillInNotifierBundle(data);
606 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 mContext.sendStickyBroadcast(intent);
608 }
609
610 private void broadcastCallStateChanged(int state, String incomingNumber) {
611 long ident = Binder.clearCallingIdentity();
612 try {
613 if (state == TelephonyManager.CALL_STATE_IDLE) {
614 mBatteryStats.notePhoneOff();
615 } else {
616 mBatteryStats.notePhoneOn();
617 }
618 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700619 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 } finally {
621 Binder.restoreCallingIdentity(ident);
622 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700625 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 if (!TextUtils.isEmpty(incomingNumber)) {
627 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
628 }
629 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
630 }
631
Robert Greenwalt42acef32009-08-12 16:08:25 -0700632 private void broadcastDataConnectionStateChanged(int state,
633 boolean isDataConnectivityPossible,
Wink Savillef61101f2010-09-16 16:36:42 -0700634 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700635 LinkCapabilities linkCapabilities, boolean roaming) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700636 // Note: not reporting to the battery stats service here, because the
637 // status bar takes care of that after taking into account all of the
638 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
640 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
641 if (!isDataConnectivityPossible) {
642 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
643 }
644 if (reason != null) {
645 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
646 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700647 if (linkProperties != null) {
648 intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700649 String iface = linkProperties.getInterfaceName();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700650 if (iface != null) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700651 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700652 }
653 }
Wink Savillef61101f2010-09-16 16:36:42 -0700654 if (linkCapabilities != null) {
655 intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
656 }
Robert Greenwalta6d42482011-09-02 15:19:31 -0700657 if (roaming) intent.putExtra(Phone.DATA_NETWORK_ROAMING_KEY, true);
658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 intent.putExtra(Phone.DATA_APN_KEY, apn);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700660 intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 mContext.sendStickyBroadcast(intent);
662 }
663
Robert Greenwalt02648a42010-05-18 10:52:51 -0700664 private void broadcastDataConnectionFailed(String reason, String apnType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
666 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700667 intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 mContext.sendStickyBroadcast(intent);
669 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700670
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700671 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700672 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
673 == PackageManager.PERMISSION_GRANTED) {
674 return true;
675 }
676 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700677 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Wink Savillec9acde92011-09-21 11:05:43 -0700678 if (DBG) Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700679 return false;
680 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700681
682 private void checkListenerPermission(int events) {
683 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
684 mContext.enforceCallingOrSelfPermission(
685 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
686
687 }
688
John Wang963db55d2012-03-30 16:04:06 -0700689 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
690 mContext.enforceCallingOrSelfPermission(
691 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
692
693 }
694
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700695 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
696 mContext.enforceCallingOrSelfPermission(
697 android.Manifest.permission.READ_PHONE_STATE, null);
698 }
699 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400700
701 private void handleRemoveListLocked() {
702 if (mRemoveList.size() > 0) {
703 for (IBinder b: mRemoveList) {
704 remove(b);
705 }
706 mRemoveList.clear();
707 }
708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709}