Loading services/core/java/com/android/server/tv/TvInputHal.java +19 −3 Original line number Diff line number Diff line Loading @@ -57,8 +57,9 @@ final class TvInputHal implements Handler.Callback { private native long nativeOpen(); private static native int nativeSetSurface(long ptr, int deviceId, int streamId, private static native int nativeAddStream(long ptr, int deviceId, int streamId, Surface surface); private static native int nativeRemoveStream(long ptr, int deviceId, int streamId); private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId, int generation); private static native void nativeClose(long ptr); Loading @@ -81,7 +82,7 @@ final class TvInputHal implements Handler.Callback { mHandler.sendEmptyMessage(EVENT_OPEN); } public int setSurface(int deviceId, Surface surface, TvStreamConfig streamConfig) { public int addStream(int deviceId, Surface surface, TvStreamConfig streamConfig) { long ptr = mPtr; if (ptr == 0) { return ERROR_NO_INIT; Loading @@ -89,7 +90,22 @@ final class TvInputHal implements Handler.Callback { if (mStreamConfigGeneration != streamConfig.getGeneration()) { return ERROR_STALE_CONFIG; } if (nativeSetSurface(ptr, deviceId, streamConfig.getStreamId(), surface) == 0) { if (nativeAddStream(ptr, deviceId, streamConfig.getStreamId(), surface) == 0) { return SUCCESS; } else { return ERROR_UNKNOWN; } } public int removeStream(int deviceId, TvStreamConfig streamConfig) { long ptr = mPtr; if (ptr == 0) { return ERROR_NO_INIT; } if (mStreamConfigGeneration != streamConfig.getGeneration()) { return ERROR_STALE_CONFIG; } if (nativeRemoveStream(ptr, deviceId, streamConfig.getStreamId()) == 0) { return SUCCESS; } else { return ERROR_UNKNOWN; Loading services/core/java/com/android/server/tv/TvInputHardwareManager.java +29 −1 Original line number Diff line number Diff line Loading @@ -269,6 +269,8 @@ class TvInputHardwareManager implements TvInputHal.Callback { private final AudioDevicePort mAudioSink; private AudioPatch mAudioPatch = null; private TvStreamConfig mActiveConfig = null; public TvInputHardwareImpl(TvInputHardwareInfo info) { mInfo = info; AudioDevicePort audioSource = null; Loading Loading @@ -311,6 +313,9 @@ class TvInputHardwareManager implements TvInputHal.Callback { } } // A TvInputHardwareImpl object holds only one active session. Therefore, if a client // attempts to call setSurface with different TvStreamConfig objects, the last call will // prevail. @Override public boolean setSurface(Surface surface, TvStreamConfig config) throws RemoteException { Loading @@ -318,6 +323,12 @@ class TvInputHardwareManager implements TvInputHal.Callback { if (mReleased) { throw new IllegalStateException("Device already released."); } if (surface != null && config == null) { return false; } if (surface == null && mActiveConfig == null) { return false; } if (mInfo.getType() == TvInputHal.TYPE_HDMI) { if (surface != null) { // Set "Active Source" for HDMI. Loading Loading @@ -347,7 +358,24 @@ class TvInputHardwareManager implements TvInputHal.Callback { mAudioPatch = null; } } return mHal.setSurface(mInfo.getDeviceId(), surface, config) == TvInputHal.SUCCESS; int result = TvInputHal.ERROR_UNKNOWN; if (surface == null) { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); mActiveConfig = null; } else { if (config != mActiveConfig && mActiveConfig != null) { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); if (result != TvInputHal.SUCCESS) { mActiveConfig = null; return false; } } result = mHal.addStream(mInfo.getDeviceId(), surface, config); if (result == TvInputHal.SUCCESS) { mActiveConfig = config; } } return result == TvInputHal.SUCCESS; } } Loading services/core/jni/com_android_server_tv_TvInputHal.cpp +66 −34 Original line number Diff line number Diff line Loading @@ -74,17 +74,17 @@ public: static JTvInputHal* createInstance(JNIEnv* env, jobject thiz); int setSurface(int deviceId, int streamId, const sp<Surface>& surface); int addStream(int deviceId, int streamId, const sp<Surface>& surface); int removeStream(int deviceId, int streamId); const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs); private: class Connection { public: Connection() : mStreamId(0) {} Connection() {} sp<Surface> mSurface; sp<NativeHandle> mSourceHandle; int mStreamId; }; JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* dev); Loading @@ -100,7 +100,7 @@ private: tv_input_device_t* mDevice; tv_input_callback_ops_t mCallback; KeyedVector<int, Connection> mConnections; KeyedVector<int, KeyedVector<int, Connection> > mConnections; }; JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* device) { Loading Loading @@ -143,31 +143,19 @@ JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz) { return new JTvInputHal(env, thiz, device); } int JTvInputHal::setSurface(int deviceId, int streamId, const sp<Surface>& surface) { Connection& connection = mConnections.editValueFor(deviceId); if (connection.mStreamId == streamId && connection.mSurface == surface) { int JTvInputHal::addStream(int deviceId, int streamId, const sp<Surface>& surface) { KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { connections.add(streamId, Connection()); } Connection& connection = connections.editValueFor(streamId); if (connection.mSurface == surface) { // Nothing to do return NO_ERROR; } if (Surface::isValid(connection.mSurface)) { connection.mSurface.clear(); } if (surface == NULL) { if (connection.mSurface != NULL) { connection.mSurface->setSidebandStream(NULL); connection.mSurface.clear(); } if (connection.mSourceHandle != NULL) { // Need to reset streams if (mDevice->close_stream( mDevice, deviceId, connection.mStreamId) != 0) { ALOGE("Couldn't remove stream"); return BAD_VALUE; } connection.mSourceHandle.clear(); } return NO_ERROR; } connection.mSurface = surface; if (connection.mSourceHandle == NULL) { // Need to configure stream Loading Loading @@ -204,12 +192,39 @@ int JTvInputHal::setSurface(int deviceId, int streamId, const sp<Surface>& surfa } connection.mSourceHandle = NativeHandle::create( stream.sideband_stream_source_handle, false); connection.mStreamId = stream.stream_id; connection.mSurface->setSidebandStream(connection.mSourceHandle); } return NO_ERROR; } int JTvInputHal::removeStream(int deviceId, int streamId) { KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { return BAD_VALUE; } Connection& connection = connections.editValueFor(streamId); if (connection.mSurface == NULL) { // Nothing to do return NO_ERROR; } if (Surface::isValid(connection.mSurface)) { connection.mSurface.clear(); } if (connection.mSurface != NULL) { connection.mSurface->setSidebandStream(NULL); connection.mSurface.clear(); } if (connection.mSourceHandle != NULL) { // Need to reset streams if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) { ALOGE("Couldn't remove stream"); return BAD_VALUE; } connection.mSourceHandle.clear(); } return NO_ERROR; } const tv_stream_config_t* JTvInputHal::getStreamConfigs(int deviceId, int* numConfigs) { const tv_stream_config_t* configs = NULL; if (mDevice->get_stream_configurations( Loading Loading @@ -241,7 +256,7 @@ void JTvInputHal::notify( void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mConnections.add(info.device_id, Connection()); mConnections.add(info.device_id, KeyedVector<int, Connection>()); jobject builder = env->NewObject( gTvInputHardwareInfoBuilderClassInfo.clazz, Loading Loading @@ -276,6 +291,11 @@ void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { void JTvInputHal::onDeviceUnavailable(int deviceId) { JNIEnv* env = AndroidRuntime::getJNIEnv(); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); for (size_t i = 0; i < connections.size(); ++i) { removeStream(deviceId, connections.keyAt(i)); } connections.clear(); mConnections.removeItem(deviceId); env->CallVoidMethod( mThiz, Loading @@ -285,7 +305,11 @@ void JTvInputHal::onDeviceUnavailable(int deviceId) { void JTvInputHal::onStreamConfigurationsChanged(int deviceId) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mConnections.removeItem(deviceId); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); for (size_t i = 0; i < connections.size(); ++i) { removeStream(deviceId, connections.keyAt(i)); } connections.clear(); env->CallVoidMethod( mThiz, gTvInputHalClassInfo.streamConfigsChanged, Loading @@ -298,14 +322,20 @@ static jlong nativeOpen(JNIEnv* env, jobject thiz) { return (jlong)JTvInputHal::createInstance(env, thiz); } static int nativeSetSurface(JNIEnv* env, jclass clazz, static int nativeAddStream(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint streamId, jobject jsurface) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; sp<Surface> surface( jsurface ? android_view_Surface_getSurface(env, jsurface) : NULL); return tvInputHal->setSurface(deviceId, streamId, surface); if (!jsurface) { return BAD_VALUE; } sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); return tvInputHal->addStream(deviceId, streamId, surface); } static int nativeRemoveStream(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint streamId) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; return tvInputHal->removeStream(deviceId, streamId); } static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz, Loading Loading @@ -349,8 +379,10 @@ static JNINativeMethod gTvInputHalMethods[] = { /* name, signature, funcPtr */ { "nativeOpen", "()J", (void*) nativeOpen }, { "nativeSetSurface", "(JIILandroid/view/Surface;)I", (void*) nativeSetSurface }, { "nativeAddStream", "(JIILandroid/view/Surface;)I", (void*) nativeAddStream }, { "nativeRemoveStream", "(JII)I", (void*) nativeRemoveStream }, { "nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;", (void*) nativeGetStreamConfigs }, { "nativeClose", "(J)V", Loading Loading
services/core/java/com/android/server/tv/TvInputHal.java +19 −3 Original line number Diff line number Diff line Loading @@ -57,8 +57,9 @@ final class TvInputHal implements Handler.Callback { private native long nativeOpen(); private static native int nativeSetSurface(long ptr, int deviceId, int streamId, private static native int nativeAddStream(long ptr, int deviceId, int streamId, Surface surface); private static native int nativeRemoveStream(long ptr, int deviceId, int streamId); private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId, int generation); private static native void nativeClose(long ptr); Loading @@ -81,7 +82,7 @@ final class TvInputHal implements Handler.Callback { mHandler.sendEmptyMessage(EVENT_OPEN); } public int setSurface(int deviceId, Surface surface, TvStreamConfig streamConfig) { public int addStream(int deviceId, Surface surface, TvStreamConfig streamConfig) { long ptr = mPtr; if (ptr == 0) { return ERROR_NO_INIT; Loading @@ -89,7 +90,22 @@ final class TvInputHal implements Handler.Callback { if (mStreamConfigGeneration != streamConfig.getGeneration()) { return ERROR_STALE_CONFIG; } if (nativeSetSurface(ptr, deviceId, streamConfig.getStreamId(), surface) == 0) { if (nativeAddStream(ptr, deviceId, streamConfig.getStreamId(), surface) == 0) { return SUCCESS; } else { return ERROR_UNKNOWN; } } public int removeStream(int deviceId, TvStreamConfig streamConfig) { long ptr = mPtr; if (ptr == 0) { return ERROR_NO_INIT; } if (mStreamConfigGeneration != streamConfig.getGeneration()) { return ERROR_STALE_CONFIG; } if (nativeRemoveStream(ptr, deviceId, streamConfig.getStreamId()) == 0) { return SUCCESS; } else { return ERROR_UNKNOWN; Loading
services/core/java/com/android/server/tv/TvInputHardwareManager.java +29 −1 Original line number Diff line number Diff line Loading @@ -269,6 +269,8 @@ class TvInputHardwareManager implements TvInputHal.Callback { private final AudioDevicePort mAudioSink; private AudioPatch mAudioPatch = null; private TvStreamConfig mActiveConfig = null; public TvInputHardwareImpl(TvInputHardwareInfo info) { mInfo = info; AudioDevicePort audioSource = null; Loading Loading @@ -311,6 +313,9 @@ class TvInputHardwareManager implements TvInputHal.Callback { } } // A TvInputHardwareImpl object holds only one active session. Therefore, if a client // attempts to call setSurface with different TvStreamConfig objects, the last call will // prevail. @Override public boolean setSurface(Surface surface, TvStreamConfig config) throws RemoteException { Loading @@ -318,6 +323,12 @@ class TvInputHardwareManager implements TvInputHal.Callback { if (mReleased) { throw new IllegalStateException("Device already released."); } if (surface != null && config == null) { return false; } if (surface == null && mActiveConfig == null) { return false; } if (mInfo.getType() == TvInputHal.TYPE_HDMI) { if (surface != null) { // Set "Active Source" for HDMI. Loading Loading @@ -347,7 +358,24 @@ class TvInputHardwareManager implements TvInputHal.Callback { mAudioPatch = null; } } return mHal.setSurface(mInfo.getDeviceId(), surface, config) == TvInputHal.SUCCESS; int result = TvInputHal.ERROR_UNKNOWN; if (surface == null) { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); mActiveConfig = null; } else { if (config != mActiveConfig && mActiveConfig != null) { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); if (result != TvInputHal.SUCCESS) { mActiveConfig = null; return false; } } result = mHal.addStream(mInfo.getDeviceId(), surface, config); if (result == TvInputHal.SUCCESS) { mActiveConfig = config; } } return result == TvInputHal.SUCCESS; } } Loading
services/core/jni/com_android_server_tv_TvInputHal.cpp +66 −34 Original line number Diff line number Diff line Loading @@ -74,17 +74,17 @@ public: static JTvInputHal* createInstance(JNIEnv* env, jobject thiz); int setSurface(int deviceId, int streamId, const sp<Surface>& surface); int addStream(int deviceId, int streamId, const sp<Surface>& surface); int removeStream(int deviceId, int streamId); const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs); private: class Connection { public: Connection() : mStreamId(0) {} Connection() {} sp<Surface> mSurface; sp<NativeHandle> mSourceHandle; int mStreamId; }; JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* dev); Loading @@ -100,7 +100,7 @@ private: tv_input_device_t* mDevice; tv_input_callback_ops_t mCallback; KeyedVector<int, Connection> mConnections; KeyedVector<int, KeyedVector<int, Connection> > mConnections; }; JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* device) { Loading Loading @@ -143,31 +143,19 @@ JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz) { return new JTvInputHal(env, thiz, device); } int JTvInputHal::setSurface(int deviceId, int streamId, const sp<Surface>& surface) { Connection& connection = mConnections.editValueFor(deviceId); if (connection.mStreamId == streamId && connection.mSurface == surface) { int JTvInputHal::addStream(int deviceId, int streamId, const sp<Surface>& surface) { KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { connections.add(streamId, Connection()); } Connection& connection = connections.editValueFor(streamId); if (connection.mSurface == surface) { // Nothing to do return NO_ERROR; } if (Surface::isValid(connection.mSurface)) { connection.mSurface.clear(); } if (surface == NULL) { if (connection.mSurface != NULL) { connection.mSurface->setSidebandStream(NULL); connection.mSurface.clear(); } if (connection.mSourceHandle != NULL) { // Need to reset streams if (mDevice->close_stream( mDevice, deviceId, connection.mStreamId) != 0) { ALOGE("Couldn't remove stream"); return BAD_VALUE; } connection.mSourceHandle.clear(); } return NO_ERROR; } connection.mSurface = surface; if (connection.mSourceHandle == NULL) { // Need to configure stream Loading Loading @@ -204,12 +192,39 @@ int JTvInputHal::setSurface(int deviceId, int streamId, const sp<Surface>& surfa } connection.mSourceHandle = NativeHandle::create( stream.sideband_stream_source_handle, false); connection.mStreamId = stream.stream_id; connection.mSurface->setSidebandStream(connection.mSourceHandle); } return NO_ERROR; } int JTvInputHal::removeStream(int deviceId, int streamId) { KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { return BAD_VALUE; } Connection& connection = connections.editValueFor(streamId); if (connection.mSurface == NULL) { // Nothing to do return NO_ERROR; } if (Surface::isValid(connection.mSurface)) { connection.mSurface.clear(); } if (connection.mSurface != NULL) { connection.mSurface->setSidebandStream(NULL); connection.mSurface.clear(); } if (connection.mSourceHandle != NULL) { // Need to reset streams if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) { ALOGE("Couldn't remove stream"); return BAD_VALUE; } connection.mSourceHandle.clear(); } return NO_ERROR; } const tv_stream_config_t* JTvInputHal::getStreamConfigs(int deviceId, int* numConfigs) { const tv_stream_config_t* configs = NULL; if (mDevice->get_stream_configurations( Loading Loading @@ -241,7 +256,7 @@ void JTvInputHal::notify( void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mConnections.add(info.device_id, Connection()); mConnections.add(info.device_id, KeyedVector<int, Connection>()); jobject builder = env->NewObject( gTvInputHardwareInfoBuilderClassInfo.clazz, Loading Loading @@ -276,6 +291,11 @@ void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { void JTvInputHal::onDeviceUnavailable(int deviceId) { JNIEnv* env = AndroidRuntime::getJNIEnv(); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); for (size_t i = 0; i < connections.size(); ++i) { removeStream(deviceId, connections.keyAt(i)); } connections.clear(); mConnections.removeItem(deviceId); env->CallVoidMethod( mThiz, Loading @@ -285,7 +305,11 @@ void JTvInputHal::onDeviceUnavailable(int deviceId) { void JTvInputHal::onStreamConfigurationsChanged(int deviceId) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mConnections.removeItem(deviceId); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); for (size_t i = 0; i < connections.size(); ++i) { removeStream(deviceId, connections.keyAt(i)); } connections.clear(); env->CallVoidMethod( mThiz, gTvInputHalClassInfo.streamConfigsChanged, Loading @@ -298,14 +322,20 @@ static jlong nativeOpen(JNIEnv* env, jobject thiz) { return (jlong)JTvInputHal::createInstance(env, thiz); } static int nativeSetSurface(JNIEnv* env, jclass clazz, static int nativeAddStream(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint streamId, jobject jsurface) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; sp<Surface> surface( jsurface ? android_view_Surface_getSurface(env, jsurface) : NULL); return tvInputHal->setSurface(deviceId, streamId, surface); if (!jsurface) { return BAD_VALUE; } sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); return tvInputHal->addStream(deviceId, streamId, surface); } static int nativeRemoveStream(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint streamId) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; return tvInputHal->removeStream(deviceId, streamId); } static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz, Loading Loading @@ -349,8 +379,10 @@ static JNINativeMethod gTvInputHalMethods[] = { /* name, signature, funcPtr */ { "nativeOpen", "()J", (void*) nativeOpen }, { "nativeSetSurface", "(JIILandroid/view/Surface;)I", (void*) nativeSetSurface }, { "nativeAddStream", "(JIILandroid/view/Surface;)I", (void*) nativeAddStream }, { "nativeRemoveStream", "(JII)I", (void*) nativeRemoveStream }, { "nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;", (void*) nativeGetStreamConfigs }, { "nativeClose", "(J)V", Loading