Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 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 | |
| 17 | package android.tv; |
| 18 | |
| 19 | import android.content.Context; |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 20 | import android.graphics.Rect; |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 21 | import android.net.Uri; |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 22 | import android.os.IBinder; |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 23 | import android.os.Looper; |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 24 | import android.os.Message; |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 25 | import android.tv.TvInputManager.Session; |
Youngsang Cho | 674e962 | 2014-04-15 11:19:41 -0700 | [diff] [blame] | 26 | import android.tv.TvInputService.TvInputSessionImpl; |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 27 | import android.util.Log; |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 28 | import android.view.InputChannel; |
| 29 | import android.view.InputEvent; |
| 30 | import android.view.InputEventReceiver; |
| 31 | import android.view.KeyEvent; |
| 32 | import android.view.MotionEvent; |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 33 | import android.view.Surface; |
| 34 | |
| 35 | import com.android.internal.os.HandlerCaller; |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 36 | import com.android.internal.os.SomeArgs; |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 37 | |
| 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 | */ |
| 44 | public 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 Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 51 | 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 Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 54 | |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 55 | private final HandlerCaller mCaller; |
| 56 | |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 57 | private TvInputSessionImpl mTvInputSessionImpl; |
| 58 | private InputChannel mChannel; |
| 59 | private TvInputEventReceiver mReceiver; |
| 60 | |
| 61 | public ITvInputSessionWrapper(Context context, TvInputSessionImpl sessionImpl, |
| 62 | InputChannel channel) { |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 63 | mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */); |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 64 | mTvInputSessionImpl = sessionImpl; |
| 65 | mChannel = channel; |
| 66 | if (channel != null) { |
| 67 | mReceiver = new TvInputEventReceiver(channel, context.getMainLooper()); |
| 68 | } |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | @Override |
| 72 | public void executeMessage(Message msg) { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 73 | if (mTvInputSessionImpl == null) { |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 74 | return; |
| 75 | } |
| 76 | |
| 77 | switch (msg.what) { |
| 78 | case DO_RELEASE: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 79 | 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 Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 89 | return; |
| 90 | } |
| 91 | case DO_SET_SURFACE: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 92 | mTvInputSessionImpl.setSurface((Surface) msg.obj); |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 93 | return; |
| 94 | } |
| 95 | case DO_SET_VOLUME: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 96 | mTvInputSessionImpl.setVolume((Float) msg.obj); |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 97 | return; |
| 98 | } |
| 99 | case DO_TUNE: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 100 | mTvInputSessionImpl.tune((Uri) msg.obj); |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 101 | return; |
| 102 | } |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 103 | case DO_CREATE_OVERLAY_VIEW: { |
| 104 | SomeArgs args = (SomeArgs) msg.obj; |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 105 | mTvInputSessionImpl.createOverlayView((IBinder) args.arg1, (Rect) args.arg2); |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 106 | args.recycle(); |
| 107 | return; |
| 108 | } |
| 109 | case DO_RELAYOUT_OVERLAY_VIEW: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 110 | mTvInputSessionImpl.relayoutOverlayView((Rect) msg.obj); |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 111 | return; |
| 112 | } |
| 113 | case DO_REMOVE_OVERLAY_VIEW: { |
Jae Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 114 | mTvInputSessionImpl.removeOverlayView(true); |
Youngsang Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 115 | return; |
| 116 | } |
Jae Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 117 | 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 Cho | 9a22f0f | 2014-04-09 22:51:54 +0900 | [diff] [blame] | 143 | |
| 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 Seo | 6a6059a | 2014-04-17 21:35:29 -0700 | [diff] [blame^] | 159 | |
| 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 Seo | 3957091 | 2014-02-20 18:23:25 -0800 | [diff] [blame] | 179 | } |