-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create abstract classes for device system tray icon
This change creates abstract classes in chrome/browser/device_notifications for common device system tray icon that will be used by WebHID and WebUSB system tray icon. There will be follow-up CLs to move common logic into these common classes. Bug: 1303193 Change-Id: Ie9a6c894381c9defe427380333dabd31a9465ef8 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4483156 Reviewed-by: Theresa Sullivan <twellington@chromium.org> Commit-Queue: Jack Hsieh <chengweih@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Cr-Commit-Position: refs/heads/main@{#1146565}
- Loading branch information
1 parent
42c273b
commit e057e15
Showing
11 changed files
with
283 additions
and
216 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
file://chrome/browser/usb/OWNERS | ||
file://chrome/browser/hid/OWNERS |
140 changes: 140 additions & 0 deletions
140
chrome/browser/device_notifications/device_connection_tracker.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/device_notifications/device_connection_tracker.h" | ||
|
||
#include <string> | ||
|
||
#include "base/notreached.h" | ||
#include "build/build_config.h" | ||
#include "chrome/browser/device_notifications/device_system_tray_icon.h" | ||
#include "chrome/browser/profiles/profile.h" | ||
#include "chrome/browser/ui/chrome_pages.h" | ||
#include "content/public/browser/browser_thread.h" | ||
#include "extensions/buildflags/buildflags.h" | ||
#include "url/origin.h" | ||
|
||
#if BUILDFLAG(ENABLE_EXTENSIONS) | ||
#include "extensions/browser/extension_registry.h" | ||
#include "extensions/common/constants.h" | ||
#endif // BUILDFLAG(ENABLE_EXTENSIONS) | ||
|
||
namespace { | ||
|
||
using base::TimeTicks; | ||
|
||
std::string GetOriginName(Profile* profile, const url::Origin& origin) { | ||
#if BUILDFLAG(ENABLE_EXTENSIONS) | ||
if (origin.scheme() == extensions::kExtensionScheme) { | ||
const auto* extension_registry = | ||
extensions::ExtensionRegistry::Get(profile); | ||
CHECK(extension_registry); | ||
const extensions::Extension* extension = | ||
extension_registry->GetExtensionById( | ||
origin.host(), extensions::ExtensionRegistry::EVERYTHING); | ||
// The extension must be installed if we are generating the name. | ||
CHECK(extension); | ||
return extension->name(); | ||
} | ||
#endif // BUILDFLAG(ENABLE_EXTENSIONS) | ||
NOTREACHED_NORETURN(); | ||
} | ||
|
||
} // namespace | ||
|
||
DeviceConnectionTracker::DeviceConnectionTracker(Profile* profile) | ||
: profile_(profile) {} | ||
|
||
DeviceConnectionTracker::~DeviceConnectionTracker() { | ||
CleanUp(); | ||
} | ||
|
||
void DeviceConnectionTracker::IncrementConnectionCount( | ||
const url::Origin& origin) { | ||
bool to_stage_profile = origins_.empty(); | ||
auto& state = origins_[origin]; | ||
|
||
CHECK_GE(state.count, 0); | ||
if (state.count == 0) { | ||
state.name = GetOriginName(profile_, origin); | ||
} | ||
++state.count; | ||
state.timestamp = TimeTicks::Now(); | ||
++total_connection_count_; | ||
|
||
auto* system_tray_icon = GetSystemTrayIcon(); | ||
if (!system_tray_icon) { | ||
return; | ||
} | ||
if (to_stage_profile) { | ||
system_tray_icon->StageProfile(profile_); | ||
} else { | ||
system_tray_icon->NotifyConnectionCountUpdated(profile_); | ||
} | ||
} | ||
|
||
void DeviceConnectionTracker::DecrementConnectionCount( | ||
const url::Origin& origin) { | ||
auto it = origins_.find(origin); | ||
CHECK(it != origins_.end()); | ||
|
||
auto& state = it->second; | ||
CHECK_GT(state.count, 0); | ||
--state.count; | ||
state.timestamp = TimeTicks::Now(); | ||
--total_connection_count_; | ||
if (state.count == 0) { | ||
content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) | ||
->PostDelayedTask( | ||
FROM_HERE, | ||
base::BindOnce(&DeviceConnectionTracker::CleanUpOrigin, | ||
weak_factory_.GetWeakPtr(), origin, state.timestamp), | ||
kOriginInactiveTime); | ||
} | ||
|
||
auto* system_tray_icon = GetSystemTrayIcon(); | ||
if (!system_tray_icon) { | ||
return; | ||
} | ||
system_tray_icon->NotifyConnectionCountUpdated(profile_); | ||
} | ||
|
||
void DeviceConnectionTracker::ShowSiteSettings(const url::Origin& origin) { | ||
chrome::ShowSiteSettings(profile_, origin.GetURL()); | ||
} | ||
|
||
void DeviceConnectionTracker::CleanUp() { | ||
if (!origins_.empty()) { | ||
origins_.clear(); | ||
total_connection_count_ = 0; | ||
auto* system_tray_icon = GetSystemTrayIcon(); | ||
if (system_tray_icon) { | ||
system_tray_icon->UnstageProfile(profile_, /*immediate=*/true); | ||
} | ||
} | ||
} | ||
|
||
void DeviceConnectionTracker::CleanUpOrigin(const url::Origin& origin, | ||
const TimeTicks& timestamp) { | ||
auto it = origins_.find(origin); | ||
if (it == origins_.end()) { | ||
// This can happen if the connection bounces within 1 microsecond, which is | ||
// the base unit of base::TimeTicks. The first CleanUpOrigin call will clear | ||
// the origin because it sees the timestamp as the same. | ||
return; | ||
} | ||
auto& state = it->second; | ||
if (state.count == 0 && state.timestamp == timestamp) { | ||
origins_.erase(it); | ||
auto* system_tray_icon = GetSystemTrayIcon(); | ||
if (!system_tray_icon) { | ||
return; | ||
} | ||
if (origins_.empty()) { | ||
system_tray_icon->UnstageProfile(profile_, /*immediate=*/true); | ||
} else { | ||
system_tray_icon->NotifyConnectionCountUpdated(profile_); | ||
} | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
chrome/browser/device_notifications/device_connection_tracker.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_CONNECTION_TRACKER_H_ | ||
#define CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_CONNECTION_TRACKER_H_ | ||
|
||
#include "base/containers/flat_map.h" | ||
#include "chrome/browser/device_notifications/device_system_tray_icon.h" | ||
#include "chrome/browser/profiles/profile.h" | ||
#include "components/keyed_service/core/keyed_service.h" | ||
#include "url/origin.h" | ||
|
||
// Manages the opened device connection count by the profile. | ||
class DeviceConnectionTracker : public KeyedService { | ||
public: | ||
struct OriginState { | ||
// The number of active connections. | ||
int count; | ||
// The last time the state was updated. | ||
base::TimeTicks timestamp; | ||
// String representation for the origin. | ||
std::string name; | ||
|
||
bool operator==(const OriginState& other) const { | ||
return count == other.count && timestamp == other.timestamp && | ||
name == other.name; | ||
} | ||
}; | ||
|
||
explicit DeviceConnectionTracker(Profile* profile); | ||
DeviceConnectionTracker(DeviceConnectionTracker&&) = delete; | ||
DeviceConnectionTracker& operator=(DeviceConnectionTracker&) = delete; | ||
~DeviceConnectionTracker() override; | ||
|
||
virtual void IncrementConnectionCount(const url::Origin& origin); | ||
virtual void DecrementConnectionCount(const url::Origin& origin); | ||
|
||
virtual void ShowContentSettingsExceptions() = 0; | ||
virtual void ShowSiteSettings(const url::Origin& origin); | ||
|
||
// This is used by either the destructor or | ||
// the corresponding ConnectionTrackerFactory::BrowserContextShutdown to | ||
// remove its profile from DeviceSystemTrayIcon. | ||
void CleanUp(); | ||
|
||
int total_connection_count() { return total_connection_count_; } | ||
Profile* profile() { return profile_; } | ||
|
||
const base::flat_map<url::Origin, OriginState>& origins() { return origins_; } | ||
|
||
// The time period that an origin remains tracked before it is removed from | ||
// `origins_`. | ||
static constexpr base::TimeDelta kOriginInactiveTime = base::Seconds(10); | ||
|
||
// Removes the `origin` from the `origins_` list if it has not had any new | ||
// connections since `timestamp`. | ||
void CleanUpOrigin(const url::Origin& origin, | ||
const base::TimeTicks& timestamp); | ||
|
||
int total_connection_count_ = 0; | ||
raw_ptr<Profile> profile_; | ||
|
||
// The structure that tracks the connection count for each origin that has | ||
// active connection(s). | ||
base::flat_map<url::Origin, OriginState> origins_; | ||
|
||
private: | ||
virtual DeviceSystemTrayIcon* GetSystemTrayIcon() = 0; | ||
|
||
base::WeakPtrFactory<DeviceConnectionTracker> weak_factory_{this}; | ||
}; | ||
|
||
#endif // CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_CONNECTION_TRACKER_H_ |
9 changes: 9 additions & 0 deletions
9
chrome/browser/device_notifications/device_system_tray_icon.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/device_notifications/device_system_tray_icon.h" | ||
|
||
DeviceSystemTrayIcon::DeviceSystemTrayIcon() = default; | ||
|
||
DeviceSystemTrayIcon::~DeviceSystemTrayIcon() = default; |
40 changes: 40 additions & 0 deletions
40
chrome/browser/device_notifications/device_system_tray_icon.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_SYSTEM_TRAY_ICON_H_ | ||
#define CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_SYSTEM_TRAY_ICON_H_ | ||
|
||
class Profile; | ||
|
||
class DeviceSystemTrayIcon { | ||
public: | ||
DeviceSystemTrayIcon(); | ||
DeviceSystemTrayIcon(const DeviceSystemTrayIcon&) = delete; | ||
DeviceSystemTrayIcon& operator=(const DeviceSystemTrayIcon&) = delete; | ||
virtual ~DeviceSystemTrayIcon(); | ||
|
||
// Stage `profile` to be shown in the system tray icon. | ||
virtual void StageProfile(Profile* profile) = 0; | ||
|
||
// TODO(crbug.com/1353104): Remove support for non-immediate unstage request. | ||
// Unstage `profile` that is being shown in the system tray icon. The profile | ||
// will be removed immediately when `immediate` is true, otherwise it is | ||
// scheduled to be removed later. | ||
virtual void UnstageProfile(Profile* profile, bool immediate) = 0; | ||
|
||
// Notify the system tray icon the connection count of the `profile` has | ||
// changed. | ||
virtual void NotifyConnectionCountUpdated(Profile* profile) = 0; | ||
|
||
protected: | ||
// This function is called after the `profile` object is added to the | ||
// `profiles_`. | ||
virtual void ProfileAdded(Profile* profile) = 0; | ||
|
||
// This function is called after the `profile` object is removed from the | ||
// `profiles_`. | ||
virtual void ProfileRemoved(Profile* profile) = 0; | ||
}; | ||
|
||
#endif // CHROME_BROWSER_DEVICE_NOTIFICATIONS_DEVICE_SYSTEM_TRAY_ICON_H_ |
Oops, something went wrong.