Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video streaming manager implementation #826

Conversation

askirk
Copy link
Contributor

@askirk askirk commented Jul 25, 2018

Partial fix to #782
This PR is ready for review.

Risk

This PR makes no API changes.

Testing Plan

Unit tests in VideoStreamingManagerTests file, also via manual testing internally.

Summary

Adds described functionality of VideoStreamingManager from Android Manager API proposal.

askirk added 13 commits July 23, 2018 17:25
- Implements methods outlined in evolution proposal
- Adds method to get wiProVersion in ISdl, makes method public in SdlProxyBase
- Enables implementation of VideoStreamingManager in SdlManager
- Also added some preliminary testing with Mockito
- Added listener in VideoStreamingManager to check that HMILevel is FULL before streaming
- Remove listeners added in constructor with dispose() method
- Adding mocked responses to properly start a video stream
- Includes setting whether haptic spatial data is supported in GENERAL_VIDEOSTREAMINGCAPABILITY
…om/smartdevicelink/sdl_android into feature/issue_782_video_streaming_manager

# Conflicts:
#	sdl_android/src/main/java/com/smartdevicelink/api/SdlManager.java
- Added new StreamingStateMachine that better represents state of video/audio managers
- Allows to support public methods that check state to match iOS
- Added test for classic video streaming
This covers adding the methods used in sample apps
- createOpenGLInputSurface
- startEncoder
- drainEncoder
- releaseEncoder
- testClassicVideoStreaming test that was failing will now pass, and test getting a service and starting the encoder
…om/smartdevicelink/sdl_android into feature/issue_782_video_streaming_manager

# Conflicts:
#	sdl_android/src/main/java/com/smartdevicelink/api/SdlManager.java
-Add test for convertTouchEvent
-Make convertTouchEvent method protected
- Remove encoder drain and release calls in attempt to fix travis failures
@codecov-io
Copy link

codecov-io commented Aug 2, 2018

Codecov Report

Merging #826 into feature/issue_782_Android_Managers will increase coverage by 2.06%.
The diff coverage is 48.37%.

Impacted file tree graph

@@                           Coverage Diff                            @@
##             feature/issue_782_Android_Managers     #826      +/-   ##
========================================================================
+ Coverage                                  41.6%   43.67%   +2.06%     
- Complexity                                 3169     3182      +13     
========================================================================
  Files                                       394      395       +1     
  Lines                                     19556    18531    -1025     
  Branches                                   2112     1892     -220     
========================================================================
- Hits                                       8137     8094      -43     
+ Misses                                    11046    10025    -1021     
- Partials                                    373      412      +39
Impacted Files Coverage Δ Complexity Δ
.../main/java/com/smartdevicelink/api/SdlManager.java 45% <0%> (-2.13%) 24 <0> (ø)
...n/java/com/smartdevicelink/proxy/SdlProxyBase.java 4.69% <20%> (+1.18%) 6 <4> (ø) ⬇️
...com/smartdevicelink/api/StreamingStateMachine.java 33.33% <33.33%> (ø) 6 <6> (?)
...com/smartdevicelink/api/VideoStreamingManager.java 55.29% <55.29%> (ø) 14 <14> (?)
...martdevicelink/transport/SdlBroadcastReceiver.java 3.43% <0%> (-1.21%) 2% <0%> (-1%)
...martdevicelink/proxy/rpc/enums/StaticIconName.java
...celink/proxy/rpc/RegisterAppInterfaceResponse.java 80% <0%> (+0.25%) 37% <0%> (-1%) ⬇️
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 78a3fb2...fe9a8db. Read the comment docs.

@askirk askirk changed the title [WIP] Video streaming manager implementation Video streaming manager implementation Aug 2, 2018
* Get wiProVersion
* @return byte representing wiProVersion
*/
byte getWiProVersion();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not continue the misleading naming of the protocol layer. This method should be Version getProtocolVersion

