blob: 9f2856c694bbbcb1e22e59c2e05beb0d32489e75 [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;
22import android.os.Binder;
23import android.os.Bundle;
24import android.os.IBinder;
25import android.os.RemoteException;
26import android.telephony.CellLocation;
27import android.telephony.PhoneStateListener;
28import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070029import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.telephony.TelephonyManager;
31import android.text.TextUtils;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070032import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
34import java.util.ArrayList;
35import java.io.FileDescriptor;
36import java.io.PrintWriter;
37
38import com.android.internal.app.IBatteryStats;
39import com.android.internal.telephony.ITelephonyRegistry;
40import com.android.internal.telephony.IPhoneStateListener;
41import com.android.internal.telephony.DefaultPhoneNotifier;
42import com.android.internal.telephony.Phone;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import com.android.internal.telephony.TelephonyIntents;
44import com.android.server.am.BatteryStatsService;
45
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046/**
Wink Savillee9b06d72009-05-18 21:47:50 -070047 * Since phone process can be restarted, this class provides a centralized place
48 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 */
50class TelephonyRegistry extends ITelephonyRegistry.Stub {
51 private static final String TAG = "TelephonyRegistry";
52
53 private static class Record {
54 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 int events;
61 }
62
63 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 private final ArrayList<Record> mRecords = new ArrayList();
Wink Savillee9b06d72009-05-18 21:47:50 -070066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 private final IBatteryStats mBatteryStats;
68
69 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -070074
75 private SignalStrength mSignalStrength = new SignalStrength();
76
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -070082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
Wink Savillee9b06d72009-05-18 21:47:50 -070084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -070086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 private String mDataConnectionInterfaceName = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 private Bundle mCellLocation = new Bundle();
94
Jaikumar Ganesh45515652009-04-23 15:20:21 -070095 static final int PHONE_STATE_PERMISSION_MASK =
96 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
97 PhoneStateListener.LISTEN_CALL_STATE |
98 PhoneStateListener.LISTEN_DATA_ACTIVITY |
99 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
100 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
101
Wink Savillee9b06d72009-05-18 21:47:50 -0700102 // we keep a copy of all of the state so we can send it out when folks
103 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700105 // In these calls we call with the lock held. This is safe becasuse remote
106 // calls go through a oneway interface and local calls going through a
107 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
109 TelephonyRegistry(Context context) {
110 CellLocation.getEmpty().fillInNotifierBundle(mCellLocation);
111 mContext = context;
112 mBatteryStats = BatteryStatsService.getService();
113 }
114
115 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
116 boolean notifyNow) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700117 // Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
118 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700120 /* Checks permission and throws Security exception */
121 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122
123 synchronized (mRecords) {
124 // register
125 Record r = null;
126 find_and_add: {
127 IBinder b = callback.asBinder();
128 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700129 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 r = mRecords.get(i);
131 if (b == r.binder) {
132 break find_and_add;
133 }
134 }
135 r = new Record();
136 r.binder = b;
137 r.callback = callback;
138 r.pkgForDebug = pkgForDebug;
139 mRecords.add(r);
140 }
141 int send = events & (events ^ r.events);
142 r.events = events;
143 if (notifyNow) {
144 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
145 sendServiceState(r, mServiceState);
146 }
147 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
148 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700149 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
150 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
151 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 } catch (RemoteException ex) {
153 remove(r.binder);
154 }
155 }
156 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
157 try {
158 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
159 } catch (RemoteException ex) {
160 remove(r.binder);
161 }
162 }
163 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
164 try {
165 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
166 } catch (RemoteException ex) {
167 remove(r.binder);
168 }
169 }
170 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
171 sendCellLocation(r, mCellLocation);
172 }
173 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
174 try {
175 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
176 } catch (RemoteException ex) {
177 remove(r.binder);
178 }
179 }
180 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
181 try {
182 r.callback.onDataConnectionStateChanged(mDataConnectionState);
183 } catch (RemoteException ex) {
184 remove(r.binder);
185 }
186 }
187 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
188 try {
189 r.callback.onDataActivity(mDataActivity);
190 } catch (RemoteException ex) {
191 remove(r.binder);
192 }
193 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700194 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
195 try {
196 r.callback.onSignalStrengthsChanged(mSignalStrength);
197 } catch (RemoteException ex) {
198 remove(r.binder);
199 }
200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202 }
203 } else {
204 remove(callback.asBinder());
205 }
206 }
207
208 private void remove(IBinder binder) {
209 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700210 final int recordCount = mRecords.size();
211 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 if (mRecords.get(i).binder == binder) {
213 mRecords.remove(i);
214 return;
215 }
216 }
217 }
218 }
219
220 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700221 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700222 return;
223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 synchronized (mRecords) {
225 mCallState = state;
226 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700227 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 Record r = mRecords.get(i);
229 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
230 try {
231 r.callback.onCallStateChanged(state, incomingNumber);
232 } catch (RemoteException ex) {
233 remove(r.binder);
234 }
235 }
236 }
237 }
238 broadcastCallStateChanged(state, incomingNumber);
239 }
240
241 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700242 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700243 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 synchronized (mRecords) {
246 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700247 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 Record r = mRecords.get(i);
249 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
250 sendServiceState(r, state);
251 }
252 }
253 }
254 broadcastServiceStateChanged(state);
255 }
256
Wink Savillee9b06d72009-05-18 21:47:50 -0700257 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700258 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700259 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700262 mSignalStrength = signalStrength;
263 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700265 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
266 sendSignalStrength(r, signalStrength);
267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
269 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700270 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
271 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
272 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 } catch (RemoteException ex) {
274 remove(r.binder);
275 }
276 }
277 }
278 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700279 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 }
281
282 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700283 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700284 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 synchronized (mRecords) {
287 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700288 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 Record r = mRecords.get(i);
290 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
291 try {
292 r.callback.onMessageWaitingIndicatorChanged(mwi);
293 } catch (RemoteException ex) {
294 remove(r.binder);
295 }
296 }
297 }
298 }
299 }
300
301 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700302 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700303 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 synchronized (mRecords) {
306 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700307 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 Record r = mRecords.get(i);
309 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
310 try {
311 r.callback.onCallForwardingIndicatorChanged(cfi);
312 } catch (RemoteException ex) {
313 remove(r.binder);
314 }
315 }
316 }
317 }
318 }
319
320 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700321 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700322 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 synchronized (mRecords) {
325 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700326 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 Record r = mRecords.get(i);
328 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
329 try {
330 r.callback.onDataActivity(state);
331 } catch (RemoteException ex) {
332 remove(r.binder);
333 }
334 }
335 }
336 }
337 }
338
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700339 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
340 String reason, String apn, String interfaceName) {
341 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700342 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 synchronized (mRecords) {
345 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700346 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 mDataConnectionReason = reason;
348 mDataConnectionApn = apn;
349 mDataConnectionInterfaceName = interfaceName;
Wink Savillee9b06d72009-05-18 21:47:50 -0700350 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 Record r = mRecords.get(i);
352 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
353 try {
354 r.callback.onDataConnectionStateChanged(state);
355 } catch (RemoteException ex) {
356 remove(r.binder);
357 }
358 }
359 }
360 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700361 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
362 interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
364
365 public void notifyDataConnectionFailed(String reason) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700366 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700367 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 /*
370 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700371 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 synchronized (mRecords) {
373 mDataConnectionFailedReason = reason;
374 final int N = mRecords.size();
375 for (int i=N-1; i>=0; i--) {
376 Record r = mRecords.get(i);
377 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
378 // XXX
379 }
380 }
381 }
382 */
383 broadcastDataConnectionFailed(reason);
384 }
385
386 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700387 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700388 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 synchronized (mRecords) {
391 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700392 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 Record r = mRecords.get(i);
394 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
395 sendCellLocation(r, cellLocation);
396 }
397 }
398 }
399 }
400
Wink Savillee9b06d72009-05-18 21:47:50 -0700401 /**
402 * Copy the service state object so they can't mess it up in the local calls
403 */
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700404 public void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 try {
406 r.callback.onServiceStateChanged(new ServiceState(state));
407 } catch (RemoteException ex) {
408 remove(r.binder);
409 }
410 }
411
Wink Savillee9b06d72009-05-18 21:47:50 -0700412 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 try {
414 r.callback.onCellLocationChanged(new Bundle(cellLocation));
415 } catch (RemoteException ex) {
416 remove(r.binder);
417 }
418 }
419
Wink Savillee9b06d72009-05-18 21:47:50 -0700420 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
421 try {
422 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
423 } catch (RemoteException ex) {
424 remove(r.binder);
425 }
426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427
428 @Override
429 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
430 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
431 != PackageManager.PERMISSION_GRANTED) {
432 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700433 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 return;
435 }
436 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700437 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 pw.println("last known state:");
439 pw.println(" mCallState=" + mCallState);
440 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
441 pw.println(" mServiceState=" + mServiceState);
442 pw.println(" mSignalStrength=" + mSignalStrength);
443 pw.println(" mMessageWaiting=" + mMessageWaiting);
444 pw.println(" mCallForwarding=" + mCallForwarding);
445 pw.println(" mDataActivity=" + mDataActivity);
446 pw.println(" mDataConnectionState=" + mDataConnectionState);
447 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
448 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
449 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
450 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
451 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700452 pw.println("registrations: count=" + recordCount);
453 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 Record r = mRecords.get(i);
455 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
456 }
457 }
458 }
459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 //
461 // the legacy intent broadcasting
462 //
463
464 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700465 long ident = Binder.clearCallingIdentity();
466 try {
467 mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
468 } catch (RemoteException re) {
469 // Can't do much
470 } finally {
471 Binder.restoreCallingIdentity(ident);
472 }
473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
475 Bundle data = new Bundle();
476 state.fillInNotifierBundle(data);
477 intent.putExtras(data);
478 mContext.sendStickyBroadcast(intent);
479 }
480
Wink Savillee9b06d72009-05-18 21:47:50 -0700481 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700482 long ident = Binder.clearCallingIdentity();
483 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700484 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700485 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700486 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700487 } finally {
488 Binder.restoreCallingIdentity(ident);
489 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700492 Bundle data = new Bundle();
493 signalStrength.fillInNotifierBundle(data);
494 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 mContext.sendStickyBroadcast(intent);
496 }
497
498 private void broadcastCallStateChanged(int state, String incomingNumber) {
499 long ident = Binder.clearCallingIdentity();
500 try {
501 if (state == TelephonyManager.CALL_STATE_IDLE) {
502 mBatteryStats.notePhoneOff();
503 } else {
504 mBatteryStats.notePhoneOn();
505 }
506 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700507 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 } finally {
509 Binder.restoreCallingIdentity(ident);
510 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700513 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 if (!TextUtils.isEmpty(incomingNumber)) {
515 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
516 }
517 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
518 }
519
520 private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible,
521 String reason, String apn, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700522 // Note: not reporting to the battery stats service here, because the
523 // status bar takes care of that after taking into account all of the
524 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
526 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
527 if (!isDataConnectivityPossible) {
528 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
529 }
530 if (reason != null) {
531 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
532 }
533 intent.putExtra(Phone.DATA_APN_KEY, apn);
534 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
535 mContext.sendStickyBroadcast(intent);
536 }
537
538 private void broadcastDataConnectionFailed(String reason) {
539 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
540 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
541 mContext.sendStickyBroadcast(intent);
542 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700543
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700544 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700545 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
546 == PackageManager.PERMISSION_GRANTED) {
547 return true;
548 }
549 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700550 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700551 Log.w(TAG, msg);
552 return false;
553 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700554
555 private void checkListenerPermission(int events) {
556 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
557 mContext.enforceCallingOrSelfPermission(
558 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
559
560 }
561
562 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
563 mContext.enforceCallingOrSelfPermission(
564 android.Manifest.permission.READ_PHONE_STATE, null);
565 }
566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567}