blob: 37acfe93c306f1f6dff5ec1614ee81ec6603dd7b [file] [log] [blame]
// Copyright 2015 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/history_report/history_report_jni_bridge.h"
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "chrome/browser/android/history_report/data_observer.h"
#include "chrome/browser/android/history_report/data_provider.h"
#include "chrome/browser/android/history_report/delta_file_commons.h"
#include "chrome/browser/android/history_report/delta_file_service.h"
#include "chrome/browser/android/history_report/usage_report_util.h"
#include "chrome/browser/android/history_report/usage_reports_buffer_service.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/history/core/browser/history_service.h"
#include "content/public/browser/browser_thread.h"
#include "jni/HistoryReportJniBridge_jni.h"
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
namespace history_report {
static jlong JNI_HistoryReportJniBridge_Init(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
HistoryReportJniBridge* bridge = new HistoryReportJniBridge(env, obj);
return reinterpret_cast<intptr_t>(bridge);
}
HistoryReportJniBridge::HistoryReportJniBridge(JNIEnv* env, jobject obj)
: weak_java_provider_(env, obj) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Profile* profile = g_browser_process->profile_manager()->
GetLastUsedProfile()->GetOriginalProfile();
delta_file_service_.reset(new DeltaFileService(profile->GetPath()));
usage_reports_buffer_service_.reset(
new UsageReportsBufferService(profile->GetPath()));
usage_reports_buffer_service_->Init();
bookmark_model_.reset(BookmarkModelFactory::GetForBrowserContext(profile));
base::Callback<void(void)> on_change = base::Bind(
&history_report::HistoryReportJniBridge::NotifyDataChanged,
base::Unretained(this));
base::Callback<void(void)> on_clear = base::Bind(
&history_report::HistoryReportJniBridge::NotifyDataCleared,
base::Unretained(this));
base::Callback<void(void)> stop_reporting = base::Bind(
&history_report::HistoryReportJniBridge::StopReporting,
base::Unretained(this));
history::HistoryService* history_service =
HistoryServiceFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS);
data_observer_.reset(new DataObserver(on_change,
on_clear,
stop_reporting,
delta_file_service_.get(),
usage_reports_buffer_service_.get(),
bookmark_model_.get(),
history_service));
data_provider_.reset(new DataProvider(profile,
delta_file_service_.get(),
bookmark_model_.get()));
}
HistoryReportJniBridge::~HistoryReportJniBridge() {}
jlong HistoryReportJniBridge::TrimDeltaFile(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong seq_no_lower_bound) {
return delta_file_service_->Trim(seq_no_lower_bound);
}
base::android::ScopedJavaLocalRef<jobjectArray> HistoryReportJniBridge::Query(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong last_seq_no,
jint limit) {
std::unique_ptr<std::vector<DeltaFileEntryWithData>> entries =
data_provider_->Query(last_seq_no, limit);
ScopedJavaLocalRef<jobjectArray> jentries_array =
history_report::Java_HistoryReportJniBridge_createDeltaFileEntriesArray(
env, entries->size());
int64_t max_seq_no = 0;
for (size_t i = 0; i < entries->size(); ++i) {
const DeltaFileEntryWithData& entry = (*entries)[i];
max_seq_no = max_seq_no < entry.SeqNo() ? entry.SeqNo() : max_seq_no;
history_report::Java_HistoryReportJniBridge_setDeltaFileEntry(
env, jentries_array, i, entry.SeqNo(),
base::android::ConvertUTF8ToJavaString(env, entry.Type()),
base::android::ConvertUTF8ToJavaString(env, entry.Id()),
base::android::ConvertUTF8ToJavaString(env, entry.Url()), entry.Score(),
base::android::ConvertUTF16ToJavaString(env, entry.Title()),
base::android::ConvertUTF8ToJavaString(env, entry.IndexedUrl()));
}
// Check if all entries from delta file were synced and start reporting usage
// if it's true.
if (entries->empty() || delta_file_service_->Query(max_seq_no, 1)->empty())
StartReporting();
return jentries_array;
}
base::android::ScopedJavaLocalRef<jobjectArray>
HistoryReportJniBridge::GetUsageReportsBatch(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jint batch_size) {
std::unique_ptr<std::vector<UsageReport>> reports =
usage_reports_buffer_service_->GetUsageReportsBatch(batch_size);
ScopedJavaLocalRef<jobjectArray> jreports_array =
history_report::Java_HistoryReportJniBridge_createUsageReportsArray(env,
reports->size());
for (size_t i = 0; i < reports->size(); ++i) {
const UsageReport& report = (*reports)[i];
std::string key = usage_report_util::ReportToKey(report);
history_report::Java_HistoryReportJniBridge_setUsageReport(
env, jreports_array, i,
base::android::ConvertUTF8ToJavaString(env, key),
base::android::ConvertUTF8ToJavaString(env, report.id()),
report.timestamp_ms(), report.typed_visit());
}
return jreports_array;
}
void HistoryReportJniBridge::RemoveUsageReports(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
const JavaParamRef<jobjectArray>& batch) {
std::vector<std::string> to_remove;
base::android::AppendJavaStringArrayToStringVector(env, batch, &to_remove);
usage_reports_buffer_service_->Remove(to_remove);
}
void HistoryReportJniBridge::NotifyDataChanged() {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
if (!obj.is_null())
history_report::Java_HistoryReportJniBridge_onDataChanged(env, obj);
}
void HistoryReportJniBridge::NotifyDataCleared() {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
if (!obj.is_null())
history_report::Java_HistoryReportJniBridge_onDataCleared(env, obj);
}
void HistoryReportJniBridge::StopReporting() {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
if (!obj.is_null())
history_report::Java_HistoryReportJniBridge_stopReportingTask(env, obj);
}
void HistoryReportJniBridge::StartReporting() {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
if (!obj.is_null())
history_report::Java_HistoryReportJniBridge_startReportingTask(env, obj);
}
jboolean HistoryReportJniBridge::AddHistoricVisitsToUsageReportsBuffer(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
data_provider_->StartVisitMigrationToUsageBuffer(
usage_reports_buffer_service_.get());
// TODO(nileshagrawal): Return true when actually done,
// or callback on success.
return true;
}
base::android::ScopedJavaLocalRef<jstring> HistoryReportJniBridge::Dump(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
std::string dump;
dump.append(delta_file_service_->Dump());
dump.append(usage_reports_buffer_service_->Dump());
return base::android::ConvertUTF8ToJavaString(env, dump);
}
} // namespace history_report