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/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h"
6 
7 #include "base/feature_list.h"
8 #include "base/metrics/histogram_functions.h"
9 #include "base/metrics/user_metrics.h"
10 #include "chrome/browser/browser_features.h"
11 #include "chrome/browser/command_updater_impl.h"
12 #include "chrome/browser/enterprise/util/managed_browser_utils.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/search/promos/promo_service.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_navigator.h"
17 #include "chrome/browser/ui/chrome_pages.h"
18 #include "chrome/common/webui_url_constants.h"
19 #include "components/safe_browsing/content/web_ui/safe_browsing_ui.h"
20 #include "components/safe_browsing/core/common/safe_browsing_policy_handler.h"
21 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
22 #include "ui/base/page_transition_types.h"
23 #include "ui/base/window_open_disposition.h"
24 
25 using promo_browser_command::mojom::ClickInfoPtr;
26 using promo_browser_command::mojom::Command;
27 using promo_browser_command::mojom::CommandHandler;
28 
29 // static
30 const char PromoBrowserCommandHandler::kPromoBrowserCommandHistogramName[] =
31     "NewTabPage.Promos.PromoBrowserCommand";
32 
PromoBrowserCommandHandler(mojo::PendingReceiver<CommandHandler> pending_page_handler,Profile * profile)33 PromoBrowserCommandHandler::PromoBrowserCommandHandler(
34     mojo::PendingReceiver<CommandHandler> pending_page_handler,
35     Profile* profile)
36     : profile_(profile),
37       command_updater_(std::make_unique<CommandUpdaterImpl>(this)),
38       page_handler_(this, std::move(pending_page_handler)) {
39   if (!base::FeatureList::IsEnabled(features::kPromoBrowserCommands))
40     return;
41   EnableCommands();
42 }
43 
44 PromoBrowserCommandHandler::~PromoBrowserCommandHandler() = default;
45 
CanShowPromoWithCommand(promo_browser_command::mojom::Command command_id,CanShowPromoWithCommandCallback callback)46 void PromoBrowserCommandHandler::CanShowPromoWithCommand(
47     promo_browser_command::mojom::Command command_id,
48     CanShowPromoWithCommandCallback callback) {
49   bool can_show = false;
50   switch (static_cast<Command>(command_id)) {
51     case Command::kUnknownCommand:
52       // Nothing to do.
53       break;
54     case Command::kOpenSafetyCheck:
55       can_show = chrome::enterprise_util::HasBrowserPoliciesApplied(profile_);
56       break;
57     case Command::kOpenSafeBrowsingEnhancedProtectionSettings: {
58       bool managed = safe_browsing::SafeBrowsingPolicyHandler::
59           IsSafeBrowsingProtectionLevelSetByPolicy(profile_->GetPrefs());
60       bool already_enabled =
61           safe_browsing::IsEnhancedProtectionEnabled(*(profile_->GetPrefs()));
62       can_show = !managed && !already_enabled;
63     } break;
64     default:
65       NOTREACHED() << "Unspecified behavior for command " << command_id;
66       break;
67   }
68   std::move(callback).Run(can_show);
69 }
70 
ExecuteCommand(Command command_id,ClickInfoPtr click_info,ExecuteCommandCallback callback)71 void PromoBrowserCommandHandler::ExecuteCommand(
72     Command command_id,
73     ClickInfoPtr click_info,
74     ExecuteCommandCallback callback) {
75   const auto disposition = ui::DispositionFromClick(
76       click_info->middle_button, click_info->alt_key, click_info->ctrl_key,
77       click_info->meta_key, click_info->shift_key);
78   const bool command_executed =
79       GetCommandUpdater()->ExecuteCommandWithDisposition(
80           static_cast<int>(command_id), disposition);
81   std::move(callback).Run(command_executed);
82 }
83 
ExecuteCommandWithDisposition(int id,WindowOpenDisposition disposition)84 void PromoBrowserCommandHandler::ExecuteCommandWithDisposition(
85     int id,
86     WindowOpenDisposition disposition) {
87   const auto command = static_cast<Command>(id);
88   base::UmaHistogramEnumeration(kPromoBrowserCommandHistogramName, command);
89 
90   switch (command) {
91     case Command::kUnknownCommand:
92       // Nothing to do.
93       break;
94     case Command::kOpenSafetyCheck:
95       NavigateToURL(GURL(chrome::GetSettingsUrl(chrome::kSafetyCheckSubPage)),
96                     disposition);
97       base::RecordAction(
98           base::UserMetricsAction("NewTabPage_Promos_SafetyCheck"));
99       break;
100     case Command::kOpenSafeBrowsingEnhancedProtectionSettings:
101       NavigateToURL(GURL(chrome::GetSettingsUrl(
102                         chrome::kSafeBrowsingEnhancedProtectionSubPage)),
103                     disposition);
104       base::RecordAction(
105           base::UserMetricsAction("NewTabPage_Promos_EnhancedProtection"));
106       break;
107     default:
108       NOTREACHED() << "Unspecified behavior for command " << id;
109       break;
110   }
111 }
112 
EnableCommands()113 void PromoBrowserCommandHandler::EnableCommands() {
114   // Explicitly enable supported commands.
115   GetCommandUpdater()->UpdateCommandEnabled(
116       static_cast<int>(Command::kUnknownCommand), true);
117   GetCommandUpdater()->UpdateCommandEnabled(
118       static_cast<int>(Command::kOpenSafetyCheck), true);
119   GetCommandUpdater()->UpdateCommandEnabled(
120       static_cast<int>(Command::kOpenSafeBrowsingEnhancedProtectionSettings),
121       true);
122 }
123 
GetCommandUpdater()124 CommandUpdater* PromoBrowserCommandHandler::GetCommandUpdater() {
125   return command_updater_.get();
126 }
127 
NavigateToURL(const GURL & url,WindowOpenDisposition disposition)128 void PromoBrowserCommandHandler::NavigateToURL(
129     const GURL& url,
130     WindowOpenDisposition disposition) {
131   NavigateParams params(profile_, url, ui::PAGE_TRANSITION_LINK);
132   params.disposition = disposition;
133   Navigate(&params);
134 }
135