blob: 88f47fda431fec19ea734cc2fc0839e11964cafe [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
Wink Savillee9b06d72009-05-18 21:47:50 -070095 // we keep a copy of all of the state so we can send it out when folks
96 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 //
Wink Savillee9b06d72009-05-18 21:47:50 -070098 // In these calls we call with the lock held. This is safe becasuse remote
99 // calls go through a oneway interface and local calls going through a
100 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
102 TelephonyRegistry(Context context) {
103 CellLocation.getEmpty().fillInNotifierBundle(mCellLocation);
104 mContext = context;
105 mBatteryStats = BatteryStatsService.getService();
106 }
107
108 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
109 boolean notifyNow) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700110 // Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
111 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 if (events != 0) {
113 // check permissions
114 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
Mike Lockwoodac61f6b2009-05-19 09:14:41 -0400115 // ACCESS_FINE_LOCATION implies ACCESS_COARSE_LOCATION
116 if (mContext.checkCallingPermission(
117 android.Manifest.permission.ACCESS_FINE_LOCATION)
118 != PackageManager.PERMISSION_GRANTED) {
119 mContext.enforceCallingOrSelfPermission(
120 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 }
123
124 synchronized (mRecords) {
125 // register
126 Record r = null;
127 find_and_add: {
128 IBinder b = callback.asBinder();
129 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700130 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 r = mRecords.get(i);
132 if (b == r.binder) {
133 break find_and_add;
134 }
135 }
136 r = new Record();
137 r.binder = b;
138 r.callback = callback;
139 r.pkgForDebug = pkgForDebug;
140 mRecords.add(r);
141 }
142 int send = events & (events ^ r.events);
143 r.events = events;
144 if (notifyNow) {
145 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
146 sendServiceState(r, mServiceState);
147 }
148 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
149 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700150 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
151 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
152 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 } catch (RemoteException ex) {
154 remove(r.binder);
155 }
156 }
157 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
158 try {
159 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
160 } catch (RemoteException ex) {
161 remove(r.binder);
162 }
163 }
164 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
165 try {
166 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
167 } catch (RemoteException ex) {
168 remove(r.binder);
169 }
170 }
171 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
172 sendCellLocation(r, mCellLocation);
173 }
174 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
175 try {
176 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
177 } catch (RemoteException ex) {
178 remove(r.binder);
179 }
180 }
181 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
182 try {
183 r.callback.onDataConnectionStateChanged(mDataConnectionState);
184 } catch (RemoteException ex) {
185 remove(r.binder);
186 }
187 }
188 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
189 try {
190 r.callback.onDataActivity(mDataActivity);
191 } catch (RemoteException ex) {
192 remove(r.binder);
193 }
194 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700195 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
196 try {
197 r.callback.onSignalStrengthsChanged(mSignalStrength);
198 } catch (RemoteException ex) {
199 remove(r.binder);
200 }
201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 }
203 }
204 } else {
205 remove(callback.asBinder());
206 }
207 }
208
209 private void remove(IBinder binder) {
210 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700211 final int recordCount = mRecords.size();
212 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 if (mRecords.get(i).binder == binder) {
214 mRecords.remove(i);
215 return;
216 }
217 }
218 }
219 }
220
221 public void notifyCallState(int state, String incomingNumber) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700222 if (!checkPhoneStatePermission("notifyCallState()")) {
223 return;
224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 synchronized (mRecords) {
226 mCallState = state;
227 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700228 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 Record r = mRecords.get(i);
230 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
231 try {
232 r.callback.onCallStateChanged(state, incomingNumber);
233 } catch (RemoteException ex) {
234 remove(r.binder);
235 }
236 }
237 }
238 }
239 broadcastCallStateChanged(state, incomingNumber);
240 }
241
242 public void notifyServiceState(ServiceState state) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700243 if (!checkPhoneStatePermission("notifyServiceState()")) {
244 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 synchronized (mRecords) {
247 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700248 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 Record r = mRecords.get(i);
250 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
251 sendServiceState(r, state);
252 }
253 }
254 }
255 broadcastServiceStateChanged(state);
256 }
257
Wink Savillee9b06d72009-05-18 21:47:50 -0700258 public void notifySignalStrength(SignalStrength signalStrength) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700259 if (!checkPhoneStatePermission("notifySignalStrength()")) {
260 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700261 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700263 mSignalStrength = signalStrength;
264 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700266 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
267 sendSignalStrength(r, signalStrength);
268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
270 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700271 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
272 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
273 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 } catch (RemoteException ex) {
275 remove(r.binder);
276 }
277 }
278 }
279 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700280 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 }
282
283 public void notifyMessageWaitingChanged(boolean mwi) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700284 if (!checkPhoneStatePermission("notifyMessageWaitingChanged()")) {
285 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 synchronized (mRecords) {
288 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700289 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 Record r = mRecords.get(i);
291 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
292 try {
293 r.callback.onMessageWaitingIndicatorChanged(mwi);
294 } catch (RemoteException ex) {
295 remove(r.binder);
296 }
297 }
298 }
299 }
300 }
301
302 public void notifyCallForwardingChanged(boolean cfi) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700303 if (!checkPhoneStatePermission("notifyCallForwardingChanged()")) {
304 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 synchronized (mRecords) {
307 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700308 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 Record r = mRecords.get(i);
310 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
311 try {
312 r.callback.onCallForwardingIndicatorChanged(cfi);
313 } catch (RemoteException ex) {
314 remove(r.binder);
315 }
316 }
317 }
318 }
319 }
320
321 public void notifyDataActivity(int state) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700322 if (!checkPhoneStatePermission("notifyDataActivity()")) {
323 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 synchronized (mRecords) {
326 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700327 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 Record r = mRecords.get(i);
329 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
330 try {
331 r.callback.onDataActivity(state);
332 } catch (RemoteException ex) {
333 remove(r.binder);
334 }
335 }
336 }
337 }
338 }
339
Wink Savillee9b06d72009-05-18 21:47:50 -0700340 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason,
341 String apn, String interfaceName) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700342 if (!checkPhoneStatePermission("notifyDataConnection()")) {
343 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 synchronized (mRecords) {
346 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700347 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 mDataConnectionReason = reason;
349 mDataConnectionApn = apn;
350 mDataConnectionInterfaceName = interfaceName;
Wink Savillee9b06d72009-05-18 21:47:50 -0700351 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 Record r = mRecords.get(i);
353 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
354 try {
355 r.callback.onDataConnectionStateChanged(state);
356 } catch (RemoteException ex) {
357 remove(r.binder);
358 }
359 }
360 }
361 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700362 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
363 interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 }
365
366 public void notifyDataConnectionFailed(String reason) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700367 if (!checkPhoneStatePermission("notifyDataConnectionFailed()")) {
368 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 /*
371 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700372 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 synchronized (mRecords) {
374 mDataConnectionFailedReason = reason;
375 final int N = mRecords.size();
376 for (int i=N-1; i>=0; i--) {
377 Record r = mRecords.get(i);
378 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
379 // XXX
380 }
381 }
382 }
383 */
384 broadcastDataConnectionFailed(reason);
385 }
386
387 public void notifyCellLocation(Bundle cellLocation) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700388 if (!checkPhoneStatePermission("notifyCellLocation()")) {
389 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 synchronized (mRecords) {
392 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700393 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 Record r = mRecords.get(i);
395 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
396 sendCellLocation(r, cellLocation);
397 }
398 }
399 }
400 }
401
Wink Savillee9b06d72009-05-18 21:47:50 -0700402 /**
403 * Copy the service state object so they can't mess it up in the local calls
404 */
405 private void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 try {
407 r.callback.onServiceStateChanged(new ServiceState(state));
408 } catch (RemoteException ex) {
409 remove(r.binder);
410 }
411 }
412
Wink Savillee9b06d72009-05-18 21:47:50 -0700413 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 try {
415 r.callback.onCellLocationChanged(new Bundle(cellLocation));
416 } catch (RemoteException ex) {
417 remove(r.binder);
418 }
419 }
420
Wink Savillee9b06d72009-05-18 21:47:50 -0700421 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
422 try {
423 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
424 } catch (RemoteException ex) {
425 remove(r.binder);
426 }
427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428
429 @Override
430 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
431 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
432 != PackageManager.PERMISSION_GRANTED) {
433 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700434 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 return;
436 }
437 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700438 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 pw.println("last known state:");
440 pw.println(" mCallState=" + mCallState);
441 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
442 pw.println(" mServiceState=" + mServiceState);
443 pw.println(" mSignalStrength=" + mSignalStrength);
444 pw.println(" mMessageWaiting=" + mMessageWaiting);
445 pw.println(" mCallForwarding=" + mCallForwarding);
446 pw.println(" mDataActivity=" + mDataActivity);
447 pw.println(" mDataConnectionState=" + mDataConnectionState);
448 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
449 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
450 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
451 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
452 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700453 pw.println("registrations: count=" + recordCount);
454 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 Record r = mRecords.get(i);
456 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
457 }
458 }
459 }
460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 //
462 // the legacy intent broadcasting
463 //
464
465 private void broadcastServiceStateChanged(ServiceState state) {
466 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
467 Bundle data = new Bundle();
468 state.fillInNotifierBundle(data);
469 intent.putExtras(data);
470 mContext.sendStickyBroadcast(intent);
471 }
472
Wink Savillee9b06d72009-05-18 21:47:50 -0700473 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700474 long ident = Binder.clearCallingIdentity();
475 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700476 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700477 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700478 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700479 } finally {
480 Binder.restoreCallingIdentity(ident);
481 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700484 Bundle data = new Bundle();
485 signalStrength.fillInNotifierBundle(data);
486 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 mContext.sendStickyBroadcast(intent);
488 }
489
490 private void broadcastCallStateChanged(int state, String incomingNumber) {
491 long ident = Binder.clearCallingIdentity();
492 try {
493 if (state == TelephonyManager.CALL_STATE_IDLE) {
494 mBatteryStats.notePhoneOff();
495 } else {
496 mBatteryStats.notePhoneOn();
497 }
498 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700499 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 } finally {
501 Binder.restoreCallingIdentity(ident);
502 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700505 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 if (!TextUtils.isEmpty(incomingNumber)) {
507 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
508 }
509 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
510 }
511
512 private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible,
513 String reason, String apn, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700514 // Note: not reporting to the battery stats service here, because the
515 // status bar takes care of that after taking into account all of the
516 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
518 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
519 if (!isDataConnectivityPossible) {
520 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
521 }
522 if (reason != null) {
523 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
524 }
525 intent.putExtra(Phone.DATA_APN_KEY, apn);
526 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
527 mContext.sendStickyBroadcast(intent);
528 }
529
530 private void broadcastDataConnectionFailed(String reason) {
531 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
532 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
533 mContext.sendStickyBroadcast(intent);
534 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700535
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700536 private boolean checkPhoneStatePermission(String method) {
537 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
538 == PackageManager.PERMISSION_GRANTED) {
539 return true;
540 }
541 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700542 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700543 Log.w(TAG, msg);
544 return false;
545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546}