1 /* 2 * Copyright (C) 2015 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.car.dialer.telecom; 17 18 import android.content.Intent; 19 import android.os.Binder; 20 import android.os.IBinder; 21 import android.telecom.Call; 22 import android.telecom.CallAudioState; 23 import android.telecom.InCallService; 24 import android.telecom.TelecomManager; 25 import android.util.Log; 26 27 import java.util.concurrent.CopyOnWriteArrayList; 28 29 /** 30 * An implementation of {@link InCallService}. This service is bounded by android telecom and 31 * {@link UiCallManager}. For incoming calls it will launch Dialer app. 32 */ 33 public class InCallServiceImpl extends InCallService { 34 private static final String TAG = "Em.InCallService"; 35 36 static final String ACTION_LOCAL_BIND = "local_bind"; 37 38 private CopyOnWriteArrayList<Callback> mCallbacks = new CopyOnWriteArrayList<>(); 39 40 private TelecomManager mTelecomManager; 41 42 @Override 43 public void onCreate() { 44 super.onCreate(); 45 mTelecomManager = getApplicationContext().getSystemService(TelecomManager.class); 46 } 47 48 @Override 49 public void onCallAdded(Call telecomCall) { 50 super.onCallAdded(telecomCall); 51 if (Log.isLoggable(TAG, Log.DEBUG)) { 52 Log.d(TAG, "onCallAdded: " + telecomCall + ", state: " + telecomCall); 53 } 54 55 telecomCall.registerCallback(mCallListener); 56 mCallListener.onStateChanged(telecomCall, telecomCall.getState()); 57 58 for (Callback callback : mCallbacks) { 59 callback.onTelecomCallAdded(telecomCall); 60 } 61 } 62 63 @Override 64 public void onCallRemoved(Call telecomCall) { 65 if (Log.isLoggable(TAG, Log.DEBUG)) { 66 Log.d(TAG, "onCallRemoved: " + telecomCall); 67 } 68 for (Callback callback : mCallbacks) { 69 callback.onTelecomCallRemoved(telecomCall); 70 } 71 telecomCall.unregisterCallback(mCallListener); 72 super.onCallRemoved(telecomCall); 73 } 74 75 @Override 76 public IBinder onBind(Intent intent) { 77 if (Log.isLoggable(TAG, Log.DEBUG)) { 78 Log.d(TAG, "onBind: " + intent); 79 } 80 81 return ACTION_LOCAL_BIND.equals(intent.getAction()) 82 ? new LocalBinder() 83 : super.onBind(intent); 84 } 85 86 private final Call.Callback mCallListener = new Call.Callback() { 87 @Override 88 public void onStateChanged(Call call, int state) { 89 if (Log.isLoggable(TAG, Log.DEBUG)) { 90 Log.d(TAG, "onStateChanged call: " + call + ", state: " + state ); 91 } 92 93 if (state == Call.STATE_RINGING || state == Call.STATE_DIALING) { 94 if (Log.isLoggable(TAG, Log.INFO)) { 95 Log.i(TAG, "Incoming/outgoing call: " + call); 96 } 97 98 // TODO(b/25190782): here we should show heads-up notification for incoming call, 99 // however system notifications are disabled by System UI and we haven't implemented 100 // a way to show heads-up notifications in embedded mode. 101 Intent launchIntent = getPackageManager() 102 .getLaunchIntentForPackage(mTelecomManager.getDefaultDialerPackage()); 103 startActivity(launchIntent); 104 } 105 } 106 }; 107 108 @Override 109 public boolean onUnbind(Intent intent) { 110 if (Log.isLoggable(TAG, Log.DEBUG)) { 111 Log.d(TAG, "onUnbind, intent: " + intent); 112 } 113 return super.onUnbind(intent); 114 } 115 116 @Override 117 public void onCallAudioStateChanged(CallAudioState audioState) { 118 for (Callback callback : mCallbacks) { 119 callback.onCallAudioStateChanged(audioState); 120 } 121 } 122 123 public void registerCallback(Callback callback) { 124 mCallbacks.add(callback); 125 } 126 127 public void unregisterCallback(Callback callback) { 128 mCallbacks.remove(callback); 129 } 130 131 interface Callback { 132 void onTelecomCallAdded(Call telecomCall); 133 void onTelecomCallRemoved(Call telecomCall); 134 void onCallAudioStateChanged(CallAudioState audioState); 135 } 136 137 class LocalBinder extends Binder { 138 InCallServiceImpl getService() { 139 return InCallServiceImpl.this; 140 } 141 } 142 } 143