#include "chrome/browser/share/share_ranking.h"
#include <vector>
#include "base/containers/to_vector.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/share/default_ranking.h"
#include "chrome/browser/share/share_history.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
#include "content/public/browser/storage_partition.h"
#include "ui/base/l10n/l10n_util.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/callback_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/locale_utils.h"
#include "chrome/browser/share/jni_headers/ShareRankingBridge_jni.h"
using base::android::JavaParamRef;
#endif
namespace sharing {
const char* const ShareRanking::kMoreTarget = …;
namespace {
const char* const kShareRankingFolder = …;
const char* const kShareRankingKey = …;
const int kRecentWindowDays = …;
std::unique_ptr<ShareRanking::BackingDb> MakeDefaultDbForProfile(
Profile* profile) { … }
bool RankingContains(const std::vector<std::string>& ranking,
const std::string& element,
size_t upto_index = SIZE_MAX) { … }
std::vector<std::string> OrderByUses(const std::vector<std::string>& ranking,
const std::map<std::string, int>& uses) { … }
std::string HighestUnshown(const std::vector<std::string>& ranking,
const std::map<std::string, int>& uses,
size_t length) { … }
std::string LowestShown(const std::vector<std::string>& ranking,
const std::map<std::string, int>& uses,
size_t length) { … }
void SwapRankingElement(std::vector<std::string>& ranking,
const std::string& from,
const std::string& to) { … }
std::vector<std::string> ReplaceUnavailableEntries(
const std::vector<std::string>& ranking,
const std::vector<std::string>& available) { … }
void FillGaps(std::vector<std::string>& ranking,
const std::vector<std::string>& available,
size_t length) { … }
std::vector<std::string> MaybeUpdateRankingFromHistory(
const std::vector<std::string>& old_ranking,
const std::map<std::string, int>& recent_share_history,
const std::map<std::string, int>& all_share_history,
size_t length) { … }
ShareRanking::Ranking AppendUpToLength(
const ShareRanking::Ranking& ranking,
const std::map<std::string, int>& history,
size_t length) { … }
#if BUILDFLAG(IS_ANDROID)
void RunJniRankCallback(base::android::ScopedJavaGlobalRef<jobject> callback,
JNIEnv* env,
std::optional<ShareRanking::Ranking> ranking) {
auto result = base::android::ToJavaArrayOfStrings(env, ranking.value());
base::android::RunObjectCallbackAndroid(callback, result);
}
#endif
#if DCHECK_IS_ON()
bool EveryElementInList(const std::vector<std::string>& ranking,
const std::vector<std::string>& available) { … }
bool ElementIndexesAreUnchanged(const std::vector<std::string>& display,
const std::vector<std::string>& old,
size_t length) { … }
bool AtMostOneSlotChanged(const std::vector<std::string>& old_ranking,
const std::vector<std::string>& new_ranking,
size_t length) { … }
#endif
std::map<std::string, int> BuildHistoryMap(
const std::vector<ShareHistory::Target>& flat_history) { … }
std::vector<std::string> AddMissingItemsFromHistory(
const std::vector<std::string> existing,
const std::map<std::string, int> history) { … }
}
ShareRanking* ShareRanking::Get(Profile* profile) { … }
ShareRanking::ShareRanking(Profile* profile,
std::unique_ptr<BackingDb> backing_db)
: … { … }
ShareRanking::~ShareRanking() = default;
void ShareRanking::UpdateRanking(const std::string& type, Ranking ranking) { … }
void ShareRanking::GetRanking(const std::string& type,
GetRankingCallback callback) { … }
void ShareRanking::Rank(ShareHistory* history,
const std::string& type,
const std::vector<std::string>& available_on_system,
size_t fold,
size_t length,
bool persist_update,
GetRankingCallback callback) { … }
void ShareRanking::Clear(const base::Time& start, const base::Time& end) { … }
void ShareRanking::ComputeRanking(
const std::map<std::string, int>& all_share_history,
const std::map<std::string, int>& recent_share_history,
const Ranking& old_ranking,
const std::vector<std::string>& available_on_system,
size_t fold,
size_t length,
Ranking* display_ranking,
Ranking* persisted_ranking) { … }
ShareRanking::PendingRankCall::PendingRankCall() = default;
ShareRanking::PendingRankCall::~PendingRankCall() = default;
void ShareRanking::Init() { … }
void ShareRanking::OnInitDone(leveldb_proto::Enums::InitStatus status) { … }
void ShareRanking::OnBackingGetDone(
std::string key,
GetRankingCallback callback,
bool ok,
std::unique_ptr<proto::ShareRanking> ranking) { … }
void ShareRanking::FlushToBackingDb(const std::string& key) { … }
void ShareRanking::OnRankGetAllDone(std::unique_ptr<PendingRankCall> pending,
std::vector<ShareHistory::Target> history) { … }
void ShareRanking::OnRankGetRecentDone(
std::unique_ptr<PendingRankCall> pending,
std::vector<ShareHistory::Target> history) { … }
void ShareRanking::OnRankGetOldRankingDone(
std::unique_ptr<PendingRankCall> pending,
std::optional<Ranking> ranking) { … }
ShareRanking::Ranking ShareRanking::GetDefaultInitialRankingForType(
const std::string& type) { … }
}
#if BUILDFLAG(IS_ANDROID)
void JNI_ShareRankingBridge_Rank(JNIEnv* env,
Profile* profile,
std::string& type,
std::vector<std::string>& available,
jint jfold,
jint jlength,
jboolean jpersist,
const JavaParamRef<jobject>& jcallback) {
base::android::ScopedJavaGlobalRef<jobject> callback(jcallback);
if (profile->IsOffTheRecord()) {
CHECK(!jpersist);
profile = profile->GetOriginalProfile();
}
auto* history = sharing::ShareHistory::Get(profile);
auto* ranking = sharing::ShareRanking::Get(profile);
CHECK(history);
CHECK(ranking);
ranking->Rank(
history, type, available, jfold, jlength, jpersist,
base::BindOnce(&sharing::RunJniRankCallback, std::move(callback),
base::Unretained(env)));
}
#endif