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