TvInputHal.java revision d5cc4a281e7ce29d1e8687ff3394b57a3a549260
1/*
2 * Copyright 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 com.android.server.tv;
18
19import android.media.tv.TvInputHardwareInfo;
20import android.media.tv.TvStreamConfig;
21import android.os.Handler;
22import android.os.HandlerThread;
23import android.view.Surface;
24
25/**
26 * Provides access to the low-level TV input hardware abstraction layer.
27 */
28final class TvInputHal {
29    public final static int SUCCESS = 0;
30    public final static int ERROR_NO_INIT = -1;
31    public final static int ERROR_STALE_CONFIG = -2;
32    public final static int ERROR_UNKNOWN = -3;
33
34    public static final int TYPE_HDMI = 1;
35    public static final int TYPE_BUILT_IN_TUNER = 2;
36    public static final int TYPE_PASSTHROUGH = 3;
37
38    public interface Callback {
39        public void onDeviceAvailable(
40                TvInputHardwareInfo info, TvStreamConfig[] configs);
41        public void onDeviceUnavailable(int deviceId);
42        public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
43    }
44
45    private native long nativeOpen();
46
47    private static native int nativeSetSurface(long ptr, int deviceId, int streamId,
48            Surface surface);
49    private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId,
50            int generation);
51    private static native void nativeClose(long ptr);
52
53    private long mPtr = 0l;
54    private final Callback mCallback;
55    private final HandlerThread mThread = new HandlerThread("TV input HAL event thread");
56    private final Handler mHandler;
57    private int mStreamConfigGeneration = 0;
58    private TvStreamConfig[] mStreamConfigs;
59
60    public TvInputHal(Callback callback) {
61        mCallback = callback;
62        mThread.start();
63        mHandler = new Handler(mThread.getLooper());
64    }
65
66    public void init() {
67        mPtr = nativeOpen();
68    }
69
70    public int setSurface(int deviceId, Surface surface, TvStreamConfig streamConfig) {
71        if (mPtr == 0) {
72            return ERROR_NO_INIT;
73        }
74        if (mStreamConfigGeneration != streamConfig.getGeneration()) {
75            return ERROR_STALE_CONFIG;
76        }
77        if (nativeSetSurface(mPtr, deviceId, streamConfig.getStreamId(), surface) == 0) {
78            return SUCCESS;
79        } else {
80            return ERROR_UNKNOWN;
81        }
82    }
83
84    public void close() {
85        if (mPtr != 0l) {
86            nativeClose(mPtr);
87            mThread.quitSafely();
88        }
89    }
90
91    private synchronized void retrieveStreamConfigs(int deviceId) {
92        ++mStreamConfigGeneration;
93        mStreamConfigs = nativeGetStreamConfigs(mPtr, deviceId, mStreamConfigGeneration);
94    }
95
96    // Called from native
97    private void deviceAvailableFromNative(int deviceId, int type) {
98        final TvInputHardwareInfo info = new TvInputHardwareInfo(deviceId, type);
99        mHandler.post(new Runnable() {
100            @Override
101            public void run() {
102                retrieveStreamConfigs(info.getDeviceId());
103                mCallback.onDeviceAvailable(info, mStreamConfigs);
104            }
105        });
106    }
107
108    private void deviceUnavailableFromNative(int deviceId) {
109        final int id = deviceId;
110        mHandler.post(new Runnable() {
111            @Override
112            public void run() {
113                mCallback.onDeviceUnavailable(id);
114            }
115        });
116    }
117
118    private void streamConfigsChangedFromNative(int deviceId) {
119        final int id = deviceId;
120        mHandler.post(new Runnable() {
121            @Override
122            public void run() {
123                retrieveStreamConfigs(id);
124                mCallback.onStreamConfigurationChanged(id, mStreamConfigs);
125            }
126        });
127    }
128}
129