Bug 14658 - Streaming audio fails in 3G mode via Sprint & TMobile
Summary: Streaming audio fails in 3G mode via Sprint & TMobile
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.8.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
Depends on:
Reported: 2013-09-11 14:34 UTC by Allie Miller
Modified: 2013-11-04 13:28 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Updated Test Case (502.51 KB, application/zip)
2013-09-19 13:52 UTC, Allie Miller
Latest Test Case To Reproduce issue (502.58 KB, application/zip)
2013-09-23 10:17 UTC, Allie Miller

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Allie Miller 2013-09-11 14:34:43 UTC
From Case #44220:

The attached test project is small radio player app designed to play shoutcast stream from an online radio and load and display current track metadata.
The main work we do inside of the PlayerService class.

The issue we encounter is the app works fine in wifi, but doesn't stream audio or displays track metadata when working in 3G mode via Sprint mobile service provider in US. Although some third party media streaming apps do work in the same environment and on the same devices (we tested Droid, and Galaxy S II).
With our local mobile service providers in Ukraine app works fine in 3G or GRPS modes.

But it looks like it’s somehow related to Xamarin mediaplayer wrapper implementation. Because the same stream works with TuneIn and WinAmp radio app on the same device, without any additional configuration.

Restarting the player doesn’t help – current version of the app gives up after 3 retries. Previous version of the app never gave up, so Android had to shutdown the app after about a minute of trial and errors.

The restarting is done in the PlayerService.OnError method, where I just invoke StartPlayback method. The method essentially calls mediaPlayer.Reset, mediaPlayer.SetDataSource and then mediaPlayer.PrepareAsync.

It’s the same error – it appears after each retry.
Comment 4 Jonathan Pryor 2013-09-11 16:17:15 UTC
I do not believe that this is a binding bug.

Media playback on Android is a multi-process affair: you use the MediaPlayer type to control playback, but the MediaPlayer type itself does not perform the playback. Instead, MediaPlayer interacts with a system service which performs the media playback on your processes behalf. This is the AwesomePlayer service.

We can see the interaction in the Debug Log:

> 09-06 17:50:14.262 D/guerrilla( 5764): PlayerService.OnCreate
> 09-06 17:50:15.092 I/guerrilla( 5764): Connection: Connected
> 09-06 17:50:15.102 D/guerrilla( 5764): PlayerService.StartPlayback
> 09-06 17:50:15.132 I/AwesomePlayer(   40): setDataSource_l(URL suppressed)

PlayerService.StartPlayback() invokes MediaPlayer.SetDataSource(), which (eventually) invokes AwesomePlayer::setDataSource_l()!

(line 284)

Later, the phone state changes:

> 09-06 17:50:15.882 I/guerrilla( 5764): PlayerService=>OnPhoneStateChanged state:Idle

At which point everything breaks:

> 09-06 17:51:35.795 I/ChromiumHTTPDataSourceSupport(   40): Request failed with status 4 and os_error -105
> 09-06 17:51:35.795 I/AwesomePlayer(   40): mConnectingDataSource->connect() returned -1004

The above is ENTIRELY outside of Xamarin.Android's control. It's in an entirely different process (pid 40, as opposed to your process' pid 5764).

The error is then percolated back to your process:

> 09-06 17:51:35.801 E/MediaPlayer( 5764): error (1, -1004)
> 09-06 17:51:35.813 E/MediaPlayer( 5764): Error (1,-1004)
> 09-06 17:51:35.831 I/guerrilla( 5764): Connection: Connected
> 09-06 17:51:35.881 E/guerrilla( 5764): Media Error Unknown -1004

...and so it repeats (three times, in Debug Log).

Cursory search of the AOSP source indicates that error -1004 is ERROR_IO:


ERROR_IO is being raised by ChromiumHTTPDataSourceSupport:

> 09-06 17:51:35.795 I/ChromiumHTTPDataSourceSupport(   40): Request failed with status 4 and os_error -105


What I can't easily find is what os_error -105 would be.

Regardless, your app is losing the connection to the URL because AwesomePlayer is losing the connection. AwesomePlayer is in another process; even if there were an error in the Xamarin.Android binding, I cannot think of an error that would cause AwesomePlayer to have errors.

> Although some third party media streaming apps do work in the
> same environment and on the same devices (we tested Droid, and Galaxy S II).

It would be interesting to see the `adb logcat` output for those apps in the same usage scenario. I suspect that they too will have the messages from AwesomePlayer and/or ChromiumHTTPDataSourceSupport.

It would also be interesting to know if using `new MediaPlayer` instead of _mediaPlayer.Reset() changes anything.
Comment 7 Allie Miller 2013-09-19 13:52:42 UTC
Created attachment 4933 [details]
Updated Test Case
Comment 9 Jonathan Pryor 2013-09-20 10:58:12 UTC
Thank you for the updated test case.

Please provide repro steps. What am I looking for, exactly?

As a "stab-in-the-dark", I ran the app, and heard audio. I then turned off Wi-Fi. The audio stopped playing, and I see the following in logcat:

> I/ChromiumHTTPDataSourceSupport(  122): OnReadCompleted, read failed, status 4


...and an app crash:

> D/guerrilla(13642): Parsing metadata... 
> W/SocketClient(  117): write error (Broken pipe)
> E/mono    (13642): 
> E/mono    (13642): Unhandled Exception:
> E/mono    (13642): System.Net.WebException: Error: NameResolutionFailure
> E/mono    (13642):   at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
> E/mono    (13642):   at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0 
> E/mono    (13642):   at Guerrilla.MetaDataReader.GetMetadataStream (System.Int32& icyMetaint) [0x00000] in <filename unknown>:0 
> E/mono    (13642):   at Guerrilla.MetaDataReader.ParseMetaData (System.Action`1 callback) [0x00000] in <filename unknown>:0 
> E/mono    (13642):   at Guerrilla.MetaDataReader.LoadTrackMetadata (System.Object source) [0x00000] in <filename unknown>:0 
> E/mono    (13642):   at System.Threading.Timer+Scheduler.TimerCB (System.Object o) [0x00000] in <filename unknown>:0 
> I/ActivityManager(  369): Process Guerrilla.Guerrilla (pid 13642) has died.

Apparently the app doesn't like the network disappearing while it's running. (Go figure.)

Restart the app, and it notifies that the connection has been lost, and to reconnect to the internet. Fair enough.

Re-enable Wi-Fi, return to the app, and I can hit Play and hear audio.

I'm not at all sure where to go with the above. Clearly the app needs to be resilient to transient network failures (i.e. not crash with NameResolutionFailure when the network disappears), but beyond that...
Comment 11 Allie Miller 2013-09-23 10:17:09 UTC
Created attachment 4957 [details]
Latest Test Case To Reproduce issue
Comment 14 Jonathan Pryor 2013-11-04 13:28:11 UTC
Marking as INVALID as per Comment #13.