From 049d905d7dc5b5318de2b1a402a185fc35913e93 Mon Sep 17 00:00:00 2001 From: Javi Rueda Date: Fri, 26 Jun 2020 21:06:12 +0200 Subject: [PATCH 1/6] Bintray repository is no longer needed LBRY SDK is now hosted on JCenter, which is already available out-of-the-box on Android Studio. The Bintray url is no longer reguired. When building LBRY on F-Droid, I have to remove this line on the build YAML script and it is building correctly. On my local machine, it builds after commenting it. --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3bbaee86..e14841db 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,6 @@ allprojects { google() jcenter() maven { url "https://jitpack.io" } - maven { url "https://dl.bintray.com/lbryio/io.lbry" } } } -- 2.45.3 From e829d5483a7c292733f367a2e0c46c12da28bbbd Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 1 Jul 2020 14:51:31 +0100 Subject: [PATCH 2/6] check buffering events --- .../lbry/browser/tasks/BufferEventTask.java | 59 +++++++++++++++++++ .../ui/findcontent/FileViewFragment.java | 23 ++++++++ .../io/lbry/browser/utils/LbryAnalytics.java | 1 + 3 files changed, 83 insertions(+) create mode 100644 app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java diff --git a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java new file mode 100644 index 00000000..310da3ae --- /dev/null +++ b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java @@ -0,0 +1,59 @@ +package io.lbry.browser.tasks; + +import android.os.AsyncTask; +import android.util.Log; + +import org.json.JSONObject; + +import java.util.concurrent.TimeUnit; + +import io.lbry.browser.utils.Helper; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class BufferEventTask extends AsyncTask { + private static final String TAG = "LbryBufferEvent"; + private static final String ENDPOINT = "https://api.lbry.tv/api/v1/metric/ui"; + + private String streamUrl; + private String userIdHash; + private long streamDuration; + private long streamPosition; + + public BufferEventTask(String streamUrl, long streamDuration, long streamPosition, String userIdHash) { + this.streamUrl = streamUrl; + this.streamDuration = streamDuration; + this.streamPosition = streamPosition; + this.userIdHash = userIdHash; + } + + protected Void doInBackground(Void... params) { + JSONObject requestBody = new JSONObject(); + try { + requestBody.put("name", "buffer"); + requestBody.put("mobile", true); + requestBody.put("url", streamUrl); + requestBody.put("stream_duration", streamDuration); + requestBody.put("stream_position", streamPosition); + requestBody.put("user_id_hash", userIdHash); + + RequestBody body = RequestBody.create(requestBody.toString(), Helper.JSON_MEDIA_TYPE); + Request request = new Request.Builder().url(ENDPOINT).post(body).build(); + OkHttpClient client = new OkHttpClient.Builder(). + writeTimeout(60, TimeUnit.SECONDS). + readTimeout(60, TimeUnit.SECONDS). + build(); + + Response response = client.newCall(request).execute(); + String responseString = response.body().string(); + Log.d(TAG, responseString); + } catch (Exception ex) { + // we don't want to fail if a buffer event fails to register + Log.d(TAG, String.format("buffer event log failed: %s", ex.getMessage()), ex); + } + + return null; + } +} diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index a3d0a1d1..196dbd9e 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -119,6 +119,7 @@ import io.lbry.browser.model.UrlSuggestion; import io.lbry.browser.model.WalletBalance; import io.lbry.browser.model.lbryinc.Reward; import io.lbry.browser.model.lbryinc.Subscription; +import io.lbry.browser.tasks.BufferEventTask; import io.lbry.browser.tasks.CommentCreateWithTipTask; import io.lbry.browser.tasks.CommentListHandler; import io.lbry.browser.tasks.CommentListTask; @@ -163,6 +164,7 @@ public class FileViewFragment extends BaseFragment implements WalletBalanceListener { private static final int RELATED_CONTENT_SIZE = 16; private static final String DEFAULT_PLAYBACK_SPEED = "1x"; + private static final String CDN_PREFIX = "https://cdn.lbryplayer.xyz"; private PlayerControlView castControlView; private Player currentPlayer; @@ -290,6 +292,27 @@ public class FileViewFragment extends BaseFragment implements loadingNewClaim = false; } } else if (playbackState == Player.STATE_BUFFERING) { + if (MainActivity.appPlayer != null && MainActivity.appPlayer.getCurrentPosition() > 0) { + // we only want to log a buffer event after the media has already started playing + String mediaSourceUrl = getStreamingUrl(); + long duration = MainActivity.appPlayer.getDuration(); + long position = MainActivity.appPlayer.getCurrentPosition(); + // TODO: Determine a hash for the userId + String userIdHash = Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0"; + if (mediaSourceUrl.startsWith(CDN_PREFIX)) { + BufferEventTask bufferEvent = new BufferEventTask(getStreamingUrl(), duration, position, userIdHash); + bufferEvent.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); + } else { + // sdk stream buffer events should be handled differently + Bundle bundle = new Bundle(); + bundle.putString("url", claim.getPermanentUrl()); + bundle.putLong("stream_duration", duration); + bundle.putLong("stream_position", position); + bundle.putString("user_id_hash", userIdHash); + LbryAnalytics.logEvent(LbryAnalytics.EVENT_BUFFER, bundle); + } + } + showBuffering(); } else { hideBuffering(); diff --git a/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java b/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java index 17b66b69..d5eadd7c 100644 --- a/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java +++ b/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java @@ -11,6 +11,7 @@ public class LbryAnalytics { public static final String EVENT_APP_ERROR = "app_error"; public static final String EVENT_APP_LAUNCH = "app_launch"; public static final String EVENT_COMMENT_CREATE = "comment_create"; + public static final String EVENT_BUFFER = "buffer"; public static final String EVENT_EMAIL_ADDED = "email_added"; public static final String EVENT_EMAIL_VERIFIED = "email_verified"; public static final String EVENT_FIRST_RUN_COMPLETED = "first_run_completed"; -- 2.45.3 From c737b750fcfaa8c79ab50adc79eae9b7a3b08ef1 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 1 Jul 2020 15:00:55 +0100 Subject: [PATCH 3/6] use the claim permanent url for buffer events --- .../java/io/lbry/browser/ui/findcontent/FileViewFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index 196dbd9e..d30a159a 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -300,7 +300,7 @@ public class FileViewFragment extends BaseFragment implements // TODO: Determine a hash for the userId String userIdHash = Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0"; if (mediaSourceUrl.startsWith(CDN_PREFIX)) { - BufferEventTask bufferEvent = new BufferEventTask(getStreamingUrl(), duration, position, userIdHash); + BufferEventTask bufferEvent = new BufferEventTask(claim.getPermanentUrl(), duration, position, userIdHash); bufferEvent.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); } else { // sdk stream buffer events should be handled differently -- 2.45.3 From 3930b36b4abe7166eb2fbdb2fab22081598beab7 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 13 Jul 2020 17:18:57 +0100 Subject: [PATCH 4/6] update request parameters --- .../lbry/browser/tasks/BufferEventTask.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java index 310da3ae..33a6ffec 100644 --- a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java @@ -21,9 +21,11 @@ public class BufferEventTask extends AsyncTask { private String userIdHash; private long streamDuration; private long streamPosition; + private long bufferDuration; - public BufferEventTask(String streamUrl, long streamDuration, long streamPosition, String userIdHash) { + public BufferEventTask(String streamUrl, long streamDuration, long streamPosition, long bufferDuration, String userIdHash) { this.streamUrl = streamUrl; + this.bufferDuration = bufferDuration; this.streamDuration = streamDuration; this.streamPosition = streamPosition; this.userIdHash = userIdHash; @@ -31,13 +33,17 @@ public class BufferEventTask extends AsyncTask { protected Void doInBackground(Void... params) { JSONObject requestBody = new JSONObject(); + JSONObject data = new JSONObject(); try { - requestBody.put("name", "buffer"); - requestBody.put("mobile", true); - requestBody.put("url", streamUrl); - requestBody.put("stream_duration", streamDuration); - requestBody.put("stream_position", streamPosition); - requestBody.put("user_id_hash", userIdHash); + data.put("url", streamUrl); + data.put("position", streamPosition); + data.put("stream_duration", streamDuration); + data.put("duration", bufferDuration); + + requestBody.put("device", "mobile"); + requestBody.put("type", "buffering"); + requestBody.put("client", userIdHash); + requestBody.put("data", data); RequestBody body = RequestBody.create(requestBody.toString(), Helper.JSON_MEDIA_TYPE); Request request = new Request.Builder().url(ENDPOINT).post(body).build(); -- 2.45.3 From d9047b64e7f478c188d64c279b8ce7ab0f254ddf Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 21 Jul 2020 19:25:18 +0100 Subject: [PATCH 5/6] hash user ids for buffer events --- .../io/lbry/browser/tasks/BufferEventTask.java | 4 ++-- .../browser/ui/findcontent/FileViewFragment.java | 4 ++-- .../main/java/io/lbry/browser/utils/Helper.java | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java index 33a6ffec..82dd89b7 100644 --- a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java @@ -15,7 +15,7 @@ import okhttp3.Response; public class BufferEventTask extends AsyncTask { private static final String TAG = "LbryBufferEvent"; - private static final String ENDPOINT = "https://api.lbry.tv/api/v1/metric/ui"; + private static final String ENDPOINT = "https://collector-service.lbry.tv/api/v1/events/video"; private String streamUrl; private String userIdHash; @@ -40,7 +40,7 @@ public class BufferEventTask extends AsyncTask { data.put("stream_duration", streamDuration); data.put("duration", bufferDuration); - requestBody.put("device", "mobile"); + requestBody.put("device", "android"); requestBody.put("type", "buffering"); requestBody.put("client", userIdHash); requestBody.put("data", data); diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index d30a159a..84422474 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -298,9 +298,9 @@ public class FileViewFragment extends BaseFragment implements long duration = MainActivity.appPlayer.getDuration(); long position = MainActivity.appPlayer.getCurrentPosition(); // TODO: Determine a hash for the userId - String userIdHash = Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0"; + String userIdHash = Helper.SHA256(Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0"); if (mediaSourceUrl.startsWith(CDN_PREFIX)) { - BufferEventTask bufferEvent = new BufferEventTask(claim.getPermanentUrl(), duration, position, userIdHash); + BufferEventTask bufferEvent = new BufferEventTask(claim.getPermanentUrl(), duration, position, 1, userIdHash); bufferEvent.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); } else { // sdk stream buffer events should be handled differently diff --git a/app/src/main/java/io/lbry/browser/utils/Helper.java b/app/src/main/java/io/lbry/browser/utils/Helper.java index a2883ca2..eac70533 100644 --- a/app/src/main/java/io/lbry/browser/utils/Helper.java +++ b/app/src/main/java/io/lbry/browser/utils/Helper.java @@ -30,6 +30,8 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.gms.common.util.Hex; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -37,6 +39,9 @@ import org.json.JSONObject; import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -766,4 +771,14 @@ public final class Helper { } return id.toString(); } + + public static String SHA256(String value) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(value.getBytes("UTF-8")); + return Hex.bytesToStringLowercase(hash); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { + return null; + } + } } -- 2.45.3 From 9283c3eecb41a4fc397e492c5d2dc8c7711838ab Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 21 Jul 2020 19:29:56 +0100 Subject: [PATCH 6/6] update buffer event endpoint --- app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java index 82dd89b7..18ca7fe0 100644 --- a/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/BufferEventTask.java @@ -15,7 +15,7 @@ import okhttp3.Response; public class BufferEventTask extends AsyncTask { private static final String TAG = "LbryBufferEvent"; - private static final String ENDPOINT = "https://collector-service.lbry.tv/api/v1/events/video"; + private static final String ENDPOINT = "https://collector-service.api.lbry.tv/api/v1/events/video"; private String streamUrl; private String userIdHash; @@ -54,7 +54,7 @@ public class BufferEventTask extends AsyncTask { Response response = client.newCall(request).execute(); String responseString = response.body().string(); - Log.d(TAG, responseString); + Log.d(TAG, String.format("buffer event sent: %s", responseString)); } catch (Exception ex) { // we don't want to fail if a buffer event fails to register Log.d(TAG, String.format("buffer event log failed: %s", ex.getMessage()), ex); -- 2.45.3