blob: 3ccccf391a756e1945cb697db83121b829350142 [file] [log] [blame]
Jae Seo39570912014-02-20 18:23:25 -08001/*
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.tv;
18
19import android.content.Context;
Youngsang Cho9a22f0f2014-04-09 22:51:54 +090020import android.graphics.Rect;
Jae Seo39570912014-02-20 18:23:25 -080021import android.net.Uri;
Youngsang Cho9a22f0f2014-04-09 22:51:54 +090022import android.os.IBinder;
Jae Seo6a6059a2014-04-17 21:35:29 -070023import android.os.Looper;
Jae Seo39570912014-02-20 18:23:25 -080024import android.os.Message;
Jae Seo6a6059a2014-04-17 21:35:29 -070025import android.tv.TvInputManager.Session;
Youngsang Cho674e9622014-04-15 11:19:41 -070026import android.tv.TvInputService.TvInputSessionImpl;
Jae Seo39570912014-02-20 18:23:25 -080027import android.util.Log;
Jae Seo6a6059a2014-04-17 21:35:29 -070028import android.view.InputChannel;
29import android.view.InputEvent;
30import android.view.InputEventReceiver;
31import android.view.KeyEvent;
32import android.view.MotionEvent;
Jae Seo39570912014-02-20 18:23:25 -080033import android.view.Surface;
34
35import com.android.internal.os.HandlerCaller;
Youngsang Cho9a22f0f2014-04-09 22:51:54 +090036import com.android.internal.os.SomeArgs;
Jae Seo39570912014-02-20 18:23:25 -080037
38/**
39 * Implements the internal ITvInputSession interface to convert incoming calls on to it back to
40 * calls on the public TvInputSession interface, scheduling them on the main thread of the process.
41 *
42 * @hide
43 */
44public class ITvInputSessionWrapper extends ITvInputSession.Stub implements HandlerCaller.Callback {
45 private static final String TAG = "TvInputSessionWrapper";
46
47 private static final int DO_RELEASE = 1;
48 private static final int DO_SET_SURFACE = 2;
49 private static final int DO_SET_VOLUME = 3;
50 private static final int DO_TUNE = 4;
Youngsang Cho9a22f0f2014-04-09 22:51:54 +090051 private static final int DO_CREATE_OVERLAY_VIEW = 5;
52 private static final int DO_RELAYOUT_OVERLAY_VIEW = 6;
53 private static final int DO_REMOVE_OVERLAY_VIEW = 7;
Jae Seo39570912014-02-20 18:23:25 -080054
Jae Seo39570912014-02-20 18:23:25 -080055 private final HandlerCaller mCaller;
56
Jae Seo6a6059a2014-04-17 21:35:29 -070057 private TvInputSessionImpl mTvInputSessionImpl;
58 private InputChannel mChannel;
59 private TvInputEventReceiver mReceiver;
60
61 public ITvInputSessionWrapper(Context context, TvInputSessionImpl sessionImpl,
62 InputChannel channel) {
Jae Seo39570912014-02-20 18:23:25 -080063 mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
Jae Seo6a6059a2014-04-17 21:35:29 -070064 mTvInputSessionImpl = sessionImpl;
65 mChannel = channel;
66 if (channel != null) {
67 mReceiver = new TvInputEventReceiver(channel, context.getMainLooper());
68 }
Jae Seo39570912014-02-20 18:23:25 -080069 }
70
71 @Override
72 public void executeMessage(Message msg) {
Jae Seo6a6059a2014-04-17 21:35:29 -070073 if (mTvInputSessionImpl == null) {
Jae Seo39570912014-02-20 18:23:25 -080074 return;
75 }
76
77 switch (msg.what) {
78 case DO_RELEASE: {
Jae Seo6a6059a2014-04-17 21:35:29 -070079 mTvInputSessionImpl.release();
80 mTvInputSessionImpl = null;
81 if (mReceiver != null) {
82 mReceiver.dispose();
83 mReceiver = null;
84 }
85 if (mChannel != null) {
86 mChannel.dispose();
87 mChannel = null;
88 }
Jae Seo39570912014-02-20 18:23:25 -080089 return;
90 }
91 case DO_SET_SURFACE: {
Jae Seo6a6059a2014-04-17 21:35:29 -070092 mTvInputSessionImpl.setSurface((Surface) msg.obj);
Jae Seo39570912014-02-20 18:23:25 -080093 return;
94 }
95 case DO_SET_VOLUME: {
Jae Seo6a6059a2014-04-17 21:35:29 -070096 mTvInputSessionImpl.setVolume((Float) msg.obj);
Jae Seo39570912014-02-20 18:23:25 -080097 return;
98 }
99 case DO_TUNE: {
Jae Seo6a6059a2014-04-17 21:35:29 -0700100 mTvInputSessionImpl.tune((Uri) msg.obj);
Jae Seo39570912014-02-20 18:23:25 -0800101 return;
102 }
Youngsang Cho9a22f0f2014-04-09 22:51:54 +0900103 case DO_CREATE_OVERLAY_VIEW: {
104 SomeArgs args = (SomeArgs) msg.obj;
Jae Seo6a6059a2014-04-17 21:35:29 -0700105 mTvInputSessionImpl.createOverlayView((IBinder) args.arg1, (Rect) args.arg2);
Youngsang Cho9a22f0f2014-04-09 22:51:54 +0900106 args.recycle();
107 return;
108 }
109 case DO_RELAYOUT_OVERLAY_VIEW: {
Jae Seo6a6059a2014-04-17 21:35:29 -0700110 mTvInputSessionImpl.relayoutOverlayView((Rect) msg.obj);
Youngsang Cho9a22f0f2014-04-09 22:51:54 +0900111 return;
112 }
113 case DO_REMOVE_OVERLAY_VIEW: {
Jae Seo6a6059a2014-04-17 21:35:29 -0700114 mTvInputSessionImpl.removeOverlayView(true);
Youngsang Cho9a22f0f2014-04-09 22:51:54 +0900115 return;
116 }
Jae Seo39570912014-02-20 18:23:25 -0800117 default: {
118 Log.w(TAG, "Unhandled message code: " + msg.what);
119 return;
120 }
121 }
122 }
123
124 @Override
125 public void release() {
126 mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_RELEASE));
127 }
128
129 @Override
130 public void setSurface(Surface surface) {
131 mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_SURFACE, surface));
132 }
133
134 @Override
135 public final void setVolume(float volume) {
136 mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_VOLUME, volume));
137 }
138
139 @Override
140 public void tune(Uri channelUri) {
141 mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TUNE, channelUri));
142 }
Youngsang Cho9a22f0f2014-04-09 22:51:54 +0900143
144 @Override
145 public void createOverlayView(IBinder windowToken, Rect frame) {
146 mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_OVERLAY_VIEW, windowToken,
147 frame));
148 }
149
150 @Override
151 public void relayoutOverlayView(Rect frame) {
152 mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RELAYOUT_OVERLAY_VIEW, frame));
153 }
154
155 @Override
156 public void removeOverlayView() {
157 mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_OVERLAY_VIEW));
158 }
Jae Seo6a6059a2014-04-17 21:35:29 -0700159
160 private final class TvInputEventReceiver extends InputEventReceiver {
161 public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
162 super(inputChannel, looper);
163 }
164
165 @Override
166 public void onInputEvent(InputEvent event) {
167 if (mTvInputSessionImpl == null) {
168 // The session has been finished.
169 finishInputEvent(event, false);
170 return;
171 }
172
173 int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
174 if (handled != Session.DISPATCH_IN_PROGRESS) {
175 finishInputEvent(event, handled == Session.DISPATCH_HANDLED);
176 }
177 }
178 }
Jae Seo39570912014-02-20 18:23:25 -0800179}