@@ -141,28 +141,29 @@ protected void initialize(){
this.permissionManager = new PermissionManager(_internalInterface);
this.permissionManager.start(subManagerListener);

this.videoStreamingManager = new VideoStreamingManager(_internalInterface);
this.videoStreamingManager.start(subManagerListener);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it makes sense to create the video streaming manager for every app. It seems as if the most responsible way to handle this would be to only create and start the manager when requested by the developer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we could do it based on AppType. If its nav or proj, then we could start it. same w/ the audiostreammanager

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea that's a good idea. Though I'm not sure if audio streaming is limited to those two app types, something need to check into

private static String TAG = "VideoStreamingManager";

private WeakReference<Context> context;
private volatile VirtualDisplayEncoder encoder;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there are two encoders of different types in this class, the names should be more specific to their types.

* Starts the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
* @see #createOpenGLInputSurface(int, int, int, int, int, boolean)
*/
public void startEncoder(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that these are exposed to the developer and they are responsible for handling them. I would assume the manager would take care of this instead. I'm wondering if allowing this is even useful for developers since they could create an SdlRemoteDisplay that contains a surface view on which they could draw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I just call this internally in createOpenGLInputSurface after creating the surface then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, if we remove the createOpenGLInputSurface functionality for this release these methods can also be removed. We will instruct developers to create a remote display with a surface view for now.

}

@Override
public void onServiceError(SdlSession session, SessionType type, String reason) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should transition to ERROR state

private final OnRPCNotificationListener hmiListener = new OnRPCNotificationListener() {
@Override
public void onNotified(RPCNotification notification) {
hmiLevel = ((OnHMIStatus)notification).getHmiLevel();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential NPE

* @return IVideoStreamListener interface if service is opened successfully and streaming is
* started, null otherwise
*/
public IVideoStreamListener startVideoStream(VideoStreamingParameters parameters, boolean encrypted){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this is public? I believe this is better protected at least.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming between startVideoStream and startVideoStreaming is very confusing. We should provide clearer naming conventions here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change to protected, make the other method startRemoteDisplayStreaming

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe startVideoStream is more related to starting the video service so I think maybe it's better named according to that. startVideoService. Correct me if I'm wrong though.

/**
* Stops streaming service and remote display encoder if applicable.
*/
public void stopStreaming(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this is public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To give a way to stop streaming, I suppose dispose does the same thing, so this could be private

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, no I think that is smart. If stopped is called, the manager has to be able to restart properly without being recreated and as long as that is possible a stopStreaming method would be useful for developers. I would add javadoc to this method that explains what steps (at a high level) would need to be done to restart the stream.

- Change getWiProVersion to getProtocolVersion with Version obj
- Only create and start video manager if AppHMIType is Projection or Navigation
* Check if a video service is currently active
* @return boolean (true = active, false = inactive)
*/
public boolean isVideoConnected(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by the return here since it will return true even if the state is STOPPED. I think the naming could be better here as well, since this is already the video streaming manager we don't need to preface everything with video, could just be isStreaming or isActive but it will depend on what info it's intending to return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should change the name to isActive(). I intended this for this to give developer an idea of whether the video service was started / is running successfully

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there are a few different states and I think we just need to define what is important for the developer to know:

  1. Video manager is ready to be used
  2. Video service has been started
  3. Streaming has started and is active

So what does active mean? Maybe we have different methods to define those states. I'm open for suggestions here.

* Check if video streaming has been paused due to app moving to background
* @return boolean (true = not paused, false = paused)
*/
public boolean isVideoStreamingPaused(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment on naming; isPaused, isStreamingPaused, etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change to isPaused

@@ -1713,7 +1718,7 @@ private void dispatchIncomingMessage(ProtocolMessage message) {
}
}

private byte getWiProVersion() {
public byte getWiProVersion() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be changed to protocol version as well

@@ -354,6 +354,11 @@ public SdlMsgVersion getSdlMsgVersion(){
return null;
}

@Override
public com.smartdevicelink.util.Version getProtocolVersion() {
return new com.smartdevicelink.util.Version(Byte.toString(SdlProxyBase.this.getWiProVersion()) + ".0.0");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we can access this information directly from wiproprotocol and should not just use the major byte as previously used. https://github.com/smartdevicelink/sdl_android/blob/master/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java#L96

- eliminate manual surface method of video streaming and corresponding unit tests
- change getWiProVersion() and setWiProVersion) methods in SdlProxyBase to use protocolVersion (Version vs. byte)
- changed ambiguous naming in VideoStreamingManager- isPaused(), isStreaming(), isServiceActive()
- added a way to stop and restart a video stream for dev
…om/smartdevicelink/sdl_android into feature/issue_782_video_streaming_manager

# Conflicts:
#	sdl_android/src/main/java/com/smartdevicelink/api/SdlManager.java
#	sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
@joeygrover joeygrover merged commit d5dcd03 into feature/issue_782_Android_Managers Aug 23, 2018
@joeygrover joeygrover deleted the feature/issue_782_video_streaming_manager branch August 23, 2018 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants