blob: 8361477ee3f1384880a4256a978b9d22ff4f37ec [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;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070028import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.telephony.CellLocation;
30import android.telephony.PhoneStateListener;
31import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070032import android.telephony.SignalStrength;
John Wang963db55d2012-03-30 16:04:06 -070033import android.telephony.CellInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.telephony.TelephonyManager;
35import android.text.TextUtils;
Joe Onorato8a9b2202010-02-26 18:56:32 -080036import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
38import java.util.ArrayList;
Wink Savilleb208a242012-07-25 14:08:09 -070039import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.io.FileDescriptor;
41import java.io.PrintWriter;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070042import java.net.NetworkInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043
44import com.android.internal.app.IBatteryStats;
45import com.android.internal.telephony.ITelephonyRegistry;
46import com.android.internal.telephony.IPhoneStateListener;
47import com.android.internal.telephony.DefaultPhoneNotifier;
48import com.android.internal.telephony.Phone;
Wink Savillea639b312012-07-10 12:37:54 -070049import com.android.internal.telephony.PhoneConstants;
Wink Savillec9330dd2011-01-12 13:37:38 -080050import com.android.internal.telephony.ServiceStateTracker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import com.android.internal.telephony.TelephonyIntents;
52import com.android.server.am.BatteryStatsService;
53
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054/**
Wink Savillee9b06d72009-05-18 21:47:50 -070055 * Since phone process can be restarted, this class provides a centralized place
56 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 */
58class TelephonyRegistry extends ITelephonyRegistry.Stub {
59 private static final String TAG = "TelephonyRegistry";
Wink Savillec9acde92011-09-21 11:05:43 -070060 private static final boolean DBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
62 private static class Record {
63 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 int events;
70 }
71
72 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070073
Joe Onorato163d8d92010-10-21 13:21:20 -040074 // access should be inside synchronized (mRecords) for these two fields
75 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
76 private final ArrayList<Record> mRecords = new ArrayList<Record>();
Wink Savillee9b06d72009-05-18 21:47:50 -070077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 private final IBatteryStats mBatteryStats;
79
80 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -070085
86 private SignalStrength mSignalStrength = new SignalStrength();
87
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -070093
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -080094 private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -070095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -0700101
Robert Greenwalt02648a42010-05-18 10:52:51 -0700102 private ArrayList<String> mConnectedApns;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700103
Wink Savillef61101f2010-09-16 16:36:42 -0700104 private LinkProperties mDataConnectionLinkProperties;
105
106 private LinkCapabilities mDataConnectionLinkCapabilities;
Wink Savillee9b06d72009-05-18 21:47:50 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 private Bundle mCellLocation = new Bundle();
109
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700110 private int mDataConnectionNetworkType;
111
Wink Savillec9330dd2011-01-12 13:37:38 -0800112 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
Wink Savillefd2d0132010-10-28 14:22:26 -0700113
Wink Savilleb208a242012-07-25 14:08:09 -0700114 private List<CellInfo> mCellInfo = null;
John Wang963db55d2012-03-30 16:04:06 -0700115
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700116 static final int PHONE_STATE_PERMISSION_MASK =
117 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
118 PhoneStateListener.LISTEN_CALL_STATE |
119 PhoneStateListener.LISTEN_DATA_ACTIVITY |
120 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
121 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
122
Wink Savillee9b06d72009-05-18 21:47:50 -0700123 // we keep a copy of all of the state so we can send it out when folks
124 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700126 // In these calls we call with the lock held. This is safe becasuse remote
127 // calls go through a oneway interface and local calls going through a
128 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129
130 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700131 CellLocation location = CellLocation.getEmpty();
132
133 // Note that location can be null for non-phone builds like
134 // like the generic one.
135 if (location != null) {
136 location.fillInNotifierBundle(mCellLocation);
137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 mContext = context;
139 mBatteryStats = BatteryStatsService.getService();
Robert Greenwalt02648a42010-05-18 10:52:51 -0700140 mConnectedApns = new ArrayList<String>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 }
142
143 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
144 boolean notifyNow) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800145 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
Wink Savillee9b06d72009-05-18 21:47:50 -0700146 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700148 /* Checks permission and throws Security exception */
149 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
151 synchronized (mRecords) {
152 // register
153 Record r = null;
154 find_and_add: {
155 IBinder b = callback.asBinder();
156 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700157 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 r = mRecords.get(i);
159 if (b == r.binder) {
160 break find_and_add;
161 }
162 }
163 r = new Record();
164 r.binder = b;
165 r.callback = callback;
166 r.pkgForDebug = pkgForDebug;
167 mRecords.add(r);
168 }
169 int send = events & (events ^ r.events);
170 r.events = events;
171 if (notifyNow) {
172 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400173 try {
174 r.callback.onServiceStateChanged(new ServiceState(mServiceState));
175 } catch (RemoteException ex) {
176 remove(r.binder);
177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 }
179 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
180 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700181 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
182 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
183 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 } catch (RemoteException ex) {
185 remove(r.binder);
186 }
187 }
188 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
189 try {
190 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
191 } catch (RemoteException ex) {
192 remove(r.binder);
193 }
194 }
195 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
196 try {
197 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
198 } catch (RemoteException ex) {
199 remove(r.binder);
200 }
201 }
202 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400203 try {
204 r.callback.onCellLocationChanged(new Bundle(mCellLocation));
205 } catch (RemoteException ex) {
206 remove(r.binder);
207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 }
209 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
210 try {
211 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
212 } catch (RemoteException ex) {
213 remove(r.binder);
214 }
215 }
216 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
217 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700218 r.callback.onDataConnectionStateChanged(mDataConnectionState,
219 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 } catch (RemoteException ex) {
221 remove(r.binder);
222 }
223 }
224 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
225 try {
226 r.callback.onDataActivity(mDataActivity);
227 } catch (RemoteException ex) {
228 remove(r.binder);
229 }
230 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700231 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
232 try {
233 r.callback.onSignalStrengthsChanged(mSignalStrength);
234 } catch (RemoteException ex) {
235 remove(r.binder);
236 }
237 }
Wink Savillefd2d0132010-10-28 14:22:26 -0700238 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
239 try {
240 r.callback.onOtaspChanged(mOtaspMode);
241 } catch (RemoteException ex) {
242 remove(r.binder);
243 }
244 }
John Wang963db55d2012-03-30 16:04:06 -0700245 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
246 try {
Wink Savilleb208a242012-07-25 14:08:09 -0700247 r.callback.onCellInfoChanged(mCellInfo);
John Wang963db55d2012-03-30 16:04:06 -0700248 } catch (RemoteException ex) {
249 remove(r.binder);
250 }
251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
253 }
254 } else {
255 remove(callback.asBinder());
256 }
257 }
258
259 private void remove(IBinder binder) {
260 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700261 final int recordCount = mRecords.size();
262 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 if (mRecords.get(i).binder == binder) {
264 mRecords.remove(i);
265 return;
266 }
267 }
268 }
269 }
270
271 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700272 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700273 return;
274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 synchronized (mRecords) {
276 mCallState = state;
277 mCallIncomingNumber = incomingNumber;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700278 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
280 try {
281 r.callback.onCallStateChanged(state, incomingNumber);
282 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400283 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 }
285 }
286 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400287 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 }
289 broadcastCallStateChanged(state, incomingNumber);
290 }
291
292 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700293 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700294 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 synchronized (mRecords) {
297 mServiceState = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700298 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400300 try {
301 r.callback.onServiceStateChanged(new ServiceState(state));
302 } catch (RemoteException ex) {
303 mRemoveList.add(r.binder);
304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
306 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400307 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 }
309 broadcastServiceStateChanged(state);
310 }
311
Wink Savillee9b06d72009-05-18 21:47:50 -0700312 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700313 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700314 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700317 mSignalStrength = signalStrength;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700318 for (Record r : mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700319 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400320 try {
321 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
322 } catch (RemoteException ex) {
323 mRemoveList.add(r.binder);
324 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
327 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700328 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
329 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
330 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400332 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 }
334 }
335 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400336 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700338 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 }
340
Wink Savilleb208a242012-07-25 14:08:09 -0700341 public void notifyCellInfo(List<CellInfo> cellInfo) {
John Wang963db55d2012-03-30 16:04:06 -0700342 if (!checkNotifyPermission("notifyCellInfo()")) {
343 return;
344 }
345
346 synchronized (mRecords) {
347 mCellInfo = cellInfo;
348 for (Record r : mRecords) {
349 if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
350 try {
Wink Savilleb208a242012-07-25 14:08:09 -0700351 r.callback.onCellInfoChanged(cellInfo);
John Wang963db55d2012-03-30 16:04:06 -0700352 } catch (RemoteException ex) {
353 mRemoveList.add(r.binder);
354 }
355 }
356 }
357 handleRemoveListLocked();
358 }
359 }
360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700362 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700363 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 synchronized (mRecords) {
366 mMessageWaiting = mwi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700367 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
369 try {
370 r.callback.onMessageWaitingIndicatorChanged(mwi);
371 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400372 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 }
374 }
375 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400376 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 }
378 }
379
380 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700381 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700382 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 synchronized (mRecords) {
385 mCallForwarding = cfi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700386 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
388 try {
389 r.callback.onCallForwardingIndicatorChanged(cfi);
390 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400391 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
393 }
394 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400395 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 }
397 }
398
399 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700400 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700401 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 synchronized (mRecords) {
404 mDataActivity = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700405 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
407 try {
408 r.callback.onDataActivity(state);
409 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400410 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
412 }
413 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400414 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 }
416 }
417
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700418 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700419 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700420 LinkCapabilities linkCapabilities, int networkType, boolean roaming) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700421 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700422 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700423 }
Wink Savillec9acde92011-09-21 11:05:43 -0700424 if (DBG) {
425 Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
Wink Saville26f5a382010-11-24 16:44:29 -0800426 + isDataConnectivityPossible + " reason='" + reason
427 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType);
Wink Savillec9acde92011-09-21 11:05:43 -0700428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 synchronized (mRecords) {
Robert Greenwalt02648a42010-05-18 10:52:51 -0700430 boolean modified = false;
431 if (state == TelephonyManager.DATA_CONNECTED) {
432 if (!mConnectedApns.contains(apnType)) {
433 mConnectedApns.add(apnType);
434 if (mDataConnectionState != state) {
435 mDataConnectionState = state;
436 modified = true;
437 }
438 }
439 } else {
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800440 if (mConnectedApns.remove(apnType)) {
441 if (mConnectedApns.isEmpty()) {
442 mDataConnectionState = state;
443 modified = true;
444 } else {
445 // leave mDataConnectionState as is and
446 // send out the new status for the APN in question.
447 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700448 }
449 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700450 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 mDataConnectionReason = reason;
Wink Savillef61101f2010-09-16 16:36:42 -0700452 mDataConnectionLinkProperties = linkProperties;
453 mDataConnectionLinkCapabilities = linkCapabilities;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700454 if (mDataConnectionNetworkType != networkType) {
455 mDataConnectionNetworkType = networkType;
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800456 // need to tell registered listeners about the new network type
Robert Greenwalt02648a42010-05-18 10:52:51 -0700457 modified = true;
458 }
459 if (modified) {
Wink Savillec9acde92011-09-21 11:05:43 -0700460 if (DBG) {
461 Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
yoonsung.name6fa1202011-08-20 21:39:12 -0700462 + ", " + mDataConnectionNetworkType + ")");
Wink Savillec9acde92011-09-21 11:05:43 -0700463 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700464 for (Record r : mRecords) {
465 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
466 try {
yoonsung.name6fa1202011-08-20 21:39:12 -0700467 r.callback.onDataConnectionStateChanged(mDataConnectionState,
468 mDataConnectionNetworkType);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700469 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400470 mRemoveList.add(r.binder);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 }
473 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400474 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 }
476 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700477 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700478 apnType, linkProperties, linkCapabilities, roaming);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 }
480
Robert Greenwalt02648a42010-05-18 10:52:51 -0700481 public void notifyDataConnectionFailed(String reason, String apnType) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700482 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700483 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700484 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 /*
Robert Greenwalt02648a42010-05-18 10:52:51 -0700486 * This is commented out because there is no onDataConnectionFailed callback
487 * in PhoneStateListener. There should be.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 synchronized (mRecords) {
489 mDataConnectionFailedReason = reason;
490 final int N = mRecords.size();
491 for (int i=N-1; i>=0; i--) {
492 Record r = mRecords.get(i);
493 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
494 // XXX
495 }
496 }
497 }
498 */
Robert Greenwalt02648a42010-05-18 10:52:51 -0700499 broadcastDataConnectionFailed(reason, apnType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 }
501
502 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700503 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700504 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 synchronized (mRecords) {
507 mCellLocation = cellLocation;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700508 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400510 try {
511 r.callback.onCellLocationChanged(new Bundle(cellLocation));
512 } catch (RemoteException ex) {
513 mRemoveList.add(r.binder);
514 }
515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 }
517 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400518 handleRemoveListLocked();
Wink Savillee9b06d72009-05-18 21:47:50 -0700519 }
520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
Wink Savillefd2d0132010-10-28 14:22:26 -0700522 public void notifyOtaspChanged(int otaspMode) {
523 if (!checkNotifyPermission("notifyOtaspChanged()" )) {
524 return;
525 }
526 synchronized (mRecords) {
527 mOtaspMode = otaspMode;
528 for (Record r : mRecords) {
529 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
530 try {
531 r.callback.onOtaspChanged(otaspMode);
532 } catch (RemoteException ex) {
533 mRemoveList.add(r.binder);
534 }
535 }
536 }
537 handleRemoveListLocked();
538 }
539 }
540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 @Override
542 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
543 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
544 != PackageManager.PERMISSION_GRANTED) {
545 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700546 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 return;
548 }
549 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700550 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 pw.println("last known state:");
552 pw.println(" mCallState=" + mCallState);
553 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
554 pw.println(" mServiceState=" + mServiceState);
555 pw.println(" mSignalStrength=" + mSignalStrength);
556 pw.println(" mMessageWaiting=" + mMessageWaiting);
557 pw.println(" mCallForwarding=" + mCallForwarding);
558 pw.println(" mDataActivity=" + mDataActivity);
559 pw.println(" mDataConnectionState=" + mDataConnectionState);
560 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
561 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
562 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
Wink Savillef61101f2010-09-16 16:36:42 -0700563 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
564 pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 pw.println(" mCellLocation=" + mCellLocation);
John Wang963db55d2012-03-30 16:04:06 -0700566 pw.println(" mCellInfo=" + mCellInfo);
Wink Savillee9b06d72009-05-18 21:47:50 -0700567 pw.println("registrations: count=" + recordCount);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700568 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
570 }
571 }
572 }
573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 //
575 // the legacy intent broadcasting
576 //
577
578 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700579 long ident = Binder.clearCallingIdentity();
580 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700581 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700582 } catch (RemoteException re) {
583 // Can't do much
584 } finally {
585 Binder.restoreCallingIdentity(ident);
586 }
587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
589 Bundle data = new Bundle();
590 state.fillInNotifierBundle(data);
591 intent.putExtras(data);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700592 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 }
594
Wink Savillee9b06d72009-05-18 21:47:50 -0700595 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700596 long ident = Binder.clearCallingIdentity();
597 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700598 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700599 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700600 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700601 } finally {
602 Binder.restoreCallingIdentity(ident);
603 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800606 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700607 Bundle data = new Bundle();
608 signalStrength.fillInNotifierBundle(data);
609 intent.putExtras(data);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700610 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 }
612
613 private void broadcastCallStateChanged(int state, String incomingNumber) {
614 long ident = Binder.clearCallingIdentity();
615 try {
616 if (state == TelephonyManager.CALL_STATE_IDLE) {
617 mBatteryStats.notePhoneOff();
618 } else {
619 mBatteryStats.notePhoneOn();
620 }
621 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700622 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 } finally {
624 Binder.restoreCallingIdentity(ident);
625 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700628 intent.putExtra(PhoneConstants.STATE_KEY,
629 DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 if (!TextUtils.isEmpty(incomingNumber)) {
631 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
632 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700633 mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
634 android.Manifest.permission.READ_PHONE_STATE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
636
Robert Greenwalt42acef32009-08-12 16:08:25 -0700637 private void broadcastDataConnectionStateChanged(int state,
638 boolean isDataConnectivityPossible,
Wink Savillef61101f2010-09-16 16:36:42 -0700639 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700640 LinkCapabilities linkCapabilities, boolean roaming) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700641 // Note: not reporting to the battery stats service here, because the
642 // status bar takes care of that after taking into account all of the
643 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700645 intent.putExtra(PhoneConstants.STATE_KEY,
646 DefaultPhoneNotifier.convertDataState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 if (!isDataConnectivityPossible) {
Wink Savillea639b312012-07-10 12:37:54 -0700648 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 }
650 if (reason != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700651 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700653 if (linkProperties != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700654 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700655 String iface = linkProperties.getInterfaceName();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700656 if (iface != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700657 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700658 }
659 }
Wink Savillef61101f2010-09-16 16:36:42 -0700660 if (linkCapabilities != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700661 intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
Wink Savillef61101f2010-09-16 16:36:42 -0700662 }
Wink Savillea639b312012-07-10 12:37:54 -0700663 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
Robert Greenwalta6d42482011-09-02 15:19:31 -0700664
Wink Savillea639b312012-07-10 12:37:54 -0700665 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
666 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700667 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 }
669
Robert Greenwalt02648a42010-05-18 10:52:51 -0700670 private void broadcastDataConnectionFailed(String reason, String apnType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Wink Savillea639b312012-07-10 12:37:54 -0700672 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
673 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700674 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700676
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700677 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700678 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
679 == PackageManager.PERMISSION_GRANTED) {
680 return true;
681 }
682 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700683 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Wink Savillec9acde92011-09-21 11:05:43 -0700684 if (DBG) Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700685 return false;
686 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700687
688 private void checkListenerPermission(int events) {
689 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
690 mContext.enforceCallingOrSelfPermission(
691 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
692
693 }
694
John Wang963db55d2012-03-30 16:04:06 -0700695 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
696 mContext.enforceCallingOrSelfPermission(
697 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
698
699 }
700
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700701 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
702 mContext.enforceCallingOrSelfPermission(
703 android.Manifest.permission.READ_PHONE_STATE, null);
704 }
705 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400706
707 private void handleRemoveListLocked() {
708 if (mRemoveList.size() > 0) {
709 for (IBinder b: mRemoveList) {
710 remove(b);
711 }
712 mRemoveList.clear();
713 }
714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715}