1/*
2 * Copyright (C) 2014 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 R* limitations under the License.
15 */
16
17package android.telecom;
18
19import android.net.Uri;
20import android.os.Bundle;
21import android.os.Handler;
22import android.os.Message;
23import android.os.RemoteException;
24
25import com.android.internal.os.SomeArgs;
26import com.android.internal.telecom.IConnectionServiceAdapter;
27import com.android.internal.telecom.IVideoProvider;
28import com.android.internal.telecom.RemoteServiceCallback;
29
30import java.util.List;
31
32/**
33 * A component that provides an RPC servant implementation of {@link IConnectionServiceAdapter},
34 * posting incoming messages on the main thread on a client-supplied delegate object.
35 *
36 * TODO: Generate this and similar classes using a compiler starting from AIDL interfaces.
37 *
38 * @hide
39 */
40final class ConnectionServiceAdapterServant {
41    private static final int MSG_HANDLE_CREATE_CONNECTION_COMPLETE = 1;
42    private static final int MSG_SET_ACTIVE = 2;
43    private static final int MSG_SET_RINGING = 3;
44    private static final int MSG_SET_DIALING = 4;
45    private static final int MSG_SET_DISCONNECTED = 5;
46    private static final int MSG_SET_ON_HOLD = 6;
47    private static final int MSG_SET_RINGBACK_REQUESTED = 7;
48    private static final int MSG_SET_CONNECTION_CAPABILITIES = 8;
49    private static final int MSG_SET_IS_CONFERENCED = 9;
50    private static final int MSG_ADD_CONFERENCE_CALL = 10;
51    private static final int MSG_REMOVE_CALL = 11;
52    private static final int MSG_ON_POST_DIAL_WAIT = 12;
53    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
54    private static final int MSG_SET_VIDEO_STATE = 14;
55    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15;
56    private static final int MSG_SET_IS_VOIP_AUDIO_MODE = 16;
57    private static final int MSG_SET_STATUS_HINTS = 17;
58    private static final int MSG_SET_ADDRESS = 18;
59    private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
60    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
61    private static final int MSG_ADD_EXISTING_CONNECTION = 21;
62    private static final int MSG_ON_POST_DIAL_CHAR = 22;
63    private static final int MSG_SET_CONFERENCE_MERGE_FAILED = 23;
64    private static final int MSG_PUT_EXTRAS = 24;
65    private static final int MSG_REMOVE_EXTRAS = 25;
66    private static final int MSG_ON_CONNECTION_EVENT = 26;
67    private static final int MSG_SET_CONNECTION_PROPERTIES = 27;
68
69    private final IConnectionServiceAdapter mDelegate;
70
71    private final Handler mHandler = new Handler() {
72        @Override
73        public void handleMessage(Message msg) {
74            try {
75                internalHandleMessage(msg);
76            } catch (RemoteException e) {
77            }
78        }
79
80        // Internal method defined to centralize handling of RemoteException
81        private void internalHandleMessage(Message msg) throws RemoteException {
82            switch (msg.what) {
83                case MSG_HANDLE_CREATE_CONNECTION_COMPLETE: {
84                    SomeArgs args = (SomeArgs) msg.obj;
85                    try {
86                        mDelegate.handleCreateConnectionComplete(
87                                (String) args.arg1,
88                                (ConnectionRequest) args.arg2,
89                                (ParcelableConnection) args.arg3);
90                    } finally {
91                        args.recycle();
92                    }
93                    break;
94                }
95                case MSG_SET_ACTIVE:
96                    mDelegate.setActive((String) msg.obj);
97                    break;
98                case MSG_SET_RINGING:
99                    mDelegate.setRinging((String) msg.obj);
100                    break;
101                case MSG_SET_DIALING:
102                    mDelegate.setDialing((String) msg.obj);
103                    break;
104                case MSG_SET_DISCONNECTED: {
105                    SomeArgs args = (SomeArgs) msg.obj;
106                    try {
107                        mDelegate.setDisconnected((String) args.arg1, (DisconnectCause) args.arg2);
108                    } finally {
109                        args.recycle();
110                    }
111                    break;
112                }
113                case MSG_SET_ON_HOLD:
114                    mDelegate.setOnHold((String) msg.obj);
115                    break;
116                case MSG_SET_RINGBACK_REQUESTED:
117                    mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1);
118                    break;
119                case MSG_SET_CONNECTION_CAPABILITIES:
120                    mDelegate.setConnectionCapabilities((String) msg.obj, msg.arg1);
121                    break;
122                case MSG_SET_CONNECTION_PROPERTIES:
123                    mDelegate.setConnectionProperties((String) msg.obj, msg.arg1);
124                    break;
125                case MSG_SET_IS_CONFERENCED: {
126                    SomeArgs args = (SomeArgs) msg.obj;
127                    try {
128                        mDelegate.setIsConferenced((String) args.arg1, (String) args.arg2);
129                    } finally {
130                        args.recycle();
131                    }
132                    break;
133                }
134                case MSG_ADD_CONFERENCE_CALL: {
135                    SomeArgs args = (SomeArgs) msg.obj;
136                    try {
137                        mDelegate.addConferenceCall(
138                                (String) args.arg1, (ParcelableConference) args.arg2);
139                    } finally {
140                        args.recycle();
141                    }
142                    break;
143                }
144                case MSG_REMOVE_CALL:
145                    mDelegate.removeCall((String) msg.obj);
146                    break;
147                case MSG_ON_POST_DIAL_WAIT: {
148                    SomeArgs args = (SomeArgs) msg.obj;
149                    try {
150                        mDelegate.onPostDialWait((String) args.arg1, (String) args.arg2);
151                    } finally {
152                        args.recycle();
153                    }
154                    break;
155                }
156                case MSG_ON_POST_DIAL_CHAR: {
157                    SomeArgs args = (SomeArgs) msg.obj;
158                    try {
159                        mDelegate.onPostDialChar((String) args.arg1, (char) args.argi1);
160                    } finally {
161                        args.recycle();
162                    }
163                    break;
164                }
165                case MSG_QUERY_REMOTE_CALL_SERVICES:
166                    mDelegate.queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
167                    break;
168                case MSG_SET_VIDEO_STATE:
169                    mDelegate.setVideoState((String) msg.obj, msg.arg1);
170                    break;
171                case MSG_SET_VIDEO_CALL_PROVIDER: {
172                    SomeArgs args = (SomeArgs) msg.obj;
173                    try {
174                        mDelegate.setVideoProvider((String) args.arg1,
175                                (IVideoProvider) args.arg2);
176                    } finally {
177                        args.recycle();
178                    }
179                    break;
180                }
181                case MSG_SET_IS_VOIP_AUDIO_MODE:
182                    mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1);
183                    break;
184                case MSG_SET_STATUS_HINTS: {
185                    SomeArgs args = (SomeArgs) msg.obj;
186                    try {
187                        mDelegate.setStatusHints((String) args.arg1, (StatusHints) args.arg2);
188                    } finally {
189                        args.recycle();
190                    }
191                    break;
192                }
193                case MSG_SET_ADDRESS: {
194                    SomeArgs args = (SomeArgs) msg.obj;
195                    try {
196                        mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1);
197                    } finally {
198                        args.recycle();
199                    }
200                    break;
201                }
202                case MSG_SET_CALLER_DISPLAY_NAME: {
203                    SomeArgs args = (SomeArgs) msg.obj;
204                    try {
205                        mDelegate.setCallerDisplayName(
206                                (String) args.arg1, (String) args.arg2, args.argi1);
207                    } finally {
208                        args.recycle();
209                    }
210                    break;
211                }
212                case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
213                    SomeArgs args = (SomeArgs) msg.obj;
214                    try {
215                        mDelegate.setConferenceableConnections(
216                                (String) args.arg1, (List<String>) args.arg2);
217                    } finally {
218                        args.recycle();
219                    }
220                    break;
221                }
222                case MSG_ADD_EXISTING_CONNECTION: {
223                    SomeArgs args = (SomeArgs) msg.obj;
224                    try {
225                        mDelegate.addExistingConnection(
226                                (String) args.arg1, (ParcelableConnection) args.arg2);
227                    } finally {
228                        args.recycle();
229                    }
230                    break;
231                }
232                case MSG_SET_CONFERENCE_MERGE_FAILED: {
233                    SomeArgs args = (SomeArgs) msg.obj;
234                    try {
235                        mDelegate.setConferenceMergeFailed((String) args.arg1);
236                    } finally {
237                        args.recycle();
238                    }
239                    break;
240                }
241                case MSG_PUT_EXTRAS: {
242                    SomeArgs args = (SomeArgs) msg.obj;
243                    try {
244                        mDelegate.putExtras((String) args.arg1, (Bundle) args.arg2);
245                    } finally {
246                        args.recycle();
247                    }
248                    break;
249                }
250                case MSG_REMOVE_EXTRAS: {
251                    SomeArgs args = (SomeArgs) msg.obj;
252                    try {
253                        mDelegate.removeExtras((String) args.arg1, (List<String>) args.arg2);
254                    } finally {
255                        args.recycle();
256                    }
257                    break;
258                }
259                case MSG_ON_CONNECTION_EVENT: {
260                    SomeArgs args = (SomeArgs) msg.obj;
261                    try {
262                        mDelegate.onConnectionEvent((String) args.arg1, (String) args.arg2,
263                                (Bundle) args.arg3);
264                    } finally {
265                        args.recycle();
266                    }
267                    break;
268                }
269            }
270        }
271    };
272
273    private final IConnectionServiceAdapter mStub = new IConnectionServiceAdapter.Stub() {
274        @Override
275        public void handleCreateConnectionComplete(
276                String id,
277                ConnectionRequest request,
278                ParcelableConnection connection) {
279            SomeArgs args = SomeArgs.obtain();
280            args.arg1 = id;
281            args.arg2 = request;
282            args.arg3 = connection;
283            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
284        }
285
286        @Override
287        public void setActive(String connectionId) {
288            mHandler.obtainMessage(MSG_SET_ACTIVE, connectionId).sendToTarget();
289        }
290
291        @Override
292        public void setRinging(String connectionId) {
293            mHandler.obtainMessage(MSG_SET_RINGING, connectionId).sendToTarget();
294        }
295
296        @Override
297        public void setDialing(String connectionId) {
298            mHandler.obtainMessage(MSG_SET_DIALING, connectionId).sendToTarget();
299        }
300
301        @Override
302        public void setDisconnected(
303                String connectionId, DisconnectCause disconnectCause) {
304            SomeArgs args = SomeArgs.obtain();
305            args.arg1 = connectionId;
306            args.arg2 = disconnectCause;
307            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
308        }
309
310        @Override
311        public void setOnHold(String connectionId) {
312            mHandler.obtainMessage(MSG_SET_ON_HOLD, connectionId).sendToTarget();
313        }
314
315        @Override
316        public void setRingbackRequested(String connectionId, boolean ringback) {
317            mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, connectionId)
318                    .sendToTarget();
319        }
320
321        @Override
322        public void setConnectionCapabilities(String connectionId, int connectionCapabilities) {
323            mHandler.obtainMessage(
324                    MSG_SET_CONNECTION_CAPABILITIES, connectionCapabilities, 0, connectionId)
325                    .sendToTarget();
326        }
327
328        @Override
329        public void setConnectionProperties(String connectionId, int connectionProperties) {
330            mHandler.obtainMessage(
331                    MSG_SET_CONNECTION_PROPERTIES, connectionProperties, 0, connectionId)
332                    .sendToTarget();
333        }
334
335        @Override
336        public void setConferenceMergeFailed(String callId) {
337            SomeArgs args = SomeArgs.obtain();
338            args.arg1 = callId;
339            mHandler.obtainMessage(MSG_SET_CONFERENCE_MERGE_FAILED, args).sendToTarget();
340        }
341
342        @Override
343        public void setIsConferenced(String callId, String conferenceCallId) {
344            SomeArgs args = SomeArgs.obtain();
345            args.arg1 = callId;
346            args.arg2 = conferenceCallId;
347            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
348        }
349
350        @Override
351        public void addConferenceCall(String callId, ParcelableConference parcelableConference) {
352            SomeArgs args = SomeArgs.obtain();
353            args.arg1 = callId;
354            args.arg2 = parcelableConference;
355            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, args).sendToTarget();
356        }
357
358        @Override
359        public void removeCall(String connectionId) {
360            mHandler.obtainMessage(MSG_REMOVE_CALL, connectionId).sendToTarget();
361        }
362
363        @Override
364        public void onPostDialWait(String connectionId, String remainingDigits) {
365            SomeArgs args = SomeArgs.obtain();
366            args.arg1 = connectionId;
367            args.arg2 = remainingDigits;
368            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
369        }
370
371        @Override
372        public void onPostDialChar(String connectionId, char nextChar) {
373            SomeArgs args = SomeArgs.obtain();
374            args.arg1 = connectionId;
375            args.argi1 = nextChar;
376            mHandler.obtainMessage(MSG_ON_POST_DIAL_CHAR, args).sendToTarget();
377        }
378
379        @Override
380        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
381            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
382        }
383
384        @Override
385        public void setVideoState(String connectionId, int videoState) {
386            mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, connectionId).sendToTarget();
387        }
388
389        @Override
390        public void setVideoProvider(String connectionId, IVideoProvider videoProvider) {
391            SomeArgs args = SomeArgs.obtain();
392            args.arg1 = connectionId;
393            args.arg2 = videoProvider;
394            mHandler.obtainMessage(MSG_SET_VIDEO_CALL_PROVIDER, args).sendToTarget();
395        }
396
397        @Override
398        public final void setIsVoipAudioMode(String connectionId, boolean isVoip) {
399            mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0,
400                    connectionId).sendToTarget();
401        }
402
403        @Override
404        public final void setStatusHints(String connectionId, StatusHints statusHints) {
405            SomeArgs args = SomeArgs.obtain();
406            args.arg1 = connectionId;
407            args.arg2 = statusHints;
408            mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
409        }
410
411        @Override
412        public final void setAddress(String connectionId, Uri address, int presentation) {
413            SomeArgs args = SomeArgs.obtain();
414            args.arg1 = connectionId;
415            args.arg2 = address;
416            args.argi1 = presentation;
417            mHandler.obtainMessage(MSG_SET_ADDRESS, args).sendToTarget();
418        }
419
420        @Override
421        public final void setCallerDisplayName(
422                String connectionId, String callerDisplayName, int presentation) {
423            SomeArgs args = SomeArgs.obtain();
424            args.arg1 = connectionId;
425            args.arg2 = callerDisplayName;
426            args.argi1 = presentation;
427            mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
428        }
429
430        @Override
431        public final void setConferenceableConnections(
432                String connectionId, List<String> conferenceableConnectionIds) {
433            SomeArgs args = SomeArgs.obtain();
434            args.arg1 = connectionId;
435            args.arg2 = conferenceableConnectionIds;
436            mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
437        }
438
439        @Override
440        public final void addExistingConnection(
441                String connectionId, ParcelableConnection connection) {
442            SomeArgs args = SomeArgs.obtain();
443            args.arg1 = connectionId;
444            args.arg2 = connection;
445            mHandler.obtainMessage(MSG_ADD_EXISTING_CONNECTION, args).sendToTarget();
446        }
447
448        @Override
449        public final void putExtras(String connectionId, Bundle extras) {
450            SomeArgs args = SomeArgs.obtain();
451            args.arg1 = connectionId;
452            args.arg2 = extras;
453            mHandler.obtainMessage(MSG_PUT_EXTRAS, args).sendToTarget();
454        }
455
456        @Override
457        public final void removeExtras(String connectionId, List<String> keys) {
458            SomeArgs args = SomeArgs.obtain();
459            args.arg1 = connectionId;
460            args.arg2 = keys;
461            mHandler.obtainMessage(MSG_REMOVE_EXTRAS, args).sendToTarget();
462        }
463
464        @Override
465        public final void onConnectionEvent(String connectionId, String event, Bundle extras) {
466            SomeArgs args = SomeArgs.obtain();
467            args.arg1 = connectionId;
468            args.arg2 = event;
469            args.arg3 = extras;
470            mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
471        }
472    };
473
474    public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
475        mDelegate = delegate;
476    }
477
478    public IConnectionServiceAdapter getStub() {
479        return mStub;
480    }
481}
482