1 // Copyright 2020 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 "chrome/browser/ui/ash/clipboard_image_model_factory_impl.h"
6
7 #include "chrome/browser/profiles/profile.h"
8
ClipboardImageModelFactoryImpl(Profile * primary_profile)9 ClipboardImageModelFactoryImpl::ClipboardImageModelFactoryImpl(
10 Profile* primary_profile)
11 : primary_profile_(primary_profile),
12 idle_timer_(FROM_HERE,
13 base::TimeDelta::FromMinutes(2),
14 this,
15 &ClipboardImageModelFactoryImpl::OnRequestIdle) {
16 DCHECK(primary_profile_);
17 }
18
19 ClipboardImageModelFactoryImpl::~ClipboardImageModelFactoryImpl() = default;
20
Render(const base::UnguessableToken & id,const std::string & html_markup,ImageModelCallback callback)21 void ClipboardImageModelFactoryImpl::Render(const base::UnguessableToken& id,
22 const std::string& html_markup,
23 ImageModelCallback callback) {
24 DCHECK(!html_markup.empty());
25 pending_list_.emplace_front(id, html_markup, std::move(callback));
26 StartNextRequest();
27 }
28
CancelRequest(const base::UnguessableToken & id)29 void ClipboardImageModelFactoryImpl::CancelRequest(
30 const base::UnguessableToken& id) {
31 if (request_ && request_->IsRunningRequest(id)) {
32 request_->Stop();
33 return;
34 }
35
36 auto iter =
37 std::find_if(pending_list_.begin(), pending_list_.end(),
38 [&id](const ClipboardImageModelRequest::Params& params) {
39 return id == params.id;
40 });
41 if (iter == pending_list_.end())
42 return;
43
44 pending_list_.erase(iter);
45 }
46
Activate()47 void ClipboardImageModelFactoryImpl::Activate() {
48 active_ = true;
49 StartNextRequest();
50 }
51
Deactivate()52 void ClipboardImageModelFactoryImpl::Deactivate() {
53 active_ = false;
54
55 if (!request_ || !request_->IsModifyingClipboard())
56 return;
57
58 // Stop the currently running request if it is modifying the clipboard.
59 // ClipboardImageModelFactory is `Deactivate()`-ed prior to the user pasting
60 // and a modified clipboard could interfere with pasting from
61 // ClipboardHistory.
62 pending_list_.emplace_front(request_->StopAndGetParams());
63 }
64
OnShutdown()65 void ClipboardImageModelFactoryImpl::OnShutdown() {
66 // Reset |request_| to drop its reference to Profile, specifically the
67 // RenderProcessHost of its WebContents.
68 request_.reset();
69 }
70
StartNextRequest()71 void ClipboardImageModelFactoryImpl::StartNextRequest() {
72 if (pending_list_.empty() || !active_ ||
73 (request_ && request_->IsRunningRequest())) {
74 return;
75 }
76
77 if (!request_) {
78 request_ = std::make_unique<ClipboardImageModelRequest>(
79 primary_profile_,
80 base::BindRepeating(&ClipboardImageModelFactoryImpl::StartNextRequest,
81 weak_ptr_factory_.GetWeakPtr()));
82 }
83
84 // Reset the timer that cleans up |request_|. If StartNextRequest() is not
85 // called again in 2 minutes, |request_| will be reset.
86 idle_timer_.Reset();
87 request_->Start(std::move(pending_list_.front()));
88 pending_list_.pop_front();
89 }
90
OnRequestIdle()91 void ClipboardImageModelFactoryImpl::OnRequestIdle() {
92 if (!request_)
93 return;
94
95 DCHECK(!request_->IsRunningRequest())
96 << "Running requests should timeout or complete before being cleaned up.";
97 request_.reset();
98 }
99