Exception on streaming the audio on android media player, on okhttp buffering - android

E/JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
java.lang.ArrayIndexOutOfBoundsException: length=8192; index=8192
at com.android.okhttp.okio.Buffer.writeByte(Buffer.java:973)
at com.android.okhttp.internal.Platform.concatLengthPrefixed(Platform.java:212)
at com.android.okhttp.internal.Platform.configureTlsExtensions(Platform.java:116)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:187)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26)
at android.media.MediaHTTPConnection.seekTo(MediaHTTPConnection.java:212)
at android.media.MediaHTTPConnection.getSize(MediaHTTPConnection.java:374)
at android.media.IMediaHTTPConnection$Stub.onTransact(IMediaHTTPConnection.java:81)
at android.os.Binder.execTransact(Binder.java:731)
This exception occurs on android media player streaming and buffering, the player got stuck on the same position for unusual period of time and sometimes forever.

I don't think there's much you can do. It's been reported to the okhttp devs. But, as they point out, the error is with the internally packaged version of okhttp that is included with android. There's no bug with square's externally developed version, so they have rightfully closed the issue as a non-issue.
The bug has been reported to google, but it doesn't look like any action has been taken in the last almost 2 years.
Perhaps you could include the newer, upstream version of okhttp from square in your project and somehow tell MediaHTTPConnection to use the okhttp3 implementation of HttpURLConnection. There's the OkUrlFactory that could be used with java's URL.setURLStreamHandlerFactory. However that's deprecated and it might not be a good idea to override the built-in url stream handler logic.
In fact, it's been removed from recent versions of okhttp. The dev who removed it did make an ObsoleteUrlFactory.java that you can copy/paste yourself into your project and use as:
OkHttpClient okHttpClient = new OkHttpClient();
URL.setURLStreamHandlerFactory(new ObsoleteUrlFactory(okHttpClient));

Related

React native video unable to play m3u8 file

Problem
I'm trying to stream a m3u8 file in a react native app (for android TV) and I'm getting this error:
LOG {"error": {"errorCode": "22004", "errorException": "com.google.android.exoplayer2.ExoPlaybackException: Source error", "errorStackTrace": "com.google.android.exoplayer2.ExoPlaybackException: Source error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:604)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:223)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 403
at com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource.open(OkHttpDataSource.java:329)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:258)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
at com.google.android.exoplayer2.upstream.DataSourceInputStream.checkOpened(DataSourceInputStream.java:99)
at com.google.android.exoplayer2.upstream.DataSourceInputStream.open(DataSourceInputStream.java:62)
at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:174)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
", "errorString": "ExoPlaybackException: ERROR_CODE_IO_BAD_HTTP_STATUS"}}
I don't know java so from the above traceback I'm guessing that the server is responding with an HTTP 403 and therefore it is unable to stream the file.
What I've tried
This one is not much of a solution but I tried switching to the react-native-video-player instead of react-native-video but that didn't work.
I tried passing the type: 'm3u8' and type: 'hls' inside the source attribute of the video tag along with the uri and this didn't help at all.
Tried to check if another m3u8 url (i.e. from another domain/server) is working, and it is working.
Downgrading react-native-video version, problem persists with different error message.
I decided to ssh into my android TV and directly use curl to fetch the m3u8 file and it responds with this:
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Moreover, many of the issues I found on github having a similar problem contain a URL that gives the same response when fetched directly with curl. Interestingly, if I use the fetch API in JS to console log the response from the m3u8 url, it works perfectly. So I'm guessing the problem is somewhere in exoplayer.
Specs
react-native : 'npm:react-native-tvos#0.69.6-0'
react-native-video : '^6.0.0-alpha.3'
Android TV : Tested both on a Raspberry Pi running Android TV (LineageOS I think) and an actual android tv set top box with same results.
The issue was with the user-agent header, exoplayer was setting a user-agent which was causing an HTTP 403. I had to use a proxy to figure this out and still have no clue as per why android studio was not showing the request that had an error.

E/com.facebook.appevents.RestrictiveDataManager: updateRulesFromSetting failed

