/services/java/com/android/server/TelephonyRegistry.java

https://github.com/aizuzi/platform_frameworks_base · Java · 956 lines · 824 code · 89 blank · 43 comment · 164 complexity · 73f264e8125d482545289b6534106329 MD5 · raw file

  1. /*
  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. package com.android.server;
  17. import android.app.ActivityManager;
  18. import android.content.BroadcastReceiver;
  19. import android.content.Context;
  20. import android.content.Intent;
  21. import android.content.IntentFilter;
  22. import android.content.pm.PackageManager;
  23. import android.net.LinkCapabilities;
  24. import android.net.LinkProperties;
  25. import android.os.Binder;
  26. import android.os.Bundle;
  27. import android.os.Handler;
  28. import android.os.IBinder;
  29. import android.os.Message;
  30. import android.os.RemoteException;
  31. import android.os.UserHandle;
  32. import android.telephony.CellLocation;
  33. import android.telephony.PhoneStateListener;
  34. import android.telephony.ServiceState;
  35. import android.telephony.SignalStrength;
  36. import android.telephony.CellInfo;
  37. import android.telephony.TelephonyManager;
  38. import android.telephony.DisconnectCause;
  39. import android.telephony.PreciseCallState;
  40. import android.telephony.PreciseDataConnectionState;
  41. import android.telephony.PreciseDisconnectCause;
  42. import android.text.TextUtils;
  43. import android.util.Slog;
  44. import java.util.ArrayList;
  45. import java.util.List;
  46. import java.io.FileDescriptor;
  47. import java.io.PrintWriter;
  48. import com.android.internal.app.IBatteryStats;
  49. import com.android.internal.telephony.ITelephonyRegistry;
  50. import com.android.internal.telephony.IPhoneStateListener;
  51. import com.android.internal.telephony.DefaultPhoneNotifier;
  52. import com.android.internal.telephony.PhoneConstants;
  53. import com.android.internal.telephony.ServiceStateTracker;
  54. import com.android.internal.telephony.TelephonyIntents;
  55. import com.android.server.am.BatteryStatsService;
  56. /**
  57. * Since phone process can be restarted, this class provides a centralized place
  58. * that applications can register and be called back from.
  59. */
  60. class TelephonyRegistry extends ITelephonyRegistry.Stub {
  61. private static final String TAG = "TelephonyRegistry";
  62. private static final boolean DBG = false;
  63. private static final boolean DBG_LOC = false;
  64. private static class Record {
  65. String pkgForDebug;
  66. IBinder binder;
  67. IPhoneStateListener callback;
  68. int callerUid;
  69. int events;
  70. @Override
  71. public String toString() {
  72. return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid +
  73. " events=" + Integer.toHexString(events) + "}";
  74. }
  75. }
  76. private final Context mContext;
  77. // access should be inside synchronized (mRecords) for these two fields
  78. private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
  79. private final ArrayList<Record> mRecords = new ArrayList<Record>();
  80. private final IBatteryStats mBatteryStats;
  81. private int mCallState = TelephonyManager.CALL_STATE_IDLE;
  82. private String mCallIncomingNumber = "";
  83. private ServiceState mServiceState = new ServiceState();
  84. private SignalStrength mSignalStrength = new SignalStrength();
  85. private boolean mMessageWaiting = false;
  86. private boolean mCallForwarding = false;
  87. private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
  88. private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
  89. private boolean mDataConnectionPossible = false;
  90. private String mDataConnectionReason = "";
  91. private String mDataConnectionApn = "";
  92. private ArrayList<String> mConnectedApns;
  93. private LinkProperties mDataConnectionLinkProperties;
  94. private LinkCapabilities mDataConnectionLinkCapabilities;
  95. private Bundle mCellLocation = new Bundle();
  96. private int mDataConnectionNetworkType;
  97. private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
  98. private List<CellInfo> mCellInfo = null;
  99. private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
  100. private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
  101. private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
  102. private PreciseCallState mPreciseCallState = new PreciseCallState();
  103. private PreciseDataConnectionState mPreciseDataConnectionState =
  104. new PreciseDataConnectionState();
  105. static final int PHONE_STATE_PERMISSION_MASK =
  106. PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
  107. PhoneStateListener.LISTEN_CALL_STATE |
  108. PhoneStateListener.LISTEN_DATA_ACTIVITY |
  109. PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
  110. PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
  111. static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
  112. PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
  113. PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
  114. private static final int MSG_USER_SWITCHED = 1;
  115. private final Handler mHandler = new Handler() {
  116. @Override
  117. public void handleMessage(Message msg) {
  118. switch (msg.what) {
  119. case MSG_USER_SWITCHED: {
  120. if (DBG) Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1);
  121. TelephonyRegistry.this.notifyCellLocation(mCellLocation);
  122. break;
  123. }
  124. }
  125. }
  126. };
  127. private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
  128. @Override
  129. public void onReceive(Context context, Intent intent) {
  130. String action = intent.getAction();
  131. if (Intent.ACTION_USER_SWITCHED.equals(action)) {
  132. mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
  133. intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
  134. }
  135. }
  136. };
  137. // we keep a copy of all of the state so we can send it out when folks
  138. // register for it
  139. //
  140. // In these calls we call with the lock held. This is safe becasuse remote
  141. // calls go through a oneway interface and local calls going through a
  142. // handler before they get to app code.
  143. TelephonyRegistry(Context context) {
  144. CellLocation location = CellLocation.getEmpty();
  145. // Note that location can be null for non-phone builds like
  146. // like the generic one.
  147. if (location != null) {
  148. location.fillInNotifierBundle(mCellLocation);
  149. }
  150. mContext = context;
  151. mBatteryStats = BatteryStatsService.getService();
  152. mConnectedApns = new ArrayList<String>();
  153. }
  154. public void systemRunning() {
  155. // Watch for interesting updates
  156. final IntentFilter filter = new IntentFilter();
  157. filter.addAction(Intent.ACTION_USER_SWITCHED);
  158. filter.addAction(Intent.ACTION_USER_REMOVED);
  159. mContext.registerReceiver(mBroadcastReceiver, filter);
  160. }
  161. @Override
  162. public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
  163. boolean notifyNow) {
  164. int callerUid = UserHandle.getCallingUserId();
  165. int myUid = UserHandle.myUserId();
  166. if (DBG) {
  167. Slog.d(TAG, "listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
  168. + " myUid=" + myUid
  169. + " callerUid=" + callerUid);
  170. }
  171. if (events != 0) {
  172. /* Checks permission and throws Security exception */
  173. checkListenerPermission(events);
  174. synchronized (mRecords) {
  175. // register
  176. Record r = null;
  177. find_and_add: {
  178. IBinder b = callback.asBinder();
  179. final int N = mRecords.size();
  180. for (int i = 0; i < N; i++) {
  181. r = mRecords.get(i);
  182. if (b == r.binder) {
  183. break find_and_add;
  184. }
  185. }
  186. r = new Record();
  187. r.binder = b;
  188. r.callback = callback;
  189. r.pkgForDebug = pkgForDebug;
  190. r.callerUid = callerUid;
  191. mRecords.add(r);
  192. if (DBG) Slog.i(TAG, "listen: add new record=" + r);
  193. }
  194. int send = events & (events ^ r.events);
  195. r.events = events;
  196. if (notifyNow) {
  197. if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
  198. try {
  199. r.callback.onServiceStateChanged(new ServiceState(mServiceState));
  200. } catch (RemoteException ex) {
  201. remove(r.binder);
  202. }
  203. }
  204. if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
  205. try {
  206. int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
  207. r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
  208. : gsmSignalStrength));
  209. } catch (RemoteException ex) {
  210. remove(r.binder);
  211. }
  212. }
  213. if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
  214. try {
  215. r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
  216. } catch (RemoteException ex) {
  217. remove(r.binder);
  218. }
  219. }
  220. if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
  221. try {
  222. r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
  223. } catch (RemoteException ex) {
  224. remove(r.binder);
  225. }
  226. }
  227. if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
  228. try {
  229. if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation=" + mCellLocation);
  230. r.callback.onCellLocationChanged(new Bundle(mCellLocation));
  231. } catch (RemoteException ex) {
  232. remove(r.binder);
  233. }
  234. }
  235. if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
  236. try {
  237. r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
  238. } catch (RemoteException ex) {
  239. remove(r.binder);
  240. }
  241. }
  242. if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
  243. try {
  244. r.callback.onDataConnectionStateChanged(mDataConnectionState,
  245. mDataConnectionNetworkType);
  246. } catch (RemoteException ex) {
  247. remove(r.binder);
  248. }
  249. }
  250. if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
  251. try {
  252. r.callback.onDataActivity(mDataActivity);
  253. } catch (RemoteException ex) {
  254. remove(r.binder);
  255. }
  256. }
  257. if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
  258. try {
  259. r.callback.onSignalStrengthsChanged(mSignalStrength);
  260. } catch (RemoteException ex) {
  261. remove(r.binder);
  262. }
  263. }
  264. if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
  265. try {
  266. r.callback.onOtaspChanged(mOtaspMode);
  267. } catch (RemoteException ex) {
  268. remove(r.binder);
  269. }
  270. }
  271. if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
  272. try {
  273. if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo=" + mCellInfo);
  274. r.callback.onCellInfoChanged(mCellInfo);
  275. } catch (RemoteException ex) {
  276. remove(r.binder);
  277. }
  278. }
  279. if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
  280. try {
  281. r.callback.onPreciseCallStateChanged(mPreciseCallState);
  282. } catch (RemoteException ex) {
  283. remove(r.binder);
  284. }
  285. }
  286. if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
  287. try {
  288. r.callback.onPreciseDataConnectionStateChanged(
  289. mPreciseDataConnectionState);
  290. } catch (RemoteException ex) {
  291. remove(r.binder);
  292. }
  293. }
  294. }
  295. }
  296. } else {
  297. remove(callback.asBinder());
  298. }
  299. }
  300. private void remove(IBinder binder) {
  301. synchronized (mRecords) {
  302. final int recordCount = mRecords.size();
  303. for (int i = 0; i < recordCount; i++) {
  304. if (mRecords.get(i).binder == binder) {
  305. mRecords.remove(i);
  306. return;
  307. }
  308. }
  309. }
  310. }
  311. public void notifyCallState(int state, String incomingNumber) {
  312. if (!checkNotifyPermission("notifyCallState()")) {
  313. return;
  314. }
  315. synchronized (mRecords) {
  316. mCallState = state;
  317. mCallIncomingNumber = incomingNumber;
  318. for (Record r : mRecords) {
  319. if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
  320. try {
  321. r.callback.onCallStateChanged(state, incomingNumber);
  322. } catch (RemoteException ex) {
  323. mRemoveList.add(r.binder);
  324. }
  325. }
  326. }
  327. handleRemoveListLocked();
  328. }
  329. broadcastCallStateChanged(state, incomingNumber);
  330. }
  331. public void notifyServiceState(ServiceState state) {
  332. if (!checkNotifyPermission("notifyServiceState()")){
  333. return;
  334. }
  335. synchronized (mRecords) {
  336. mServiceState = state;
  337. for (Record r : mRecords) {
  338. if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
  339. try {
  340. r.callback.onServiceStateChanged(new ServiceState(state));
  341. } catch (RemoteException ex) {
  342. mRemoveList.add(r.binder);
  343. }
  344. }
  345. }
  346. handleRemoveListLocked();
  347. }
  348. broadcastServiceStateChanged(state);
  349. }
  350. public void notifySignalStrength(SignalStrength signalStrength) {
  351. if (!checkNotifyPermission("notifySignalStrength()")) {
  352. return;
  353. }
  354. synchronized (mRecords) {
  355. mSignalStrength = signalStrength;
  356. for (Record r : mRecords) {
  357. if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
  358. try {
  359. r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
  360. } catch (RemoteException ex) {
  361. mRemoveList.add(r.binder);
  362. }
  363. }
  364. if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
  365. try {
  366. int gsmSignalStrength = signalStrength.getGsmSignalStrength();
  367. r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
  368. : gsmSignalStrength));
  369. } catch (RemoteException ex) {
  370. mRemoveList.add(r.binder);
  371. }
  372. }
  373. }
  374. handleRemoveListLocked();
  375. }
  376. broadcastSignalStrengthChanged(signalStrength);
  377. }
  378. public void notifyCellInfo(List<CellInfo> cellInfo) {
  379. if (!checkNotifyPermission("notifyCellInfo()")) {
  380. return;
  381. }
  382. synchronized (mRecords) {
  383. mCellInfo = cellInfo;
  384. for (Record r : mRecords) {
  385. if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
  386. try {
  387. if (DBG_LOC) {
  388. Slog.d(TAG, "notifyCellInfo: mCellInfo=" + mCellInfo + " r=" + r);
  389. }
  390. r.callback.onCellInfoChanged(cellInfo);
  391. } catch (RemoteException ex) {
  392. mRemoveList.add(r.binder);
  393. }
  394. }
  395. }
  396. handleRemoveListLocked();
  397. }
  398. }
  399. public void notifyMessageWaitingChanged(boolean mwi) {
  400. if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
  401. return;
  402. }
  403. synchronized (mRecords) {
  404. mMessageWaiting = mwi;
  405. for (Record r : mRecords) {
  406. if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
  407. try {
  408. r.callback.onMessageWaitingIndicatorChanged(mwi);
  409. } catch (RemoteException ex) {
  410. mRemoveList.add(r.binder);
  411. }
  412. }
  413. }
  414. handleRemoveListLocked();
  415. }
  416. }
  417. public void notifyCallForwardingChanged(boolean cfi) {
  418. if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
  419. return;
  420. }
  421. synchronized (mRecords) {
  422. mCallForwarding = cfi;
  423. for (Record r : mRecords) {
  424. if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
  425. try {
  426. r.callback.onCallForwardingIndicatorChanged(cfi);
  427. } catch (RemoteException ex) {
  428. mRemoveList.add(r.binder);
  429. }
  430. }
  431. }
  432. handleRemoveListLocked();
  433. }
  434. }
  435. public void notifyDataActivity(int state) {
  436. if (!checkNotifyPermission("notifyDataActivity()" )) {
  437. return;
  438. }
  439. synchronized (mRecords) {
  440. mDataActivity = state;
  441. for (Record r : mRecords) {
  442. if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
  443. try {
  444. r.callback.onDataActivity(state);
  445. } catch (RemoteException ex) {
  446. mRemoveList.add(r.binder);
  447. }
  448. }
  449. }
  450. handleRemoveListLocked();
  451. }
  452. }
  453. public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
  454. String reason, String apn, String apnType, LinkProperties linkProperties,
  455. LinkCapabilities linkCapabilities, int networkType, boolean roaming) {
  456. if (!checkNotifyPermission("notifyDataConnection()" )) {
  457. return;
  458. }
  459. if (DBG) {
  460. Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
  461. + isDataConnectivityPossible + " reason='" + reason
  462. + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
  463. + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords);
  464. }
  465. synchronized (mRecords) {
  466. boolean modified = false;
  467. if (state == TelephonyManager.DATA_CONNECTED) {
  468. if (!mConnectedApns.contains(apnType)) {
  469. mConnectedApns.add(apnType);
  470. if (mDataConnectionState != state) {
  471. mDataConnectionState = state;
  472. modified = true;
  473. }
  474. }
  475. } else {
  476. if (mConnectedApns.remove(apnType)) {
  477. if (mConnectedApns.isEmpty()) {
  478. mDataConnectionState = state;
  479. modified = true;
  480. } else {
  481. // leave mDataConnectionState as is and
  482. // send out the new status for the APN in question.
  483. }
  484. }
  485. }
  486. mDataConnectionPossible = isDataConnectivityPossible;
  487. mDataConnectionReason = reason;
  488. mDataConnectionLinkProperties = linkProperties;
  489. mDataConnectionLinkCapabilities = linkCapabilities;
  490. if (mDataConnectionNetworkType != networkType) {
  491. mDataConnectionNetworkType = networkType;
  492. // need to tell registered listeners about the new network type
  493. modified = true;
  494. }
  495. if (modified) {
  496. if (DBG) {
  497. Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
  498. + ", " + mDataConnectionNetworkType + ")");
  499. }
  500. for (Record r : mRecords) {
  501. if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
  502. try {
  503. r.callback.onDataConnectionStateChanged(mDataConnectionState,
  504. mDataConnectionNetworkType);
  505. } catch (RemoteException ex) {
  506. mRemoveList.add(r.binder);
  507. }
  508. }
  509. }
  510. handleRemoveListLocked();
  511. }
  512. mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
  513. apnType, apn, reason, linkProperties, "");
  514. for (Record r : mRecords) {
  515. if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
  516. try {
  517. r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
  518. } catch (RemoteException ex) {
  519. mRemoveList.add(r.binder);
  520. }
  521. }
  522. }
  523. handleRemoveListLocked();
  524. }
  525. broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
  526. apnType, linkProperties, linkCapabilities, roaming);
  527. broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
  528. linkProperties, "");
  529. }
  530. public void notifyDataConnectionFailed(String reason, String apnType) {
  531. if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
  532. return;
  533. }
  534. synchronized (mRecords) {
  535. mPreciseDataConnectionState = new PreciseDataConnectionState(
  536. TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
  537. apnType, "", reason, null, "");
  538. for (Record r : mRecords) {
  539. if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
  540. try {
  541. r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
  542. } catch (RemoteException ex) {
  543. mRemoveList.add(r.binder);
  544. }
  545. }
  546. }
  547. handleRemoveListLocked();
  548. }
  549. broadcastDataConnectionFailed(reason, apnType);
  550. broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
  551. TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
  552. }
  553. public void notifyCellLocation(Bundle cellLocation) {
  554. if (!checkNotifyPermission("notifyCellLocation()")) {
  555. return;
  556. }
  557. synchronized (mRecords) {
  558. mCellLocation = cellLocation;
  559. for (Record r : mRecords) {
  560. if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
  561. try {
  562. if (DBG_LOC) {
  563. Slog.d(TAG, "notifyCellLocation: mCellLocation=" + mCellLocation
  564. + " r=" + r);
  565. }
  566. r.callback.onCellLocationChanged(new Bundle(cellLocation));
  567. } catch (RemoteException ex) {
  568. mRemoveList.add(r.binder);
  569. }
  570. }
  571. }
  572. handleRemoveListLocked();
  573. }
  574. }
  575. public void notifyOtaspChanged(int otaspMode) {
  576. if (!checkNotifyPermission("notifyOtaspChanged()" )) {
  577. return;
  578. }
  579. synchronized (mRecords) {
  580. mOtaspMode = otaspMode;
  581. for (Record r : mRecords) {
  582. if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
  583. try {
  584. r.callback.onOtaspChanged(otaspMode);
  585. } catch (RemoteException ex) {
  586. mRemoveList.add(r.binder);
  587. }
  588. }
  589. }
  590. handleRemoveListLocked();
  591. }
  592. }
  593. public void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
  594. int backgroundCallState) {
  595. if (!checkNotifyPermission("notifyPreciseCallState()")) {
  596. return;
  597. }
  598. synchronized (mRecords) {
  599. mRingingCallState = ringingCallState;
  600. mForegroundCallState = foregroundCallState;
  601. mBackgroundCallState = backgroundCallState;
  602. mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState,
  603. backgroundCallState,
  604. DisconnectCause.NOT_VALID,
  605. PreciseDisconnectCause.NOT_VALID);
  606. for (Record r : mRecords) {
  607. if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
  608. try {
  609. r.callback.onPreciseCallStateChanged(mPreciseCallState);
  610. } catch (RemoteException ex) {
  611. mRemoveList.add(r.binder);
  612. }
  613. }
  614. }
  615. handleRemoveListLocked();
  616. }
  617. broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
  618. DisconnectCause.NOT_VALID,
  619. PreciseDisconnectCause.NOT_VALID);
  620. }
  621. public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
  622. if (!checkNotifyPermission("notifyDisconnectCause()")) {
  623. return;
  624. }
  625. synchronized (mRecords) {
  626. mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
  627. mBackgroundCallState, disconnectCause, preciseDisconnectCause);
  628. for (Record r : mRecords) {
  629. if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
  630. try {
  631. r.callback.onPreciseCallStateChanged(mPreciseCallState);
  632. } catch (RemoteException ex) {
  633. mRemoveList.add(r.binder);
  634. }
  635. }
  636. }
  637. handleRemoveListLocked();
  638. }
  639. broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
  640. mBackgroundCallState, disconnectCause, preciseDisconnectCause);
  641. }
  642. public void notifyPreciseDataConnectionFailed(String reason, String apnType,
  643. String apn, String failCause) {
  644. if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
  645. return;
  646. }
  647. synchronized (mRecords) {
  648. mPreciseDataConnectionState = new PreciseDataConnectionState(
  649. TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
  650. apnType, apn, reason, null, failCause);
  651. for (Record r : mRecords) {
  652. if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
  653. try {
  654. r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
  655. } catch (RemoteException ex) {
  656. mRemoveList.add(r.binder);
  657. }
  658. }
  659. }
  660. handleRemoveListLocked();
  661. }
  662. broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
  663. TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
  664. }
  665. @Override
  666. public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
  667. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
  668. != PackageManager.PERMISSION_GRANTED) {
  669. pw.println("Permission Denial: can't dump telephony.registry from from pid="
  670. + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
  671. return;
  672. }
  673. synchronized (mRecords) {
  674. final int recordCount = mRecords.size();
  675. pw.println("last known state:");
  676. pw.println(" mCallState=" + mCallState);
  677. pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
  678. pw.println(" mServiceState=" + mServiceState);
  679. pw.println(" mSignalStrength=" + mSignalStrength);
  680. pw.println(" mMessageWaiting=" + mMessageWaiting);
  681. pw.println(" mCallForwarding=" + mCallForwarding);
  682. pw.println(" mDataActivity=" + mDataActivity);
  683. pw.println(" mDataConnectionState=" + mDataConnectionState);
  684. pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
  685. pw.println(" mDataConnectionReason=" + mDataConnectionReason);
  686. pw.println(" mDataConnectionApn=" + mDataConnectionApn);
  687. pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
  688. pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
  689. pw.println(" mCellLocation=" + mCellLocation);
  690. pw.println(" mCellInfo=" + mCellInfo);
  691. pw.println("registrations: count=" + recordCount);
  692. for (Record r : mRecords) {
  693. pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
  694. }
  695. }
  696. }
  697. //
  698. // the legacy intent broadcasting
  699. //
  700. private void broadcastServiceStateChanged(ServiceState state) {
  701. long ident = Binder.clearCallingIdentity();
  702. try {
  703. mBatteryStats.notePhoneState(state.getState());
  704. } catch (RemoteException re) {
  705. // Can't do much
  706. } finally {
  707. Binder.restoreCallingIdentity(ident);
  708. }
  709. Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
  710. Bundle data = new Bundle();
  711. state.fillInNotifierBundle(data);
  712. intent.putExtras(data);
  713. mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
  714. }
  715. private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
  716. long ident = Binder.clearCallingIdentity();
  717. try {
  718. mBatteryStats.notePhoneSignalStrength(signalStrength);
  719. } catch (RemoteException e) {
  720. /* The remote entity disappeared, we can safely ignore the exception. */
  721. } finally {
  722. Binder.restoreCallingIdentity(ident);
  723. }
  724. Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
  725. intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
  726. Bundle data = new Bundle();
  727. signalStrength.fillInNotifierBundle(data);
  728. intent.putExtras(data);
  729. mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
  730. }
  731. private void broadcastCallStateChanged(int state, String incomingNumber) {
  732. long ident = Binder.clearCallingIdentity();
  733. try {
  734. if (state == TelephonyManager.CALL_STATE_IDLE) {
  735. mBatteryStats.notePhoneOff();
  736. } else {
  737. mBatteryStats.notePhoneOn();
  738. }
  739. } catch (RemoteException e) {
  740. /* The remote entity disappeared, we can safely ignore the exception. */
  741. } finally {
  742. Binder.restoreCallingIdentity(ident);
  743. }
  744. Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
  745. intent.putExtra(PhoneConstants.STATE_KEY,
  746. DefaultPhoneNotifier.convertCallState(state).toString());
  747. if (!TextUtils.isEmpty(incomingNumber)) {
  748. intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
  749. }
  750. mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
  751. android.Manifest.permission.READ_PHONE_STATE);
  752. }
  753. private void broadcastDataConnectionStateChanged(int state,
  754. boolean isDataConnectivityPossible,
  755. String reason, String apn, String apnType, LinkProperties linkProperties,
  756. LinkCapabilities linkCapabilities, boolean roaming) {
  757. // Note: not reporting to the battery stats service here, because the
  758. // status bar takes care of that after taking into account all of the
  759. // required info.
  760. Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
  761. intent.putExtra(PhoneConstants.STATE_KEY,
  762. DefaultPhoneNotifier.convertDataState(state).toString());
  763. if (!isDataConnectivityPossible) {
  764. intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
  765. }
  766. if (reason != null) {
  767. intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
  768. }
  769. if (linkProperties != null) {
  770. intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
  771. String iface = linkProperties.getInterfaceName();
  772. if (iface != null) {
  773. intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
  774. }
  775. }
  776. if (linkCapabilities != null) {
  777. intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
  778. }
  779. if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
  780. intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
  781. intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
  782. mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
  783. }
  784. private void broadcastDataConnectionFailed(String reason, String apnType) {
  785. Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
  786. intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
  787. intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
  788. mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
  789. }
  790. private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
  791. int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
  792. Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
  793. intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
  794. intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
  795. intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
  796. intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
  797. intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
  798. mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
  799. android.Manifest.permission.READ_PRECISE_PHONE_STATE);
  800. }
  801. private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
  802. String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
  803. Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
  804. intent.putExtra(PhoneConstants.STATE_KEY, state);
  805. intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
  806. if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
  807. if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
  808. if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
  809. if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
  810. if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
  811. mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
  812. android.Manifest.permission.READ_PRECISE_PHONE_STATE);
  813. }
  814. private boolean checkNotifyPermission(String method) {
  815. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
  816. == PackageManager.PERMISSION_GRANTED) {
  817. return true;
  818. }
  819. String msg = "Modify Phone State Permission Denial: " + method + " from pid="
  820. + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
  821. if (DBG) Slog.w(TAG, msg);
  822. return false;
  823. }
  824. private void checkListenerPermission(int events) {
  825. if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
  826. mContext.enforceCallingOrSelfPermission(
  827. android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
  828. }
  829. if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
  830. mContext.enforceCallingOrSelfPermission(
  831. android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
  832. }
  833. if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
  834. mContext.enforceCallingOrSelfPermission(
  835. android.Manifest.permission.READ_PHONE_STATE, null);
  836. }
  837. if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
  838. mContext.enforceCallingOrSelfPermission(
  839. android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
  840. }
  841. }
  842. private void handleRemoveListLocked() {
  843. if (mRemoveList.size() > 0) {
  844. for (IBinder b: mRemoveList) {
  845. remove(b);
  846. }
  847. mRemoveList.clear();
  848. }
  849. }
  850. private boolean validateEventsAndUserLocked(Record r, int events) {
  851. int foregroundUser;
  852. long callingIdentity = Binder.clearCallingIdentity();
  853. boolean valid = false;
  854. try {
  855. foregroundUser = ActivityManager.getCurrentUser();
  856. valid = r.callerUid == foregroundUser && (r.events & events) != 0;
  857. if (DBG | DBG_LOC) {
  858. Slog.d(TAG, "validateEventsAndUserLocked: valid=" + valid
  859. + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
  860. + " r.events=" + r.events + " events=" + events);
  861. }
  862. } finally {
  863. Binder.restoreCallingIdentity(callingIdentity);
  864. }
  865. return valid;
  866. }
  867. }