PstnIncomingCallNotifier.java revision 3199aa7f8bcb48569eb8289abc055ba0f8496ba8
12afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon/* 22afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Copyright (C) 2014 The Android Open Source Project 32afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * 42afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 52afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * you may not use this file except in compliance with the License. 62afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * You may obtain a copy of the License at 72afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * 82afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * http://www.apache.org/licenses/LICENSE-2.0 92afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * 102afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Unless required by applicable law or agreed to in writing, software 112afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 122afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * See the License for the specific language governing permissions and 142afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * limitations under the License. 152afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 162afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 172afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonpackage com.android.services.telephony; 182afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 19aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport android.content.BroadcastReceiver; 202afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.content.Context; 212afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.content.Intent; 22aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport android.content.IntentFilter; 233199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepalimport android.net.Uri; 242afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.os.AsyncResult; 252afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.os.Handler; 262afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.os.Message; 2773a742ec224ee1f39ba50955e6ffa6130e00297bAmith Yamasaniimport android.os.UserHandle; 282afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport android.telecomm.TelecommConstants; 292afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 302afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport com.android.internal.telephony.Call; 312afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport com.android.internal.telephony.Connection; 322afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordonimport com.android.internal.telephony.Phone; 33aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport com.android.internal.telephony.PhoneConstants; 34aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport com.android.internal.telephony.PhoneProxy; 35aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport com.android.internal.telephony.TelephonyIntents; 36aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordonimport com.google.common.base.Preconditions; 372afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 382afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon/** 392afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Listens to incoming-call events from the associated phone object and notifies Telecomm upon each 402afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * occurence. One instance of these exists for each of the telephony-based call services. 412afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 42aa7340388473c1676495a60e30dc6a48d318a489Ihab Awadfinal class PstnIncomingCallNotifier { 432afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon /** New ringing connection event code. */ 442afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon private static final int EVENT_NEW_RINGING_CONNECTION = 100; 452afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 46aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon /** The phone proxy object to listen to. */ 47aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon private final PhoneProxy mPhoneProxy; 48aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 49aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon /** 50aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * The base phone implementation behind phone proxy. The underlying phone implementation can 51aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * change underneath when the radio technology changes. We listen for these events and update 52aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * the base phone in this variable. We save it so that when the change happens, we can 53aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * unregister from the events we were listening to. 54aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon */ 55aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon private Phone mPhoneBase; 562afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 572afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon /** 58aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * Used to listen to events from {@link #mPhoneBase}. 592afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 602afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon private final Handler mHandler = new Handler() { 612afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon @Override 622afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon public void handleMessage(Message msg) { 632afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon switch(msg.what) { 642afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon case EVENT_NEW_RINGING_CONNECTION: 652afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon handleNewRingingConnection((AsyncResult) msg.obj); 662afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon break; 672afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon default: 682afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon break; 692afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 702afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 712afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon }; 722afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 732afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon /** 74aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * Receiver to listen for radio technology change events. 75aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon */ 76aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon private final BroadcastReceiver mRATReceiver = new BroadcastReceiver() { 77aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon @Override 78aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon public void onReceive(Context context, Intent intent) { 79aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon String action = intent.getAction(); 80aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon if (TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED.equals(action)) { 81aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY); 82aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Log.d(this, "Radio technology switched. Now %s is active.", newPhone); 83aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 84aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon registerForNotifications(); 85aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 86aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 87aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon }; 88aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 89aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon /** 902afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Persists the specified parameters and starts listening to phone events. 912afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * 92aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * @param phoneProxy The phone object for listening to incoming calls. 932afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 94aa7340388473c1676495a60e30dc6a48d318a489Ihab Awad PstnIncomingCallNotifier(PhoneProxy phoneProxy) { 95aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Preconditions.checkNotNull(phoneProxy); 962afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 97aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mPhoneProxy = phoneProxy; 98aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 99aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon registerForNotifications(); 100aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 101aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon IntentFilter intentFilter = 102aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon new IntentFilter(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); 103aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mPhoneProxy.getContext().registerReceiver(mRATReceiver, intentFilter); 104aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 1052afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 106aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon /** 107aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * Register for notifications from the base phone. 108aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * TODO(santoscordon): We should only need to interact with the phoneproxy directly. However, 109aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * since the phoneproxy only interacts directly with CallManager we either listen to callmanager 110aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * or we have to poke into the proxy like this. Neither is desirable. It would be better if 111aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * this class and callManager could register generically with the phone proxy instead and get 112aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * radio techonology changes directly. Or better yet, just register for the notifications 113aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * directly with phone proxy and never worry about the technology changes. This requires a 114aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon * change in opt/telephony code. 115aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon */ 116aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon private void registerForNotifications() { 117aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Phone newPhone = mPhoneProxy.getActivePhone(); 118aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon if (newPhone != mPhoneBase) { 119aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon if (mPhoneBase != null) { 120aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Log.i(this, "Unregistering: %s", mPhoneBase); 121aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mPhoneBase.unregisterForNewRingingConnection(mHandler); 122aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 123aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon 124aa7340388473c1676495a60e30dc6a48d318a489Ihab Awad if (newPhone != null) { 125aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Log.i(this, "Registering: %s", newPhone); 126aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mPhoneBase = newPhone; 127aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mPhoneBase.registerForNewRingingConnection( 128aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon mHandler, EVENT_NEW_RINGING_CONNECTION, null); 129aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 130aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon } 1312afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 1322afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 1332afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon /** 1342afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Verifies the incoming call and triggers sending the incoming-call intent to Telecomm. 1352afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * 1362afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * @param asyncResult The result object from the new ringing event. 1372afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 1382afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon private void handleNewRingingConnection(AsyncResult asyncResult) { 1394822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal Log.d(this, "handleNewRingingConnection"); 1402afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon Connection connection = (Connection) asyncResult.result; 1412afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon if (connection != null) { 1422afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon Call call = connection.getCall(); 1432afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 1442afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon // Final verification of the ringing state before sending the intent to Telecomm. 1452afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon if (call != null && call.getState().isRinging()) { 1463199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal sendIncomingCallIntent(connection); 1472afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 1482afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 1492afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 1502afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 1512afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon /** 1522afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon * Sends the incoming call intent to telecomm. 1532afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon */ 1543199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal private void sendIncomingCallIntent(Connection connection) { 155aac7719aa36cbef5b52ec45aef75005084d60c4aSantos Cordon Context context = mPhoneProxy.getContext(); 1562afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 1572afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon Intent intent = new Intent(TelecommConstants.ACTION_INCOMING_CALL); 158c910f9b18fad0a82de96b23fe559825e81b28040Evan Charlton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1593199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal intent.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT, 1603199aa7f8bcb48569eb8289abc055ba0f8496ba8Sailesh Nepal TelephonyConnectionService.getPhoneAccount(context)); 1612afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon 1624822ee866dd3fc138f566afb2da810b491b68a6eSailesh Nepal Log.d(this, "Sending incoming call intent: %s", intent); 16373a742ec224ee1f39ba50955e6ffa6130e00297bAmith Yamasani context.startActivityAsUser(intent, UserHandle.CURRENT); 1642afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon } 1652afb2bebbb9c88f5ab8752f602a9148e14d14009Santos Cordon} 166