• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.os.Process;
22 import android.telecom.Call;
23 import android.telecom.CallAudioState;
24 import android.telecom.InCallService;
25 
26 import com.android.car.dialer.log.L;
27 
28 import java.util.concurrent.CopyOnWriteArrayList;
29 
30 /**
31  * An implementation of {@link InCallService}. This service is bounded by android telecom and
32  * {@link UiCallManager}. For incoming calls it will launch Dialer app.
33  */
34 public class InCallServiceImpl extends InCallService {
35     private static final String TAG = "CD.InCallService";
36 
37     /** An action which indicates a bind is from local component. */
38     public static final String ACTION_LOCAL_BIND = "local_bind";
39 
40     private CopyOnWriteArrayList<Callback> mCallbacks = new CopyOnWriteArrayList<>();
41 
42     private InCallRouter mInCallRouter;
43 
44     /** Listens to active call list changes. Callbacks will be called on main thread. */
45     public interface ActiveCallListChangedCallback {
46 
47         /**
48          * Called when a new call is added.
49          *
50          * @return if the given call has been handled by this callback.
51          */
onTelecomCallAdded(Call telecomCall)52         boolean onTelecomCallAdded(Call telecomCall);
53 
54         /**
55          * Called when an existing call is removed.
56          *
57          * @return if the given call has been handled by this callback.
58          */
onTelecomCallRemoved(Call telecomCall)59         boolean onTelecomCallRemoved(Call telecomCall);
60     }
61 
62     @Override
onCreate()63     public void onCreate() {
64         super.onCreate();
65         mInCallRouter = new InCallRouter(getApplicationContext());
66         mInCallRouter.start();
67     }
68 
69     @Override
onDestroy()70     public void onDestroy() {
71         super.onDestroy();
72         mInCallRouter.stop();
73         mInCallRouter = null;
74     }
75 
76     @Override
onCallAdded(Call telecomCall)77     public void onCallAdded(Call telecomCall) {
78         L.d(TAG, "onCallAdded: %s", telecomCall);
79 
80         for (Callback callback : mCallbacks) {
81             callback.onTelecomCallAdded(telecomCall);
82         }
83 
84         mInCallRouter.onCallAdded(telecomCall);
85     }
86 
87     @Override
onCallRemoved(Call telecomCall)88     public void onCallRemoved(Call telecomCall) {
89         L.d(TAG, "onCallRemoved: %s", telecomCall);
90         for (Callback callback : mCallbacks) {
91             callback.onTelecomCallRemoved(telecomCall);
92         }
93 
94         mInCallRouter.onCallRemoved(telecomCall);
95     }
96 
97     @Override
onBind(Intent intent)98     public IBinder onBind(Intent intent) {
99         L.d(TAG, "onBind: %s", intent);
100         return ACTION_LOCAL_BIND.equals(intent.getAction())
101                 ? new LocalBinder()
102                 : super.onBind(intent);
103     }
104 
105     @Override
onUnbind(Intent intent)106     public boolean onUnbind(Intent intent) {
107         L.d(TAG, "onUnbind, intent: %s", intent);
108         if (ACTION_LOCAL_BIND.equals(intent.getAction())) {
109             return false;
110         }
111         return super.onUnbind(intent);
112     }
113 
114     @Override
onCallAudioStateChanged(CallAudioState audioState)115     public void onCallAudioStateChanged(CallAudioState audioState) {
116         for (Callback callback : mCallbacks) {
117             callback.onCallAudioStateChanged(audioState);
118         }
119     }
120 
registerCallback(Callback callback)121     public void registerCallback(Callback callback) {
122         mCallbacks.add(callback);
123     }
124 
unregisterCallback(Callback callback)125     public void unregisterCallback(Callback callback) {
126         mCallbacks.remove(callback);
127     }
128 
addActiveCallListChangedCallback(ActiveCallListChangedCallback callback)129     public void addActiveCallListChangedCallback(ActiveCallListChangedCallback callback) {
130         mInCallRouter.registerActiveCallListChangedCallback(callback);
131     }
132 
removeActiveCallListChangedCallback(ActiveCallListChangedCallback callback)133     public void removeActiveCallListChangedCallback(ActiveCallListChangedCallback callback) {
134         mInCallRouter.unregisterActiveCallHandler(callback);
135     }
136 
137     @Deprecated
138     interface Callback {
onTelecomCallAdded(Call telecomCall)139         void onTelecomCallAdded(Call telecomCall);
140 
onTelecomCallRemoved(Call telecomCall)141         void onTelecomCallRemoved(Call telecomCall);
142 
onCallAudioStateChanged(CallAudioState audioState)143         void onCallAudioStateChanged(CallAudioState audioState);
144     }
145 
146     /**
147      * Local binder only available for Car Dialer package.
148      */
149     public class LocalBinder extends Binder {
150 
151         /**
152          * Returns a reference to {@link InCallServiceImpl}. Any process other than Dialer
153          * process won't be able to get a reference.
154          */
getService()155         public InCallServiceImpl getService() {
156             if (getCallingPid() == Process.myPid()) {
157                 return InCallServiceImpl.this;
158             }
159             return null;
160         }
161     }
162 }
163