blob: 22af02b5436f1bebf4606ec63520d054b8abe85a [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) {
115 mContext.enforceCallingOrSelfPermission(
116 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
117
118 }
119
120 synchronized (mRecords) {
121 // register
122 Record r = null;
123 find_and_add: {
124 IBinder b = callback.asBinder();
125 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700126 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 r = mRecords.get(i);
128 if (b == r.binder) {
129 break find_and_add;
130 }
131 }
132 r = new Record();
133 r.binder = b;
134 r.callback = callback;
135 r.pkgForDebug = pkgForDebug;
136 mRecords.add(r);
137 }
138 int send = events & (events ^ r.events);
139 r.events = events;
140 if (notifyNow) {
141 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
142 sendServiceState(r, mServiceState);
143 }
144 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
145 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700146 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
147 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
148 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 } catch (RemoteException ex) {
150 remove(r.binder);
151 }
152 }
153 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
154 try {
155 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
156 } catch (RemoteException ex) {
157 remove(r.binder);
158 }
159 }
160 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
161 try {
162 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
163 } catch (RemoteException ex) {
164 remove(r.binder);
165 }
166 }
167 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
168 sendCellLocation(r, mCellLocation);
169 }
170 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
171 try {
172 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
173 } catch (RemoteException ex) {
174 remove(r.binder);
175 }
176 }
177 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
178 try {
179 r.callback.onDataConnectionStateChanged(mDataConnectionState);
180 } catch (RemoteException ex) {
181 remove(r.binder);
182 }
183 }
184 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
185 try {
186 r.callback.onDataActivity(mDataActivity);
187 } catch (RemoteException ex) {
188 remove(r.binder);
189 }
190 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700191 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
192 try {
193 r.callback.onSignalStrengthsChanged(mSignalStrength);
194 } catch (RemoteException ex) {
195 remove(r.binder);
196 }
197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 }
199 }
200 } else {
201 remove(callback.asBinder());
202 }
203 }
204
205 private void remove(IBinder binder) {
206 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700207 final int recordCount = mRecords.size();
208 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 if (mRecords.get(i).binder == binder) {
210 mRecords.remove(i);
211 return;
212 }
213 }
214 }
215 }
216
217 public void notifyCallState(int state, String incomingNumber) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700218 if (!checkPhoneStatePermission("notifyCallState()")) {
219 return;
220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 synchronized (mRecords) {
222 mCallState = state;
223 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700224 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 Record r = mRecords.get(i);
226 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
227 try {
228 r.callback.onCallStateChanged(state, incomingNumber);
229 } catch (RemoteException ex) {
230 remove(r.binder);
231 }
232 }
233 }
234 }
235 broadcastCallStateChanged(state, incomingNumber);
236 }
237
238 public void notifyServiceState(ServiceState state) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700239 if (!checkPhoneStatePermission("notifyServiceState()")) {
240 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 synchronized (mRecords) {
243 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700244 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 Record r = mRecords.get(i);
246 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
247 sendServiceState(r, state);
248 }
249 }
250 }
251 broadcastServiceStateChanged(state);
252 }
253
Wink Savillee9b06d72009-05-18 21:47:50 -0700254 public void notifySignalStrength(SignalStrength signalStrength) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700255 if (!checkPhoneStatePermission("notifySignalStrength()")) {
256 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700259 mSignalStrength = signalStrength;
260 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700262 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
263 sendSignalStrength(r, signalStrength);
264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
266 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700267 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
268 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
269 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 } catch (RemoteException ex) {
271 remove(r.binder);
272 }
273 }
274 }
275 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700276 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 }
278
279 public void notifyMessageWaitingChanged(boolean mwi) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700280 if (!checkPhoneStatePermission("notifyMessageWaitingChanged()")) {
281 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 synchronized (mRecords) {
284 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700285 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 Record r = mRecords.get(i);
287 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
288 try {
289 r.callback.onMessageWaitingIndicatorChanged(mwi);
290 } catch (RemoteException ex) {
291 remove(r.binder);
292 }
293 }
294 }
295 }
296 }
297
298 public void notifyCallForwardingChanged(boolean cfi) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700299 if (!checkPhoneStatePermission("notifyCallForwardingChanged()")) {
300 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 synchronized (mRecords) {
303 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700304 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 Record r = mRecords.get(i);
306 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
307 try {
308 r.callback.onCallForwardingIndicatorChanged(cfi);
309 } catch (RemoteException ex) {
310 remove(r.binder);
311 }
312 }
313 }
314 }
315 }
316
317 public void notifyDataActivity(int state) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700318 if (!checkPhoneStatePermission("notifyDataActivity()")) {
319 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 synchronized (mRecords) {
322 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700323 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 Record r = mRecords.get(i);
325 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
326 try {
327 r.callback.onDataActivity(state);
328 } catch (RemoteException ex) {
329 remove(r.binder);
330 }
331 }
332 }
333 }
334 }
335
Wink Savillee9b06d72009-05-18 21:47:50 -0700336 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason,
337 String apn, String interfaceName) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700338 if (!checkPhoneStatePermission("notifyDataConnection()")) {
339 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 synchronized (mRecords) {
342 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700343 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 mDataConnectionReason = reason;
345 mDataConnectionApn = apn;
346 mDataConnectionInterfaceName = interfaceName;
Wink Savillee9b06d72009-05-18 21:47:50 -0700347 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 Record r = mRecords.get(i);
349 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
350 try {
351 r.callback.onDataConnectionStateChanged(state);
352 } catch (RemoteException ex) {
353 remove(r.binder);
354 }
355 }
356 }
357 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700358 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
359 interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
361
362 public void notifyDataConnectionFailed(String reason) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700363 if (!checkPhoneStatePermission("notifyDataConnectionFailed()")) {
364 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 /*
367 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700368 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 synchronized (mRecords) {
370 mDataConnectionFailedReason = reason;
371 final int N = mRecords.size();
372 for (int i=N-1; i>=0; i--) {
373 Record r = mRecords.get(i);
374 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
375 // XXX
376 }
377 }
378 }
379 */
380 broadcastDataConnectionFailed(reason);
381 }
382
383 public void notifyCellLocation(Bundle cellLocation) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700384 if (!checkPhoneStatePermission("notifyCellLocation()")) {
385 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 synchronized (mRecords) {
388 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700389 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 Record r = mRecords.get(i);
391 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
392 sendCellLocation(r, cellLocation);
393 }
394 }
395 }
396 }
397
Wink Savillee9b06d72009-05-18 21:47:50 -0700398 /**
399 * Copy the service state object so they can't mess it up in the local calls
400 */
401 private void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 try {
403 r.callback.onServiceStateChanged(new ServiceState(state));
404 } catch (RemoteException ex) {
405 remove(r.binder);
406 }
407 }
408
Wink Savillee9b06d72009-05-18 21:47:50 -0700409 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 try {
411 r.callback.onCellLocationChanged(new Bundle(cellLocation));
412 } catch (RemoteException ex) {
413 remove(r.binder);
414 }
415 }
416
Wink Savillee9b06d72009-05-18 21:47:50 -0700417 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
418 try {
419 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
420 } catch (RemoteException ex) {
421 remove(r.binder);
422 }
423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424
425 @Override
426 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
427 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
428 != PackageManager.PERMISSION_GRANTED) {
429 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700430 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 return;
432 }
433 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700434 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 pw.println("last known state:");
436 pw.println(" mCallState=" + mCallState);
437 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
438 pw.println(" mServiceState=" + mServiceState);
439 pw.println(" mSignalStrength=" + mSignalStrength);
440 pw.println(" mMessageWaiting=" + mMessageWaiting);
441 pw.println(" mCallForwarding=" + mCallForwarding);
442 pw.println(" mDataActivity=" + mDataActivity);
443 pw.println(" mDataConnectionState=" + mDataConnectionState);
444 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
445 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
446 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
447 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
448 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700449 pw.println("registrations: count=" + recordCount);
450 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 Record r = mRecords.get(i);
452 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
453 }
454 }
455 }
456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 //
458 // the legacy intent broadcasting
459 //
460
461 private void broadcastServiceStateChanged(ServiceState state) {
462 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
463 Bundle data = new Bundle();
464 state.fillInNotifierBundle(data);
465 intent.putExtras(data);
466 mContext.sendStickyBroadcast(intent);
467 }
468
Wink Savillee9b06d72009-05-18 21:47:50 -0700469 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700470 long ident = Binder.clearCallingIdentity();
471 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700472 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700473 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700474 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700475 } finally {
476 Binder.restoreCallingIdentity(ident);
477 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700480 Bundle data = new Bundle();
481 signalStrength.fillInNotifierBundle(data);
482 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 mContext.sendStickyBroadcast(intent);
484 }
485
486 private void broadcastCallStateChanged(int state, String incomingNumber) {
487 long ident = Binder.clearCallingIdentity();
488 try {
489 if (state == TelephonyManager.CALL_STATE_IDLE) {
490 mBatteryStats.notePhoneOff();
491 } else {
492 mBatteryStats.notePhoneOn();
493 }
494 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700495 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 } finally {
497 Binder.restoreCallingIdentity(ident);
498 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700501 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 if (!TextUtils.isEmpty(incomingNumber)) {
503 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
504 }
505 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
506 }
507
508 private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible,
509 String reason, String apn, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700510 // Note: not reporting to the battery stats service here, because the
511 // status bar takes care of that after taking into account all of the
512 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
514 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
515 if (!isDataConnectivityPossible) {
516 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
517 }
518 if (reason != null) {
519 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
520 }
521 intent.putExtra(Phone.DATA_APN_KEY, apn);
522 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
523 mContext.sendStickyBroadcast(intent);
524 }
525
526 private void broadcastDataConnectionFailed(String reason) {
527 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
528 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
529 mContext.sendStickyBroadcast(intent);
530 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700531
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700532 private boolean checkPhoneStatePermission(String method) {
533 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
534 == PackageManager.PERMISSION_GRANTED) {
535 return true;
536 }
537 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700538 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700539 Log.w(TAG, msg);
540 return false;
541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542}