blob: 77f518232b40990b7bd20de69475d356c5bf76f7 [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
Wink Savillea12a7b32012-09-20 10:09:45 -070019import android.app.ActivityManager;
20import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
22import android.content.Intent;
Wink Savillea12a7b32012-09-20 10:09:45 -070023import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.pm.PackageManager;
Wink Savillef61101f2010-09-16 16:36:42 -070025import android.net.LinkCapabilities;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070026import android.net.LinkProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.os.Binder;
28import android.os.Bundle;
Wink Savillea12a7b32012-09-20 10:09:45 -070029import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.IBinder;
Wink Savillea12a7b32012-09-20 10:09:45 -070031import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.RemoteException;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070033import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.telephony.CellLocation;
35import android.telephony.PhoneStateListener;
36import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070037import android.telephony.SignalStrength;
John Wang963db55d2012-03-30 16:04:06 -070038import android.telephony.CellInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.telephony.TelephonyManager;
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +020040import android.telephony.DisconnectCause;
41import android.telephony.PreciseCallState;
42import android.telephony.PreciseDataConnectionState;
43import android.telephony.PreciseDisconnectCause;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.text.TextUtils;
Joe Onorato8a9b2202010-02-26 18:56:32 -080045import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
47import java.util.ArrayList;
Wink Savilleb208a242012-07-25 14:08:09 -070048import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import java.io.FileDescriptor;
50import java.io.PrintWriter;
51
52import com.android.internal.app.IBatteryStats;
53import com.android.internal.telephony.ITelephonyRegistry;
54import com.android.internal.telephony.IPhoneStateListener;
55import com.android.internal.telephony.DefaultPhoneNotifier;
Wink Savillea639b312012-07-10 12:37:54 -070056import com.android.internal.telephony.PhoneConstants;
Wink Savillec9330dd2011-01-12 13:37:38 -080057import com.android.internal.telephony.ServiceStateTracker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import com.android.internal.telephony.TelephonyIntents;
59import com.android.server.am.BatteryStatsService;
60
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061/**
Wink Savillee9b06d72009-05-18 21:47:50 -070062 * Since phone process can be restarted, this class provides a centralized place
63 * that applications can register and be called back from.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 */
65class TelephonyRegistry extends ITelephonyRegistry.Stub {
66 private static final String TAG = "TelephonyRegistry";
Wink Savillec9acde92011-09-21 11:05:43 -070067 private static final boolean DBG = false;
Wink Savillea12a7b32012-09-20 10:09:45 -070068 private static final boolean DBG_LOC = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
70 private static class Record {
71 String pkgForDebug;
Wink Savillee9b06d72009-05-18 21:47:50 -070072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 IBinder binder;
Wink Savillee9b06d72009-05-18 21:47:50 -070074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 IPhoneStateListener callback;
Wink Savillee9b06d72009-05-18 21:47:50 -070076
Wink Savillea12a7b32012-09-20 10:09:45 -070077 int callerUid;
78
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 int events;
Wink Savillea12a7b32012-09-20 10:09:45 -070080
81 @Override
82 public String toString() {
83 return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid +
84 " events=" + Integer.toHexString(events) + "}";
85 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 }
87
88 private final Context mContext;
Wink Savillee9b06d72009-05-18 21:47:50 -070089
Joe Onorato163d8d92010-10-21 13:21:20 -040090 // access should be inside synchronized (mRecords) for these two fields
91 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
92 private final ArrayList<Record> mRecords = new ArrayList<Record>();
Wink Savillee9b06d72009-05-18 21:47:50 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private final IBatteryStats mBatteryStats;
95
96 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
Wink Savillee9b06d72009-05-18 21:47:50 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private String mCallIncomingNumber = "";
Wink Savillee9b06d72009-05-18 21:47:50 -070099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 private ServiceState mServiceState = new ServiceState();
Wink Savillee9b06d72009-05-18 21:47:50 -0700101
102 private SignalStrength mSignalStrength = new SignalStrength();
103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 private boolean mMessageWaiting = false;
Wink Savillee9b06d72009-05-18 21:47:50 -0700105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 private boolean mCallForwarding = false;
Wink Savillee9b06d72009-05-18 21:47:50 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
Wink Savillee9b06d72009-05-18 21:47:50 -0700109
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800110 private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -0700111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 private boolean mDataConnectionPossible = false;
Wink Savillee9b06d72009-05-18 21:47:50 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 private String mDataConnectionReason = "";
Wink Savillee9b06d72009-05-18 21:47:50 -0700115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 private String mDataConnectionApn = "";
Wink Savillee9b06d72009-05-18 21:47:50 -0700117
Robert Greenwalt02648a42010-05-18 10:52:51 -0700118 private ArrayList<String> mConnectedApns;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700119
Wink Savillef61101f2010-09-16 16:36:42 -0700120 private LinkProperties mDataConnectionLinkProperties;
121
122 private LinkCapabilities mDataConnectionLinkCapabilities;
Wink Savillee9b06d72009-05-18 21:47:50 -0700123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 private Bundle mCellLocation = new Bundle();
125
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700126 private int mDataConnectionNetworkType;
127
Wink Savillec9330dd2011-01-12 13:37:38 -0800128 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
Wink Savillefd2d0132010-10-28 14:22:26 -0700129
Wink Savilleb208a242012-07-25 14:08:09 -0700130 private List<CellInfo> mCellInfo = null;
John Wang963db55d2012-03-30 16:04:06 -0700131
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200132 private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
133
134 private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
135
136 private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
137
138 private PreciseCallState mPreciseCallState = new PreciseCallState();
139
140 private PreciseDataConnectionState mPreciseDataConnectionState =
141 new PreciseDataConnectionState();
142
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700143 static final int PHONE_STATE_PERMISSION_MASK =
144 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
145 PhoneStateListener.LISTEN_CALL_STATE |
146 PhoneStateListener.LISTEN_DATA_ACTIVITY |
147 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
148 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
149
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200150 static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
151 PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
152 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
153
Wink Savillea12a7b32012-09-20 10:09:45 -0700154 private static final int MSG_USER_SWITCHED = 1;
155
156 private final Handler mHandler = new Handler() {
157 @Override
158 public void handleMessage(Message msg) {
159 switch (msg.what) {
160 case MSG_USER_SWITCHED: {
Dianne Hackborn40e9f292012-11-27 19:12:23 -0800161 if (DBG) Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1);
Wink Savillea12a7b32012-09-20 10:09:45 -0700162 TelephonyRegistry.this.notifyCellLocation(mCellLocation);
163 break;
164 }
165 }
166 }
167 };
168
169 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
170 @Override
171 public void onReceive(Context context, Intent intent) {
172 String action = intent.getAction();
173 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
174 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
175 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
176 }
177 }
178 };
179
Wink Savillee9b06d72009-05-18 21:47:50 -0700180 // we keep a copy of all of the state so we can send it out when folks
181 // register for it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 //
Wink Savillee9b06d72009-05-18 21:47:50 -0700183 // In these calls we call with the lock held. This is safe becasuse remote
184 // calls go through a oneway interface and local calls going through a
185 // handler before they get to app code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 TelephonyRegistry(Context context) {
David 'Digit' Turner4ef8ec32009-09-25 11:33:24 -0700188 CellLocation location = CellLocation.getEmpty();
189
190 // Note that location can be null for non-phone builds like
191 // like the generic one.
192 if (location != null) {
193 location.fillInNotifierBundle(mCellLocation);
194 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 mContext = context;
196 mBatteryStats = BatteryStatsService.getService();
Robert Greenwalt02648a42010-05-18 10:52:51 -0700197 mConnectedApns = new ArrayList<String>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 }
199
Svetoslav Ganova0027152013-06-25 14:59:53 -0700200 public void systemRunning() {
Wink Savillea12a7b32012-09-20 10:09:45 -0700201 // Watch for interesting updates
202 final IntentFilter filter = new IntentFilter();
203 filter.addAction(Intent.ACTION_USER_SWITCHED);
204 filter.addAction(Intent.ACTION_USER_REMOVED);
205 mContext.registerReceiver(mBroadcastReceiver, filter);
206 }
207
208 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
210 boolean notifyNow) {
Wink Savillea12a7b32012-09-20 10:09:45 -0700211 int callerUid = UserHandle.getCallingUserId();
212 int myUid = UserHandle.myUserId();
213 if (DBG) {
214 Slog.d(TAG, "listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
215 + " myUid=" + myUid
216 + " callerUid=" + callerUid);
217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 if (events != 0) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700219 /* Checks permission and throws Security exception */
220 checkListenerPermission(events);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 synchronized (mRecords) {
223 // register
224 Record r = null;
225 find_and_add: {
226 IBinder b = callback.asBinder();
227 final int N = mRecords.size();
Wink Savillee9b06d72009-05-18 21:47:50 -0700228 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 r = mRecords.get(i);
230 if (b == r.binder) {
231 break find_and_add;
232 }
233 }
234 r = new Record();
235 r.binder = b;
236 r.callback = callback;
237 r.pkgForDebug = pkgForDebug;
Wink Savillea12a7b32012-09-20 10:09:45 -0700238 r.callerUid = callerUid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 mRecords.add(r);
Wink Savillea12a7b32012-09-20 10:09:45 -0700240 if (DBG) Slog.i(TAG, "listen: add new record=" + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 }
242 int send = events & (events ^ r.events);
243 r.events = events;
244 if (notifyNow) {
245 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400246 try {
247 r.callback.onServiceStateChanged(new ServiceState(mServiceState));
248 } catch (RemoteException ex) {
249 remove(r.binder);
250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 }
252 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
253 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700254 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
255 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
256 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 } catch (RemoteException ex) {
258 remove(r.binder);
259 }
260 }
261 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
262 try {
263 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
264 } catch (RemoteException ex) {
265 remove(r.binder);
266 }
267 }
268 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
269 try {
270 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
271 } catch (RemoteException ex) {
272 remove(r.binder);
273 }
274 }
Wink Savillea12a7b32012-09-20 10:09:45 -0700275 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400276 try {
Wink Savillea12a7b32012-09-20 10:09:45 -0700277 if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation=" + mCellLocation);
Joe Onorato163d8d92010-10-21 13:21:20 -0400278 r.callback.onCellLocationChanged(new Bundle(mCellLocation));
279 } catch (RemoteException ex) {
280 remove(r.binder);
281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 }
283 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
284 try {
285 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
286 } catch (RemoteException ex) {
287 remove(r.binder);
288 }
289 }
290 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
291 try {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700292 r.callback.onDataConnectionStateChanged(mDataConnectionState,
293 mDataConnectionNetworkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 } catch (RemoteException ex) {
295 remove(r.binder);
296 }
297 }
298 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
299 try {
300 r.callback.onDataActivity(mDataActivity);
301 } catch (RemoteException ex) {
302 remove(r.binder);
303 }
304 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700305 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
306 try {
307 r.callback.onSignalStrengthsChanged(mSignalStrength);
308 } catch (RemoteException ex) {
309 remove(r.binder);
310 }
311 }
Wink Savillefd2d0132010-10-28 14:22:26 -0700312 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
313 try {
314 r.callback.onOtaspChanged(mOtaspMode);
315 } catch (RemoteException ex) {
316 remove(r.binder);
317 }
318 }
Wink Savillea12a7b32012-09-20 10:09:45 -0700319 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
John Wang963db55d2012-03-30 16:04:06 -0700320 try {
Wink Savillea12a7b32012-09-20 10:09:45 -0700321 if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo=" + mCellInfo);
Wink Savilleb208a242012-07-25 14:08:09 -0700322 r.callback.onCellInfoChanged(mCellInfo);
John Wang963db55d2012-03-30 16:04:06 -0700323 } catch (RemoteException ex) {
324 remove(r.binder);
325 }
326 }
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200327 if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
328 try {
329 r.callback.onPreciseCallStateChanged(mPreciseCallState);
330 } catch (RemoteException ex) {
331 remove(r.binder);
332 }
333 }
334 if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
335 try {
336 r.callback.onPreciseDataConnectionStateChanged(
337 mPreciseDataConnectionState);
338 } catch (RemoteException ex) {
339 remove(r.binder);
340 }
341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343 }
344 } else {
345 remove(callback.asBinder());
346 }
347 }
348
349 private void remove(IBinder binder) {
350 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700351 final int recordCount = mRecords.size();
352 for (int i = 0; i < recordCount; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 if (mRecords.get(i).binder == binder) {
354 mRecords.remove(i);
355 return;
356 }
357 }
358 }
359 }
360
361 public void notifyCallState(int state, String incomingNumber) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700362 if (!checkNotifyPermission("notifyCallState()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700363 return;
364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 synchronized (mRecords) {
366 mCallState = state;
367 mCallIncomingNumber = incomingNumber;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700368 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
370 try {
371 r.callback.onCallStateChanged(state, incomingNumber);
372 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400373 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
375 }
376 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400377 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 }
379 broadcastCallStateChanged(state, incomingNumber);
380 }
381
382 public void notifyServiceState(ServiceState state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700383 if (!checkNotifyPermission("notifyServiceState()")){
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700384 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 synchronized (mRecords) {
387 mServiceState = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700388 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400390 try {
391 r.callback.onServiceStateChanged(new ServiceState(state));
392 } catch (RemoteException ex) {
393 mRemoveList.add(r.binder);
394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
396 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400397 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 }
399 broadcastServiceStateChanged(state);
400 }
401
Wink Savillee9b06d72009-05-18 21:47:50 -0700402 public void notifySignalStrength(SignalStrength signalStrength) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700403 if (!checkNotifyPermission("notifySignalStrength()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700404 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700407 mSignalStrength = signalStrength;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700408 for (Record r : mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700409 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400410 try {
411 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
412 } catch (RemoteException ex) {
413 mRemoveList.add(r.binder);
414 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
417 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700418 int gsmSignalStrength = signalStrength.getGsmSignalStrength();
419 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
420 : gsmSignalStrength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400422 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
424 }
425 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400426 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700428 broadcastSignalStrengthChanged(signalStrength);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 }
430
Wink Savilleb208a242012-07-25 14:08:09 -0700431 public void notifyCellInfo(List<CellInfo> cellInfo) {
John Wang963db55d2012-03-30 16:04:06 -0700432 if (!checkNotifyPermission("notifyCellInfo()")) {
433 return;
434 }
435
436 synchronized (mRecords) {
437 mCellInfo = cellInfo;
438 for (Record r : mRecords) {
Wink Savillea12a7b32012-09-20 10:09:45 -0700439 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
John Wang963db55d2012-03-30 16:04:06 -0700440 try {
Wink Savillea12a7b32012-09-20 10:09:45 -0700441 if (DBG_LOC) {
442 Slog.d(TAG, "notifyCellInfo: mCellInfo=" + mCellInfo + " r=" + r);
443 }
Wink Savilleb208a242012-07-25 14:08:09 -0700444 r.callback.onCellInfoChanged(cellInfo);
John Wang963db55d2012-03-30 16:04:06 -0700445 } catch (RemoteException ex) {
446 mRemoveList.add(r.binder);
447 }
448 }
449 }
450 handleRemoveListLocked();
451 }
452 }
453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 public void notifyMessageWaitingChanged(boolean mwi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700455 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700456 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 synchronized (mRecords) {
459 mMessageWaiting = mwi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700460 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
462 try {
463 r.callback.onMessageWaitingIndicatorChanged(mwi);
464 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400465 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 }
467 }
468 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400469 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 }
471 }
472
473 public void notifyCallForwardingChanged(boolean cfi) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700474 if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700475 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 synchronized (mRecords) {
478 mCallForwarding = cfi;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700479 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
481 try {
482 r.callback.onCallForwardingIndicatorChanged(cfi);
483 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400484 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 }
486 }
487 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400488 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 }
490 }
491
492 public void notifyDataActivity(int state) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700493 if (!checkNotifyPermission("notifyDataActivity()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700494 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 synchronized (mRecords) {
497 mDataActivity = state;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700498 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
500 try {
501 r.callback.onDataActivity(state);
502 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400503 mRemoveList.add(r.binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 }
505 }
506 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400507 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 }
509 }
510
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700511 public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700512 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700513 LinkCapabilities linkCapabilities, int networkType, boolean roaming) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700514 if (!checkNotifyPermission("notifyDataConnection()" )) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700515 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700516 }
Wink Savillec9acde92011-09-21 11:05:43 -0700517 if (DBG) {
518 Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
Wink Saville26f5a382010-11-24 16:44:29 -0800519 + isDataConnectivityPossible + " reason='" + reason
Wink Savillea12a7b32012-09-20 10:09:45 -0700520 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
521 + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords);
Wink Savillec9acde92011-09-21 11:05:43 -0700522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 synchronized (mRecords) {
Robert Greenwalt02648a42010-05-18 10:52:51 -0700524 boolean modified = false;
525 if (state == TelephonyManager.DATA_CONNECTED) {
526 if (!mConnectedApns.contains(apnType)) {
527 mConnectedApns.add(apnType);
528 if (mDataConnectionState != state) {
529 mDataConnectionState = state;
530 modified = true;
531 }
532 }
533 } else {
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800534 if (mConnectedApns.remove(apnType)) {
535 if (mConnectedApns.isEmpty()) {
536 mDataConnectionState = state;
537 modified = true;
538 } else {
539 // leave mDataConnectionState as is and
540 // send out the new status for the APN in question.
541 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700542 }
543 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700544 mDataConnectionPossible = isDataConnectivityPossible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 mDataConnectionReason = reason;
Wink Savillef61101f2010-09-16 16:36:42 -0700546 mDataConnectionLinkProperties = linkProperties;
547 mDataConnectionLinkCapabilities = linkCapabilities;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700548 if (mDataConnectionNetworkType != networkType) {
549 mDataConnectionNetworkType = networkType;
Robert Greenwalt8e7e0a92010-11-09 10:24:40 -0800550 // need to tell registered listeners about the new network type
Robert Greenwalt02648a42010-05-18 10:52:51 -0700551 modified = true;
552 }
553 if (modified) {
Wink Savillec9acde92011-09-21 11:05:43 -0700554 if (DBG) {
555 Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
yoonsung.name6fa1202011-08-20 21:39:12 -0700556 + ", " + mDataConnectionNetworkType + ")");
Wink Savillec9acde92011-09-21 11:05:43 -0700557 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700558 for (Record r : mRecords) {
559 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
560 try {
yoonsung.name6fa1202011-08-20 21:39:12 -0700561 r.callback.onDataConnectionStateChanged(mDataConnectionState,
562 mDataConnectionNetworkType);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700563 } catch (RemoteException ex) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400564 mRemoveList.add(r.binder);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 }
567 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400568 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 }
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200570 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
571 apnType, apn, reason, linkProperties, "");
572 for (Record r : mRecords) {
573 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
574 try {
575 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
576 } catch (RemoteException ex) {
577 mRemoveList.add(r.binder);
578 }
579 }
580 }
581 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700583 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700584 apnType, linkProperties, linkCapabilities, roaming);
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200585 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
586 linkProperties, "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
588
Robert Greenwalt02648a42010-05-18 10:52:51 -0700589 public void notifyDataConnectionFailed(String reason, String apnType) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700590 if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700591 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 synchronized (mRecords) {
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200594 mPreciseDataConnectionState = new PreciseDataConnectionState(
595 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
596 apnType, "", reason, null, "");
597 for (Record r : mRecords) {
598 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
599 try {
600 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
601 } catch (RemoteException ex) {
602 mRemoveList.add(r.binder);
603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
605 }
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200606 handleRemoveListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 }
Robert Greenwalt02648a42010-05-18 10:52:51 -0700608 broadcastDataConnectionFailed(reason, apnType);
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200609 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
610 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 }
612
613 public void notifyCellLocation(Bundle cellLocation) {
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700614 if (!checkNotifyPermission("notifyCellLocation()")) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700615 return;
Wink Savillee9b06d72009-05-18 21:47:50 -0700616 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 synchronized (mRecords) {
618 mCellLocation = cellLocation;
Robert Greenwalt02648a42010-05-18 10:52:51 -0700619 for (Record r : mRecords) {
Wink Savillea12a7b32012-09-20 10:09:45 -0700620 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
Joe Onorato163d8d92010-10-21 13:21:20 -0400621 try {
Wink Savillea12a7b32012-09-20 10:09:45 -0700622 if (DBG_LOC) {
623 Slog.d(TAG, "notifyCellLocation: mCellLocation=" + mCellLocation
624 + " r=" + r);
625 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400626 r.callback.onCellLocationChanged(new Bundle(cellLocation));
627 } catch (RemoteException ex) {
628 mRemoveList.add(r.binder);
629 }
630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 }
632 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400633 handleRemoveListLocked();
Wink Savillee9b06d72009-05-18 21:47:50 -0700634 }
635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636
Wink Savillefd2d0132010-10-28 14:22:26 -0700637 public void notifyOtaspChanged(int otaspMode) {
638 if (!checkNotifyPermission("notifyOtaspChanged()" )) {
639 return;
640 }
641 synchronized (mRecords) {
642 mOtaspMode = otaspMode;
643 for (Record r : mRecords) {
644 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
645 try {
646 r.callback.onOtaspChanged(otaspMode);
647 } catch (RemoteException ex) {
648 mRemoveList.add(r.binder);
649 }
650 }
651 }
652 handleRemoveListLocked();
653 }
654 }
655
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200656 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
657 int backgroundCallState) {
658 if (!checkNotifyPermission("notifyPreciseCallState()")) {
659 return;
660 }
661 synchronized (mRecords) {
662 mRingingCallState = ringingCallState;
663 mForegroundCallState = foregroundCallState;
664 mBackgroundCallState = backgroundCallState;
665 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState,
666 backgroundCallState,
667 DisconnectCause.NOT_VALID,
668 PreciseDisconnectCause.NOT_VALID);
669 for (Record r : mRecords) {
670 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
671 try {
672 r.callback.onPreciseCallStateChanged(mPreciseCallState);
673 } catch (RemoteException ex) {
674 mRemoveList.add(r.binder);
675 }
676 }
677 }
678 handleRemoveListLocked();
679 }
680 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
681 DisconnectCause.NOT_VALID,
682 PreciseDisconnectCause.NOT_VALID);
683 }
684
685 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
686 if (!checkNotifyPermission("notifyDisconnectCause()")) {
687 return;
688 }
689 synchronized (mRecords) {
690 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
691 mBackgroundCallState, disconnectCause, preciseDisconnectCause);
692 for (Record r : mRecords) {
693 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
694 try {
695 r.callback.onPreciseCallStateChanged(mPreciseCallState);
696 } catch (RemoteException ex) {
697 mRemoveList.add(r.binder);
698 }
699 }
700 }
701 handleRemoveListLocked();
702 }
703 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
704 mBackgroundCallState, disconnectCause, preciseDisconnectCause);
705 }
706
707 public void notifyPreciseDataConnectionFailed(String reason, String apnType,
708 String apn, String failCause) {
709 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
710 return;
711 }
712 synchronized (mRecords) {
713 mPreciseDataConnectionState = new PreciseDataConnectionState(
714 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
715 apnType, apn, reason, null, failCause);
716 for (Record r : mRecords) {
717 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
718 try {
719 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
720 } catch (RemoteException ex) {
721 mRemoveList.add(r.binder);
722 }
723 }
724 }
725 handleRemoveListLocked();
726 }
727 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
728 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
729 }
730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 @Override
732 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
733 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
734 != PackageManager.PERMISSION_GRANTED) {
735 pw.println("Permission Denial: can't dump telephony.registry from from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700736 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 return;
738 }
739 synchronized (mRecords) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700740 final int recordCount = mRecords.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 pw.println("last known state:");
742 pw.println(" mCallState=" + mCallState);
743 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
744 pw.println(" mServiceState=" + mServiceState);
745 pw.println(" mSignalStrength=" + mSignalStrength);
746 pw.println(" mMessageWaiting=" + mMessageWaiting);
747 pw.println(" mCallForwarding=" + mCallForwarding);
748 pw.println(" mDataActivity=" + mDataActivity);
749 pw.println(" mDataConnectionState=" + mDataConnectionState);
750 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
751 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
752 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
Wink Savillef61101f2010-09-16 16:36:42 -0700753 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
754 pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 pw.println(" mCellLocation=" + mCellLocation);
John Wang963db55d2012-03-30 16:04:06 -0700756 pw.println(" mCellInfo=" + mCellInfo);
Wink Savillee9b06d72009-05-18 21:47:50 -0700757 pw.println("registrations: count=" + recordCount);
Robert Greenwalt02648a42010-05-18 10:52:51 -0700758 for (Record r : mRecords) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
760 }
761 }
762 }
763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 //
765 // the legacy intent broadcasting
766 //
767
768 private void broadcastServiceStateChanged(ServiceState state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700769 long ident = Binder.clearCallingIdentity();
770 try {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700771 mBatteryStats.notePhoneState(state.getState());
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700772 } catch (RemoteException re) {
773 // Can't do much
774 } finally {
775 Binder.restoreCallingIdentity(ident);
776 }
777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
779 Bundle data = new Bundle();
780 state.fillInNotifierBundle(data);
781 intent.putExtras(data);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700782 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 }
784
Wink Savillee9b06d72009-05-18 21:47:50 -0700785 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700786 long ident = Binder.clearCallingIdentity();
787 try {
Wink Savillee9b06d72009-05-18 21:47:50 -0700788 mBatteryStats.notePhoneSignalStrength(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700789 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700790 /* The remote entity disappeared, we can safely ignore the exception. */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700791 } finally {
792 Binder.restoreCallingIdentity(ident);
793 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800796 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Wink Savillee9b06d72009-05-18 21:47:50 -0700797 Bundle data = new Bundle();
798 signalStrength.fillInNotifierBundle(data);
799 intent.putExtras(data);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700800 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802
803 private void broadcastCallStateChanged(int state, String incomingNumber) {
804 long ident = Binder.clearCallingIdentity();
805 try {
806 if (state == TelephonyManager.CALL_STATE_IDLE) {
807 mBatteryStats.notePhoneOff();
808 } else {
809 mBatteryStats.notePhoneOn();
810 }
811 } catch (RemoteException e) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700812 /* The remote entity disappeared, we can safely ignore the exception. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 } finally {
814 Binder.restoreCallingIdentity(ident);
815 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700818 intent.putExtra(PhoneConstants.STATE_KEY,
819 DefaultPhoneNotifier.convertCallState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 if (!TextUtils.isEmpty(incomingNumber)) {
821 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
822 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700823 mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
824 android.Manifest.permission.READ_PHONE_STATE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 }
826
Robert Greenwalt42acef32009-08-12 16:08:25 -0700827 private void broadcastDataConnectionStateChanged(int state,
828 boolean isDataConnectivityPossible,
Wink Savillef61101f2010-09-16 16:36:42 -0700829 String reason, String apn, String apnType, LinkProperties linkProperties,
Robert Greenwalta6d42482011-09-02 15:19:31 -0700830 LinkCapabilities linkCapabilities, boolean roaming) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700831 // Note: not reporting to the battery stats service here, because the
832 // status bar takes care of that after taking into account all of the
833 // required info.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
Wink Savillea639b312012-07-10 12:37:54 -0700835 intent.putExtra(PhoneConstants.STATE_KEY,
836 DefaultPhoneNotifier.convertDataState(state).toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 if (!isDataConnectivityPossible) {
Wink Savillea639b312012-07-10 12:37:54 -0700838 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 }
840 if (reason != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700841 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700843 if (linkProperties != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700844 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700845 String iface = linkProperties.getInterfaceName();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700846 if (iface != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700847 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700848 }
849 }
Wink Savillef61101f2010-09-16 16:36:42 -0700850 if (linkCapabilities != null) {
Wink Savillea639b312012-07-10 12:37:54 -0700851 intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
Wink Savillef61101f2010-09-16 16:36:42 -0700852 }
Wink Savillea639b312012-07-10 12:37:54 -0700853 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
Robert Greenwalta6d42482011-09-02 15:19:31 -0700854
Wink Savillea639b312012-07-10 12:37:54 -0700855 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
856 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700857 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 }
859
Robert Greenwalt02648a42010-05-18 10:52:51 -0700860 private void broadcastDataConnectionFailed(String reason, String apnType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
Wink Savillea639b312012-07-10 12:37:54 -0700862 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
863 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700864 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700866
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200867 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
868 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
869 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
870 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
871 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
872 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
873 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
874 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
875 mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
876 android.Manifest.permission.READ_PRECISE_PHONE_STATE);
877 }
878
879 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
880 String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
881 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
882 intent.putExtra(PhoneConstants.STATE_KEY, state);
883 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
884 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
885 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
886 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
887 if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
888 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
889
890 mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
891 android.Manifest.permission.READ_PRECISE_PHONE_STATE);
892 }
893
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700894 private boolean checkNotifyPermission(String method) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700895 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
896 == PackageManager.PERMISSION_GRANTED) {
897 return true;
898 }
899 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
Wink Savillee9b06d72009-05-18 21:47:50 -0700900 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Wink Savillec9acde92011-09-21 11:05:43 -0700901 if (DBG) Slog.w(TAG, msg);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700902 return false;
903 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700904
905 private void checkListenerPermission(int events) {
906 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
907 mContext.enforceCallingOrSelfPermission(
908 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
909
910 }
911
John Wang963db55d2012-03-30 16:04:06 -0700912 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
913 mContext.enforceCallingOrSelfPermission(
914 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
915
916 }
917
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700918 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
919 mContext.enforceCallingOrSelfPermission(
920 android.Manifest.permission.READ_PHONE_STATE, null);
921 }
Antonio Marín Cerezuelac5ac15a2013-05-27 11:36:36 +0200922
923 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
924 mContext.enforceCallingOrSelfPermission(
925 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
926
927 }
Jaikumar Ganesh45515652009-04-23 15:20:21 -0700928 }
Joe Onorato163d8d92010-10-21 13:21:20 -0400929
930 private void handleRemoveListLocked() {
931 if (mRemoveList.size() > 0) {
932 for (IBinder b: mRemoveList) {
933 remove(b);
934 }
935 mRemoveList.clear();
936 }
937 }
Wink Savillea12a7b32012-09-20 10:09:45 -0700938
939 private boolean validateEventsAndUserLocked(Record r, int events) {
940 int foregroundUser;
941 long callingIdentity = Binder.clearCallingIdentity();
942 boolean valid = false;
943 try {
944 foregroundUser = ActivityManager.getCurrentUser();
945 valid = r.callerUid == foregroundUser && (r.events & events) != 0;
946 if (DBG | DBG_LOC) {
947 Slog.d(TAG, "validateEventsAndUserLocked: valid=" + valid
948 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
949 + " r.events=" + r.events + " events=" + events);
950 }
951 } finally {
952 Binder.restoreCallingIdentity(callingIdentity);
953 }
954 return valid;
955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956}