blob: 4ae80900386c5e9d31bc8474394d07bf2225b77d [file] [log] [blame]
Santos Cordon89647a62013-07-16 13:38:09 -07001/*
2 * Copyright (C) 2013 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
17package com.android.phone;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.ServiceConnection;
23import android.os.AsyncResult;
24import android.os.Handler;
25import android.os.IBinder;
26import android.os.Message;
27import android.os.RemoteException;
28import android.os.SystemProperties;
29import android.util.Log;
30
Santos Cordon9b7bac72013-08-06 08:04:52 -070031import com.android.phone.AudioRouter.AudioModeListener;
32import com.android.services.telephony.common.AudioMode;
Santos Cordonf4046882013-07-25 18:49:27 -070033import com.android.services.telephony.common.Call;
Santos Cordon345350e2013-07-19 17:16:14 -070034import com.android.services.telephony.common.ICallHandlerService;
Santos Cordoncba1b442013-07-18 12:43:58 -070035import com.android.services.telephony.common.ICallCommandService;
Santos Cordon89647a62013-07-16 13:38:09 -070036
Christine Chenee09a492013-08-06 16:02:29 -070037import java.util.ArrayList;
Santos Cordona3d05142013-07-29 11:25:17 -070038import java.util.List;
39
Santos Cordon89647a62013-07-16 13:38:09 -070040/**
Santos Cordon345350e2013-07-19 17:16:14 -070041 * This class is responsible for passing through call state changes to the CallHandlerService.
Santos Cordon89647a62013-07-16 13:38:09 -070042 */
Santos Cordon9b7bac72013-08-06 08:04:52 -070043public class CallHandlerServiceProxy extends Handler implements CallModeler.Listener,
44 AudioModeListener {
Santos Cordon89647a62013-07-16 13:38:09 -070045
Santos Cordon345350e2013-07-19 17:16:14 -070046 private static final String TAG = CallHandlerServiceProxy.class.getSimpleName();
Santos Cordon89647a62013-07-16 13:38:09 -070047 private static final boolean DBG =
48 (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
Chiao Chenge41661c2013-07-23 13:28:26 -070049
Santos Cordon89647a62013-07-16 13:38:09 -070050
Santos Cordon593ab382013-08-06 21:58:23 -070051 private AudioRouter mAudioRouter;
Santos Cordoncba1b442013-07-18 12:43:58 -070052 private CallCommandService mCallCommandService;
Santos Cordon593ab382013-08-06 21:58:23 -070053 private CallModeler mCallModeler;
54 private Context mContext;
55 private ICallHandlerService mCallHandlerService;
56 private ServiceConnection mConnection;
Santos Cordon89647a62013-07-16 13:38:09 -070057
Santos Cordon63a84242013-07-23 13:32:52 -070058 public CallHandlerServiceProxy(Context context, CallModeler callModeler,
Santos Cordon593ab382013-08-06 21:58:23 -070059 CallCommandService callCommandService, AudioRouter audioRouter) {
Santos Cordon89647a62013-07-16 13:38:09 -070060 mContext = context;
Santos Cordoncba1b442013-07-18 12:43:58 -070061 mCallCommandService = callCommandService;
Santos Cordon63a84242013-07-23 13:32:52 -070062 mCallModeler = callModeler;
Santos Cordon593ab382013-08-06 21:58:23 -070063 mAudioRouter = audioRouter;
Santos Cordon89647a62013-07-16 13:38:09 -070064
Santos Cordon593ab382013-08-06 21:58:23 -070065 mAudioRouter.addAudioModeListener(this);
Christine Chendaf7bf62013-08-05 19:12:31 -070066 mCallModeler.addListener(this);
Santos Cordon63a84242013-07-23 13:32:52 -070067 }
Santos Cordon89647a62013-07-16 13:38:09 -070068
Santos Cordon63a84242013-07-23 13:32:52 -070069 @Override
Santos Cordon995c8162013-07-29 09:22:22 -070070 public void onDisconnect(Call call) {
Santos Cordon63a84242013-07-23 13:32:52 -070071 if (mCallHandlerService != null) {
72 try {
Santos Cordon4ad64cd2013-08-15 00:36:14 -070073 if (DBG) Log.d(TAG, "onDisconnect: " + call);
Santos Cordon995c8162013-07-29 09:22:22 -070074 mCallHandlerService.onDisconnect(call);
Santos Cordonaf763a12013-08-19 20:04:58 -070075 maybeUnbind();
Santos Cordon63a84242013-07-23 13:32:52 -070076 } catch (RemoteException e) {
77 Log.e(TAG, "Remote exception handling onDisconnect ", e);
78 }
Santos Cordon89647a62013-07-16 13:38:09 -070079 }
80 }
81
Santos Cordona3d05142013-07-29 11:25:17 -070082 @Override
Christine Chenee09a492013-08-06 16:02:29 -070083 public void onIncoming(Call call, ArrayList<String> textResponses) {
Santos Cordonaf763a12013-08-19 20:04:58 -070084 if (maybeBindToService() && mCallHandlerService != null) {
Christine Chenee09a492013-08-06 16:02:29 -070085 try {
Santos Cordon4ad64cd2013-08-15 00:36:14 -070086 if (DBG) Log.d(TAG, "onIncoming: " + call);
Christine Chenee09a492013-08-06 16:02:29 -070087 mCallHandlerService.onIncoming(call, textResponses);
88 } catch (RemoteException e) {
89 Log.e(TAG, "Remote exception handling onUpdate", e);
90 }
91 }
92 }
93
94 @Override
Santos Cordon998f42b2013-08-02 16:13:12 -070095 public void onUpdate(List<Call> calls, boolean fullUpdate) {
Santos Cordonaf763a12013-08-19 20:04:58 -070096 if (maybeBindToService() && mCallHandlerService != null) {
Santos Cordona3d05142013-07-29 11:25:17 -070097 try {
Santos Cordon4ad64cd2013-08-15 00:36:14 -070098 if (DBG) Log.d(TAG, "onUpdate: " + calls.toString());
Santos Cordon998f42b2013-08-02 16:13:12 -070099 mCallHandlerService.onUpdate(calls, fullUpdate);
Santos Cordonaf763a12013-08-19 20:04:58 -0700100 maybeUnbind();
Santos Cordona3d05142013-07-29 11:25:17 -0700101 } catch (RemoteException e) {
102 Log.e(TAG, "Remote exception handling onUpdate", e);
103 }
104 }
105 }
106
Santos Cordon9b7bac72013-08-06 08:04:52 -0700107 @Override
108 public void onAudioModeChange(int previousMode, int newMode) {
109 // Just do a simple log for now.
110 Log.i(TAG, "Updating with new audio mode: " + AudioMode.toString(newMode) +
111 " from " + AudioMode.toString(previousMode));
112
113 if (mCallHandlerService != null) {
114 try {
Santos Cordon593ab382013-08-06 21:58:23 -0700115 if (DBG) Log.d(TAG, "onSupportAudioModeChange");
116
Santos Cordon9b7bac72013-08-06 08:04:52 -0700117 mCallHandlerService.onAudioModeChange(newMode);
118 } catch (RemoteException e) {
119 Log.e(TAG, "Remote exception handling onAudioModeChange", e);
120 }
121 }
122 }
123
Santos Cordon593ab382013-08-06 21:58:23 -0700124 @Override
125 public void onSupportedAudioModeChange(int modeMask) {
126 if (mCallHandlerService != null) {
127 try {
128 if (DBG) Log.d(TAG, "onSupportAudioModeChange: " + AudioMode.toString(modeMask));
129
130 mCallHandlerService.onSupportedAudioModeChange(modeMask);
131 } catch (RemoteException e) {
132 Log.e(TAG, "Remote exception handling onAudioModeChange", e);
133 }
134 }
135 }
136
Santos Cordon406c0342013-08-28 00:07:47 -0700137 public void bringToForeground() {
138 // only support this call if the service is already connected.
139 if (mCallHandlerService != null && mCallModeler.hasLiveCall()) {
140 try {
141 if (DBG) Log.d(TAG, "bringToForeground");
142 mCallHandlerService.bringToForeground();
143 } catch (RemoteException e) {
144 Log.e(TAG, "Exception handling bringToForeground", e);
145 }
146 }
147 }
148
Santos Cordon89647a62013-07-16 13:38:09 -0700149 /**
Santos Cordon345350e2013-07-19 17:16:14 -0700150 * Sets up the connection with ICallHandlerService
Santos Cordon89647a62013-07-16 13:38:09 -0700151 */
152 private void setupServiceConnection() {
153 mConnection = new ServiceConnection() {
154 @Override
155 public void onServiceConnected(ComponentName className, IBinder service) {
156 if (DBG) {
157 Log.d(TAG, "Service Connected");
158 }
Santos Cordon345350e2013-07-19 17:16:14 -0700159 onCallHandlerServiceConnected(ICallHandlerService.Stub.asInterface(service));
Santos Cordon89647a62013-07-16 13:38:09 -0700160 }
161
162 @Override
163 public void onServiceDisconnected(ComponentName className) {
Santos Cordonaf763a12013-08-19 20:04:58 -0700164 Log.i(TAG, "Disconnected from UI service.");
Santos Cordon345350e2013-07-19 17:16:14 -0700165 mCallHandlerService = null;
Santos Cordonaf763a12013-08-19 20:04:58 -0700166
167 // clean up our current binding.
168 mContext.unbindService(mConnection);
169 mConnection = null;
170
171 // potentially attempt to rebind if there are still active calls.
172 maybeBindToService();
Santos Cordon89647a62013-07-16 13:38:09 -0700173 }
174 };
175
Santos Cordonaf763a12013-08-19 20:04:58 -0700176 final Intent serviceIntent = new Intent(ICallHandlerService.class.getName());
177 final ComponentName component = new ComponentName(
178 mContext.getResources().getString(R.string.incall_ui_default_package),
179 mContext.getResources().getString(R.string.incall_ui_default_class));
180 serviceIntent.setComponent(component);
Santos Cordon89647a62013-07-16 13:38:09 -0700181 if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
Santos Cordon345350e2013-07-19 17:16:14 -0700182 Log.e(TAG, "Cound not bind to ICallHandlerService");
Santos Cordon89647a62013-07-16 13:38:09 -0700183 }
184 }
185
186 /**
Santos Cordonaf763a12013-08-19 20:04:58 -0700187 * Checks To see if there are any calls left. If not, unbind the callhandler service.
188 */
189 private void maybeUnbind() {
190 if (!mCallModeler.hasLiveCall()) {
191 if (mConnection != null) {
192 mContext.unbindService(mConnection);
193 mConnection = null;
194 }
195 }
196 }
197
198 /**
199 * Checks to see if there are any active calls. If so, binds the call handler service.
200 * @return true if already bound. False otherwise.
201 */
202 private boolean maybeBindToService() {
203 if (mCallModeler.hasLiveCall()) {
204 // mConnection is set to non-null once an attempt is made to connect.
205 // We do not check against mCallHandlerService here because we could potentially
206 // create multiple bindings to the UI.
207 if (mConnection != null) {
208 return true;
209 }
210 setupServiceConnection();
211 }
212 return false;
213 }
214
215 /**
Santos Cordoncba1b442013-07-18 12:43:58 -0700216 * Called when the in-call UI service is connected. Send command interface to in-call.
217 */
Santos Cordon63a84242013-07-23 13:32:52 -0700218 private void onCallHandlerServiceConnected(ICallHandlerService callHandlerService) {
219 mCallHandlerService = callHandlerService;
Santos Cordoncba1b442013-07-18 12:43:58 -0700220
221 try {
Santos Cordon345350e2013-07-19 17:16:14 -0700222 mCallHandlerService.setCallCommandService(mCallCommandService);
Santos Cordonaf763a12013-08-19 20:04:58 -0700223
224 // start with a full update
225 onUpdate(mCallModeler.getFullList(), true);
Santos Cordoncba1b442013-07-18 12:43:58 -0700226 } catch (RemoteException e) {
Santos Cordon63a84242013-07-23 13:32:52 -0700227 Log.e(TAG, "Remote exception calling CallHandlerService::setCallCommandService", e);
Santos Cordon89647a62013-07-16 13:38:09 -0700228 }
229 }
230}