blob: d5745896a4b84fdbe5e5892ef7da7c0ec7e727ad [file] [log] [blame]
Sailesh Nepal810735e2014-03-18 18:15:46 -07001/*
2 * Copyright (C) 2014 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
Tyler Gunn7cc70b42014-09-12 22:17:27 -070017package com.android.server.telecom;
Sailesh Nepal810735e2014-03-18 18:15:46 -070018
Yorke Leee19d33e2014-09-08 16:07:07 -070019import android.os.RemoteException;
20import android.os.ServiceManager;
Brad Ebingera3eccfe2016-10-05 15:45:22 -070021import android.telecom.Log;
Sailesh Nepal810735e2014-03-18 18:15:46 -070022import android.telephony.TelephonyManager;
23
Yorke Leee19d33e2014-09-08 16:07:07 -070024import com.android.internal.telephony.ITelephonyRegistry;
25
Sailesh Nepal810735e2014-03-18 18:15:46 -070026/**
27 * Send a {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} broadcast when the call state
28 * changes.
29 */
30final class PhoneStateBroadcaster extends CallsManagerListenerBase {
Yorke Leee19d33e2014-09-08 16:07:07 -070031
Ihab Awad8de76912015-02-17 12:25:52 -080032 private final CallsManager mCallsManager;
Yorke Leee19d33e2014-09-08 16:07:07 -070033 private final ITelephonyRegistry mRegistry;
34 private int mCurrentState = TelephonyManager.CALL_STATE_IDLE;
35
Ihab Awad8de76912015-02-17 12:25:52 -080036 public PhoneStateBroadcaster(CallsManager callsManager) {
37 mCallsManager = callsManager;
Yorke Leee19d33e2014-09-08 16:07:07 -070038 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
39 "telephony.registry"));
40 if (mRegistry == null) {
41 Log.w(this, "TelephonyRegistry is null");
Sailesh Nepal810735e2014-03-18 18:15:46 -070042 }
Sailesh Nepal810735e2014-03-18 18:15:46 -070043 }
44
Yorke Leee19d33e2014-09-08 16:07:07 -070045 @Override
46 public void onCallStateChanged(Call call, int oldState, int newState) {
Tyler Gunnf15dc332016-06-07 16:01:41 -070047 if (call.isExternalCall()) {
48 return;
49 }
Santos Cordon880b9832016-01-22 14:18:48 -080050 updateStates(call);
Yorke Leee19d33e2014-09-08 16:07:07 -070051 }
Sailesh Nepal810735e2014-03-18 18:15:46 -070052
Yorke Leee19d33e2014-09-08 16:07:07 -070053 @Override
54 public void onCallAdded(Call call) {
Tyler Gunn1a40c4f2016-04-14 14:29:45 -070055 if (call.isExternalCall()) {
56 return;
57 }
Santos Cordon880b9832016-01-22 14:18:48 -080058 updateStates(call);
59 }
Sailesh Nepal810735e2014-03-18 18:15:46 -070060
Yorke Leee19d33e2014-09-08 16:07:07 -070061 @Override
62 public void onCallRemoved(Call call) {
Tyler Gunn1a40c4f2016-04-14 14:29:45 -070063 if (call.isExternalCall()) {
64 return;
65 }
66 updateStates(call);
67 }
68
69 /**
70 * Handles changes to a call's external property. If the call becomes external, we end up
71 * updating the call state to idle. If the call becomes non-external, then the call state can
72 * update to off hook.
73 *
74 * @param call The call.
75 * @param isExternalCall {@code True} if the call is external, {@code false} otherwise.
76 */
77 @Override
78 public void onExternalCallChanged(Call call, boolean isExternalCall) {
Santos Cordon880b9832016-01-22 14:18:48 -080079 updateStates(call);
80 }
81
82 private void updateStates(Call call) {
Yorke Lee677e8112014-09-27 14:16:47 -070083 // Recalculate the current phone state based on the consolidated state of the remaining
84 // calls in the call list.
Tyler Gunn1a40c4f2016-04-14 14:29:45 -070085 // Note: CallsManager#hasRingingCall() and CallsManager#getFirstCallWithState(..) do not
86 // consider external calls, so an external call is going to cause the state to be idle.
Yorke Lee677e8112014-09-27 14:16:47 -070087 int callState = TelephonyManager.CALL_STATE_IDLE;
Ihab Awad8de76912015-02-17 12:25:52 -080088 if (mCallsManager.hasRingingCall()) {
Yorke Lee677e8112014-09-27 14:16:47 -070089 callState = TelephonyManager.CALL_STATE_RINGING;
Tyler Gunn1e37be52016-07-11 08:54:23 -070090 } else if (mCallsManager.getFirstCallWithState(CallState.DIALING, CallState.PULLING,
91 CallState.ACTIVE, CallState.ON_HOLD) != null) {
Yorke Lee677e8112014-09-27 14:16:47 -070092 callState = TelephonyManager.CALL_STATE_OFFHOOK;
Yorke Leee19d33e2014-09-08 16:07:07 -070093 }
Yorke Lee677e8112014-09-27 14:16:47 -070094 sendPhoneStateChangedBroadcast(call, callState);
Yorke Leee19d33e2014-09-08 16:07:07 -070095 }
96
Yorke Leef86db2e2014-09-12 17:56:48 -070097 int getCallState() {
98 return mCurrentState;
99 }
100
Yorke Leee19d33e2014-09-08 16:07:07 -0700101 private void sendPhoneStateChangedBroadcast(Call call, int phoneState) {
102 if (phoneState == mCurrentState) {
103 return;
104 }
105
106 mCurrentState = phoneState;
107
108 String callHandle = null;
Tyler Gunn054e6662018-05-07 07:50:29 -0700109 // Only report phone numbers in phone state broadcast for regular mobile calls; do not
110 // include numbers from 3rd party apps.
111 if (!call.isSelfManaged() && call.getHandle() != null) {
Yorke Leee19d33e2014-09-08 16:07:07 -0700112 callHandle = call.getHandle().getSchemeSpecificPart();
Ihab Awad12de5492014-06-19 10:41:41 -0700113 }
Sailesh Nepal810735e2014-03-18 18:15:46 -0700114
Yorke Leee19d33e2014-09-08 16:07:07 -0700115 try {
116 if (mRegistry != null) {
117 mRegistry.notifyCallState(phoneState, callHandle);
118 Log.i(this, "Broadcasted state change: %s", mCurrentState);
Sailesh Nepal53fb8c12014-04-01 23:38:39 -0700119 }
Yorke Leee19d33e2014-09-08 16:07:07 -0700120 } catch (RemoteException e) {
121 Log.w(this, "RemoteException when notifying TelephonyRegistry of call state change.");
Sailesh Nepal53fb8c12014-04-01 23:38:39 -0700122 }
Sailesh Nepal810735e2014-03-18 18:15:46 -0700123 }
124}