blob: 7379b5d7594d758444d3ff66321bafa1a6c43348 [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
Robert Greenwalt42acef32009-08-12 16:08:25 -070091 private String[] mDataConnectionApnTypes = null;
92
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 private String mDataConnectionInterfaceName = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 private Bundle mCellLocation = new Bundle();
96
Jaikumar Ganesh45515652009-04-23 15:20:21 -070097 static final int PHONE_STATE_PERMISSION_MASK =
98 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
99 PhoneStateListener.LISTEN_CALL_STATE |
100 PhoneStateListener.LISTEN_DATA_ACTIVITY |
101 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
102 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
103
Wink Savillee9b06d72009-05-18 21:47:50 -0700104 // we keep a copy of all of the state so we can send it out when folks
105 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700107 // In these calls we call with the lock held. This is safe becasuse remote
108 // calls go through a oneway interface and local calls going through a
109 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
111 TelephonyRegistry(Context context) {
112 CellLocation.getEmpty().fillInNotifierBundle(mCellLocation);
113 mContext = context;
114 mBatteryStats = BatteryStatsService.getService();
115 }
116
117 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
118 boolean notifyNow) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700119 // Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
120 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700122 /* Checks permission and throws Security exception */
123 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
125 synchronized (mRecords) {
126 // register
127 Record r = null;
128 find_and_add: {
129 IBinder b = callback.asBinder();
130 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700131 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 r = mRecords.get(i);
133 if (b == r.binder) {
134 break find_and_add;
135 }
136 }
137 r = new Record();
138 r.binder = b;
139 r.callback = callback;
140 r.pkgForDebug = pkgForDebug;
141 mRecords.add(r);
142 }
143 int send = events & (events ^ r.events);
144 r.events = events;
145 if (notifyNow) {
146 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
147 sendServiceState(r, mServiceState);
148 }
149 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
150 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700151 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
152 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
153 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 } catch (RemoteException ex) {
155 remove(r.binder);
156 }
157 }
158 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
159 try {
160 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
161 } catch (RemoteException ex) {
162 remove(r.binder);
163 }
164 }
165 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
166 try {
167 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
168 } catch (RemoteException ex) {
169 remove(r.binder);
170 }
171 }
172 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
173 sendCellLocation(r, mCellLocation);
174 }
175 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
176 try {
177 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
178 } catch (RemoteException ex) {
179 remove(r.binder);
180 }
181 }
182 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
183 try {
184 r.callback.onDataConnectionStateChanged(mDataConnectionState);
185 } catch (RemoteException ex) {
186 remove(r.binder);
187 }
188 }
189 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
190 try {
191 r.callback.onDataActivity(mDataActivity);
192 } catch (RemoteException ex) {
193 remove(r.binder);
194 }
195 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700196 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
197 try {
198 r.callback.onSignalStrengthsChanged(mSignalStrength);
199 } catch (RemoteException ex) {
200 remove(r.binder);
201 }
202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 }
204 }
205 } else {
206 remove(callback.asBinder());
207 }
208 }
209
210 private void remove(IBinder binder) {
211 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700212 final int recordCount = mRecords.size();
213 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 if (mRecords.get(i).binder == binder) {
215 mRecords.remove(i);
216 return;
217 }
218 }
219 }
220 }
221
222 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700223 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700224 return;
225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 synchronized (mRecords) {
227 mCallState = state;
228 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700229 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 Record r = mRecords.get(i);
231 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
232 try {
233 r.callback.onCallStateChanged(state, incomingNumber);
234 } catch (RemoteException ex) {
235 remove(r.binder);
236 }
237 }
238 }
239 }
240 broadcastCallStateChanged(state, incomingNumber);
241 }
242
243 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700244 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700245 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 synchronized (mRecords) {
248 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700249 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 Record r = mRecords.get(i);
251 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
252 sendServiceState(r, state);
253 }
254 }
255 }
256 broadcastServiceStateChanged(state);
257 }
258
Wink Savillee9b06d72009-05-18 21:47:50 -0700259 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700260 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700261 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700264 mSignalStrength = signalStrength;
265 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700267 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
268 sendSignalStrength(r, signalStrength);
269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
271 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700272 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
273 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
274 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 } catch (RemoteException ex) {
276 remove(r.binder);
277 }
278 }
279 }
280 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700281 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 }
283
284 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700285 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700286 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 synchronized (mRecords) {
289 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700290 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 Record r = mRecords.get(i);
292 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
293 try {
294 r.callback.onMessageWaitingIndicatorChanged(mwi);
295 } catch (RemoteException ex) {
296 remove(r.binder);
297 }
298 }
299 }
300 }
301 }
302
303 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700304 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700305 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 synchronized (mRecords) {
308 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700309 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 Record r = mRecords.get(i);
311 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
312 try {
313 r.callback.onCallForwardingIndicatorChanged(cfi);
314 } catch (RemoteException ex) {
315 remove(r.binder);
316 }
317 }
318 }
319 }
320 }
321
322 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700323 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700324 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 synchronized (mRecords) {
327 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700328 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 Record r = mRecords.get(i);
330 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
331 try {
332 r.callback.onDataActivity(state);
333 } catch (RemoteException ex) {
334 remove(r.binder);
335 }
336 }
337 }
338 }
339 }
340
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700341 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt42acef32009-08-12 16:08:25 -0700342 String reason, String apn, String[] apnTypes, String interfaceName) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700343 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700344 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 synchronized (mRecords) {
347 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700348 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 mDataConnectionReason = reason;
350 mDataConnectionApn = apn;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700351 mDataConnectionApnTypes = apnTypes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 mDataConnectionInterfaceName = interfaceName;
Wink Savillee9b06d72009-05-18 21:47:50 -0700353 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 Record r = mRecords.get(i);
355 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
356 try {
357 r.callback.onDataConnectionStateChanged(state);
358 } catch (RemoteException ex) {
359 remove(r.binder);
360 }
361 }
362 }
363 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700364 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalt42acef32009-08-12 16:08:25 -0700365 apnTypes, interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 }
367
368 public void notifyDataConnectionFailed(String reason) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700369 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700370 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 /*
373 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700374 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 synchronized (mRecords) {
376 mDataConnectionFailedReason = reason;
377 final int N = mRecords.size();
378 for (int i=N-1; i>=0; i--) {
379 Record r = mRecords.get(i);
380 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
381 // XXX
382 }
383 }
384 }
385 */
386 broadcastDataConnectionFailed(reason);
387 }
388
389 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700390 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700391 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 synchronized (mRecords) {
394 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700395 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 Record r = mRecords.get(i);
397 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
398 sendCellLocation(r, cellLocation);
399 }
400 }
401 }
402 }
403
Wink Savillee9b06d72009-05-18 21:47:50 -0700404 /**
405 * Copy the service state object so they can't mess it up in the local calls
406 */
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700407 public void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 try {
409 r.callback.onServiceStateChanged(new ServiceState(state));
410 } catch (RemoteException ex) {
411 remove(r.binder);
412 }
413 }
414
Wink Savillee9b06d72009-05-18 21:47:50 -0700415 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 try {
417 r.callback.onCellLocationChanged(new Bundle(cellLocation));
418 } catch (RemoteException ex) {
419 remove(r.binder);
420 }
421 }
422
Wink Savillee9b06d72009-05-18 21:47:50 -0700423 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
424 try {
425 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
426 } catch (RemoteException ex) {
427 remove(r.binder);
428 }
429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430
431 @Override
432 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
433 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
434 != PackageManager.PERMISSION_GRANTED) {
435 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700436 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 return;
438 }
439 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700440 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 pw.println("last known state:");
442 pw.println(" mCallState=" + mCallState);
443 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
444 pw.println(" mServiceState=" + mServiceState);
445 pw.println(" mSignalStrength=" + mSignalStrength);
446 pw.println(" mMessageWaiting=" + mMessageWaiting);
447 pw.println(" mCallForwarding=" + mCallForwarding);
448 pw.println(" mDataActivity=" + mDataActivity);
449 pw.println(" mDataConnectionState=" + mDataConnectionState);
450 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
451 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
452 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
453 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
454 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700455 pw.println("registrations: count=" + recordCount);
456 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 Record r = mRecords.get(i);
458 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
459 }
460 }
461 }
462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 //
464 // the legacy intent broadcasting
465 //
466
467 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700468 long ident = Binder.clearCallingIdentity();
469 try {
470 mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
471 } catch (RemoteException re) {
472 // Can't do much
473 } finally {
474 Binder.restoreCallingIdentity(ident);
475 }
476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
478 Bundle data = new Bundle();
479 state.fillInNotifierBundle(data);
480 intent.putExtras(data);
481 mContext.sendStickyBroadcast(intent);
482 }
483
Wink Savillee9b06d72009-05-18 21:47:50 -0700484 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700485 long ident = Binder.clearCallingIdentity();
486 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700487 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700488 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700489 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700490 } finally {
491 Binder.restoreCallingIdentity(ident);
492 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700495 Bundle data = new Bundle();
496 signalStrength.fillInNotifierBundle(data);
497 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 mContext.sendStickyBroadcast(intent);
499 }
500
501 private void broadcastCallStateChanged(int state, String incomingNumber) {
502 long ident = Binder.clearCallingIdentity();
503 try {
504 if (state == TelephonyManager.CALL_STATE_IDLE) {
505 mBatteryStats.notePhoneOff();
506 } else {
507 mBatteryStats.notePhoneOn();
508 }
509 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700510 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 } finally {
512 Binder.restoreCallingIdentity(ident);
513 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700516 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 if (!TextUtils.isEmpty(incomingNumber)) {
518 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
519 }
520 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
521 }
522
Robert Greenwalt42acef32009-08-12 16:08:25 -0700523 private void broadcastDataConnectionStateChanged(int state,
524 boolean isDataConnectivityPossible,
525 String reason, String apn, String[] apnTypes, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700526 // Note: not reporting to the battery stats service here, because the
527 // status bar takes care of that after taking into account all of the
528 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
530 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
531 if (!isDataConnectivityPossible) {
532 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
533 }
534 if (reason != null) {
535 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
536 }
537 intent.putExtra(Phone.DATA_APN_KEY, apn);
Robert Greenwalt42acef32009-08-12 16:08:25 -0700538 String types = apnTypes[0];
539 for (int i = 1; i < apnTypes.length; i++) {
540 types = types+","+apnTypes[i];
541 }
542 intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
544 mContext.sendStickyBroadcast(intent);
545 }
546
547 private void broadcastDataConnectionFailed(String reason) {
548 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
549 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
550 mContext.sendStickyBroadcast(intent);
551 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700552
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700553 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700554 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
555 == PackageManager.PERMISSION_GRANTED) {
556 return true;
557 }
558 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700559 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700560 Log.w(TAG, msg);
561 return false;
562 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700563
564 private void checkListenerPermission(int events) {
565 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
566 mContext.enforceCallingOrSelfPermission(
567 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
568
569 }
570
571 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
572 mContext.enforceCallingOrSelfPermission(
573 android.Manifest.permission.READ_PHONE_STATE, null);
574 }
575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576}