Migrate device_info from location/nearby to third_party/nearby

PiperOrigin-RevId: 504935151
This commit is contained in:
Qin Wang
2023-01-26 14:01:11 -08:00
committed by Copybara-Service
parent 54fec27c00
commit a0692e6306
38 changed files with 942 additions and 625 deletions
-32
View File
@@ -27,13 +27,10 @@ cc_library(
name = "platform_windows",
srcs = [
"ble_gatt_client.cc",
"device_info.cc",
"fast_pair_platform.cc",
"utils.cc",
],
hdrs = [
"ble_gatt_client.h",
"device_info.h",
"utils.h",
],
copts = [
@@ -42,7 +39,6 @@ cc_library(
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
visibility = ["//fastpair:__subpackages__"],
deps = [
"//fastpair/internal/api:platform",
"//internal/platform:base",
"//internal/platform:logging",
"//internal/platform/implementation/windows",
@@ -54,31 +50,3 @@ cc_library(
"@com_google_absl//absl/synchronization",
],
)
cc_test(
name = "platform_windows_test",
size = "small",
timeout = "short",
srcs = [
"device_info_test.cc",
],
copts = [
"-Ithird_party/nearby/internal/platform/implementation/windows/generated",
],
shard_count = 1,
deps = [
":platform_windows",
":platform_windows_libs",
"//fastpair/internal/api:platform",
"//internal/platform:base",
"//internal/platform:logging",
"//internal/platform/implementation:types",
"//internal/platform/implementation/windows",
"//internal/platform/implementation/windows/generated:types",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_googletest//:gtest_main",
],
)
@@ -1,200 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastpair/internal/impl/windows/device_info.h"
#include <shlobj_core.h>
#include <windows.h>
#include <wtsapi32.h>
#include <array>
#include <functional>
#include <optional>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "fastpair/internal/api/device_info.h"
#include "internal/platform/logging.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.System.h"
namespace nearby {
namespace windows {
constexpr char window_class_name[] = "FastPairDLL_MessageWindowClass";
constexpr char window_name[] = "FastPairDLL_MessageWindow";
namespace {
// This WindowProc method must be static for the successful initialization of
// WNDCLASS
// window_class.lpfnWndProc = (WNDPROC) &DeviceInfo::WindowProc;
// where a WNDPROC typed function pointer is expected
// typedef LRESULT (CALLBACK* WNDPROC)(HWND,UINT,WPARAM,LPARAM)
// the calling convention used here CALLBACK is a macro defined as
// #define CALLBACK __stdcall
//
// If WindProc is not static and defined as a member function, it uses the
// __thiscall calling convention instead
// https://docs.microsoft.com/en-us/cpp/cpp/thiscall?view=msvc-170
// https://isocpp.org/wiki/faq/pointers-to-members
// https://en.cppreference.com/w/cpp/language/pointer
//
// This is problematic because the function pointer now looks like this
// typedef LRESULT (CALLBACK* DeviceInfo_WNDPROC)(DeviceInfo*
// this,HWND,UINT,WPARAM,LPARAM)
// which causes casting errors
LRESULT CALLBACK WindowProc(HWND window_handle, UINT message, WPARAM wparam,
LPARAM lparam) {
DeviceInfo* self = reinterpret_cast<DeviceInfo*>(
GetWindowLongPtr(window_handle, GWLP_USERDATA));
CREATESTRUCT* create_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
LONG_PTR result = 0L;
switch (message) {
case WM_CREATE:
self = reinterpret_cast<DeviceInfo*>(create_struct->lpCreateParams);
self->message_window_handle_ = window_handle;
// Store pointer to the self to the window's user data.
SetLastError(0);
result = SetWindowLongPtr(window_handle, GWLP_USERDATA,
reinterpret_cast<LONG_PTR>(self));
if (result == 0 && GetLastError() != 0) {
NEARBY_LOGS(ERROR)
<< __func__
<< ": Error connecting message window to Fast Pair DLL.";
}
break;
case WM_WTSSESSION_CHANGE:
if (self) {
switch (wparam) {
case WTS_SESSION_LOCK:
for (auto& listener : self->screen_locked_listeners_) {
listener.second(api::DeviceInfo::ScreenStatus::
kLocked); // Trigger registered callbacks
}
break;
case WTS_SESSION_UNLOCK:
for (auto& listener : self->screen_locked_listeners_) {
listener.second(api::DeviceInfo::ScreenStatus::
kUnlocked); // Trigger registered callbacks
}
break;
}
}
break;
case WM_DESTROY:
SetLastError(0);
result = SetWindowLongPtr(window_handle, GWLP_USERDATA, NULL);
if (result == 0 && GetLastError() != 0) {
NEARBY_LOGS(ERROR)
<< __func__
<< ": Error disconnecting message window to Fast Pair DLL.";
}
break;
}
return DefWindowProc(window_handle, message, wparam, lparam);
}
} // namespace
DeviceInfo::~DeviceInfo() {
UnregisterClass(MAKEINTATOM(registered_class_), instance_);
}
api::DeviceInfo::OsType DeviceInfo::GetOsType() const {
return api::DeviceInfo::OsType::kWindows;
}
bool DeviceInfo::IsScreenLocked() const {
DWORD session_id = WTSGetActiveConsoleSessionId();
WTS_INFO_CLASS wts_info_class = WTSSessionInfoEx;
LPTSTR session_info_buffer = nullptr;
DWORD session_info_buffer_size_bytes = 0;
WTSINFOEXW* wts_info = nullptr;
LONG session_state = WTS_SESSIONSTATE_UNKNOWN;
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
wts_info_class, &session_info_buffer,
&session_info_buffer_size_bytes)) {
if (session_info_buffer_size_bytes > 0) {
wts_info = (WTSINFOEXW*)session_info_buffer;
if (wts_info->Level == 1) {
session_state = wts_info->Data.WTSInfoExLevel1.SessionFlags;
}
}
WTSFreeMemory(session_info_buffer);
session_info_buffer = nullptr;
}
bool isScreenLocked = session_state == WTS_SESSIONSTATE_LOCK;
NEARBY_LOGS(INFO) << __func__ << "ScreenStatus: "
<< (isScreenLocked ? "Locked" : "NotLocked");
return isScreenLocked;
}
void DeviceInfo::RegisterScreenLockedListener(
absl::string_view listener_name,
std::function<void(api::DeviceInfo::ScreenStatus)> callback) {
if (message_window_handle_ == nullptr) {
instance_ = (HINSTANCE)GetModuleHandle(NULL);
WNDCLASS window_class;
window_class.style = 0;
window_class.lpfnWndProc = (WNDPROC)&WindowProc;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = instance_;
window_class.hIcon = nullptr;
window_class.hCursor = nullptr;
window_class.hbrBackground = nullptr;
window_class.lpszMenuName = nullptr;
window_class.lpszClassName = window_class_name;
registered_class_ = RegisterClass(&window_class);
message_window_handle_ = CreateWindow(
MAKEINTATOM(registered_class_), // class atom from RegisterClass
window_name, // window name
0, // window style
0, // initial x position of window
0, // initial y position of window
0, // width
0, // height
HWND_MESSAGE, // handle to the parent of window
// (message-only window in this case)
nullptr, // handle to a menu
instance_, // handle to the instance of the module
// associated to the window
this); // pointer to be passed to the window for additional data
if (!message_window_handle_) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to create message window for Fast Pair DLL.";
}
}
screen_locked_listeners_.emplace(listener_name, callback);
}
void DeviceInfo::UnregisterScreenLockedListener(
absl::string_view listener_name) {
screen_locked_listeners_.erase(listener_name);
}
} // namespace windows
} // namespace nearby
@@ -1,54 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
#include <guiddef.h>
#include <windows.h>
#include <functional>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "fastpair/internal/api/device_info.h"
namespace nearby {
namespace windows {
class DeviceInfo : public api::DeviceInfo {
public:
~DeviceInfo() override;
api::DeviceInfo::OsType GetOsType() const override;
bool IsScreenLocked() const override;
void RegisterScreenLockedListener(
absl::string_view listener_name,
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override;
void UnregisterScreenLockedListener(absl::string_view listener_name) override;
absl::flat_hash_map<std::string,
std::function<void(api::DeviceInfo::ScreenStatus)>>
screen_locked_listeners_;
HINSTANCE instance_ = nullptr;
ATOM registered_class_ = NULL;
HWND message_window_handle_ = nullptr;
};
} // namespace windows
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
@@ -1,93 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastpair/internal/impl/windows/device_info.h"
#include <functional>
#include <string>
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "fastpair/internal/api/device_info.h"
namespace nearby {
namespace windows {
namespace {
TEST(DeviceInfo, DISABLED_GetOsType) {
EXPECT_EQ(DeviceInfo().GetOsType(), api::DeviceInfo::OsType::kWindows);
}
TEST(DeviceInfo, DISABLED_IsScreenLocked) {
EXPECT_TRUE(DeviceInfo().IsScreenLocked());
}
TEST(DeviceInfo, DISABLED_RegisterScreenLockedListener) {
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
[](api::DeviceInfo::ScreenStatus) {};
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
[](api::DeviceInfo::ScreenStatus) {};
DeviceInfo device_info;
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
device_info.RegisterScreenLockedListener("listener_1", listener_1);
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
device_info.RegisterScreenLockedListener("listener_2", listener_2);
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
}
TEST(DeviceInfo, DISABLED_UnregisterScreenLockedListener) {
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
[](api::DeviceInfo::ScreenStatus) {};
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
[](api::DeviceInfo::ScreenStatus) {};
DeviceInfo device_info;
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
device_info.RegisterScreenLockedListener("listener_1", listener_1);
device_info.RegisterScreenLockedListener("listener_2", listener_2);
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
device_info.UnregisterScreenLockedListener("listener_1");
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
device_info.UnregisterScreenLockedListener("listener_2");
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
}
TEST(DeviceInfo, DISABLED_UpdateScreenLockedListener) {
absl::Notification notification;
api::DeviceInfo::ScreenStatus screen_locked_tracker =
api::DeviceInfo::ScreenStatus::kUndetermined;
std::function<void(api::DeviceInfo::ScreenStatus)> listener =
[&screen_locked_tracker,
&notification](api::DeviceInfo::ScreenStatus status) {
screen_locked_tracker = api::DeviceInfo::ScreenStatus::kLocked;
notification.Notify();
};
DeviceInfo device_info;
device_info.RegisterScreenLockedListener("listener", listener);
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(absl::Seconds(5)));
EXPECT_EQ(screen_locked_tracker, api::DeviceInfo::ScreenStatus::kLocked);
}
} // namespace
} // namespace windows
} // namespace nearby
@@ -1,33 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastpair/internal/api/fast_pair_platform.h"
#include <functional>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "fastpair/internal/impl/windows/device_info.h"
namespace nearby {
namespace api {
std::unique_ptr<api::DeviceInfo>
ImplementationFastPairPlatform::CreateDeviceInfo() {
return std::make_unique<windows::DeviceInfo>();
}
} // namespace api
} // namespace nearby