1 // Copyright 2017 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/android/background_tab_manager.h"
6 
7 #include "base/memory/singleton.h"
8 #include "components/history/core/browser/history_service.h"
9 #include "components/history/core/browser/history_types.h"
10 #include "content/public/browser/browser_thread.h"
11 
12 using content::BrowserThread;
13 
14 namespace chrome {
15 namespace android {
16 
WebContentsDestroyedObserver(BackgroundTabManager * owner,content::WebContents * watched_contents)17 WebContentsDestroyedObserver::WebContentsDestroyedObserver(
18     BackgroundTabManager* owner,
19     content::WebContents* watched_contents)
20     : content::WebContentsObserver(watched_contents), owner_(owner) {}
21 
~WebContentsDestroyedObserver()22 WebContentsDestroyedObserver::~WebContentsDestroyedObserver() {}
23 
WebContentsDestroyed()24 void WebContentsDestroyedObserver::WebContentsDestroyed() {
25   DCHECK(owner_->IsBackgroundTab(web_contents()));
26   owner_->UnregisterBackgroundTab();
27 }
28 
BackgroundTabManager()29 BackgroundTabManager::BackgroundTabManager() {
30   DCHECK_CURRENTLY_ON(BrowserThread::UI);
31   web_contents_ = nullptr;
32   profile_ = nullptr;
33 }
34 
~BackgroundTabManager()35 BackgroundTabManager::~BackgroundTabManager() {
36   DCHECK_CURRENTLY_ON(BrowserThread::UI);
37   web_contents_ = nullptr;
38   profile_ = nullptr;
39 }
40 
IsBackgroundTab(content::WebContents * web_contents) const41 bool BackgroundTabManager::IsBackgroundTab(
42     content::WebContents* web_contents) const {
43   DCHECK_CURRENTLY_ON(BrowserThread::UI);
44   if (!web_contents)
45     return false;
46   return web_contents_ == web_contents;
47 }
48 
RegisterBackgroundTab(content::WebContents * web_contents,Profile * profile)49 void BackgroundTabManager::RegisterBackgroundTab(
50     content::WebContents* web_contents,
51     Profile* profile) {
52   DCHECK_CURRENTLY_ON(BrowserThread::UI);
53   DCHECK(!web_contents_);
54   web_contents_ = web_contents;
55   profile_ = profile;
56   web_contents_observer_ =
57       std::make_unique<WebContentsDestroyedObserver>(this, web_contents);
58 }
59 
UnregisterBackgroundTab()60 void BackgroundTabManager::UnregisterBackgroundTab() {
61   DCHECK_CURRENTLY_ON(BrowserThread::UI);
62   DCHECK(web_contents_);
63   web_contents_ = nullptr;
64   profile_ = nullptr;
65   cached_history_.clear();
66   web_contents_observer_.reset();
67 }
68 
GetProfile() const69 Profile* BackgroundTabManager::GetProfile() const {
70   DCHECK_CURRENTLY_ON(BrowserThread::UI);
71   return profile_;
72 }
73 
CacheHistory(const history::HistoryAddPageArgs & history_item)74 void BackgroundTabManager::CacheHistory(
75     const history::HistoryAddPageArgs& history_item) {
76   DCHECK_CURRENTLY_ON(BrowserThread::UI);
77   cached_history_.push_back(history_item);
78 }
79 
CommitHistory(history::HistoryService * history_service)80 void BackgroundTabManager::CommitHistory(
81     history::HistoryService* history_service) {
82   DCHECK_CURRENTLY_ON(BrowserThread::UI);
83   // History service can be null in non exceptional conditions, e.g. incognito
84   // mode. We clear the cached history in any case.
85   if (history_service) {
86     for (const auto& history_item : cached_history_) {
87       history_service->AddPage(history_item);
88     }
89   }
90   cached_history_.clear();
91 }
92 
GetInstance()93 BackgroundTabManager* BackgroundTabManager::GetInstance() {
94   return base::Singleton<BackgroundTabManager>::get();
95 }
96 
97 }  // namespace android
98 }  // namespace chrome
99