blob: 2e6be1bd0fec438b7e68880bae656358a1990f35 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/feed/v2/feed_stream.h"
#include <string>
#include <vector>
#include "base/android/callback_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/strings/string_piece.h"
#include "chrome/android/chrome_jni_headers/FeedStream_jni.h"
#include "chrome/browser/android/feed/v2/feed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/feed/core/proto/v2/ui.pb.h"
#include "components/feed/core/v2/public/feed_api.h"
#include "components/feed/core/v2/public/feed_service.h"
#include "components/variations/variations_ids_provider.h"
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
using base::android::ToJavaByteArray;
namespace feed {
namespace android {
static jlong JNI_FeedStream_Init(JNIEnv* env,
const JavaParamRef<jobject>& j_this,
jboolean is_for_you_stream) {
return reinterpret_cast<intptr_t>(new FeedStream(j_this, is_for_you_stream));
}
static base::android::ScopedJavaLocalRef<jintArray>
JNI_FeedStream_GetExperimentIds(JNIEnv* env) {
auto* variations_ids_provider =
variations::VariationsIdsProvider::GetInstance();
DCHECK(variations_ids_provider != nullptr);
return base::android::ToJavaIntArray(
env, variations_ids_provider->GetVariationsVectorForWebPropertiesKeys());
}
FeedStream::FeedStream(const JavaRef<jobject>& j_this,
jboolean is_for_you_stream)
: ::feed::FeedStreamSurface(is_for_you_stream ? kForYouStream
: kWebFeedStream),
feed_stream_api_(nullptr) {
java_ref_.Reset(j_this);
FeedService* service = FeedServiceFactory::GetForBrowserContext(
ProfileManager::GetLastUsedProfile());
if (!service)
return;
feed_stream_api_ = service->GetStream();
}
FeedStream::~FeedStream() {
if (feed_stream_api_)
feed_stream_api_->DetachSurface(this);
}
void FeedStream::StreamUpdate(const feedui::StreamUpdate& stream_update) {
JNIEnv* env = base::android::AttachCurrentThread();
int32_t data_size = stream_update.ByteSize();
std::vector<uint8_t> data;
data.resize(data_size);
stream_update.SerializeToArray(data.data(), data_size);
ScopedJavaLocalRef<jbyteArray> j_data =
ToJavaByteArray(env, data.data(), data_size);
Java_FeedStream_onStreamUpdated(env, java_ref_, j_data);
}
void FeedStream::ReplaceDataStoreEntry(base::StringPiece key,
base::StringPiece data) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_FeedStream_replaceDataStoreEntry(
env, java_ref_, base::android::ConvertUTF8ToJavaString(env, key),
base::android::ToJavaByteArray(
env, reinterpret_cast<const uint8_t*>(data.data()), data.size()));
}
void FeedStream::RemoveDataStoreEntry(base::StringPiece key) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_FeedStream_removeDataStoreEntry(
env, java_ref_, base::android::ConvertUTF8ToJavaString(env, key));
}
void FeedStream::LoadMore(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jobject>& callback_obj) {
if (!feed_stream_api_)
return;
feed_stream_api_->LoadMore(
*this, base::BindOnce(&base::android::RunBooleanCallbackAndroid,
ScopedJavaGlobalRef<jobject>(callback_obj)));
}
void FeedStream::ProcessThereAndBackAgain(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jbyteArray>& data) {
if (!feed_stream_api_)
return;
std::string data_string;
base::android::JavaByteArrayToString(env, data, &data_string);
feed_stream_api_->ProcessThereAndBackAgain(data_string);
}
void FeedStream::ProcessViewAction(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jbyteArray>& data) {
if (!feed_stream_api_)
return;
std::string data_string;
base::android::JavaByteArrayToString(env, data, &data_string);
feed_stream_api_->ProcessViewAction(data_string);
}
int FeedStream::ExecuteEphemeralChange(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jbyteArray>& data) {
if (!feed_stream_api_)
return 0;
std::string data_string;
base::android::JavaByteArrayToString(env, data, &data_string);
return feed_stream_api_
->CreateEphemeralChangeFromPackedData(GetStreamType(), data_string)
.GetUnsafeValue();
}
void FeedStream::CommitEphemeralChange(JNIEnv* env,
const JavaParamRef<jobject>& obj,
int change_id) {
if (!feed_stream_api_)
return;
feed_stream_api_->CommitEphemeralChange(GetStreamType(),
EphemeralChangeId(change_id));
}
void FeedStream::DiscardEphemeralChange(JNIEnv* env,
const JavaParamRef<jobject>& obj,
int change_id) {
if (!feed_stream_api_)
return;
feed_stream_api_->RejectEphemeralChange(GetStreamType(),
EphemeralChangeId(change_id));
}
void FeedStream::SurfaceOpened(JNIEnv* env, const JavaParamRef<jobject>& obj) {
if (feed_stream_api_ && !attached_) {
attached_ = true;
feed_stream_api_->AttachSurface(this);
}
}
void FeedStream::SurfaceClosed(JNIEnv* env, const JavaParamRef<jobject>& obj) {
if (feed_stream_api_ && attached_) {
attached_ = false;
feed_stream_api_->DetachSurface(this);
}
}
bool FeedStream::IsActivityLoggingEnabled(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
return feed_stream_api_ &&
feed_stream_api_->IsActivityLoggingEnabled(GetStreamType());
}
base::android::ScopedJavaLocalRef<jstring> FeedStream::GetSessionId(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj) {
return base::android::ConvertUTF8ToJavaString(
env, feed_stream_api_ ? feed_stream_api_->GetSessionId() : std::string());
}
void FeedStream::ReportOpenAction(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& slice_id) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportOpenAction(
GetStreamType(), base::android::ConvertJavaStringToUTF8(env, slice_id));
}
void FeedStream::ReportOpenInNewTabAction(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& slice_id) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportOpenInNewTabAction(
GetStreamType(), base::android::ConvertJavaStringToUTF8(env, slice_id));
}
void FeedStream::ReportSliceViewed(JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jstring>& slice_id) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportSliceViewed(
GetSurfaceId(), GetStreamType(),
base::android::ConvertJavaStringToUTF8(env, slice_id));
}
void FeedStream::ReportFeedViewed(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportFeedViewed(GetSurfaceId());
}
void FeedStream::ReportPageLoaded(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jboolean in_new_tab) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportPageLoaded();
}
void FeedStream::ReportStreamScrolled(JNIEnv* env,
const JavaParamRef<jobject>& obj,
int distance_dp) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportStreamScrolled(GetStreamType(), distance_dp);
}
void FeedStream::ReportStreamScrollStart(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (!feed_stream_api_)
return;
feed_stream_api_->ReportStreamScrollStart();
}
void FeedStream::ReportOtherUserAction(JNIEnv* env,
const JavaParamRef<jobject>& obj,
int action_type) {
feed_stream_api_->ReportOtherUserAction(
GetStreamType(), static_cast<FeedUserActionType>(action_type));
}
} // namespace android
} // namespace feed