ITvInputSessionWrapper.java revision 4c52697dbed682a19dacc78b0c08931ea8dbc6b5
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 * limitations under the License.
15 */
16
17package android.media.tv;
18
19import android.content.Context;
20import android.graphics.Rect;
21import android.net.Uri;
22import android.os.Bundle;
23import android.os.IBinder;
24import android.os.Looper;
25import android.os.Message;
26import android.util.Log;
27import android.view.InputChannel;
28import android.view.InputEvent;
29import android.view.InputEventReceiver;
30import android.view.Surface;
31
32import com.android.internal.os.HandlerCaller;
33import com.android.internal.os.SomeArgs;
34
35/**
36 * Implements the internal ITvInputSession interface to convert incoming calls on to it back to
37 * calls on the public TvInputSession interface, scheduling them on the main thread of the process.
38 *
39 * @hide
40 */
41public class ITvInputSessionWrapper extends ITvInputSession.Stub implements HandlerCaller.Callback {
42    private static final String TAG = "TvInputSessionWrapper";
43
44    private static final int DO_RELEASE = 1;
45    private static final int DO_SET_MAIN_SESSION = 2;
46    private static final int DO_SET_SURFACE = 3;
47    private static final int DO_DISPATCH_SURFACE_CHANGED = 4;
48    private static final int DO_SET_STREAM_VOLUME = 5;
49    private static final int DO_TUNE = 6;
50    private static final int DO_SET_CAPTION_ENABLED = 7;
51    private static final int DO_SELECT_TRACK = 8;
52    private static final int DO_UNSELECT_TRACK = 9;
53    private static final int DO_APP_PRIVATE_COMMAND = 10;
54    private static final int DO_CREATE_OVERLAY_VIEW = 11;
55    private static final int DO_RELAYOUT_OVERLAY_VIEW = 12;
56    private static final int DO_REMOVE_OVERLAY_VIEW = 13;
57    private static final int DO_REQUEST_UNBLOCK_CONTENT = 14;
58
59    private final HandlerCaller mCaller;
60
61    private TvInputService.Session mTvInputSessionImpl;
62    private InputChannel mChannel;
63    private TvInputEventReceiver mReceiver;
64
65    public ITvInputSessionWrapper(Context context, TvInputService.Session sessionImpl,
66            InputChannel channel) {
67        mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
68        mTvInputSessionImpl = sessionImpl;
69        mChannel = channel;
70        if (channel != null) {
71            mReceiver = new TvInputEventReceiver(channel, context.getMainLooper());
72        }
73    }
74
75    @Override
76    public void executeMessage(Message msg) {
77        if (mTvInputSessionImpl == null) {
78            return;
79        }
80
81        switch (msg.what) {
82            case DO_RELEASE: {
83                mTvInputSessionImpl.release();
84                mTvInputSessionImpl = null;
85                if (mReceiver != null) {
86                    mReceiver.dispose();
87                    mReceiver = null;
88                }
89                if (mChannel != null) {
90                    mChannel.dispose();
91                    mChannel = null;
92                }
93                return;
94            }
95            case DO_SET_MAIN_SESSION: {
96                mTvInputSessionImpl.setMainSession((Boolean) msg.obj);
97                return;
98            }
99            case DO_SET_SURFACE: {
100                mTvInputSessionImpl.setSurface((Surface) msg.obj);
101                return;
102            }
103            case DO_DISPATCH_SURFACE_CHANGED: {
104                SomeArgs args = (SomeArgs) msg.obj;
105                mTvInputSessionImpl.dispatchSurfaceChanged(args.argi1, args.argi2, args.argi3);
106                args.recycle();
107                return;
108            }
109            case DO_SET_STREAM_VOLUME: {
110                mTvInputSessionImpl.setStreamVolume((Float) msg.obj);
111                return;
112            }
113            case DO_TUNE: {
114                mTvInputSessionImpl.tune((Uri) msg.obj);
115                return;
116            }
117            case DO_SET_CAPTION_ENABLED: {
118                mTvInputSessionImpl.setCaptionEnabled((Boolean) msg.obj);
119                return;
120            }
121            case DO_SELECT_TRACK: {
122                mTvInputSessionImpl.selectTrack((TvTrackInfo) msg.obj);
123                return;
124            }
125            case DO_UNSELECT_TRACK: {
126                mTvInputSessionImpl.unselectTrack((TvTrackInfo) msg.obj);
127                return;
128            }
129            case DO_APP_PRIVATE_COMMAND: {
130                SomeArgs args = (SomeArgs) msg.obj;
131                mTvInputSessionImpl.appPrivateCommand((String) args.arg1, (Bundle) args.arg2);
132                args.recycle();
133                return;
134            }
135            case DO_CREATE_OVERLAY_VIEW: {
136                SomeArgs args = (SomeArgs) msg.obj;
137                mTvInputSessionImpl.createOverlayView((IBinder) args.arg1, (Rect) args.arg2);
138                args.recycle();
139                return;
140            }
141            case DO_RELAYOUT_OVERLAY_VIEW: {
142                mTvInputSessionImpl.relayoutOverlayView((Rect) msg.obj);
143                return;
144            }
145            case DO_REMOVE_OVERLAY_VIEW: {
146                mTvInputSessionImpl.removeOverlayView(true);
147                return;
148            }
149            case DO_REQUEST_UNBLOCK_CONTENT: {
150                mTvInputSessionImpl.requestUnblockContent((String) msg.obj);
151                return;
152            }
153            default: {
154                Log.w(TAG, "Unhandled message code: " + msg.what);
155                return;
156            }
157        }
158    }
159
160    @Override
161    public void release() {
162        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_RELEASE));
163    }
164
165    @Override
166    public void setMainSession(boolean isMain) {
167        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN_SESSION, isMain));
168    }
169
170    @Override
171    public void setSurface(Surface surface) {
172        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_SURFACE, surface));
173    }
174
175    @Override
176    public void dispatchSurfaceChanged(int format, int width, int height) {
177        mCaller.executeOrSendMessage(mCaller.obtainMessageIIII(DO_DISPATCH_SURFACE_CHANGED,
178                format, width, height, 0));
179    }
180
181    @Override
182    public final void setVolume(float volume) {
183        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_STREAM_VOLUME, volume));
184    }
185
186    @Override
187    public void tune(Uri channelUri) {
188        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TUNE, channelUri));
189    }
190
191    @Override
192    public void setCaptionEnabled(boolean enabled) {
193        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_CAPTION_ENABLED, enabled));
194    }
195
196    @Override
197    public void selectTrack(TvTrackInfo track) {
198        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SELECT_TRACK, track));
199    }
200
201    @Override
202    public void unselectTrack(TvTrackInfo track) {
203        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_UNSELECT_TRACK, track));
204    }
205
206    @Override
207    public void appPrivateCommand(String action, Bundle data) {
208        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_APP_PRIVATE_COMMAND, action,
209                data));
210    }
211
212    @Override
213    public void createOverlayView(IBinder windowToken, Rect frame) {
214        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_OVERLAY_VIEW, windowToken,
215                frame));
216    }
217
218    @Override
219    public void relayoutOverlayView(Rect frame) {
220        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RELAYOUT_OVERLAY_VIEW, frame));
221    }
222
223    @Override
224    public void removeOverlayView() {
225        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_OVERLAY_VIEW));
226    }
227
228    @Override
229    public void requestUnblockContent(String unblockedRating) {
230        mCaller.executeOrSendMessage(mCaller.obtainMessageO(
231                DO_REQUEST_UNBLOCK_CONTENT, unblockedRating));
232    }
233
234    private final class TvInputEventReceiver extends InputEventReceiver {
235        public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
236            super(inputChannel, looper);
237        }
238
239        @Override
240        public void onInputEvent(InputEvent event) {
241            if (mTvInputSessionImpl == null) {
242                // The session has been finished.
243                finishInputEvent(event, false);
244                return;
245            }
246
247            int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
248            if (handled != TvInputManager.Session.DISPATCH_IN_PROGRESS) {
249                finishInputEvent(event, handled == TvInputManager.Session.DISPATCH_HANDLED);
250            }
251        }
252    }
253}
254