blob: 664dfa531e2ed5bd1e9d9d14079b18462cb9c241 [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;
Joe Onorato8a9b2202010-02-26 18:56:32 -080032import android.util.Slog;
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
Robert Greenwalt98e0b142009-10-08 21:15:52 -070097 private int mDataConnectionNetworkType;
98
Jaikumar Ganesh45515652009-04-23 15:20:21 -070099 static final int PHONE_STATE_PERMISSION_MASK =
100 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
101 PhoneStateListener.LISTEN_CALL_STATE |
102 PhoneStateListener.LISTEN_DATA_ACTIVITY |
103 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
104 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
105
Wink Savillee9b06d72009-05-18 21:47:50 -0700106 // we keep a copy of all of the state so we can send it out when folks
107 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700109 // In these calls we call with the lock held. This is safe becasuse remote
110 // calls go through a oneway interface and local calls going through a
111 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
113 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700114 CellLocation location = CellLocation.getEmpty();
115
116 // Note that location can be null for non-phone builds like
117 // like the generic one.
118 if (location != null) {
119 location.fillInNotifierBundle(mCellLocation);
120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 mContext = context;
122 mBatteryStats = BatteryStatsService.getService();
123 }
124
125 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
126 boolean notifyNow) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800127 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
Wink Savillee9b06d72009-05-18 21:47:50 -0700128 // Integer.toHexString(events));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700130 /* Checks permission and throws Security exception */
131 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132
133 synchronized (mRecords) {
134 // register
135 Record r = null;
136 find_and_add: {
137 IBinder b = callback.asBinder();
138 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700139 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 r = mRecords.get(i);
141 if (b == r.binder) {
142 break find_and_add;
143 }
144 }
145 r = new Record();
146 r.binder = b;
147 r.callback = callback;
148 r.pkgForDebug = pkgForDebug;
149 mRecords.add(r);
150 }
151 int send = events & (events ^ r.events);
152 r.events = events;
153 if (notifyNow) {
154 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
155 sendServiceState(r, mServiceState);
156 }
157 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
158 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700159 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
160 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
161 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 } catch (RemoteException ex) {
163 remove(r.binder);
164 }
165 }
166 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
167 try {
168 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
169 } catch (RemoteException ex) {
170 remove(r.binder);
171 }
172 }
173 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
174 try {
175 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
176 } catch (RemoteException ex) {
177 remove(r.binder);
178 }
179 }
180 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
181 sendCellLocation(r, mCellLocation);
182 }
183 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
184 try {
185 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
186 } catch (RemoteException ex) {
187 remove(r.binder);
188 }
189 }
190 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
191 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700192 r.callback.onDataConnectionStateChanged(mDataConnectionState,
193 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 } catch (RemoteException ex) {
195 remove(r.binder);
196 }
197 }
198 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
199 try {
200 r.callback.onDataActivity(mDataActivity);
201 } catch (RemoteException ex) {
202 remove(r.binder);
203 }
204 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700205 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
206 try {
207 r.callback.onSignalStrengthsChanged(mSignalStrength);
208 } catch (RemoteException ex) {
209 remove(r.binder);
210 }
211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 }
213 }
214 } else {
215 remove(callback.asBinder());
216 }
217 }
218
219 private void remove(IBinder binder) {
220 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700221 final int recordCount = mRecords.size();
222 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 if (mRecords.get(i).binder == binder) {
224 mRecords.remove(i);
225 return;
226 }
227 }
228 }
229 }
230
231 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700232 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700233 return;
234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 synchronized (mRecords) {
236 mCallState = state;
237 mCallIncomingNumber = incomingNumber;
Wink Savillee9b06d72009-05-18 21:47:50 -0700238 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 Record r = mRecords.get(i);
240 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
241 try {
242 r.callback.onCallStateChanged(state, incomingNumber);
243 } catch (RemoteException ex) {
244 remove(r.binder);
245 }
246 }
247 }
248 }
249 broadcastCallStateChanged(state, incomingNumber);
250 }
251
252 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700253 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700254 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 synchronized (mRecords) {
257 mServiceState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700258 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 Record r = mRecords.get(i);
260 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
261 sendServiceState(r, state);
262 }
263 }
264 }
265 broadcastServiceStateChanged(state);
266 }
267
Wink Savillee9b06d72009-05-18 21:47:50 -0700268 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700269 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700270 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700273 mSignalStrength = signalStrength;
274 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 Record r = mRecords.get(i);
Wink Savillee9b06d72009-05-18 21:47:50 -0700276 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
277 sendSignalStrength(r, signalStrength);
278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
280 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700281 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
282 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
283 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 } catch (RemoteException ex) {
285 remove(r.binder);
286 }
287 }
288 }
289 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700290 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 }
292
293 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700294 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700295 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 synchronized (mRecords) {
298 mMessageWaiting = mwi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700299 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 Record r = mRecords.get(i);
301 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
302 try {
303 r.callback.onMessageWaitingIndicatorChanged(mwi);
304 } catch (RemoteException ex) {
305 remove(r.binder);
306 }
307 }
308 }
309 }
310 }
311
312 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700313 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700314 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 synchronized (mRecords) {
317 mCallForwarding = cfi;
Wink Savillee9b06d72009-05-18 21:47:50 -0700318 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 Record r = mRecords.get(i);
320 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
321 try {
322 r.callback.onCallForwardingIndicatorChanged(cfi);
323 } catch (RemoteException ex) {
324 remove(r.binder);
325 }
326 }
327 }
328 }
329 }
330
331 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700332 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700333 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 synchronized (mRecords) {
336 mDataActivity = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700337 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 Record r = mRecords.get(i);
339 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
340 try {
341 r.callback.onDataActivity(state);
342 } catch (RemoteException ex) {
343 remove(r.binder);
344 }
345 }
346 }
347 }
348 }
349
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700350 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700351 String reason, String apn, String[] apnTypes, String interfaceName, int networkType) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700352 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700353 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 synchronized (mRecords) {
356 mDataConnectionState = state;
Wink Savillee9b06d72009-05-18 21:47:50 -0700357 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 mDataConnectionReason = reason;
359 mDataConnectionApn = apn;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700360 mDataConnectionApnTypes = apnTypes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 mDataConnectionInterfaceName = interfaceName;
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700362 mDataConnectionNetworkType = networkType;
Wink Savillee9b06d72009-05-18 21:47:50 -0700363 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 Record r = mRecords.get(i);
365 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
366 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700367 r.callback.onDataConnectionStateChanged(state, networkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 } catch (RemoteException ex) {
369 remove(r.binder);
370 }
371 }
372 }
373 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700374 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalt42acef32009-08-12 16:08:25 -0700375 apnTypes, interfaceName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 }
377
378 public void notifyDataConnectionFailed(String reason) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700379 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700380 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 /*
383 * This is commented out because there is on onDataConnectionFailed callback
Wink Savillee9b06d72009-05-18 21:47:50 -0700384 * on PhoneStateListener. There should be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 synchronized (mRecords) {
386 mDataConnectionFailedReason = reason;
387 final int N = mRecords.size();
388 for (int i=N-1; i>=0; i--) {
389 Record r = mRecords.get(i);
390 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
391 // XXX
392 }
393 }
394 }
395 */
396 broadcastDataConnectionFailed(reason);
397 }
398
399 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700400 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700401 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 synchronized (mRecords) {
404 mCellLocation = cellLocation;
Wink Savillee9b06d72009-05-18 21:47:50 -0700405 for (int i = mRecords.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 Record r = mRecords.get(i);
407 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
408 sendCellLocation(r, cellLocation);
409 }
410 }
411 }
412 }
413
Wink Savillee9b06d72009-05-18 21:47:50 -0700414 /**
415 * Copy the service state object so they can't mess it up in the local calls
416 */
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700417 public void sendServiceState(Record r, ServiceState state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 try {
419 r.callback.onServiceStateChanged(new ServiceState(state));
420 } catch (RemoteException ex) {
421 remove(r.binder);
422 }
423 }
424
Wink Savillee9b06d72009-05-18 21:47:50 -0700425 private void sendCellLocation(Record r, Bundle cellLocation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 try {
427 r.callback.onCellLocationChanged(new Bundle(cellLocation));
428 } catch (RemoteException ex) {
429 remove(r.binder);
430 }
431 }
432
Wink Savillee9b06d72009-05-18 21:47:50 -0700433 private void sendSignalStrength(Record r, SignalStrength signalStrength) {
434 try {
435 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
436 } catch (RemoteException ex) {
437 remove(r.binder);
438 }
439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440
441 @Override
442 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
443 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
444 != PackageManager.PERMISSION_GRANTED) {
445 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700446 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 return;
448 }
449 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700450 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 pw.println("last known state:");
452 pw.println(" mCallState=" + mCallState);
453 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
454 pw.println(" mServiceState=" + mServiceState);
455 pw.println(" mSignalStrength=" + mSignalStrength);
456 pw.println(" mMessageWaiting=" + mMessageWaiting);
457 pw.println(" mCallForwarding=" + mCallForwarding);
458 pw.println(" mDataActivity=" + mDataActivity);
459 pw.println(" mDataConnectionState=" + mDataConnectionState);
460 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
461 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
462 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
463 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
464 pw.println(" mCellLocation=" + mCellLocation);
Wink Savillee9b06d72009-05-18 21:47:50 -0700465 pw.println("registrations: count=" + recordCount);
466 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 Record r = mRecords.get(i);
468 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
469 }
470 }
471 }
472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 //
474 // the legacy intent broadcasting
475 //
476
477 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700478 long ident = Binder.clearCallingIdentity();
479 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700480 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700481 } catch (RemoteException re) {
482 // Can't do much
483 } finally {
484 Binder.restoreCallingIdentity(ident);
485 }
486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800488 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 Bundle data = new Bundle();
490 state.fillInNotifierBundle(data);
491 intent.putExtras(data);
492 mContext.sendStickyBroadcast(intent);
493 }
494
Wink Savillee9b06d72009-05-18 21:47:50 -0700495 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700496 long ident = Binder.clearCallingIdentity();
497 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700498 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700499 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700500 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700501 } finally {
502 Binder.restoreCallingIdentity(ident);
503 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800506 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700507 Bundle data = new Bundle();
508 signalStrength.fillInNotifierBundle(data);
509 intent.putExtras(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 mContext.sendStickyBroadcast(intent);
511 }
512
513 private void broadcastCallStateChanged(int state, String incomingNumber) {
514 long ident = Binder.clearCallingIdentity();
515 try {
516 if (state == TelephonyManager.CALL_STATE_IDLE) {
517 mBatteryStats.notePhoneOff();
518 } else {
519 mBatteryStats.notePhoneOn();
520 }
521 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700522 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 } finally {
524 Binder.restoreCallingIdentity(ident);
525 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800528 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700529 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 if (!TextUtils.isEmpty(incomingNumber)) {
531 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
532 }
533 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
534 }
535
Robert Greenwalt42acef32009-08-12 16:08:25 -0700536 private void broadcastDataConnectionStateChanged(int state,
537 boolean isDataConnectivityPossible,
538 String reason, String apn, String[] apnTypes, String interfaceName) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700539 // Note: not reporting to the battery stats service here, because the
540 // status bar takes care of that after taking into account all of the
541 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800543 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
545 if (!isDataConnectivityPossible) {
546 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
547 }
548 if (reason != null) {
549 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
550 }
551 intent.putExtra(Phone.DATA_APN_KEY, apn);
Robert Greenwalt75e1d312009-08-19 11:18:53 -0700552 String types = new String("");
553 if (apnTypes.length > 0) {
554 types = apnTypes[0];
555 for (int i = 1; i < apnTypes.length; i++) {
556 types = types+","+apnTypes[i];
557 }
Robert Greenwalt42acef32009-08-12 16:08:25 -0700558 }
559 intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
561 mContext.sendStickyBroadcast(intent);
562 }
563
564 private void broadcastDataConnectionFailed(String reason) {
565 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800566 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
568 mContext.sendStickyBroadcast(intent);
569 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700570
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700571 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700572 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
573 == PackageManager.PERMISSION_GRANTED) {
574 return true;
575 }
576 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700577 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Joe Onorato8a9b2202010-02-26 18:56:32 -0800578 Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700579 return false;
580 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700581
582 private void checkListenerPermission(int events) {
583 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
584 mContext.enforceCallingOrSelfPermission(
585 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
586
587 }
588
589 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
590 mContext.enforceCallingOrSelfPermission(
591 android.Manifest.permission.READ_PHONE_STATE, null);
592 }
593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594}