// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/file_suggest/file_suggest_util.h"
#include "ash/constants/ash_features.h"
#include "base/time/time.h"
namespace ash {
namespace {
// The prefix of a drive file suggestion id.
constexpr char kDriveFileSuggestionPrefix[] = "zero_state_drive://";
// The prefix of a local file suggestion id.
constexpr char kLocalFileSuggestionPrefix[] = "zero_state_file://";
// The number of days within which a file must be modified, or viewed to be
// considered as a file suggestion.
constexpr int kDefaultMaxRecencyInDays = 30;
// Returns the prefix that matches `type`.
std::string GetPrefixFromSuggestionType(FileSuggestionType type) {
switch (type) {
case FileSuggestionType::kDriveFile:
return kDriveFileSuggestionPrefix;
case FileSuggestionType::kLocalFile:
return kLocalFileSuggestionPrefix;
}
}
} // namespace
base::TimeDelta GetMaxFileSuggestionRecency() {
if (base::FeatureList::IsEnabled(
features::kLauncherContinueSectionWithRecents)) {
return base::Days(base::GetFieldTrialParamByFeatureAsInt(
features::kLauncherContinueSectionWithRecents, "max_recency_in_days",
kDefaultMaxRecencyInDays));
}
return base::Days(base::GetFieldTrialParamByFeatureAsInt(
features::kLauncherContinueSectionWithRecentsRollout,
"max_recency_in_days", kDefaultMaxRecencyInDays));
}
double ToTimestampBasedScore(const FileSuggestData& data,
base::TimeDelta max_recency) {
auto score_timestamp = [&](const base::Time& timestamp, double interval_max,
double interval_size) {
return interval_max -
interval_size *
std::min(
1.0,
(base::Time::Now() - timestamp).magnitude().InSeconds() /
static_cast<double>(max_recency.InSeconds()));
};
if (data.modified_time) {
return score_timestamp(*data.modified_time,
/*interval_max=*/1.0, /*interval_size=*/0.33);
}
if (data.viewed_time) {
return score_timestamp(*data.viewed_time,
/*interval_max=*/0.66, /*interval_size=*/0.33);
}
if (data.shared_time) {
return score_timestamp(*data.shared_time,
/*interval_max=*/0.33, /*interval_size=*/0.33);
}
return 0.0;
}
// FileSuggestData -------------------------------------------------------------
FileSuggestData::FileSuggestData(
FileSuggestionType new_type,
const base::FilePath& new_file_path,
const std::optional<std::string>& title,
const std::optional<std::u16string>& new_prediction_reason,
const std::optional<base::Time>& modified_time,
const std::optional<base::Time>& viewed_time,
const std::optional<base::Time>& shared_time,
std::optional<float> new_score,
const std::optional<std::string>& drive_file_id,
const std::optional<std::string>& icon_url)
: type(new_type),
file_path(new_file_path),
title(title),
id(CalculateSuggestionId(type, file_path)),
prediction_reason(new_prediction_reason),
modified_time(modified_time),
viewed_time(viewed_time),
shared_time(shared_time),
score(new_score),
drive_file_id(drive_file_id),
icon_url(icon_url) {}
FileSuggestData::FileSuggestData(FileSuggestData&&) = default;
FileSuggestData::FileSuggestData(const FileSuggestData&) = default;
FileSuggestData& FileSuggestData::operator=(const FileSuggestData&) = default;
FileSuggestData::~FileSuggestData() = default;
// Helper functions ------------------------------------------------------------
// Calculates the ID used to remove suggestions the user doesn't want to see.
std::string CalculateSuggestionId(FileSuggestionType type,
const base::FilePath& file_path) {
return GetPrefixFromSuggestionType(type) + file_path.value();
}
} // namespace ash