blob: 5971e9ebfc23e70f1e8be15c0460e939f692a62d [file] [log] [blame]
Stuart Langleyad8728c2018-04-19 04:05:561// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/drive/chromeos/about_resource_loader.h"
6
Stuart Langleybe4035742018-05-10 05:32:277#include <memory>
Stuart Langleyad8728c2018-04-19 04:05:568#include <vector>
9
Sebastien Marchand53801a32019-01-25 16:26:1110#include "base/bind.h"
Stuart Langleyad8728c2018-04-19 04:05:5611#include "base/threading/thread_task_runner_handle.h"
12#include "components/drive/job_scheduler.h"
13
14namespace drive {
15namespace internal {
16
Stuart Langley70fd2c3a2018-08-27 03:45:1017namespace {
18// The time period that we will cache the result of UpdateAboutResource.
19constexpr base::TimeDelta kCacheEvictionTimeout =
20 base::TimeDelta::FromMinutes(1);
21} // namespace
22
23AboutResourceLoader::AboutResourceLoader(JobScheduler* scheduler,
24 const base::TickClock* clock)
Jeremy Roman47d432e2019-08-20 14:24:0025 : scheduler_(scheduler), current_update_task_id_(-1) {
Stuart Langley70fd2c3a2018-08-27 03:45:1026 cache_eviction_timer_ = std::make_unique<base::RetainingOneShotTimer>(
27 FROM_HERE, kCacheEvictionTimeout,
28 base::BindRepeating(&AboutResourceLoader::EvictCachedAboutResource,
29 base::Unretained(this)),
30 clock);
31}
Stuart Langleyad8728c2018-04-19 04:05:5632
Stuart Langleybe4035742018-05-10 05:32:2733AboutResourceLoader::~AboutResourceLoader() = default;
Stuart Langleyad8728c2018-04-19 04:05:5634
35void AboutResourceLoader::GetAboutResource(
36 const google_apis::AboutResourceCallback& callback) {
37 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
38 DCHECK(callback);
39
40 // If the latest UpdateAboutResource task is still running. Wait for it,
41 if (pending_callbacks_.count(current_update_task_id_)) {
42 pending_callbacks_[current_update_task_id_].emplace_back(callback);
43 return;
44 }
45
46 if (cached_about_resource_) {
47 base::ThreadTaskRunnerHandle::Get()->PostTask(
48 FROM_HERE, base::BindOnce(callback, google_apis::HTTP_NO_CONTENT,
49 std::make_unique<google_apis::AboutResource>(
50 *cached_about_resource_)));
51 } else {
52 UpdateAboutResource(callback);
53 }
54}
55
56void AboutResourceLoader::UpdateAboutResource(
57 const google_apis::AboutResourceCallback& callback) {
58 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
59 DCHECK(callback);
60
61 ++current_update_task_id_;
62 pending_callbacks_[current_update_task_id_].emplace_back(callback);
63
64 scheduler_->GetAboutResource(base::BindRepeating(
65 &AboutResourceLoader::UpdateAboutResourceAfterGetAbout,
66 weak_ptr_factory_.GetWeakPtr(), current_update_task_id_));
67}
68
69void AboutResourceLoader::UpdateAboutResourceAfterGetAbout(
70 int task_id,
71 google_apis::DriveApiErrorCode status,
72 std::unique_ptr<google_apis::AboutResource> about_resource) {
73 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
74 FileError error = GDataToFileError(status);
75
76 const std::vector<google_apis::AboutResourceCallback> callbacks =
77 pending_callbacks_[task_id];
78 pending_callbacks_.erase(task_id);
79
80 if (error != FILE_ERROR_OK) {
81 for (auto& callback : callbacks)
82 callback.Run(status, nullptr);
83 return;
84 }
85
86 // Updates the cache when the resource is successfully obtained.
87 if (cached_about_resource_ && cached_about_resource_->largest_change_id() >
88 about_resource->largest_change_id()) {
89 LOG(WARNING) << "Local cached about resource is fresher than server, "
90 << "local = " << cached_about_resource_->largest_change_id()
91 << ", server = " << about_resource->largest_change_id();
92 }
Stuart Langleybe4035742018-05-10 05:32:2793 cached_about_resource_ =
94 std::make_unique<google_apis::AboutResource>(*about_resource);
Stuart Langleyad8728c2018-04-19 04:05:5695
Stuart Langley70fd2c3a2018-08-27 03:45:1096 cache_eviction_timer_->Reset();
97
Stuart Langleyad8728c2018-04-19 04:05:5698 for (auto& callback : callbacks) {
99 callback.Run(status,
100 std::make_unique<google_apis::AboutResource>(*about_resource));
101 }
102}
103
Stuart Langley70fd2c3a2018-08-27 03:45:10104void AboutResourceLoader::EvictCachedAboutResource() {
105 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
106 cached_about_resource_.reset();
107}
108
Stuart Langleyad8728c2018-04-19 04:05:56109} // namespace internal
110} // namespace drive