Commit 4451cbee authored by Nicolas Ouellet-payeur's avatar Nicolas Ouellet-payeur Committed by Commit Bot

Don't discard tabs with active WebUSB connections

To keep track of WebUSB state, use the same backend as the WebUSB tab-strip
icon.

Bug: 863922
Change-Id: I89e346c3a310cfb76618a7492e2d89821c758106
Reviewed-on: https://chromium-review.googlesource.com/1140281Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Commit-Queue: Nicolas Ouellet-Payeur <nicolaso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576098}
parent 41396d6e
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "chrome/browser/resource_coordinator/time.h" #include "chrome/browser/resource_coordinator/time.h"
#include "chrome/browser/resource_coordinator/utils.h" #include "chrome/browser/resource_coordinator/utils.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/usb/usb_tab_helper.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
...@@ -892,6 +893,14 @@ void TabLifecycleUnitSource::TabLifecycleUnit::CheckIfTabIsUsedInBackground( ...@@ -892,6 +893,14 @@ void TabLifecycleUnitSource::TabLifecycleUnit::CheckIfTabIsUsedInBackground(
decision_details); decision_details);
} }
// Do not freeze/discard a tab that has active WebUSB connections.
if (auto* usb_tab_helper = UsbTabHelper::FromWebContents(GetWebContents())) {
if (usb_tab_helper->IsDeviceConnected()) {
decision_details->AddReason(
DecisionFailureReason::LIVE_STATE_USING_WEB_USB);
}
}
// Do not freeze tabs that are currently using DevTools. // Do not freeze tabs that are currently using DevTools.
if (DevToolsWindow::GetInstanceForInspectedWebContents(GetWebContents())) { if (DevToolsWindow::GetInstanceForInspectedWebContents(GetWebContents())) {
decision_details->AddReason( decision_details->AddReason(
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "chrome/browser/resource_coordinator/usage_clock.h" #include "chrome/browser/resource_coordinator/usage_clock.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h" #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
#include "chrome/browser/usb/usb_tab_helper.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/test/web_contents_tester.h" #include "content/public/test/web_contents_tester.h"
...@@ -368,6 +369,43 @@ TEST_F(TabLifecycleUnitTest, CannotDiscardRecentlyAudible) { ...@@ -368,6 +369,43 @@ TEST_F(TabLifecycleUnitTest, CannotDiscardRecentlyAudible) {
ExpectCanDiscardTrueAllReasons(&tab_lifecycle_unit); ExpectCanDiscardTrueAllReasons(&tab_lifecycle_unit);
} }
TEST_F(TabLifecycleUnitTest, CannotFreezeOrDiscardWebUsbConnectionsOpen) {
TabLifecycleUnit tab_lifecycle_unit(&observers_, usage_clock_.get(),
web_contents_, tab_strip_model_.get());
TabLoadTracker::Get()->TransitionStateForTesting(web_contents_,
LoadingState::LOADED);
UsbTabHelper* usb_tab_helper =
UsbTabHelper::GetOrCreateForWebContents(web_contents_);
usb_tab_helper->CreateChooserService(
web_contents_->GetMainFrame(),
mojo::InterfaceRequest<device::mojom::UsbChooserService>());
// Page could be intending to use the WebUSB API, but there's no connection
// open yet, so it can still be discarded/frozen.
ExpectCanDiscardTrueAllReasons(&tab_lifecycle_unit);
DecisionDetails decision_details;
EXPECT_TRUE(tab_lifecycle_unit.CanFreeze(&decision_details));
EXPECT_TRUE(decision_details.IsPositive());
// Open a USB connection. Shouldn't be freezable/discardable anymore.
usb_tab_helper->IncrementConnectionCount(web_contents_->GetMainFrame());
ExpectCanDiscardFalseAllReasons(
&tab_lifecycle_unit, DecisionFailureReason::LIVE_STATE_USING_WEB_USB);
decision_details = DecisionDetails();
EXPECT_FALSE(tab_lifecycle_unit.CanFreeze(&decision_details));
EXPECT_FALSE(decision_details.IsPositive());
EXPECT_EQ(DecisionFailureReason::LIVE_STATE_USING_WEB_USB,
decision_details.FailureReason());
// Close the USB connection. Should be freezable/discardable again.
usb_tab_helper->DecrementConnectionCount(web_contents_->GetMainFrame());
ExpectCanDiscardTrueAllReasons(&tab_lifecycle_unit);
decision_details = DecisionDetails();
EXPECT_TRUE(tab_lifecycle_unit.CanFreeze(&decision_details));
EXPECT_TRUE(decision_details.IsPositive());
}
TEST_F(TabLifecycleUnitTest, CanDiscardNeverAudibleTab) { TEST_F(TabLifecycleUnitTest, CanDiscardNeverAudibleTab) {
TabLifecycleUnit tab_lifecycle_unit(&observers_, usage_clock_.get(), TabLifecycleUnit tab_lifecycle_unit(&observers_, usage_clock_.get(),
web_contents_, tab_strip_model_.get()); web_contents_, tab_strip_model_.get());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment