blob: 3271d7b788e998f5af8b8c5ecd01c1c155ff947a [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media.tv.tuner;
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.util.List;
/**
* Tuner is used to interact with tuner devices.
*
* @hide
*/
public final class Tuner implements AutoCloseable {
private static final String TAG = "MediaTvTuner";
private static final boolean DEBUG = false;
private static final int MSG_ON_FRONTEND_EVENT = 1;
private static final int MSG_ON_FILTER_EVENT = 2;
private static final int MSG_ON_FILTER_STATUS = 3;
private static final int MSG_ON_LNB_EVENT = 4;
static {
System.loadLibrary("media_tv_tuner");
nativeInit();
}
private List<Integer> mFrontendIds;
private Frontend mFrontend;
private EventHandler mHandler;
private List<Integer> mLnbIds;
private Lnb mLnb;
public Tuner() {
nativeSetup();
}
private long mNativeContext; // used by native jMediaTuner
@Override
public void close() {}
/**
* Native Initialization.
*/
private static native void nativeInit();
/**
* Native setup.
*/
private native void nativeSetup();
/**
* Native method to get all frontend IDs.
*/
private native List<Integer> nativeGetFrontendIds();
/**
* Native method to open frontend of the given ID.
*/
private native Frontend nativeOpenFrontendById(int id);
private native Filter nativeOpenFilter(int type, int subType, int bufferSize);
private native List<Integer> nativeGetLnbIds();
private native Lnb nativeOpenLnbById(int id);
/**
* Frontend Callback.
*/
public interface FrontendCallback {
/**
* Invoked when there is a frontend event.
*/
void onEvent(int frontendEventType);
}
/**
* LNB Callback.
*/
public interface LnbCallback {
/**
* Invoked when there is a LNB event.
*/
void onEvent(int lnbEventType);
}
/**
* Frontend Callback.
*/
public interface FilterCallback {
/**
* Invoked when filter status changed.
*/
void onFilterStatus(int status);
}
@Nullable
private EventHandler createEventHandler() {
Looper looper;
if ((looper = Looper.myLooper()) != null) {
return new EventHandler(looper);
} else if ((looper = Looper.getMainLooper()) != null) {
return new EventHandler(looper);
}
return null;
}
private class EventHandler extends Handler {
private EventHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ON_FRONTEND_EVENT:
if (mFrontend != null && mFrontend.mCallback != null) {
mFrontend.mCallback.onEvent(msg.arg1);
}
break;
case MSG_ON_FILTER_STATUS: {
Filter filter = (Filter) msg.obj;
if (filter.mCallback != null) {
filter.mCallback.onFilterStatus(msg.arg1);
}
break;
}
case MSG_ON_LNB_EVENT: {
if (mLnb != null && mLnb.mCallback != null) {
mLnb.mCallback.onEvent(msg.arg1);
}
}
default:
// fall through
}
}
}
protected class Frontend {
private int mId;
private FrontendCallback mCallback;
private Frontend(int id) {
mId = id;
}
public void setCallback(@Nullable FrontendCallback callback, @Nullable Handler handler) {
mCallback = callback;
if (mCallback == null) {
return;
}
if (handler == null) {
// use default looper if handler is null
if (mHandler == null) {
mHandler = createEventHandler();
}
return;
}
Looper looper = handler.getLooper();
if (mHandler != null && mHandler.getLooper() == looper) {
// the same looper. reuse mHandler
return;
}
mHandler = new EventHandler(looper);
}
}
private List<Integer> getFrontendIds() {
mFrontendIds = nativeGetFrontendIds();
return mFrontendIds;
}
private Frontend openFrontendById(int id) {
if (mFrontendIds == null) {
mFrontendIds = getFrontendIds();
}
if (!mFrontendIds.contains(id)) {
return null;
}
mFrontend = nativeOpenFrontendById(id);
return mFrontend;
}
private void onFrontendEvent(int eventType) {
if (mHandler != null) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_FRONTEND_EVENT, eventType, 0));
}
}
protected class Filter {
private long mNativeContext;
private FilterCallback mCallback;
int mId;
private Filter(int id) {
mId = id;
}
private void onFilterStatus(int status) {
if (mHandler != null) {
mHandler.sendMessage(
mHandler.obtainMessage(MSG_ON_FILTER_STATUS, status, 0, this));
}
}
}
private Filter openFilter(int type, int subType, int bufferSize, FilterCallback cb) {
Filter filter = nativeOpenFilter(type, subType, bufferSize);
if (filter != null) {
filter.mCallback = cb;
if (mHandler == null) {
mHandler = createEventHandler();
}
}
return filter;
}
protected class Lnb {
private int mId;
private LnbCallback mCallback;
private Lnb(int id) {
mId = id;
}
public void setCallback(@Nullable LnbCallback callback) {
mCallback = callback;
if (mCallback == null) {
return;
}
if (mHandler == null) {
mHandler = createEventHandler();
}
}
}
private List<Integer> getLnbIds() {
mLnbIds = nativeGetLnbIds();
return mLnbIds;
}
private Lnb openLnbById(int id) {
if (mLnbIds == null) {
mLnbIds = getLnbIds();
}
if (!mLnbIds.contains(id)) {
return null;
}
mLnb = nativeOpenLnbById(id);
return mLnb;
}
private void onLnbEvent(int eventType) {
if (mHandler != null) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_LNB_EVENT, eventType, 0));
}
}
}