blob: 7e23422db8a210196fc2ac9d1eabda89948a75b1 [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;
Robert Greenwalt8afddad2010-08-20 10:01:55 -070022import android.net.NetworkUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.os.Binder;
24import android.os.Bundle;
25import android.os.IBinder;
26import android.os.RemoteException;
27import android.telephony.CellLocation;
28import android.telephony.PhoneStateListener;
29import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070030import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.telephony.TelephonyManager;
32import android.text.TextUtils;
Joe Onorato8a9b2202010-02-26 18:56:32 -080033import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
35import java.util.ArrayList;
36import java.io.FileDescriptor;
37import java.io.PrintWriter;
38
39import com.android.internal.app.IBatteryStats;
40import com.android.internal.telephony.ITelephonyRegistry;
41import com.android.internal.telephony.IPhoneStateListener;
42import com.android.internal.telephony.DefaultPhoneNotifier;
43import com.android.internal.telephony.Phone;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import com.android.internal.telephony.TelephonyIntents;
45import com.android.server.am.BatteryStatsService;
46
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047/**
Wink Savillee9b06d72009-05-18 21:47:50 -070048 * Since phone process can be restarted, this class provides a centralized place
49 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 */
51class TelephonyRegistry extends ITelephonyRegistry.Stub {
52 private static final String TAG = "TelephonyRegistry";
53
54 private static class Record {
55 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 int events;
62 }
63
64 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 private final ArrayList<Record> mRecords = new ArrayList();
Wink Savillee9b06d72009-05-18 21:47:50 -070067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 private final IBatteryStats mBatteryStats;
69
70 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -070075
76 private SignalStrength mSignalStrength = new SignalStrength();
77
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -070083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
Wink Savillee9b06d72009-05-18 21:47:50 -070085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070091
Robert Greenwalt42acef32009-08-12 16:08:25 -070092 private String[] mDataConnectionApnTypes = null;
93
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private String mDataConnectionInterfaceName = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private Bundle mCellLocation = new Bundle();
97
Robert Greenwalt98e0b142009-10-08 21:15:52 -070098 private int mDataConnectionNetworkType;
99
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700100 static final int PHONE_STATE_PERMISSION_MASK =
101 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
102 PhoneStateListener.LISTEN_CALL_STATE |
103 PhoneStateListener.LISTEN_DATA_ACTIVITY |
104 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
105 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
106
Wink Savillee9b06d72009-05-18 21:47:50 -0700107 // we keep a copy of all of the state so we can send it out when folks
108 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700110 // In these calls we call with the lock held. This is safe becasuse remote
111 // calls go through a oneway interface and local calls going through a
112 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
114 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700115 CellLocation location = CellLocation.getEmpty();
116
117 // Note that location can be null for non-phone builds like
118 // like the generic one.
119 if (location != null) {
120 location.fillInNotifierBundle(mCellLocation);
121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 mContext = context;
123 mBatteryStats = BatteryStatsService.getService();
124 }
125
126 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
127 boolean notifyNow) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800128 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
Wink Savillee9b06d72009-05-18 21:47:50 -0700129 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700131 /* Checks permission and throws Security exception */
132 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133
134 synchronized (mRecords) {
135 // register
136 Record r = null;
137 find_and_add: {
138 IBinder b = callback.asBinder();
139 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700140 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 r = mRecords.get(i);
142 if (b == r.binder) {
143 break find_and_add;
144 }
145 }
146 r = new Record();
147 r.binder = b;
148 r.callback = callback;
149 r.pkgForDebug = pkgForDebug;
150 mRecords.add(r);
151 }
152 int send = events & (events ^ r.events);
153 r.events = events;
154 if (notifyNow) {
155 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
156 sendServiceState(r, mServiceState);
157 }
158 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
159 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700160 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
161 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
162 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 } catch (RemoteException ex) {
164 remove(r.binder);
165 }
166 }
167 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
168 try {
169 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
170 } catch (RemoteException ex) {
171 remove(r.binder);
172 }
173 }
174 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
175 try {
176 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
177 } catch (RemoteException ex) {
178 remove(r.binder);
179 }
180 }
181 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
182 sendCellLocation(r, mCellLocation);
183 }
184 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
185 try {
186 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
187 } catch (RemoteException ex) {
188 remove(r.binder);
189 }
190 }
191 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
192 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700193 r.callback.onDataConnectionStateChanged(mDataConnectionState,
194 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 } catch (RemoteException ex) {
196 remove(r.binder);
197 }
198 }
199 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
200 try {
201 r.callback.onDataActivity(mDataActivity);
202 } catch (RemoteException ex) {
203 remove(r.binder);
204 }
205 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700206 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
207 try {
208 r.callback.onSignalStrengthsChanged(mSignalStrength);
209 } catch (RemoteException ex) {
210 remove(r.binder);
211 }
212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 }
214 }
215 } else {
216 remove(callback.asBinder());
217 }
218 }
219
220 private void remove(IBinder binder) {
221 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700222 final int recordCount = mRecords.size();
223 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 if (mRecords.get(i).binder == binder) {
225 mRecords.remove(i);
226 return;
227 }
228 }
229 }
230 }
231
232 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700233 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700234 return;
235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 synchronized (mRecords) {
237 mCallState = state;
238 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700239 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 Record r = mRecords.get(i);
241 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
242 try {
243 r.callback.onCallStateChanged(state, incomingNumber);
244 } catch (RemoteException ex) {
245 remove(r.binder);
246 }
247 }
248 }
249 }
250 broadcastCallStateChanged(state, incomingNumber);
251 }
252
253 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700254 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700255 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 synchronized (mRecords) {
258 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700259 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 Record r = mRecords.get(i);
261 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
262 sendServiceState(r, state);
263 }
264 }
265 }
266 broadcastServiceStateChanged(state);
267 }
268
Wink Savillee9b06d72009-05-18 21:47:50 -0700269 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700270 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700271 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700274 mSignalStrength = signalStrength;
275 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700277 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
278 sendSignalStrength(r, signalStrength);
279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
281 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700282 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
283 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
284 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 } catch (RemoteException ex) {
286 remove(r.binder);
287 }
288 }
289 }
290 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700291 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 }
293
294 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700295 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700296 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 synchronized (mRecords) {
299 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700300 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 Record r = mRecords.get(i);
302 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
303 try {
304 r.callback.onMessageWaitingIndicatorChanged(mwi);
305 } catch (RemoteException ex) {
306 remove(r.binder);
307 }
308 }
309 }
310 }
311 }
312
313 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700314 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700315 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 synchronized (mRecords) {
318 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700319 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 Record r = mRecords.get(i);
321 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
322 try {
323 r.callback.onCallForwardingIndicatorChanged(cfi);
324 } catch (RemoteException ex) {
325 remove(r.binder);
326 }
327 }
328 }
329 }
330 }
331
332 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700333 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700334 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 synchronized (mRecords) {
337 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700338 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 Record r = mRecords.get(i);
340 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
341 try {
342 r.callback.onDataActivity(state);
343 } catch (RemoteException ex) {
344 remove(r.binder);
345 }
346 }
347 }
348 }
349 }
350
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700351 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt8afddad2010-08-20 10:01:55 -0700352 String reason, String apn, String[] apnTypes, String interfaceName, int networkType,
353 String gateway) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700354 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700355 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 synchronized (mRecords) {
358 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700359 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 mDataConnectionReason = reason;
361 mDataConnectionApn = apn;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700362 mDataConnectionApnTypes = apnTypes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 mDataConnectionInterfaceName = interfaceName;
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700364 mDataConnectionNetworkType = networkType;
Wink Savillee9b06d72009-05-18 21:47:50 -0700365 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 Record r = mRecords.get(i);
367 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
368 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700369 r.callback.onDataConnectionStateChanged(state, networkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 } catch (RemoteException ex) {
371 remove(r.binder);
372 }
373 }
374 }
375 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700376 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalt8afddad2010-08-20 10:01:55 -0700377 apnTypes, interfaceName, gateway);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 }
379
380 public void notifyDataConnectionFailed(String reason) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700381 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
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 /*
385 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700386 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 synchronized (mRecords) {
388 mDataConnectionFailedReason = reason;
389 final int N = mRecords.size();
390 for (int i=N-1; i>=0; i--) {
391 Record r = mRecords.get(i);
392 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
393 // XXX
394 }
395 }
396 }
397 */
398 broadcastDataConnectionFailed(reason);
399 }
400
401 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700402 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700403 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 synchronized (mRecords) {
406 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700407 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 Record r = mRecords.get(i);
409 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
410 sendCellLocation(r, cellLocation);
411 }
412 }
413 }
414 }
415
Wink Savillee9b06d72009-05-18 21:47:50 -0700416 /**
417 * Copy the service state object so they can't mess it up in the local calls
418 */
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700419 public void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 try {
421 r.callback.onServiceStateChanged(new ServiceState(state));
422 } catch (RemoteException ex) {
423 remove(r.binder);
424 }
425 }
426
Wink Savillee9b06d72009-05-18 21:47:50 -0700427 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 try {
429 r.callback.onCellLocationChanged(new Bundle(cellLocation));
430 } catch (RemoteException ex) {
431 remove(r.binder);
432 }
433 }
434
Wink Savillee9b06d72009-05-18 21:47:50 -0700435 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
436 try {
437 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
438 } catch (RemoteException ex) {
439 remove(r.binder);
440 }
441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442
443 @Override
444 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
445 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
446 != PackageManager.PERMISSION_GRANTED) {
447 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700448 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 return;
450 }
451 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700452 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 pw.println("last known state:");
454 pw.println(" mCallState=" + mCallState);
455 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
456 pw.println(" mServiceState=" + mServiceState);
457 pw.println(" mSignalStrength=" + mSignalStrength);
458 pw.println(" mMessageWaiting=" + mMessageWaiting);
459 pw.println(" mCallForwarding=" + mCallForwarding);
460 pw.println(" mDataActivity=" + mDataActivity);
461 pw.println(" mDataConnectionState=" + mDataConnectionState);
462 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
463 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
464 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
465 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
466 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700467 pw.println("registrations: count=" + recordCount);
468 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 Record r = mRecords.get(i);
470 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
471 }
472 }
473 }
474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 //
476 // the legacy intent broadcasting
477 //
478
479 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700480 long ident = Binder.clearCallingIdentity();
481 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700482 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700483 } catch (RemoteException re) {
484 // Can't do much
485 } finally {
486 Binder.restoreCallingIdentity(ident);
487 }
488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800490 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 Bundle data = new Bundle();
492 state.fillInNotifierBundle(data);
493 intent.putExtras(data);
494 mContext.sendStickyBroadcast(intent);
495 }
496
Wink Savillee9b06d72009-05-18 21:47:50 -0700497 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700498 long ident = Binder.clearCallingIdentity();
499 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700500 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700501 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700502 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700503 } finally {
504 Binder.restoreCallingIdentity(ident);
505 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800508 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700509 Bundle data = new Bundle();
510 signalStrength.fillInNotifierBundle(data);
511 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 mContext.sendStickyBroadcast(intent);
513 }
514
515 private void broadcastCallStateChanged(int state, String incomingNumber) {
516 long ident = Binder.clearCallingIdentity();
517 try {
518 if (state == TelephonyManager.CALL_STATE_IDLE) {
519 mBatteryStats.notePhoneOff();
520 } else {
521 mBatteryStats.notePhoneOn();
522 }
523 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700524 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 } finally {
526 Binder.restoreCallingIdentity(ident);
527 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800530 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700531 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 if (!TextUtils.isEmpty(incomingNumber)) {
533 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
534 }
535 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
536 }
537
Robert Greenwalt42acef32009-08-12 16:08:25 -0700538 private void broadcastDataConnectionStateChanged(int state,
539 boolean isDataConnectivityPossible,
Robert Greenwalt8afddad2010-08-20 10:01:55 -0700540 String reason, String apn, String[] apnTypes, String interfaceName, String gateway) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700541 // Note: not reporting to the battery stats service here, because the
542 // status bar takes care of that after taking into account all of the
543 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800545 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
547 if (!isDataConnectivityPossible) {
548 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
549 }
550 if (reason != null) {
551 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
552 }
553 intent.putExtra(Phone.DATA_APN_KEY, apn);
Robert Greenwalt75e1d312009-08-19 11:18:53 -0700554 String types = new String("");
555 if (apnTypes.length > 0) {
556 types = apnTypes[0];
557 for (int i = 1; i < apnTypes.length; i++) {
558 types = types+","+apnTypes[i];
559 }
Robert Greenwalt42acef32009-08-12 16:08:25 -0700560 }
561 intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
Robert Greenwalt8afddad2010-08-20 10:01:55 -0700563 int gatewayAddr = 0;
564 if (gateway != null) {
565 gatewayAddr = NetworkUtils.v4StringToInt(gateway);
566 }
567 intent.putExtra(Phone.DATA_GATEWAY_KEY, gatewayAddr);
568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 mContext.sendStickyBroadcast(intent);
570 }
571
572 private void broadcastDataConnectionFailed(String reason) {
573 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800574 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
576 mContext.sendStickyBroadcast(intent);
577 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700578
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700579 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700580 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
581 == PackageManager.PERMISSION_GRANTED) {
582 return true;
583 }
584 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700585 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Joe Onorato8a9b2202010-02-26 18:56:32 -0800586 Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700587 return false;
588 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700589
590 private void checkListenerPermission(int events) {
591 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
592 mContext.enforceCallingOrSelfPermission(
593 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
594
595 }
596
597 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
598 mContext.enforceCallingOrSelfPermission(
599 android.Manifest.permission.READ_PHONE_STATE, null);
600 }
601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602}