Commit 76696f63 authored by Ovidio Henriquez's avatar Ovidio Henriquez Committed by Commit Bot

bluetooth: Scan Tab Indicator

This change adds a tab indicator that is visible when a Bluetooth scan
session is active. A scan session may be started through the Web
Bluetooth API's watchAdvertisements() method or through the Web
Bluetooth Scanning API's requestLEScan() method.

Design Doc:
https://docs.google.com/document/d/1h3uAVXJARHrNWaNACUPiQhLt7XI-fFFQoARSs1WgMDM

Bug: 1099914
Change-Id: Ieb1bc385b5da6d2c8a98bdf263751fe549c097a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2270815
Commit-Queue: Ovidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Reviewed-by: default avatarCarlos Pizano <cpu@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786137}
parent f9079a3c
......@@ -9500,6 +9500,9 @@ Please help our engineers fix this problem. Tell us what happened right before y
<message name="IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_CONNECTED" desc="Extra tool tip text, when tab is connected to a Bluetooth device.">
This tab is connected to a Bluetooth Device.
</message>
<message name="IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_SCAN_ACTIVE" desc="Extra tool tip text, when tab is actively scanning for Bluetooth devices.">
This tab is actively scanning for Bluetooth devices.
</message>
<message name="IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED" desc="Extra tool tip text, when tab is connected to a USB device.">
This tab is connected to a USB device.
</message>
......@@ -9538,6 +9541,9 @@ Please help our engineers fix this problem. Tell us what happened right before y
<message name="IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT" desc="Accessibility label text, when a tab is connected to and has access to a Bluetooth device. Example: 'Google Photos - Bluetooth device connected'">
<ph name="WINDOW_TITLE">$1<ex>Google Photos</ex></ph> - Bluetooth device connected
</message>
<message name="IDS_TAB_AX_LABEL_BLUETOOTH_SCAN_ACTIVE_FORMAT" desc="Accessibility label text, when a tab is actively scanning for Bluetooth devices. Example: 'Google Photos - Bluetooth scan active'">
<ph name="WINDOW_TITLE">$1<ex>Google Photos</ex></ph> - Bluetooth scan active
</message>
<message name="IDS_TAB_AX_LABEL_USB_CONNECTED_FORMAT" desc="Accessibility label text, when a tab is connected to a USB device. Example: 'Google Photos - USB device connected'">
<ph name="WINDOW_TITLE">$1<ex>Google Photos</ex></ph> - USB device connected
</message>
......
1ff75b6d60f25caf012a5bdf3cae37a4e4a610af
\ No newline at end of file
74ae97690a7c27296646543c6b5a53b5858c5089
\ No newline at end of file
......@@ -105,6 +105,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"tab_audio_muting_rounded.icon",
"tab_audio_rounded.icon",
"tab_bluetooth_connected.icon",
"tab_bluetooth_scan_active.icon",
"tab_close_normal.icon",
"tab_group.icon",
"tab_media_capturing.icon",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 14.24f, 12.01f,
R_LINE_TO, 2.32f,
2.32f,
R_CUBIC_TO, 0.28f, -0.72f, 0.44f, -1.51f, 0.44f, -2.33f,
R_CUBIC_TO, 0,
-0.82f, -0.16f, -1.59f, -0.43f, -2.31f,
R_LINE_TO, -2.33f,
2.32f, CLOSE,
R_MOVE_TO, 5.29f, -5.3f,
R_LINE_TO, -1.26f, 1.26f,
R_CUBIC_TO, 0.63f, 1.21f, 0.98f, 2.57f, 0.98f, 4.02f,
R_CUBIC_TO, 0, 1.45f, -0.36f, 2.82f,
-0.98f, 4.02f,
R_LINE_TO, 1.2f, 1.2f,
R_CUBIC_TO, 0.97f, -1.54f, 1.54f, -3.36f, 1.54f, -5.31f,
R_CUBIC_TO, -0.01f, -1.89f, -0.55f, -3.67f, -1.48f, -5.19f,
CLOSE,
R_MOVE_TO, -3.82f, 1,
LINE_TO, 10, 2,
H_LINE_TO, 9,
R_V_LINE_TO, 7.59f,
LINE_TO, 4.41f, 5,
LINE_TO, 3, 6.41f,
LINE_TO, 8.59f, 12,
LINE_TO, 3, 17.59f,
LINE_TO, 4.41f, 19,
LINE_TO, 9, 14.41f,
V_LINE_TO, 22,
R_H_LINE_TO, 1,
R_LINE_TO, 5.71f, -5.71f,
R_LINE_TO, -4.3f, -4.29f,
R_LINE_TO, 4.3f, -4.29f,
CLOSE,
MOVE_TO, 11, 5.83f,
R_LINE_TO, 1.88f, 1.88f,
LINE_TO, 11, 9.59f,
V_LINE_TO, 5.83f,
CLOSE,
R_MOVE_TO, 1.88f, 10.46f,
LINE_TO, 11, 18.17f,
R_V_LINE_TO, -3.76f,
R_LINE_TO, 1.88f, 1.88f,
CLOSE
......@@ -48,6 +48,9 @@ std::vector<TabAlertState> GetTabAlertStatesForContents(
if (contents->IsConnectedToBluetoothDevice())
states.push_back(TabAlertState::BLUETOOTH_CONNECTED);
if (contents->IsScanningForBluetoothDevices())
states.push_back(TabAlertState::BLUETOOTH_SCAN_ACTIVE);
UsbTabHelper* usb_tab_helper = UsbTabHelper::FromWebContents(contents);
if (usb_tab_helper && usb_tab_helper->IsDeviceConnected())
states.push_back(TabAlertState::USB_CONNECTED);
......@@ -101,6 +104,9 @@ base::string16 GetTabAlertStateText(const TabAlertState alert_state) {
case TabAlertState::BLUETOOTH_CONNECTED:
return l10n_util::GetStringUTF16(
IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_CONNECTED);
case TabAlertState::BLUETOOTH_SCAN_ACTIVE:
return l10n_util::GetStringUTF16(
IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_SCAN_ACTIVE);
case TabAlertState::USB_CONNECTED:
return l10n_util::GetStringUTF16(
IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED);
......
......@@ -20,16 +20,17 @@ class WebContents;
// Alert states for a tab. Any number of these (or none) may apply at once.
enum class TabAlertState {
MEDIA_RECORDING, // Audio/Video being recorded, consumed by tab.
TAB_CAPTURING, // Tab contents being captured.
AUDIO_PLAYING, // Audible audio is playing from the tab.
AUDIO_MUTING, // Tab audio is being muted.
BLUETOOTH_CONNECTED, // Tab is connected to a BT Device.
USB_CONNECTED, // Tab is connected to a USB device.
HID_CONNECTED, // Tab is connected to a HID device.
SERIAL_CONNECTED, // Tab is connected to a serial device.
PIP_PLAYING, // Tab contains a video in Picture-in-Picture mode.
DESKTOP_CAPTURING, // Desktop contents being recorded, consumed by tab.
MEDIA_RECORDING, // Audio/Video being recorded, consumed by tab.
TAB_CAPTURING, // Tab contents being captured.
AUDIO_PLAYING, // Audible audio is playing from the tab.
AUDIO_MUTING, // Tab audio is being muted.
BLUETOOTH_CONNECTED, // Tab is connected to a BT Device.
BLUETOOTH_SCAN_ACTIVE, // Tab is actively scanning for BT devices.
USB_CONNECTED, // Tab is connected to a USB device.
HID_CONNECTED, // Tab is connected to a HID device.
SERIAL_CONNECTED, // Tab is connected to a serial device.
PIP_PLAYING, // Tab contains a video in Picture-in-Picture mode.
DESKTOP_CAPTURING, // Desktop contents being recorded, consumed by tab.
VR_PRESENTING_IN_HEADSET, // VR content is being presented in a headset.
};
......
......@@ -2193,6 +2193,9 @@ base::string16 BrowserView::GetAccessibleTabLabel(bool include_app_name,
case TabAlertState::BLUETOOTH_CONNECTED:
return l10n_util::GetStringFUTF16(
IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT, title);
case TabAlertState::BLUETOOTH_SCAN_ACTIVE:
return l10n_util::GetStringFUTF16(
IDS_TAB_AX_LABEL_BLUETOOTH_SCAN_ACTIVE_FORMAT, title);
case TabAlertState::HID_CONNECTED:
return l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_HID_CONNECTED_FORMAT,
title);
......
......@@ -103,6 +103,9 @@ gfx::Image GetTabAlertIndicatorImage(TabAlertState alert_state,
case TabAlertState::BLUETOOTH_CONNECTED:
icon = &kTabBluetoothConnectedIcon;
break;
case TabAlertState::BLUETOOTH_SCAN_ACTIVE:
icon = &kTabBluetoothScanActiveIcon;
break;
case TabAlertState::USB_CONNECTED:
icon = &kTabUsbConnectedIcon;
break;
......
......@@ -777,6 +777,7 @@ SkColor Tab::GetAlertIndicatorColor(TabAlertState state) const {
case TabAlertState::PIP_PLAYING:
return theme_provider->GetColor(ThemeProperties::COLOR_TAB_PIP_PLAYING);
case TabAlertState::BLUETOOTH_CONNECTED:
case TabAlertState::BLUETOOTH_SCAN_ACTIVE:
case TabAlertState::USB_CONNECTED:
case TabAlertState::HID_CONNECTED:
case TabAlertState::SERIAL_CONNECTED:
......
......@@ -54,6 +54,8 @@ std::string ConvertAlertStateToString(TabAlertState alert_state) {
return "audio-muting";
case TabAlertState::BLUETOOTH_CONNECTED:
return "bluetooth-connected";
case TabAlertState::BLUETOOTH_SCAN_ACTIVE:
return "bluetooth-connected";
case TabAlertState::USB_CONNECTED:
return "usb-connected";
case TabAlertState::HID_CONNECTED:
......
......@@ -28,6 +28,7 @@
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/bluetooth_delegate.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
......@@ -183,16 +184,20 @@ class WebBluetoothServiceImpl::AdvertisementClient {
WebBluetoothServiceImpl* service,
mojo::PendingAssociatedRemote<
blink::mojom::WebBluetoothAdvertisementClient> client_info)
: client_(std::move(client_info)) {
: client_(std::move(client_info)),
web_contents_(static_cast<WebContentsImpl*>(
WebContents::FromRenderFrameHost(service->render_frame_host_))) {
// Using base::Unretained() is safe here because all instances of this class
// will be owned by |service|.
client_.set_disconnect_handler(
base::BindOnce(&WebBluetoothServiceImpl::RemoveDisconnectedClients,
base::Unretained(service)));
web_contents_->IncrementBluetoothScanningSessionsCount();
}
virtual ~AdvertisementClient() = default;
mojo::AssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient> client_;
WebContentsImpl* web_contents_;
};
class WebBluetoothServiceImpl::WatchAdvertisementsClient
......@@ -207,7 +212,10 @@ class WebBluetoothServiceImpl::WatchAdvertisementsClient
device_id_(device_id) {
DCHECK(device_id_.IsValid());
}
~WatchAdvertisementsClient() override = default;
~WatchAdvertisementsClient() override {
web_contents_->DecrementBluetoothScanningSessionsCount();
}
// AdvertisementClient implementation:
void SendEvent(blink::mojom::WebBluetoothAdvertisingEvent& event) override {
......@@ -236,7 +244,9 @@ class WebBluetoothServiceImpl::ScanningClient
options_->accept_all_advertisements);
}
~ScanningClient() override = default;
~ScanningClient() override {
web_contents_->DecrementBluetoothScanningSessionsCount();
}
void SetPromptController(
BluetoothDeviceScanningPromptController* prompt_controller) {
......
......@@ -1681,6 +1681,10 @@ bool WebContentsImpl::IsConnectedToBluetoothDevice() {
return bluetooth_connected_device_count_ > 0;
}
bool WebContentsImpl::IsScanningForBluetoothDevices() {
return bluetooth_scanning_sessions_count_ > 0;
}
bool WebContentsImpl::IsConnectedToSerialPort() {
return serial_active_frame_count_ > 0;
}
......@@ -7027,6 +7031,30 @@ void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged(
}
}
void WebContentsImpl::IncrementBluetoothScanningSessionsCount() {
// Trying to invalidate the tab state while being destroyed could result in a
// use after free.
if (IsBeingDestroyed())
return;
// Notify for UI updates if the state changes.
bluetooth_scanning_sessions_count_++;
if (bluetooth_scanning_sessions_count_ == 1)
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
}
void WebContentsImpl::DecrementBluetoothScanningSessionsCount() {
// Trying to invalidate the tab state while being destroyed could result in a
// use after free.
if (IsBeingDestroyed())
return;
DCHECK_NE(0u, bluetooth_scanning_sessions_count_);
bluetooth_scanning_sessions_count_--;
if (bluetooth_scanning_sessions_count_ == 0)
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
}
void WebContentsImpl::IncrementSerialActiveFrameCount() {
// Trying to invalidate the tab state while being destroyed could result in a
// use after free.
......
......@@ -377,6 +377,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void SetAudioMuted(bool mute) override;
bool IsCurrentlyAudible() override;
bool IsConnectedToBluetoothDevice() override;
bool IsScanningForBluetoothDevices() override;
bool IsConnectedToSerialPort() override;
bool IsConnectedToHidDevice() override;
bool HasNativeFileSystemHandles() override;
......@@ -1065,6 +1066,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void OnIsConnectedToBluetoothDeviceChanged(
bool is_connected_to_bluetooth_device);
void IncrementBluetoothScanningSessionsCount();
void DecrementBluetoothScanningSessionsCount();
// Modify the counter of frames in this WebContents actively using serial
// ports.
void IncrementSerialActiveFrameCount();
......@@ -1922,6 +1926,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
std::unique_ptr<WebContentsAudioMuter> audio_muter_;
size_t bluetooth_connected_device_count_ = 0;
size_t bluetooth_scanning_sessions_count_ = 0;
size_t serial_active_frame_count_ = 0;
size_t hid_active_frame_count_ = 0;
......
......@@ -520,6 +520,10 @@ class WebContents : public PageNavigator,
// Device.
virtual bool IsConnectedToBluetoothDevice() = 0;
// Indicates whether any frame in the WebContents is scanning for Bluetooth
// devices.
virtual bool IsScanningForBluetoothDevices() = 0;
// Indicates whether any frame in the WebContents is connected to a serial
// port.
virtual bool IsConnectedToSerialPort() = 0;
......
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