mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Handle system standby
PiperOrigin-RevId: 949324299
This commit is contained in:
committed by
Copybara-Service
parent
953d9ea26c
commit
4301bc4fce
@@ -307,6 +307,9 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) {
|
||||
<< bluetooth_classic_advertiser_client_id_;
|
||||
}
|
||||
|
||||
wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
wifi_lan_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
|
||||
bluetooth_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
ble_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
ble_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
@@ -316,9 +319,6 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) {
|
||||
client->GetAdvertisingServiceId());
|
||||
}
|
||||
|
||||
wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
wifi_lan_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::kEnableAwdl)) {
|
||||
awdl_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define PLATFORM_API_DEVICE_INFO_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -39,6 +40,7 @@ class DeviceInfo {
|
||||
kWindows,
|
||||
kMacOS
|
||||
};
|
||||
enum class SuspendResumeEvent { kSuspend, kResume };
|
||||
|
||||
virtual ~DeviceInfo() = default;
|
||||
|
||||
@@ -69,6 +71,14 @@ class DeviceInfo {
|
||||
// Control device sleep
|
||||
virtual bool PreventSleep() = 0;
|
||||
virtual bool AllowSleep() = 0;
|
||||
|
||||
// Monitor suspend/resume events.
|
||||
// Returns a listener id that can be used to unregister the listener.
|
||||
virtual int64_t RegisterSuspendResumeListener(
|
||||
std::function<void(SuspendResumeEvent)> callback) {
|
||||
return 0;
|
||||
}
|
||||
virtual void UnregisterSuspendResumeListener(int64_t listener_id) {}
|
||||
};
|
||||
|
||||
template <typename Sink>
|
||||
|
||||
@@ -72,7 +72,13 @@ cc_library(
|
||||
"timer.h",
|
||||
"utils.h",
|
||||
],
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
defines = [
|
||||
"_SILENCE_CLANG_COROUTINE_MESSAGE",
|
||||
"_WIN32_WINNT=_WIN32_WINNT_WIN10",
|
||||
],
|
||||
linkopts = [
|
||||
"powrprof.lib",
|
||||
],
|
||||
tags = ["windows"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
|
||||
@@ -14,13 +14,19 @@
|
||||
|
||||
#include "internal/platform/implementation/windows/device_info.h"
|
||||
|
||||
// clang-format off
|
||||
#include <shlobj_core.h>
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
#include <powrprof.h>
|
||||
#include <powerbase.h>
|
||||
// clang-format on
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
@@ -30,10 +36,19 @@
|
||||
#include "internal/platform/implementation/windows/device_paths.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
namespace {
|
||||
using ::nearby::windows::string_utils::WideStringToString;
|
||||
} // namespace
|
||||
|
||||
DeviceInfo::~DeviceInfo() {
|
||||
if (suspend_resume_notification_handle_ != nullptr) {
|
||||
PowerUnregisterSuspendResumeNotification(
|
||||
suspend_resume_notification_handle_);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> DeviceInfo::GetOsDeviceName() const {
|
||||
std::optional<std::wstring> device_name = GetDnsHostName();
|
||||
@@ -113,4 +128,61 @@ bool DeviceInfo::AllowSleep() {
|
||||
return session_manager_.AllowSleep();
|
||||
}
|
||||
|
||||
ULONG DeviceInfo::PowerSuspendResumeCallback(PVOID context, ULONG type,
|
||||
PVOID setting) {
|
||||
api::DeviceInfo::SuspendResumeEvent event;
|
||||
switch (type) {
|
||||
case PBT_APMSUSPEND:
|
||||
event = api::DeviceInfo::SuspendResumeEvent::kSuspend;
|
||||
break;
|
||||
case PBT_APMRESUMESUSPEND:
|
||||
event = api::DeviceInfo::SuspendResumeEvent::kResume;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
DeviceInfo* device_info = static_cast<DeviceInfo*>(context);
|
||||
device_info->OnSuspendResumeEvent(event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t DeviceInfo::RegisterSuspendResumeListener(
|
||||
std::function<void(api::DeviceInfo::SuspendResumeEvent)> callback) {
|
||||
absl::MutexLock lock(suspend_resume_mutex_);
|
||||
int64_t listener_id = ++next_suspend_resume_listener_id_;
|
||||
suspend_resume_listeners_.emplace(listener_id, std::move(callback));
|
||||
if (suspend_resume_listeners_.size() == 1) {
|
||||
DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS subscribe_params;
|
||||
subscribe_params.Callback = PowerSuspendResumeCallback;
|
||||
subscribe_params.Context = this;
|
||||
PowerRegisterSuspendResumeNotification(
|
||||
DEVICE_NOTIFY_CALLBACK, &subscribe_params,
|
||||
&suspend_resume_notification_handle_);
|
||||
}
|
||||
return listener_id;
|
||||
}
|
||||
|
||||
void DeviceInfo::UnregisterSuspendResumeListener(int64_t listener_id) {
|
||||
absl::MutexLock lock(suspend_resume_mutex_);
|
||||
suspend_resume_listeners_.erase(listener_id);
|
||||
if (suspend_resume_listeners_.empty()) {
|
||||
if (suspend_resume_notification_handle_ != nullptr) {
|
||||
PowerUnregisterSuspendResumeNotification(
|
||||
suspend_resume_notification_handle_);
|
||||
}
|
||||
suspend_resume_notification_handle_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceInfo::OnSuspendResumeEvent(
|
||||
api::DeviceInfo::SuspendResumeEvent event) {
|
||||
LOG(INFO) << "OnSuspendResumeEvent: "
|
||||
<< (event == DeviceInfo::SuspendResumeEvent::kSuspend ? "kSuspend"
|
||||
: "kResume");
|
||||
absl::MutexLock lock(suspend_resume_mutex_);
|
||||
for (auto& it : suspend_resume_listeners_) {
|
||||
it.second(event);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nearby::windows
|
||||
|
||||
@@ -15,11 +15,19 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_DEVICE_INFO_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_DEVICE_INFO_H_
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <powerbase.h>
|
||||
// clang-format on
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/base/file_path.h"
|
||||
@@ -31,7 +39,7 @@ namespace windows {
|
||||
|
||||
class DeviceInfo : public api::DeviceInfo {
|
||||
public:
|
||||
~DeviceInfo() override = default;
|
||||
~DeviceInfo() override;
|
||||
|
||||
std::optional<std::string> GetOsDeviceName() const override;
|
||||
api::DeviceInfo::DeviceType GetDeviceType() const override;
|
||||
@@ -51,9 +59,26 @@ class DeviceInfo : public api::DeviceInfo {
|
||||
bool PreventSleep() override;
|
||||
bool AllowSleep() override;
|
||||
|
||||
int64_t RegisterSuspendResumeListener(
|
||||
std::function<void(api::DeviceInfo::SuspendResumeEvent)> callback)
|
||||
override;
|
||||
void UnregisterSuspendResumeListener(int64_t listener_id) override;
|
||||
|
||||
private:
|
||||
static ULONG PowerSuspendResumeCallback(PVOID context, ULONG type,
|
||||
PVOID setting);
|
||||
void OnSuspendResumeEvent(SuspendResumeEvent event);
|
||||
|
||||
mutable absl::Mutex mutex_;
|
||||
SessionManager session_manager_ ABSL_GUARDED_BY(mutex_);
|
||||
absl::Mutex suspend_resume_mutex_;
|
||||
int64_t next_suspend_resume_listener_id_ ABSL_GUARDED_BY(
|
||||
suspend_resume_mutex_) = 0;
|
||||
absl::flat_hash_map<
|
||||
int64_t, absl::AnyInvocable<void(SuspendResumeEvent)>>
|
||||
suspend_resume_listeners_ ABSL_GUARDED_BY(suspend_resume_mutex_);
|
||||
HPOWERNOTIFY suspend_resume_notification_handle_
|
||||
ABSL_GUARDED_BY(suspend_resume_mutex_) = nullptr;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -61,6 +61,9 @@ constexpr auto kShowAutoUpdateSetting =
|
||||
// The default time in milliseconds a cached entry can be in LOST state.
|
||||
constexpr auto kDiscoveryCacheLostExpiryMs =
|
||||
flags::Flag<int64_t>(kConfigPackage, "45658774", 15000);
|
||||
// When true, enable suspend resume listener.
|
||||
constexpr auto kEnableSuspendResumeListener =
|
||||
flags::Flag<bool>(kConfigPackage, "45815625", false);
|
||||
// When true, enable wifi hotspot medium for HP Realtek devices.
|
||||
constexpr auto kEnableWifiHotspotForHpRealtekDevices =
|
||||
flags::Flag<bool>(kConfigPackage, "45673628", false);
|
||||
@@ -105,6 +108,7 @@ inline absl::btree_map<int, const flags::Flag<bool>&> GetBoolFlags() {
|
||||
{45411589, kEnableRetryResumeTransfer},
|
||||
{45459748, kEnableSendingDesktopEvents},
|
||||
{45409033, kShowAutoUpdateSetting},
|
||||
{45815625, kEnableSuspendResumeListener},
|
||||
{45673628, kEnableWifiHotspotForHpRealtekDevices},
|
||||
{45683539, kUseAlternateServiceUuidForDiscovery},
|
||||
{45776229, kEnableBackup},
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "internal/base/file_path.h"
|
||||
@@ -134,6 +135,12 @@ constexpr absl::Duration kProcessShutdownPendingTimerDelay = // NOLINT
|
||||
absl::Seconds(15);
|
||||
constexpr absl::Duration kProcessNetworkChangeTimerDelay = absl::Seconds(1);
|
||||
|
||||
// Delay invalidating the surface state after a resume event.
|
||||
// Network activities can cause system to resume for short periods before
|
||||
// suspending again. This delay allows us to ignore those and only resume
|
||||
// fully when the system is stable.
|
||||
constexpr absl::Duration kResumeDelay = absl::Milliseconds(500);
|
||||
|
||||
// The maximum number of certificate downloads that can be performed during a
|
||||
// discovery session.
|
||||
// Assuming a 2min discovery session and 10s download interval.
|
||||
@@ -337,6 +344,13 @@ NearbySharingServiceImpl::NearbySharingServiceImpl(
|
||||
OnLockStateChanged(screen_status ==
|
||||
nearby::api::DeviceInfo::ScreenStatus::kLocked);
|
||||
});
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
kEnableSuspendResumeListener)) {
|
||||
suspend_resume_listener_id_ =
|
||||
device_info_.RegisterSuspendResumeListener(absl::bind_front(
|
||||
&NearbySharingServiceImpl::OnSuspendResumeEvent, this));
|
||||
}
|
||||
|
||||
account_manager_.AddObserver(this);
|
||||
settings_->AddSettingsObserver(this);
|
||||
@@ -384,6 +398,8 @@ void NearbySharingServiceImpl::Shutdown(
|
||||
background_receive_callbacks_map_.clear();
|
||||
|
||||
device_info_.UnregisterScreenLockedListener(kScreenStateListenerName);
|
||||
device_info_.UnregisterSuspendResumeListener(
|
||||
suspend_resume_listener_id_);
|
||||
|
||||
settings_->RemoveSettingsObserver(this);
|
||||
|
||||
@@ -1415,6 +1431,42 @@ void NearbySharingServiceImpl::OnLockStateChanged(bool locked) {
|
||||
});
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::OnSuspendResumeEvent(
|
||||
nearby::api::DeviceInfo::SuspendResumeEvent event) {
|
||||
bool suspended =
|
||||
event == nearby::api::DeviceInfo::SuspendResumeEvent::kSuspend;
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
suspended_ = suspended;
|
||||
if (!suspended) {
|
||||
resume_delay_timer_ = std::make_unique<ThreadTimer>(
|
||||
*service_thread_, "suspend_resume_timer", kResumeDelay, [this]() {
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
if (suspended_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG(INFO) << "InvalidateSurfaceState due to system resume";
|
||||
InvalidateSurfaceState();
|
||||
});
|
||||
}
|
||||
}
|
||||
if (suspended) {
|
||||
RunOnNearbySharingServiceThread("on_suspend", [this]() {
|
||||
LOG(INFO) << "InvalidateSurfaceState due to system suspend";
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
if (!suspended_) {
|
||||
return;
|
||||
}
|
||||
resume_delay_timer_.reset();
|
||||
}
|
||||
InvalidateSurfaceState();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::AdapterPresentChanged(
|
||||
sharing::api::BluetoothAdapter* adapter, bool present) {
|
||||
RunOnNearbySharingServiceThread("bt_adapter_present_changed", [this, adapter,
|
||||
@@ -1873,6 +1925,16 @@ void NearbySharingServiceImpl::InvalidateSendSurfaceState() {
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateScanningState() {
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
if (suspended_) {
|
||||
StopScanning();
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping discovery because the system is suspended.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop scanning when screen is off.
|
||||
if (is_screen_locked_) {
|
||||
StopScanning();
|
||||
@@ -1910,6 +1972,17 @@ void NearbySharingServiceImpl::InvalidateScanningState() {
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateFastInitiationAdvertising() {
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
if (suspended_) {
|
||||
StopFastInitiationAdvertising();
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping fast initiation advertising because the "
|
||||
"system is suspended.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Screen is off. Do no work.
|
||||
if (is_screen_locked_) {
|
||||
StopFastInitiationAdvertising();
|
||||
@@ -1949,6 +2022,16 @@ void NearbySharingServiceImpl::InvalidateFastInitiationAdvertising() {
|
||||
}
|
||||
|
||||
void NearbySharingServiceImpl::InvalidateAdvertisingState() {
|
||||
{
|
||||
absl::MutexLock lock(suspend_mutex_);
|
||||
if (suspended_) {
|
||||
StopAdvertising();
|
||||
VLOG(1) << __func__
|
||||
<< ": Stopping advertising because the system is suspended.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool supports_advertising_on_lock_screen =
|
||||
NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_sharing_feature::
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
|
||||
#include "location/nearby/sharing/lib/sync/sync_manager.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
@@ -219,6 +220,9 @@ class NearbySharingServiceImpl
|
||||
// Handle the state changes of screen lock.
|
||||
void OnLockStateChanged(bool locked);
|
||||
|
||||
void OnSuspendResumeEvent(
|
||||
nearby::api::DeviceInfo::SuspendResumeEvent event);
|
||||
|
||||
// Handle the state changes of bluetooth adapter.
|
||||
void AdapterPresentChanged(sharing::api::BluetoothAdapter* adapter,
|
||||
bool present) override;
|
||||
@@ -550,6 +554,11 @@ class NearbySharingServiceImpl
|
||||
proto::DeviceVisibility last_advertised_device_visibility_ =
|
||||
proto::DeviceVisibility::DEVICE_VISIBILITY_UNSPECIFIED;
|
||||
bool advertising_on_screen_locked_ = false;
|
||||
int64_t suspend_resume_listener_id_ = 0;
|
||||
absl::Mutex suspend_mutex_;
|
||||
bool suspended_ ABSL_GUARDED_BY(suspend_mutex_) = false;
|
||||
std::unique_ptr<ThreadTimer> resume_delay_timer_
|
||||
ABSL_GUARDED_BY(suspend_mutex_);
|
||||
};
|
||||
|
||||
} // namespace nearby::sharing
|
||||
|
||||
Reference in New Issue
Block a user