blob: aacae1802bcd5b069f18880aa5cf267778afa6a9 [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) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700112 CellLocation location = CellLocation.getEmpty();
113
114 // Note that location can be null for non-phone builds like
115 // like the generic one.
116 if (location != null) {
117 location.fillInNotifierBundle(mCellLocation);
118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 mContext = context;
120 mBatteryStats = BatteryStatsService.getService();
121 }
122
123 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
124 boolean notifyNow) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700125 // Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
126 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700128 /* Checks permission and throws Security exception */
129 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130
131 synchronized (mRecords) {
132 // register
133 Record r = null;
134 find_and_add: {
135 IBinder b = callback.asBinder();
136 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700137 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 r = mRecords.get(i);
139 if (b == r.binder) {
140 break find_and_add;
141 }
142 }
143 r = new Record();
144 r.binder = b;
145 r.callback = callback;
146 r.pkgForDebug = pkgForDebug;
147 mRecords.add(r);
148 }
149 int send = events & (events ^ r.events);
150 r.events = events;
151 if (notifyNow) {
152 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
153 sendServiceState(r, mServiceState);
154 }
155 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
156 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700157 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
158 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
159 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 } catch (RemoteException ex) {
161 remove(r.binder);
162 }
163 }
164 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
165 try {
166 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
167 } catch (RemoteException ex) {
168 remove(r.binder);
169 }
170 }
171 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
172 try {
173 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
174 } catch (RemoteException ex) {
175 remove(r.binder);
176 }
177 }
178 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
179 sendCellLocation(r, mCellLocation);
180 }
181 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
182 try {
183 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
184 } catch (RemoteException ex) {
185 remove(r.binder);
186 }
187 }
188 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
189 try {
190 r.callback.onDataConnectionStateChanged(mDataConnectionState);
191 } catch (RemoteException ex) {
192 remove(r.binder);
193 }
194 }
195 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
196 try {
197 r.callback.onDataActivity(mDataActivity);
198 } catch (RemoteException ex) {
199 remove(r.binder);
200 }
201 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700202 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
203 try {
204 r.callback.onSignalStrengthsChanged(mSignalStrength);
205 } catch (RemoteException ex) {
206 remove(r.binder);
207 }
208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 }
210 }
211 } else {
212 remove(callback.asBinder());
213 }
214 }
215
216 private void remove(IBinder binder) {
217 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700218 final int recordCount = mRecords.size();
219 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 if (mRecords.get(i).binder == binder) {
221 mRecords.remove(i);
222 return;
223 }
224 }
225 }
226 }
227
228 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700229 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700230 return;
231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 synchronized (mRecords) {
233 mCallState = state;
234 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700235 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 Record r = mRecords.get(i);
237 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
238 try {
239 r.callback.onCallStateChanged(state, incomingNumber);
240 } catch (RemoteException ex) {
241 remove(r.binder);
242 }
243 }
244 }
245 }
246 broadcastCallStateChanged(state, incomingNumber);
247 }
248
249 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700250 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700251 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 synchronized (mRecords) {
254 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700255 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 Record r = mRecords.get(i);
257 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
258 sendServiceState(r, state);
259 }
260 }
261 }
262 broadcastServiceStateChanged(state);
263 }
264
Wink Savillee9b06d72009-05-18 21:47:50 -0700265 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700266 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700267 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700270 mSignalStrength = signalStrength;
271 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700273 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
274 sendSignalStrength(r, signalStrength);
275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
277 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700278 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
279 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
280 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 } catch (RemoteException ex) {
282 remove(r.binder);
283 }
284 }
285 }
286 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700287 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 }
289
290 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700291 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700292 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 synchronized (mRecords) {
295 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700296 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 Record r = mRecords.get(i);
298 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
299 try {
300 r.callback.onMessageWaitingIndicatorChanged(mwi);
301 } catch (RemoteException ex) {
302 remove(r.binder);
303 }
304 }
305 }
306 }
307 }
308
309 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700310 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700311 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 synchronized (mRecords) {
314 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700315 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 Record r = mRecords.get(i);
317 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
318 try {
319 r.callback.onCallForwardingIndicatorChanged(cfi);
320 } catch (RemoteException ex) {
321 remove(r.binder);
322 }
323 }
324 }
325 }
326 }
327
328 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700329 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700330 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 synchronized (mRecords) {
333 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700334 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 Record r = mRecords.get(i);
336 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
337 try {
338 r.callback.onDataActivity(state);
339 } catch (RemoteException ex) {
340 remove(r.binder);
341 }
342 }
343 }
344 }
345 }
346
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700347 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt42acef32009-08-12 16:08:25 -0700348 String reason, String apn, String[] apnTypes, String interfaceName) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700349 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700350 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 synchronized (mRecords) {
353 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700354 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 mDataConnectionReason = reason;
356 mDataConnectionApn = apn;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700357 mDataConnectionApnTypes = apnTypes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 mDataConnectionInterfaceName = interfaceName;
Wink Savillee9b06d72009-05-18 21:47:50 -0700359 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 Record r = mRecords.get(i);
361 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
362 try {
363 r.callback.onDataConnectionStateChanged(state);
364 } catch (RemoteException ex) {
365 remove(r.binder);
366 }
367 }
368 }
369 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700370 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalt42acef32009-08-12 16:08:25 -0700371 apnTypes, interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 }
373
374 public void notifyDataConnectionFailed(String reason) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700375 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700376 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 /*
379 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700380 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 synchronized (mRecords) {
382 mDataConnectionFailedReason = reason;
383 final int N = mRecords.size();
384 for (int i=N-1; i>=0; i--) {
385 Record r = mRecords.get(i);
386 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
387 // XXX
388 }
389 }
390 }
391 */
392 broadcastDataConnectionFailed(reason);
393 }
394
395 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700396 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700397 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 synchronized (mRecords) {
400 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700401 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 Record r = mRecords.get(i);
403 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
404 sendCellLocation(r, cellLocation);
405 }
406 }
407 }
408 }
409
Wink Savillee9b06d72009-05-18 21:47:50 -0700410 /**
411 * Copy the service state object so they can't mess it up in the local calls
412 */
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700413 public void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 try {
415 r.callback.onServiceStateChanged(new ServiceState(state));
416 } catch (RemoteException ex) {
417 remove(r.binder);
418 }
419 }
420
Wink Savillee9b06d72009-05-18 21:47:50 -0700421 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 try {
423 r.callback.onCellLocationChanged(new Bundle(cellLocation));
424 } catch (RemoteException ex) {
425 remove(r.binder);
426 }
427 }
428
Wink Savillee9b06d72009-05-18 21:47:50 -0700429 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
430 try {
431 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
432 } catch (RemoteException ex) {
433 remove(r.binder);
434 }
435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436
437 @Override
438 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
439 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
440 != PackageManager.PERMISSION_GRANTED) {
441 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700442 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 return;
444 }
445 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700446 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 pw.println("last known state:");
448 pw.println(" mCallState=" + mCallState);
449 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
450 pw.println(" mServiceState=" + mServiceState);
451 pw.println(" mSignalStrength=" + mSignalStrength);
452 pw.println(" mMessageWaiting=" + mMessageWaiting);
453 pw.println(" mCallForwarding=" + mCallForwarding);
454 pw.println(" mDataActivity=" + mDataActivity);
455 pw.println(" mDataConnectionState=" + mDataConnectionState);
456 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
457 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
458 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
459 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
460 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700461 pw.println("registrations: count=" + recordCount);
462 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 Record r = mRecords.get(i);
464 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
465 }
466 }
467 }
468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 //
470 // the legacy intent broadcasting
471 //
472
473 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700474 long ident = Binder.clearCallingIdentity();
475 try {
476 mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
477 } catch (RemoteException re) {
478 // Can't do much
479 } finally {
480 Binder.restoreCallingIdentity(ident);
481 }
482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
484 Bundle data = new Bundle();
485 state.fillInNotifierBundle(data);
486 intent.putExtras(data);
487 mContext.sendStickyBroadcast(intent);
488 }
489
Wink Savillee9b06d72009-05-18 21:47:50 -0700490 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700491 long ident = Binder.clearCallingIdentity();
492 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700493 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700494 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700495 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700496 } 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(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700501 Bundle data = new Bundle();
502 signalStrength.fillInNotifierBundle(data);
503 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 mContext.sendStickyBroadcast(intent);
505 }
506
507 private void broadcastCallStateChanged(int state, String incomingNumber) {
508 long ident = Binder.clearCallingIdentity();
509 try {
510 if (state == TelephonyManager.CALL_STATE_IDLE) {
511 mBatteryStats.notePhoneOff();
512 } else {
513 mBatteryStats.notePhoneOn();
514 }
515 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700516 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 } finally {
518 Binder.restoreCallingIdentity(ident);
519 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillee9b06d72009-05-18 21:47:50 -0700522 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 if (!TextUtils.isEmpty(incomingNumber)) {
524 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
525 }
526 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
527 }
528
Robert Greenwalt42acef32009-08-12 16:08:25 -0700529 private void broadcastDataConnectionStateChanged(int state,
530 boolean isDataConnectivityPossible,
531 String reason, String apn, String[] apnTypes, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700532 // Note: not reporting to the battery stats service here, because the
533 // status bar takes care of that after taking into account all of the
534 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
536 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
537 if (!isDataConnectivityPossible) {
538 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
539 }
540 if (reason != null) {
541 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
542 }
543 intent.putExtra(Phone.DATA_APN_KEY, apn);
Robert Greenwalt75e1d312009-08-19 11:18:53 -0700544 String types = new String("");
545 if (apnTypes.length > 0) {
546 types = apnTypes[0];
547 for (int i = 1; i < apnTypes.length; i++) {
548 types = types+","+apnTypes[i];
549 }
Robert Greenwalt42acef32009-08-12 16:08:25 -0700550 }
551 intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
553 mContext.sendStickyBroadcast(intent);
554 }
555
556 private void broadcastDataConnectionFailed(String reason) {
557 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
558 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
559 mContext.sendStickyBroadcast(intent);
560 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700561
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700562 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700563 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
564 == PackageManager.PERMISSION_GRANTED) {
565 return true;
566 }
567 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700568 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700569 Log.w(TAG, msg);
570 return false;
571 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700572
573 private void checkListenerPermission(int events) {
574 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
575 mContext.enforceCallingOrSelfPermission(
576 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
577
578 }
579
580 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
581 mContext.enforceCallingOrSelfPermission(
582 android.Manifest.permission.READ_PHONE_STATE, null);
583 }
584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585}