|  | // 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 |