When I launch my app from Android Studio, with Facebook SDK installed on my device, Xiaomi Mi A2, it triggers the same error trhee times. It does not stop the app, but I don't know if I am missing something or simply, it is not important, but in the end, it is an error and I want to clarify it.
I am using Android Studio 3.4.1, Android 9 on the Xiaomi A2 and the new clause in build.gradle file is implementation 'com.facebook.android:facebook-android-sdk:5.1.0'. Error has not appeared before upgrading Facebook SDK.
This is what appears in Logcat:
2019-06-24 18:24:31.202 25105-25136/com.myapp
E/com.facebook.appevents.RestrictiveDataManager:
updateRulesFromSetting failed
org.json.JSONException: End of input at character 0 of
at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
at org.json.JSONTokener.nextValue(JSONTokener.java:97)
at org.json.JSONArray.(JSONArray.java:92)
at org.json.JSONArray.(JSONArray.java:108)
at com.facebook.appevents.RestrictiveDataManager.updateFromSetting(RestrictiveDataManager.java:32)
at com.facebook.internal.FetchedAppSettingsManager.parseAppSettingsFromJSON(FetchedAppSettingsManager.java:323)
at com.facebook.internal.FetchedAppSettingsManager.access$000(FetchedAppSettingsManager.java:63)
at com.facebook.internal.FetchedAppSettingsManager$1.run(FetchedAppSettingsManager.java:181)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
EDIT
The issue has been fixed in version 5.1.1.
Revert to 5.0.3 to get rid of this.
5.1.0 is actually crashing in production at this method (there's a bug report here). GitHub commits of this file show its rather flawed, the method is called from multiple threads concluding to a concurrency crash because it's using a static ArrayList.
Lately the core FB SDK is kinda bloated with useless stuff and low-quality code. The codeless stuff "feature" that simply can't even be turned off is especially a horror to look at. If you don't strictly need the FB SDK in your app, I'd avoid it until they get their shit figured out.

How to fix a "java.io.IOException: unexpected end of stream on Connection" exception in HTTPClient on .NetStandard

I have been scratching my head with this one for a while. I'm building an Android app in Xamarin and I have a login POST request that mostly works, but will occasionally recieve this error. I notify the user and tell them to try again but I am still getting the error far too often and want to fix it so the app provides a smoother experience.
Here is the stack trace I have logged on App Center:
LoginProvider+d__1.MoveNext () C:\source\repos{MyApp}{MyApp}{MyApp}\Services\LoginProvider.cs:35
java.io.IOException: unexpected end of stream on Connection{testclarity.i-menzies.com:443, proxy=DIRECT# hostAddress=62.244.173.166 cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1} (recycle count=0)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:210)
com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:905)
com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:789)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:501)
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
Caused by: java.io.EOFException: \n not found: size=0 content=...
com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
I am using .NETStandard 2.0, with Xamarin Forms 3.2.0.871581.
I have scoured most of Google and identified that this is an issue with various Android libraries, especially OkHttp (the same one mentioned in my stack trace). I've tried investigating the .NETStandard source on Github to identify the possible cause, but I find the project very difficult to navigate, especially as this problem seems to be Android specific. Any advice on finding the right source would be ideal.
Things I have tried based on suggestions from the internet:
Setting my connection header to closed.
Setting my transfer encoding
to chunked.
Swapping out the Android HttpClient implementation from
Android to Default in the Android project's properties.
These seem to be among the popular suggestions online, some of which work for people, some of which don't.
Another common suggestion is setting the OkHttp library's configuration to OkHTTP.setRetryOnConnectionFailure(true), which apparently fixes the problem for many people, as suggested here: https://github.com/square/okhttp/issues/1517#issuecomment-144069139.
Also, a similar bug seems to have been filed in Xamarin.Android here: https://bugzilla.xamarin.com/show_bug.cgi?id=41100. But this has been marked as fixed. I'm not sure whether this would feed into my Xamarin Forms project.
Does anyone know how I can fix this problem or how I can investigate further beyond what I've already tried?
After following the information in this link: https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=macos
And changing my HTTPHandler to the native android handler:
The Xamarin.Android HttpClient configuration is in Project Options >
Android Options, then click the Advanced Options button.
These are the recommended settings for TLS 1.2 support:
Visual Studio Android Options
The one extra bit I missed was:
Projects must reference the System.Net.Http assembly.
Make sure your project references System.Net.Http otherwise it will still use OKHttp
You can just go the Android Project > Properties > AssemblyInfo.cs file.
Open the AssemblyInfo file and add the following line at the end:
[assembly: Application(UsesCleartextTraffic = true)]
This helped me solve my problem. I hope it helps you also
I was having the same issue and been tracing for this fix. My project reference
to System.Net.Http.
I was changing my HTTPHandler to the native android handler when I got this exception but getting kinda similar system exception when using a different HTTPHandler.
I tried a lot of suggestions and finally fixes the issue by using https in my base URL. Here's my reference: https://github.com/square/okhttp/issues/1517#issuecomment-560486265
IMO, the fix might be different in each case, so you might want to try other suggestions.

