summaryrefslogtreecommitdiff
authorTellen Yu <tellen.yu@amlogic.com>2018-01-19 08:04:33 (GMT)
committer Tellen Yu <tellen.yu@amlogic.com>2018-01-29 05:23:49 (GMT)
commit334498d01acf41a5093348cffdc8dff3dfcea53f (patch)
tree3d9dc93fee3f789b5f2c2698adadbaed8b9ccdf1
parentd946a3cc75b4d9bd5a71da14b1c8d90398756f87 (diff)
downloadtv-334498d01acf41a5093348cffdc8dff3dfcea53f.zip
tv-334498d01acf41a5093348cffdc8dff3dfcea53f.tar.gz
tv-334498d01acf41a5093348cffdc8dff3dfcea53f.tar.bz2
tvinput: add porting tvinput to HIDL architecture [1/12]
PD# 157786 need use hwbinder instead of binder for RPC since from O Change-Id: I7f8084d3152546e2d90ad77c9408bb47cbc5befc
Diffstat
-rw-r--r--core/java/Android.mk23
-rw-r--r--core/java/com/droidlogic/app/tv/TvControlManager.java411
-rw-r--r--core/java/droidlogic.tv.software.core.xml20
-rw-r--r--core/jni/Android.mk22
-rw-r--r--core/jni/com_droidlogic_app_tv_TvControlManager.cpp75
-rw-r--r--libtvbinder/Android.mk34
-rw-r--r--libtvbinder/TvServerHidlClient.cpp270
-rw-r--r--libtvbinder/include/TvServerHidlClient.h122
8 files changed, 780 insertions, 197 deletions
diff --git a/core/java/Android.mk b/core/java/Android.mk
index 3281309..3303724 100644
--- a/core/java/Android.mk
+++ b/core/java/Android.mk
@@ -17,4 +17,27 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
LOCAL_PROPRIETARY_MODULE := true
endif
+LOCAL_JAVA_LIBRARIES += \
+ android.hidl.base-V1.0-java \
+ android.hidl.manager-V1.0-java
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ vendor.amlogic.hardware.tvserver-V1.0-java
+
include $(BUILD_JAVA_LIBRARY)
+
+#copy xml to permissions directory
+include $(CLEAR_VARS)
+LOCAL_MODULE := droidlogic.tv.software.core.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/permissions
+else
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+endif
+
+include $(BUILD_PREBUILT) \ No newline at end of file
diff --git a/core/java/com/droidlogic/app/tv/TvControlManager.java b/core/java/com/droidlogic/app/tv/TvControlManager.java
index 0749ae0..c334d8d 100644
--- a/core/java/com/droidlogic/app/tv/TvControlManager.java
+++ b/core/java/com/droidlogic/app/tv/TvControlManager.java
@@ -1,15 +1,5 @@
package com.droidlogic.app.tv;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -20,31 +10,51 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
-import android.os.SystemProperties;
-
-import android.util.Log;
-import android.view.View;
-import android.view.Surface;
-import android.view.SurfaceHolder;
+import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.media.tv.TvContract;
import android.os.Build;
import android.os.Handler;
+import android.os.HwBinder;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
-import android.graphics.Matrix;
-
-import android.media.tv.TvContract;
+import android.os.RemoteException;
+import android.os.SystemProperties;
import android.text.TextUtils;
-//import android.media.audiofx.Srs;
-//import android.media.audiofx.Hpeq;
+import android.util.Log;
+import android.view.View;
+import android.view.Surface;
+import android.view.SurfaceHolder;
import static com.droidlogic.app.tv.TvControlCommand.*;
import com.droidlogic.app.tv.EasEvent;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import vendor.amlogic.hardware.tvserver.V1_0.ITvServer;
+import vendor.amlogic.hardware.tvserver.V1_0.ITvServerCallback;
+import vendor.amlogic.hardware.tvserver.V1_0.SignalInfo;
+import vendor.amlogic.hardware.tvserver.V1_0.TvHidlParcel;
+import vendor.amlogic.hardware.tvserver.V1_0.ConnectType;
+import vendor.amlogic.hardware.tvserver.V1_0.Result;
+
public class TvControlManager {
private static final String TAG = "TvControlManager";
private static final String OPEN_TV_LOG_FLG = "open.libtv.log.flg";
@@ -130,7 +140,7 @@ public class TvControlManager {
private native final void native_setup(Object tv_this);
private native final void native_release();
- public native void addCallbackBuffer(byte cb[]);
+ //public native void addCallbackBuffer(byte cb[]);
public native final void unlock();
public native final void lock();
public native final void reconnect() throws IOException;
@@ -153,12 +163,16 @@ public class TvControlManager {
private int sendCmdToTv(Parcel p, Parcel r) {
p.setDataPosition(0);
+
+ Log.i(TAG, "sendCmdToTv cmd:" + p.readInt());
+
int ret = processCmd(p, r);
r.setDataPosition(0);
return ret;
}
public int sendCmd(int cmd) {
+ Log.i(TAG, "sendCmd cmd:" + cmd);
libtv_log_open();
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -174,6 +188,7 @@ public class TvControlManager {
}
public int sendCmdIntArray(int cmd, int[] values) {
+ Log.i(TAG, "sendCmdIntArray cmd:" + cmd);
libtv_log_open();
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -192,6 +207,7 @@ public class TvControlManager {
}
public int sendCmdFloatArray(int cmd, float[] values) {
+ Log.i(TAG, "sendCmdFloatArray cmd:" + cmd);
libtv_log_open();
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -211,6 +227,7 @@ public class TvControlManager {
}
public int sendCmdStringArray(int cmd, String[] values) {
+ Log.i(TAG, "sendCmdStringArray cmd:" + cmd);
libtv_log_open();
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -230,6 +247,7 @@ public class TvControlManager {
}
public int sendCmdStringArray(int cmd, int id, String[] values) {
+ Log.i(TAG, "sendCmdStringArray cmd:" + cmd + " id:" + id);
libtv_log_open();
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -362,7 +380,58 @@ public class TvControlManager {
int i = 0, loop_count = 0, tmp_val = 0;
Parcel p;
+ TvHidlParcel parcel = ((TvHidlParcel) (msg.obj));
switch (msg.what) {
+ case DTV_AV_PLAYBACK_CALLBACK:
+ if (mAVPlaybackListener != null) {
+ int msgType= parcel.bodyInt.get(0);
+ int programID= parcel.bodyInt.get(1);
+ mAVPlaybackListener.onEvent(msgType, programID);
+ }
+ break;
+ case SOURCE_CONNECT_CALLBACK:
+ if (mSourceConnectChangeListener != null) {
+ mSourceConnectChangeListener.onSourceConnectChange(SourceInput.values()[parcel.bodyInt.get(0)], parcel.bodyInt.get(1));
+ }
+ break;
+
+ case SCAN_EVENT_CALLBACK:
+ p = ((Parcel) (msg.obj));
+ ScannerEvent scan_ev = new ScannerEvent();
+ readScanEvent(scan_ev, p);
+ if (mScannerListener != null)
+ mScannerListener.onEvent(scan_ev);
+ if (mStorDBListener != null)
+ mStorDBListener.StorDBonEvent(scan_ev);
+ break;
+
+ case RRT_EVENT_CALLBACK:
+ p = ((Parcel) (msg.obj));
+ if (mRrtListener != null) {
+ int result = p.readInt();
+ Log.e(TAG, "RRT_EVENT_CALLBACK:" + result);
+ rrt5XmlLoadStatus = result;
+ mRrtListener.onRRT5InfoUpdated(result);
+ }
+ break;
+
+ case EAS_EVENT_CALLBACK:
+ Log.i(TAG,"get EAS_event_callBack");
+ p = ((Parcel) (msg.obj));
+ if (mEasListener != null) {
+ Log.i(TAG,"mEaslister is not null");
+ int sectionCount = p.readInt();
+ Log.i(TAG,"eas section count = "+sectionCount);
+ for (int count = 0; count<sectionCount; count++) {
+ EasEvent curEasEvent = new EasEvent();
+ curEasEvent.readEasEvent(p);
+ if (easManager.isEasEventNeedProcess(curEasEvent)) {
+ mEasListener.processDetailsChannelAlert(curEasEvent);
+ }
+ }
+ }
+ break;
+
case SUBTITLE_UPDATE_CALLBACK:
if (mSubtitleListener != null) {
mSubtitleListener.onUpdate();
@@ -379,23 +448,7 @@ public class TvControlManager {
ev.FrameHeight= p.readInt();
}
break;
- case SCAN_EVENT_CALLBACK:
- p = ((Parcel) (msg.obj));
- if (mScannerListener != null) {
- ScannerEvent scan_ev = new ScannerEvent();
- readScanEvent(scan_ev, p);
- mScannerListener.onEvent(scan_ev);
- if (mStorDBListener != null) {
- mStorDBListener.StorDBonEvent(scan_ev);
- }
- }else if (mStorDBListener != null) {
- ScannerEvent scan_ev = new ScannerEvent();
- readScanEvent(scan_ev, p);
- mStorDBListener.StorDBonEvent(scan_ev);
- }
- if (mStorDBListener == null)
- Log.d(TAG,"mStorDBListener is null !!!");
- break;
+
case SCANNING_FRAME_STABLE_CALLBACK:
p = ((Parcel) (msg.obj));
if (mScanningFrameStableListener != null) {
@@ -418,14 +471,6 @@ public class TvControlManager {
mEpgListener.onEvent(ev);
}
break;
- case DTV_AV_PLAYBACK_CALLBACK:
- p = ((Parcel) (msg.obj));
- if (mAVPlaybackListener != null) {
- int msgType= p.readInt();
- int programID= p.readInt();
- mAVPlaybackListener.onEvent(msgType, programID);
- }
- break ;
case SEARCH_CALLBACK:
if (mSigChanSearchListener != null) {
if (msgPdu != null) {
@@ -454,11 +499,6 @@ public class TvControlManager {
mStatus3DChangeListener.onStatus3DChange(((Parcel) (msg.obj)).readInt());
}
break;
- case SOURCE_CONNECT_CALLBACK:
- if (mSourceConnectChangeListener != null) {
- mSourceConnectChangeListener.onSourceConnectChange( SourceInput.values()[((Parcel) (msg.obj)).readInt()], ((Parcel) (msg.obj)).readInt());
- }
- break;
case HDMIRX_CEC_CALLBACK:
if (mHDMIRxCECListener != null) {
if (msgPdu != null) {
@@ -542,34 +582,6 @@ public class TvControlManager {
mRecorderEventListener.onRecoderEvent(ev);
}
break;
-
- case RRT_EVENT_CALLBACK:
- p = ((Parcel) (msg.obj));
- if (mRrtListener != null) {
- int result = p.readInt();
- Log.e(TAG, "RRT_EVENT_CALLBACK:" + result);
- rrt5XmlLoadStatus = result;
- mRrtListener.onRRT5InfoUpdated(result);
- }
- break;
-
- case EAS_EVENT_CALLBACK:
- Log.i(TAG,"get EAS_event_callBack");
- p = ((Parcel) (msg.obj));
- if (mEasListener != null) {
- Log.i(TAG,"mEaslister is not null");
- int sectionCount = p.readInt();
- Log.i(TAG,"eas section count = "+sectionCount);
- for (int count = 0; count<sectionCount; count++) {
- EasEvent curEasEvent = new EasEvent();
- curEasEvent.readEasEvent(p);
- if (easManager.isEasEventNeedProcess(curEasEvent)) {
- mEasListener.processDetailsChannelAlert(curEasEvent);
- }
- }
- }
-
- break;
default:
Log.e(TAG, "Unknown message type " + msg.what);
break;
@@ -583,20 +595,193 @@ public class TvControlManager {
}
public TvControlManager() {
- Looper looper;
- if ((looper = Looper.myLooper()) != null) {
+ Looper looper = Looper.myLooper();
+ if (looper != null) {
mEventHandler = new EventHandler(looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(looper);
} else {
mEventHandler = null;
+ Log.e(TAG, "looper is null, so can not do anything");
}
- native_setup(new WeakReference<TvControlManager>(this));
- String LogFlg = TvMiscConfigGet(OPEN_TV_LOG_FLG,null);
- if ("log_open".equals(TvMiscConfigGet(OPEN_TV_LOG_FLG,null)))
+ mHALCallback = new HALCallback(this);
+ //native_setup(new WeakReference<TvControlManager>(this));
+
+ try {
+ boolean ret = IServiceManager.getService()
+ .registerForNotifications("vendor.amlogic.hardware.tvserver@1.0::ITvServer", "", mServiceNotification);
+ if (!ret) {
+ Log.e(TAG, "Failed to register service start notification");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register service start notification", e);
+ }
+ connectToProxy();
+
+ String LogFlg = TvMiscConfigGet(OPEN_TV_LOG_FLG, "");
+ if ("log_open".equals(LogFlg))
tvLogFlg =true;
}
+ private static final int TVSERVER_DEATH_COOKIE = 1000;
+
+ // Callback when the UsbPort status is changed by the kernel.
+ // Mostly due a command sent by the remote Usb device.
+ private HALCallback mHALCallback;
+
+ // Notification object used to listen to the start of the tvserver daemon.
+ private final ServiceNotification mServiceNotification = new ServiceNotification();
+
+ private ITvServer mProxy = null;
+ // Mutex for all mutable shared state.
+ private final Object mLock = new Object();
+
+ private void connectToProxy() {
+ synchronized (mLock) {
+ if (mProxy != null) {
+ return;
+ }
+
+ try {
+ mProxy = ITvServer.getService();
+ mProxy.linkToDeath(new DeathRecipient(), TVSERVER_DEATH_COOKIE);
+ mProxy.setCallback(mHALCallback, ConnectType.TYPE_EXTEND);
+ } catch (NoSuchElementException e) {
+ Log.e(TAG, "connectToProxy: tvserver HIDL service not found."
+ + " Did the service fail to start?", e);
+ } catch (RemoteException e) {
+ Log.e(TAG, "connectToProxy: tvserver HIDL service not responding", e);
+ }
+ }
+
+ Log.i(TAG, "connect to tvserve HIDL service success");
+ }
+
+ public String getSupportInputDevices() {
+ synchronized (mLock) {
+ Mutable<String> resultVal = new Mutable<>();
+ try {
+ mProxy.getSupportInputDevices((int ret, String v) -> {
+ resultVal.value = v;
+ });
+ return resultVal.value;
+ } catch (RemoteException e) {
+ Log.e(TAG, "getSupportInputDevices:" + e);
+ }
+ }
+ return "";
+ }
+
+ /**
+ * @Function: GetCurrentSignalInfo
+ * @Description: Get current signal infomation
+ * @Param:
+ * @Return: refer to class tvin_info_t
+ */
+ public TVInSignalInfo GetCurrentSignalInfo() {
+ synchronized (mLock) {
+ TVInSignalInfo info = new TVInSignalInfo();
+ try {
+ SignalInfo hidlInfo = mProxy.getCurSignalInfo();
+ info.transFmt = TVInSignalInfo.TransFmt.values()[hidlInfo.transFmt];
+ info.sigFmt = TVInSignalInfo.SignalFmt.valueOf(hidlInfo.fmt);
+ info.sigStatus = TVInSignalInfo.SignalStatus.values()[hidlInfo.status];
+ info.reserved = hidlInfo.frameRate;
+ return info;
+ } catch (RemoteException e) {
+ Log.e(TAG, "GetCurrentSignalInfo:" + e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @Function: TvMiscConfigSet
+ * @Description: Set tv config
+ * @Param: key_str tv config name string, value_str tv config set value string
+ * @Return: 0 success, -1 fail
+ */
+ public int TvMiscConfigSet(String key_str, String value_str) {
+ synchronized (mLock) {
+ try {
+ return mProxy.setMiscCfg(key_str, value_str);
+ } catch (RemoteException e) {
+ Log.e(TAG, "TvMiscConfigSet:" + e);
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * @Function: TvMiscConfigGet
+ * @Description: Get tv config
+ * @Param: key_str tv config name string, value_str tv config get value string
+ * @Return: 0 success, -1 fail
+ */
+ public String TvMiscConfigGet(String key_str, String def_str) {
+ synchronized (mLock) {
+ try {
+ return mProxy.getMiscCfg(key_str, def_str);
+ } catch (RemoteException e) {
+ Log.e(TAG, "TvMiscConfigGet:" + e);
+ }
+ }
+ return "";
+ }
+
+ private static class Mutable<E> {
+ public E value;
+
+ Mutable() {
+ value = null;
+ }
+
+ Mutable(E value) {
+ this.value = value;
+ }
+ }
+
+ private static class HALCallback extends ITvServerCallback.Stub {
+ TvControlManager tvCtrlMgr;
+ HALCallback(TvControlManager tcm) {
+ tvCtrlMgr = tcm;
+ }
+
+ public void notifyCallback(TvHidlParcel parcel) {
+ Log.i(TAG, "notifyCallback msg type:" + parcel.msgType);
+
+ if (tvCtrlMgr.mEventHandler != null) {
+ Message msg = tvCtrlMgr.mEventHandler.obtainMessage(parcel.msgType, 0, 0, parcel);
+ tvCtrlMgr.mEventHandler.sendMessage(msg);
+ }
+ }
+ }
+
+ final class DeathRecipient implements HwBinder.DeathRecipient {
+ DeathRecipient() {
+ }
+
+ @Override
+ public void serviceDied(long cookie) {
+ if (TVSERVER_DEATH_COOKIE == cookie) {
+ Log.e(TAG, "tvserver HIDL service died cookie: " + cookie);
+ synchronized (mLock) {
+ mProxy = null;
+ }
+ }
+ }
+ }
+
+ final class ServiceNotification extends IServiceNotification.Stub {
+ @Override
+ public void onRegistration(String fqName, String name, boolean preexisting) {
+ Log.i(TAG, "tvserver HIDL service started " + fqName + " " + name);
+ connectToProxy();
+ }
+ }
+
+
protected void finalize() {
//native_release();
}
@@ -766,28 +951,6 @@ public class TvControlManager {
}
/**
- * @Function: GetCurrentSignalInfo
- * @Description: Get current signal infomation
- * @Param:
- * @Return: refer to class tvin_info_t
- */
- public TVInSignalInfo GetCurrentSignalInfo() {
- libtv_log_open();
- Parcel cmd = Parcel.obtain();
- Parcel r = Parcel.obtain();
- cmd.writeInt(GET_CURRENT_SIGNAL_INFO);
- sendCmdToTv(cmd, r);
- TVInSignalInfo info = new TVInSignalInfo();
- info.transFmt = TVInSignalInfo.TransFmt.values()[r.readInt()];
- info.sigFmt = TVInSignalInfo.SignalFmt.valueOf(r.readInt());
- info.sigStatus = TVInSignalInfo.SignalStatus.values()[r.readInt()];
- info.reserved = r.readInt();
- cmd.recycle();
- r.recycle();
- return info;
- }
-
- /**
* @Function: SetSourceInput
* @Description: Set source input to switch source,
* @Param: source_input, refer to enum SourceInput; win_pos, refer to class window_pos_t
@@ -3575,36 +3738,6 @@ public class TvControlManager {
// SSM END
//MISC
- /**
- * @Function: TvMiscConfigSet
- * @Description: Set tv config
- * @Param: key_str tv config name string, value_str tv config set value string
- * @Return: 0 success, -1 fail
- */
- public int TvMiscConfigSet(String key_str, String value_str) {
- String val[] = new String[]{key_str, value_str};
- return sendCmdStringArray(MISC_CFG_SET, val);
- }
-
- /**
- * @Function: TvMiscConfigGet
- * @Description: Get tv config
- * @Param: key_str tv config name string, value_str tv config get value string
- * @Return: 0 success, -1 fail
- */
- public String TvMiscConfigGet(String key_str, String def_str) {
- libtv_log_open();
- Parcel cmd = Parcel.obtain();
- Parcel r = Parcel.obtain();
- cmd.writeInt(MISC_CFG_GET);
- cmd.writeString(key_str);
- cmd.writeString(def_str);
- sendCmdToTv(cmd, r);
- String str = r.readString();
- cmd.recycle();
- r.recycle();
- return str;
- }
/**
* @Function: TvMiscSetGPIOCtrl
@@ -5582,10 +5715,10 @@ public class TvControlManager {
}
private void libtv_log_open(){
- if (tvLogFlg) {
+ //if (tvLogFlg) {
StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
Log.i(TAG, traceElement.getMethodName());
- }
+ //}
}
public enum LEFT_RIGHT_SOUND_CHANNEL {
diff --git a/core/java/droidlogic.tv.software.core.xml b/core/java/droidlogic.tv.software.core.xml
new file mode 100644
index 0000000..4c4d8b1
--- a/dev/null
+++ b/core/java/droidlogic.tv.software.core.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<permissions>
+ <library name="droidlogic.tv.software.core"
+ file="/vendor/framework/droidlogic-tv.jar" />
+</permissions>
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index e5c68a1..4f61c68 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -6,17 +6,19 @@ LOCAL_MODULE_TAGS := optional
LIB_TV_BINDER_PATH := $(wildcard $(BOARD_AML_VENDOR_PATH)/tv/frameworks/libtvbinder)
LOCAL_SRC_FILES:= \
- com_droidlogic_app_tv_TvControlManager.cpp
+ com_droidlogic_app_tv_TvControlManager.cpp
+
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libtvbinder \
- libnativehelper \
- libandroid_runtime \
- liblog \
- libskia \
- libhardware
+ vendor.amlogic.hardware.tvserver@1.0_vendor \
+ libcutils \
+ libutils \
+ libbinder \
+ libtvbinder \
+ libnativehelper \
+ libandroid_runtime \
+ liblog \
+ libskia \
+ libhardware
LOCAL_C_INCLUDES += \
frameworks/base/core/jni \
diff --git a/core/jni/com_droidlogic_app_tv_TvControlManager.cpp b/core/jni/com_droidlogic_app_tv_TvControlManager.cpp
index 5e5ba4b..b0b2da0 100644
--- a/core/jni/com_droidlogic_app_tv_TvControlManager.cpp
+++ b/core/jni/com_droidlogic_app_tv_TvControlManager.cpp
@@ -6,7 +6,6 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/Vector.h>
-#include "TvClient.h"
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <binder/MemoryHeapBase.h>
@@ -20,6 +19,8 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include "TvServerHidlClient.h"
+
using namespace android;
struct fields_t {
@@ -31,14 +32,14 @@ static fields_t fields;
static Mutex sLock;
class JNITvContext: public TvListener {
public:
- JNITvContext(JNIEnv *env, jobject weak_this, jclass clazz, const sp<TvClient> &tv);
+ JNITvContext(JNIEnv *env, jobject weak_this, jclass clazz, const sp<TvServerHidlClient> &tv);
~JNITvContext()
{
release();
}
- virtual void notify(int32_t msgType, const Parcel &p);
+ virtual void notify(const tv_parcel_t &parcel);
void addCallbackBuffer(JNIEnv *env, jbyteArray cbb);
- sp<TvClient> getTv()
+ sp<TvServerHidlClient> getTv()
{
Mutex::Autolock _l(mLock);
return mTv;
@@ -50,7 +51,7 @@ public:
private:
jobject mTvJObjectWeak; // weak reference to java object
jclass mTvJClass; // strong reference to java class
- sp<TvClient> mTv; // strong reference to native object
+ sp<TvServerHidlClient> mTv; // strong reference to native object
Mutex mLock;
Vector<jbyteArray> mCallbackBuffers; // Global reference application managed byte[]
@@ -64,9 +65,9 @@ private:
#define CAPTURE_MAX_BITMAP_W 1920
#define CAPTURE_MAX_BITMAP_H 1080
-sp<TvClient> get_native_tv(JNIEnv *env, jobject thiz, JNITvContext **pContext)
+sp<TvServerHidlClient> get_native_tv(JNIEnv *env, jobject thiz, JNITvContext **pContext)
{
- sp<TvClient> tv;
+ sp<TvServerHidlClient> tv = nullptr;
Mutex::Autolock _l(sLock);
JNITvContext *context = reinterpret_cast<JNITvContext *>(env->GetLongField(thiz, fields.context));
if (context != NULL) {
@@ -80,7 +81,7 @@ sp<TvClient> get_native_tv(JNIEnv *env, jobject thiz, JNITvContext **pContext)
return tv;
}
-JNITvContext::JNITvContext(JNIEnv *env, jobject weak_this, jclass clazz, const sp<TvClient> &tv)
+JNITvContext::JNITvContext(JNIEnv *env, jobject weak_this, jclass clazz, const sp<TvServerHidlClient> &tv)
{
mTvJObjectWeak = env->NewGlobalRef(weak_this);
mTvJClass = (jclass)env->NewGlobalRef(clazz);
@@ -116,20 +117,19 @@ void JNITvContext::release()
// connect to tv service
static void com_droidlogic_app_tv_TvControlManager_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
- sp<TvClient> tv = TvClient::connect();
-
ALOGD("com_droidlogic_app_tv_TvControlManager_native_setup.");
- if (tv == NULL) {
+ sp<TvServerHidlClient> tv = TvServerHidlClient::connect(CONNECT_TYPE_EXTEND);
+ if (tv == nullptr) {
jniThrowException(env, "java/lang/RuntimeException", "Fail to connect to tv service");
return;
}
// make sure tv amlogic is alive
- if (tv->getStatus() != NO_ERROR) {
- jniThrowException(env, "java/lang/RuntimeException", "Tv initialization failed!");
- return;
- }
+ //if (tv->getStatus() != NO_ERROR) {
+ // jniThrowException(env, "java/lang/RuntimeException", "Tv initialization failed!");
+ // return;
+ //}
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
@@ -144,12 +144,10 @@ static void com_droidlogic_app_tv_TvControlManager_native_setup(JNIEnv *env, job
env->SetLongField(thiz, fields.context, (long)context.get());
}
-
static void com_droidlogic_app_tv_TvControlManager_release(JNIEnv *env, jobject thiz)
{
// TODO: Change to LOGE
JNITvContext *context = NULL;
- sp<TvClient> tv;
{
Mutex::Autolock _l(sLock);
context = reinterpret_cast<JNITvContext *>(env->GetLongField(thiz, fields.context));
@@ -162,7 +160,7 @@ static void com_droidlogic_app_tv_TvControlManager_release(JNIEnv *env, jobject
// clean up if release has not been called before
if (context != NULL) {
- tv = context->getTv();
+ sp<TvServerHidlClient> tv = context->getTv();
context->release();
ALOGD("native_release: context=%p tv=%p", context, tv.get());
@@ -177,8 +175,9 @@ static void com_droidlogic_app_tv_TvControlManager_release(JNIEnv *env, jobject
}
}
-void JNITvContext::notify(int32_t msgType, const Parcel &p)
+void JNITvContext::notify(const tv_parcel_t &parcel)
{
+ /*
// VM pointer will be NULL if object is released
Mutex::Autolock _l(mLock);
if (mTvJObjectWeak == NULL) {
@@ -206,6 +205,7 @@ void JNITvContext::notify(int32_t msgType, const Parcel &p)
env->CallStaticVoidMethod(mTvJClass, fields.post_event, mTvJObjectWeak, msgType, jParcel);
env->DeleteLocalRef(jParcel);
}
+ */
}
@@ -223,7 +223,7 @@ void JNITvContext::addCallbackBuffer(JNIEnv *env, jbyteArray cbb)
static jint com_droidlogic_app_tv_TvControlManager_processCmd(JNIEnv *env, jobject thiz, jobject pObj, jobject rObj)
{
- sp<TvClient> tv = get_native_tv(env, thiz, NULL);
+ sp<TvServerHidlClient> tv = get_native_tv(env, thiz, NULL);
if (tv == 0) return -1;
Parcel *p = parcelForJavaObject(env, pObj);
@@ -255,44 +255,41 @@ static void com_droidlogic_app_tv_TvControlManager_addCallbackBuffer(JNIEnv *env
static void com_droidlogic_app_tv_TvControlManager_reconnect(JNIEnv *env, jobject thiz)
{
- sp<TvClient> tv = get_native_tv(env, thiz, NULL);
- if (tv == 0) return;
+ sp<TvServerHidlClient> tv = get_native_tv(env, thiz, NULL);
+ if (tv == nullptr) return;
- if (tv->reconnect() != NO_ERROR) {
- jniThrowException(env, "java/io/IOException", "reconnect failed");
- return;
- }
+ tv->reconnect();
}
static void com_droidlogic_app_tv_TvControlManager_lock(JNIEnv *env, jobject thiz)
{
- sp<TvClient> tv = get_native_tv(env, thiz, NULL);
+ sp<TvServerHidlClient> tv = get_native_tv(env, thiz, NULL);
if (tv == 0) return;
ALOGD("lock");
- if (tv->lock() != NO_ERROR) {
- jniThrowException(env, "java/lang/RuntimeException", "lock failed");
- }
+ //if (tv->lock() != NO_ERROR) {
+ // jniThrowException(env, "java/lang/RuntimeException", "lock failed");
+ //}
}
static void com_droidlogic_app_tv_TvControlManager_unlock(JNIEnv *env, jobject thiz)
{
- sp<TvClient> tv = get_native_tv(env, thiz, NULL);
+ sp<TvServerHidlClient> tv = get_native_tv(env, thiz, NULL);
if (tv == 0) return;
ALOGD("unlock");
- if (tv->unlock() != NO_ERROR) {
- jniThrowException(env, "java/lang/RuntimeException", "unlock failed");
- }
+ //if (tv->unlock() != NO_ERROR) {
+ // jniThrowException(env, "java/lang/RuntimeException", "unlock failed");
+ //}
}
static void com_droidlogic_app_tv_TvControlManager_create_subtitle_bitmap(JNIEnv *env, jobject thiz, jobject bmpobj)
{
ALOGD("create subtitle bmp");
JNITvContext *context = reinterpret_cast<JNITvContext *>(env->GetLongField(thiz, fields.context));
- sp<TvClient> tv = get_native_tv(env, thiz, NULL);
+ sp<TvServerHidlClient> tv = get_native_tv(env, thiz, NULL);
if (tv == 0) return;
//get skbitmap
@@ -300,7 +297,7 @@ static void com_droidlogic_app_tv_TvControlManager_create_subtitle_bitmap(JNIEnv
jfieldID skbmp_fid;
jlong hbmp;
bmp_clazz = env->FindClass("android/graphics/Bitmap");
- skbmp_fid = env->GetFieldID(bmp_clazz, "mNativePtr", "J");
+ skbmp_fid = env->GetFieldID(bmp_clazz, "mNativePtr", "J");
hbmp = env->GetLongField(bmpobj, skbmp_fid);
context->pSubBmp = reinterpret_cast<SkBitmap *>(hbmp);
@@ -317,7 +314,7 @@ static void com_droidlogic_app_tv_TvControlManager_create_subtitle_bitmap(JNIEnv
//send share mem to server
- tv->createSubtitle(context->mSubMemBase);
+ //tv->createSubtitle(context->mSubMemBase);
return;
}
@@ -339,11 +336,13 @@ static JNINativeMethod camMethods[] = {
"(Landroid/os/Parcel;Landroid/os/Parcel;)I",
(void *)com_droidlogic_app_tv_TvControlManager_processCmd
},
+ /*
{
"addCallbackBuffer",
"([B)V",
(void *)com_droidlogic_app_tv_TvControlManager_addCallbackBuffer
},
+ */
{
"reconnect",
"()V",
@@ -399,7 +398,7 @@ static int find_fields(JNIEnv *env, field *fields, int count)
int register_com_droidlogic_app_tv_TvControlManager(JNIEnv *env)
{
field fields_to_find[] = {
- { "com/droidlogic/app/tv/TvControlManager", "mNativeContext", "J", &fields.context }
+ { "com/droidlogic/app/tv/TvControlManager", "mNativeContext", "J", &fields.context }
};
ALOGD("register_com_droidlogic_app_tv_TvControlManager.");
diff --git a/libtvbinder/Android.mk b/libtvbinder/Android.mk
index 9abeef4..22b65bf 100644
--- a/libtvbinder/Android.mk
+++ b/libtvbinder/Android.mk
@@ -4,17 +4,32 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES:= \
- TvClient.cpp \
- ITv.cpp \
- ITvClient.cpp \
- ITvService.cpp
+ TvServerHidlClient.cpp \
+ TvClient.cpp \
+ ITv.cpp \
+ ITvClient.cpp \
+ ITvService.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libutils \
- libbinder \
- libui
+ vendor.amlogic.hardware.tvserver@1.0_vendor \
+ libbase \
+ libhidlbase \
+ libhidltransport \
+ libhidlmemory \
+ android.hidl.allocator@1.0 \
+ liblog \
+ libcutils \
+ libutils \
+ libbinder
+
+LOCAL_C_INCLUDES += \
+ system/libhidl/transport/include/hidl \
+ system/libhidl/libhidlmemory/include
+
+LOCAL_C_INCLUDES += \
+ external/libcxx/include
+
+LOCAL_CPPFLAGS += -std=c++14
LOCAL_MODULE:= libtvbinder
@@ -22,5 +37,4 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
LOCAL_PROPRIETARY_MODULE := true
endif
-#LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
diff --git a/libtvbinder/TvServerHidlClient.cpp b/libtvbinder/TvServerHidlClient.cpp
new file mode 100644
index 0000000..2e7ad6a
--- a/dev/null
+++ b/libtvbinder/TvServerHidlClient.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2016 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.
+ * @author Tellen Yu
+ * @version 1.0
+ * @date 2018/1/12
+ * @par function description:
+ * - 1 droidlogic tv hwbinder client
+ */
+
+#define LOG_TAG "TvServerHidlClient"
+#include <utils/Log.h>
+
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include "include/TvServerHidlClient.h"
+
+namespace android {
+
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+
+Mutex TvServerHidlClient::mLock;
+
+// establish binder interface to tv service
+sp<ITvServer> TvServerHidlClient::getTvService()
+{
+ Mutex::Autolock _l(mLock);
+
+#if 1//PLATFORM_SDK_VERSION >= 26
+ sp<ITvServer> tvservice = ITvServer::tryGetService();
+ while (tvservice == nullptr) {
+ usleep(200*1000);//sleep 200ms
+ tvservice = ITvServer::tryGetService();
+ ALOGE("tryGet tvserver daemon Service");
+ };
+ mDeathRecipient = new TvServerDaemonDeathRecipient(this);
+ Return<bool> linked = tvservice->linkToDeath(mDeathRecipient, /*cookie*/ 0);
+ if (!linked.isOk()) {
+ ALOGE("Transaction error in linking to tvserver daemon service death: %s", linked.description().c_str());
+ } else if (!linked) {
+ ALOGE("Unable to link to tvserver daemon service death notifications");
+ } else {
+ ALOGI("Link to tvserver daemon service death notification successful");
+ }
+
+#else
+ Mutex::Autolock _l(mLock);
+ if (mTvService.get() == 0) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ do {
+ binder = sm->getService(String16("tvservice"));
+ if (binder != 0)
+ break;
+ ALOGW("TvService not published, waiting...");
+ usleep(500000); // 0.5 s
+ } while (true);
+ if (mDeathNotifier == NULL) {
+ mDeathNotifier = new DeathNotifier();
+ }
+ binder->linkToDeath(mDeathNotifier);
+ mTvService = interface_cast<ITvService>(binder);
+ }
+ ALOGE_IF(mTvService == 0, "no TvService!?");
+ return mTvService;
+#endif
+
+ return tvservice;
+}
+
+TvServerHidlClient::TvServerHidlClient(tv_connect_type_t type): mType(type)
+{
+ mTvServer = getTvService();
+ mTvServerHidlCallback = new TvServerHidlCallback(this);
+ mTvServer->setCallback(mTvServerHidlCallback, static_cast<ConnectType>(type));
+}
+
+TvServerHidlClient::~TvServerHidlClient()
+{
+ disconnect();
+}
+
+sp<TvServerHidlClient> TvServerHidlClient::connect(tv_connect_type_t type)
+{
+ return new TvServerHidlClient(type);
+}
+
+void TvServerHidlClient::reconnect()
+{
+ ALOGI("tvserver client type:%d reconnect", mType);
+ mTvServer.clear();
+ //reconnect to server
+ mTvServer = getTvService();
+ mTvServer->setCallback(mTvServerHidlCallback, static_cast<ConnectType>(mType));
+}
+
+void TvServerHidlClient::disconnect()
+{
+ ALOGD("disconnect");
+}
+
+status_t TvServerHidlClient::processCmd(const Parcel &p, Parcel *r __unused)
+{
+ int cmd = p.readInt32();
+
+ ALOGD("processCmd cmd=%d", cmd);
+ return 0;
+#if 0
+ sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
+ if (ashmemAllocator == nullptr) {
+ ALOGE("can not get ashmem service");
+ return -1;
+ }
+
+ size_t size = p.dataSize();
+ hidl_memory hidlMemory;
+ auto res = ashmemAllocator->allocate(size, [&](bool success, const hidl_memory& memory) {
+ if (!success) {
+ ALOGE("ashmem allocate size:%d fail", size);
+ }
+ hidlMemory = memory;
+ });
+
+ if (!res.isOk()) {
+ ALOGE("ashmem allocate result fail");
+ return -1;
+ }
+
+ sp<IMemory> memory = hardware::mapMemory(hidlMemory);
+ void* data = memory->getPointer();
+ memory->update();
+ // update memory however you wish after calling update and before calling commit
+ memcpy(data, p.data(), size);
+ memory->commit();
+ Return<int32_t> ret = mTvServer->processCmd(hidlMemory, (int)size);
+ if (!ret.isOk()) {
+ ALOGE("Failed to processCmd");
+ }
+ return ret;
+#endif
+}
+
+void TvServerHidlClient::setListener(const sp<TvListener> &listener)
+{
+ mListener = listener;
+}
+
+int TvServerHidlClient::startTv() {
+ return mTvServer->startTv();
+}
+
+int TvServerHidlClient::stopTv() {
+ return mTvServer->stopTv();
+}
+
+int TvServerHidlClient::switchInputSrc(int32_t inputSrc) {
+ return mTvServer->switchInputSrc(inputSrc);
+}
+
+int TvServerHidlClient::getInputSrcConnectStatus(int32_t inputSrc) {
+ return mTvServer->getInputSrcConnectStatus(inputSrc);
+}
+
+int TvServerHidlClient::getCurrentInputSrc() {
+ return mTvServer->getCurrentInputSrc();
+}
+
+int TvServerHidlClient::getHdmiAvHotplugStatus() {
+ return mTvServer->getHdmiAvHotplugStatus();
+}
+
+std::string TvServerHidlClient::getSupportInputDevices() {
+ int ret;
+ std::string tvDevices;
+ mTvServer->getSupportInputDevices([&](int32_t result, const ::android::hardware::hidl_string& devices) {
+ ret = result;
+ tvDevices = devices;
+ });
+ return tvDevices;
+}
+
+int TvServerHidlClient::getHdmiPorts() {
+ return mTvServer->getHdmiPorts();
+}
+
+void TvServerHidlClient::getCurSignalInfo(int &fmt, int &transFmt, int &status, int &frameRate) {
+ mTvServer->getCurSignalInfo([&](const SignalInfo& info) {
+ fmt = info.fmt;
+ transFmt = info.transFmt;
+ status = info.status;
+ frameRate = info.frameRate;
+ });
+}
+
+int TvServerHidlClient::setMiscCfg(const std::string& key, const std::string& val) {
+ return mTvServer->setMiscCfg(key, val);
+}
+
+std::string TvServerHidlClient::getMiscCfg(const std::string& key, const std::string& def) {
+ std::string miscCfg;
+ mTvServer->getMiscCfg(key, def, [&](const std::string& cfg) {
+ miscCfg = cfg;
+ });
+
+ return miscCfg;
+}
+
+
+// callback from tv service
+Return<void> TvServerHidlClient::TvServerHidlCallback::notifyCallback(const TvHidlParcel& hidlParcel)
+{
+ ALOGI("notifyCallback event type:%d", hidlParcel.msgType);
+
+#if 0
+ Parcel p;
+
+ sp<IMemory> memory = android::hardware::mapMemory(parcelMem);
+ void* data = memory->getPointer();
+ memory->update();
+ // update memory however you wish after calling update and before calling commit
+ p.setDataPosition(0);
+ p.write(data, size);
+ memory->commit();
+
+#endif
+ sp<TvListener> listener;
+ {
+ Mutex::Autolock _l(mLock);
+ listener = tvserverClient->mListener;
+ }
+
+ tv_parcel_t parcel;
+ parcel.msgType = hidlParcel.msgType;
+ for (int i = 0; i < hidlParcel.bodyInt.size(); i++) {
+ parcel.bodyInt.push_back(hidlParcel.bodyInt[i]);
+ }
+
+ for (int j = 0; j < hidlParcel.bodyString.size(); j++) {
+ parcel.bodyString.push_back(hidlParcel.bodyString[j]);
+ }
+
+ if (listener != NULL) {
+ listener->notify(parcel);
+ }
+ return Void();
+}
+
+void TvServerHidlClient::TvServerDaemonDeathRecipient::serviceDied(uint64_t cookie __unused,
+ const ::android::wp<::android::hidl::base::V1_0::IBase>& who __unused)
+{
+ ALOGE("tvserver daemon died.");
+ Mutex::Autolock _l(mLock);
+
+ usleep(200*1000);//sleep 200ms
+ tvserverClient->reconnect();
+}
+}
diff --git a/libtvbinder/include/TvServerHidlClient.h b/libtvbinder/include/TvServerHidlClient.h
new file mode 100644
index 0000000..f2df5f2
--- a/dev/null
+++ b/libtvbinder/include/TvServerHidlClient.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 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.
+ * @author Tellen Yu
+ * @version 1.0
+ * @date 2018/1/12
+ * @par function description:
+ * - 1 droidlogic tv hwbinder client
+ */
+
+#ifndef _ANDROID_TV_SERVER_HIDL_CLIENT_H_
+#define _ANDROID_TV_SERVER_HIDL_CLIENT_H_
+
+#include <utils/Timers.h>
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <utils/Mutex.h>
+#include <binder/Parcel.h>
+
+#include <vendor/amlogic/hardware/tvserver/1.0/ITvServer.h>
+
+namespace android {
+
+using ::vendor::amlogic::hardware::tvserver::V1_0::ITvServer;
+using ::vendor::amlogic::hardware::tvserver::V1_0::ITvServerCallback;
+using ::vendor::amlogic::hardware::tvserver::V1_0::ConnectType;
+using ::vendor::amlogic::hardware::tvserver::V1_0::SignalInfo;
+using ::vendor::amlogic::hardware::tvserver::V1_0::TvHidlParcel;
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+typedef enum {
+ CONNECT_TYPE_HAL = 0,
+ CONNECT_TYPE_EXTEND = 1
+} tv_connect_type_t;
+
+typedef struct tv_parcel_s {
+ int msgType;
+ std::vector<int> bodyInt;
+ std::vector<std::string> bodyString;
+} tv_parcel_t;
+
+class TvListener : virtual public RefBase {
+public:
+ virtual void notify(const tv_parcel_t &parcel) = 0;
+};
+
+class TvServerHidlClient : virtual public RefBase {
+public:
+ static sp<TvServerHidlClient> connect(tv_connect_type_t type);
+ TvServerHidlClient(tv_connect_type_t type);
+ ~TvServerHidlClient();
+
+ void reconnect();
+ void disconnect();
+ status_t processCmd(const Parcel &p, Parcel *r);
+ void setListener(const sp<TvListener> &listener);
+
+ int startTv();
+ int stopTv();
+ int switchInputSrc(int32_t inputSrc);
+ int getInputSrcConnectStatus(int32_t inputSrc);
+ int getCurrentInputSrc();
+ int getHdmiAvHotplugStatus();
+ std::string getSupportInputDevices();
+ int getHdmiPorts();
+
+ void getCurSignalInfo(int &fmt, int &transFmt, int &status, int &frameRate);
+ int setMiscCfg(const std::string& key, const std::string& val);
+ std::string getMiscCfg(const std::string& key, const std::string& def);
+
+private:
+ class TvServerHidlCallback : public ITvServerCallback {
+ public:
+ TvServerHidlCallback(TvServerHidlClient *client): tvserverClient(client) {};
+ Return<void> notifyCallback(const TvHidlParcel& parcel) override;
+
+ private:
+ TvServerHidlClient *tvserverClient;
+ };
+
+ struct TvServerDaemonDeathRecipient : public android::hardware::hidl_death_recipient {
+ TvServerDaemonDeathRecipient(TvServerHidlClient *client): tvserverClient(client) {};
+
+ // hidl_death_recipient interface
+ virtual void serviceDied(uint64_t cookie,
+ const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override;
+ private:
+ TvServerHidlClient *tvserverClient;
+ };
+ sp<TvServerDaemonDeathRecipient> mDeathRecipient = nullptr;
+
+ static Mutex mLock;
+ tv_connect_type_t mType;
+ // helper function to obtain tv service handle
+ sp<ITvServer> getTvService();
+
+ sp<TvListener> mListener;
+ sp<ITvServer> mTvServer;
+ sp<TvServerHidlCallback> mTvServerHidlCallback = nullptr;
+};
+
+}//namespace android
+
+#endif/*_ANDROID_TV_SERVER_HIDL_CLIENT_H_*/