blob: 46071d14837ca3f517fa607ee2fdb19e03628d8d [file] [log] [blame]
Sebastien Marchand578251d2020-12-11 03:44:431// 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/performance_manager/mechanisms/page_freezer.h"
6
7#include "base/bind.h"
8#include "base/task/task_traits.h"
9#include "chrome/browser/permissions/permission_manager_factory.h"
10#include "chrome/browser/profiles/profile.h"
11#include "components/content_settings/core/common/content_settings_types.h"
12#include "components/performance_manager/public/graph/page_node.h"
13#include "components/performance_manager/public/web_contents_proxy.h"
14#include "components/permissions/permission_manager.h"
15#include "components/permissions/permission_result.h"
16#include "content/public/browser/browser_task_traits.h"
17#include "content/public/browser/browser_thread.h"
Charlene Yan753d7462021-01-26 23:39:5218#include "content/public/browser/visibility.h"
Sebastien Marchand578251d2020-12-11 03:44:4319#include "content/public/browser/web_contents.h"
20
21namespace performance_manager {
22namespace mechanism {
23namespace {
24
25// Try to freeze a page on the UI thread.
Sebastien Marchandbed434c2021-03-25 19:37:2426void MaybeFreezePageOnUIThread(const WebContentsProxy& contents_proxy) {
Sebastien Marchand578251d2020-12-11 03:44:4327 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
28 content::WebContents* const contents = contents_proxy.Get();
29 if (!contents)
Sebastien Marchandbed434c2021-03-25 19:37:2430 return;
Sebastien Marchand578251d2020-12-11 03:44:4331
32 // Page with the notification permission shouldn't be frozen as this is a
33 // strong signal that the user wants to receive updates from this page while
34 // it's in background. This information isn't available in the PM graph, this
35 // has to be checked on the UI thread.
36 auto notif_permission =
37 PermissionManagerFactory::GetForProfile(
38 Profile::FromBrowserContext(contents->GetBrowserContext()))
39 ->GetPermissionStatus(ContentSettingsType::NOTIFICATIONS,
40 contents->GetLastCommittedURL(),
41 contents->GetLastCommittedURL());
42 if (notif_permission.content_setting == CONTENT_SETTING_ALLOW)
Sebastien Marchandbed434c2021-03-25 19:37:2443 return;
Sebastien Marchand578251d2020-12-11 03:44:4344
45 contents->SetPageFrozen(true);
46}
47
48void UnfreezePageOnUIThread(const WebContentsProxy& contents_proxy) {
49 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
50 content::WebContents* const content = contents_proxy.Get();
51 if (!content)
52 return;
53
Charlene Yan753d7462021-01-26 23:39:5254 // A visible page is automatically unfrozen.
55 if (content->GetVisibility() == content::Visibility::VISIBLE)
56 return;
57
Sebastien Marchand578251d2020-12-11 03:44:4358 content->SetPageFrozen(false);
59}
60
61} // namespace
62
63void PageFreezer::MaybeFreezePageNode(const PageNode* page_node) {
64 DCHECK(page_node);
65 content::GetUIThreadTaskRunner({})->PostTask(
Sebastien Marchandbed434c2021-03-25 19:37:2466 FROM_HERE, base::BindOnce(&MaybeFreezePageOnUIThread,
Sebastien Marchand578251d2020-12-11 03:44:4367 page_node->GetContentsProxy()));
68}
69
70void PageFreezer::UnfreezePageNode(const PageNode* page_node) {
71 DCHECK(page_node);
72 content::GetUIThreadTaskRunner({})->PostTask(
73 FROM_HERE,
74 base::BindOnce(&UnfreezePageOnUIThread, page_node->GetContentsProxy()));
75}
76
Sebastien Marchand578251d2020-12-11 03:44:4377} // namespace mechanism
78} // namespace performance_manager