App crashes with the error INVALID_STATE_ERR

I am using react native. I am getting the crashes on crashlytics with the error INVALID_STATE_ERR.I am using FireBase Crashlytics. I am also using MQTT client for making web socket connection.
I am not able to figure out the reason of crashing the app. Is it due to the MQTT WebSockets or due to the error occurring on javascript thread? I am also not getting any relevant message from the stack trace either.
I am pasting my Stack Trace below.
Fatal Exception: com.facebook.react.common.JavascriptException: INVALID_STATE_ERR, stack:
value#79:1340
_socket_send#557:21101
_on_socket_open#557:16408
<unknown>#557:628
value#63:1501
<unknown>#79:4566
value#32:1363
value#18:3559
<unknown>#18:1044
value#18:2986
value#18:1016
at com.facebook.react.modules.core.ExceptionsManagerModule.showOrThrowError(ExceptionsManagerModule.java:54)
at com.facebook.react.modules.core.ExceptionsManagerModule.reportFatalException(ExceptionsManagerModule.java:38)
at java.lang.reflect.Method.invoke(Method.java)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:160)
at com.facebook.react.bridge.queue.NativeRunnable.run(NativeRunnable.java)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
at android.os.Looper.loop(Looper.java:148)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:192)
at java.lang.Thread.run(Thread.java:818)
Can I get more insight to fix this issue?
According to this Wix GitHub issue, it is caused by:
Too many views on older phones. RNN added a few nested views, but it appears I may have too many anyways.
That issue links to a pull request on React Native's GitHub repo, which should now be merged in. It mentions the issue is on pre-API 21, so I suggest you try your code on later APIs and see if it persists.
Either way, reducing the number of views (or requests, in this case?) seems a good first step.

IncompatibleClassChangeError from okhttp3.internal.Util.closeQuietly()

Seeing the following stack on old versions of Android (4.3 and earlier):
Caused by: java.lang.IncompatibleClassChangeError: interface not implemented
at okhttp3.internal.Util.closeQuietly(Util.java:100)
at okhttp3.internal.connection.StreamAllocation.streamFailed(StreamAllocation.java:332)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.recover(RetryAndFollowUpInterceptor.java:209)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:132)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
at okhttp3.RealCall.execute(RealCall.java:63)
This seems to suggest an incompatibility between okhttp and Java 6, where java.net.Socket doesn't implement Closeable.
And the problem appears to occur primarily as a result of a failed stream. It was difficult to reproduce until we started calling this php page (borrowed from https://stackoverflow.com/a/141026/315702), which forces a stream failure on the client side:
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
sleep(30);
echo('Text user will never see');
?>
This appears to be a bug with the current okhttp 3.6.0-SNAPSHOT build. I filed a bug report on the okhttp github site. The exception is thrown when the connection closes unexpectedly. [Update: the bug was quickly fixed by replacing Closeable with Socket for backward compatibility with Java 6 in this pull request.]
In our case, the real heart of the problem was that we didn't mean to use okhttp 3.6.0-SNAPSHOT in the first place. In our build.gradle, we specified 3.4.1. It turned out one of our third-party libraries had a dependency on okhttp:+, which we discovered via the following gradle command:
./gradlew -q :app:dependencyInsight --dependency okhttp --configuration compile
Because of this, we were pulling in whatever happens to be the latest version of okhttp. In our case, the culprit library was the okhttp extension to exoplayer. By excluding the unwanted module dependency on okhttp:+, we were able to avoid loading 3.6.0-SNAPSHOT:
compile('com.google.android.exoplayer:extension-okhttp:r2.0.4') {
exclude module: 'okhttp'
}

Categories

Resources