blob: ab75c6e515287b67aced790c4d80345de106ff4e [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.dialer.telecom;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.telecom.InCallService;
import com.android.car.dialer.log.L;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* An implementation of {@link InCallService}. This service is bounded by android telecom and
* {@link UiCallManager}. For incoming calls it will launch Dialer app.
*/
public class InCallServiceImpl extends InCallService {
private static final String TAG = "CD.InCallService";
/** An action which indicates a bind is from local component. */
public static final String ACTION_LOCAL_BIND = "local_bind";
private CopyOnWriteArrayList<CallAudioStateCallback> mCallAudioStateCallbacks =
new CopyOnWriteArrayList<>();
private InCallRouter mInCallRouter;
/** Listens to active call list changes. Callbacks will be called on main thread. */
public interface ActiveCallListChangedCallback {
/**
* Called when a new call is added.
*
* @return if the given call has been handled by this callback.
*/
boolean onTelecomCallAdded(Call telecomCall);
/**
* Called when an existing call is removed.
*
* @return if the given call has been handled by this callback.
*/
boolean onTelecomCallRemoved(Call telecomCall);
}
/** Listens to call audio state changes. Callbacks will be called on the main thread. */
public interface CallAudioStateCallback {
/**
* Called when the call audio state has changed.
*/
void onCallAudioStateChanged(CallAudioState callAudioState);
}
@Override
public void onCreate() {
super.onCreate();
mInCallRouter = new InCallRouter(getApplicationContext());
mInCallRouter.start();
}
@Override
public void onDestroy() {
super.onDestroy();
mInCallRouter.stop();
mInCallRouter = null;
}
@Override
public void onCallAdded(Call telecomCall) {
L.d(TAG, "onCallAdded: %s", telecomCall);
mInCallRouter.onCallAdded(telecomCall);
}
@Override
public void onCallRemoved(Call telecomCall) {
L.d(TAG, "onCallRemoved: %s", telecomCall);
mInCallRouter.onCallRemoved(telecomCall);
}
@Override
public IBinder onBind(Intent intent) {
L.d(TAG, "onBind: %s", intent);
return ACTION_LOCAL_BIND.equals(intent.getAction())
? new LocalBinder()
: super.onBind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
L.d(TAG, "onUnbind, intent: %s", intent);
if (ACTION_LOCAL_BIND.equals(intent.getAction())) {
return false;
}
return super.onUnbind(intent);
}
@Override
public void onCallAudioStateChanged(CallAudioState audioState) {
for (CallAudioStateCallback callback : mCallAudioStateCallbacks) {
callback.onCallAudioStateChanged(audioState);
}
}
@Override
public void onBringToForeground(boolean showDialpad) {
L.d(TAG, "onBringToForeground: %s", showDialpad);
mInCallRouter.routeToFullScreenIncomingCallPage(showDialpad);
}
public void addCallAudioStateChangedCallback(CallAudioStateCallback callback) {
mCallAudioStateCallbacks.add(callback);
}
public void removeCallAudioStateChangedCallback(CallAudioStateCallback callback) {
mCallAudioStateCallbacks.remove(callback);
}
public void addActiveCallListChangedCallback(ActiveCallListChangedCallback callback) {
mInCallRouter.registerActiveCallListChangedCallback(callback);
}
public void removeActiveCallListChangedCallback(ActiveCallListChangedCallback callback) {
mInCallRouter.unregisterActiveCallHandler(callback);
}
/**
* Local binder only available for Car Dialer package.
*/
public class LocalBinder extends Binder {
/**
* Returns a reference to {@link InCallServiceImpl}. Any process other than Dialer
* process won't be able to get a reference.
*/
public InCallServiceImpl getService() {
if (getCallingPid() == Process.myPid()) {
return InCallServiceImpl.this;
}
return null;
}
}
}