From 9057cbea603dcf747847e5887da8eb5ab0fd121f Mon Sep 17 00:00:00 2001 From: Michael Hughes Date: Wed, 17 Apr 2024 17:51:59 +0000 Subject: [PATCH] Bug 1879975 - Adding in logging for taskbar debugging r=nrishel,mpohle Differential Revision: https://phabricator.services.mozilla.com/D206554 --- .../shell/Windows11LimitedAccessFeatures.cpp | 64 +++-- .../shell/Windows11LimitedAccessFeatures.h | 6 +- .../shell/Windows11TaskbarPinning.cpp | 226 ++++++++++++------ 3 files changed, 205 insertions(+), 91 deletions(-) diff --git a/browser/components/shell/Windows11LimitedAccessFeatures.cpp b/browser/components/shell/Windows11LimitedAccessFeatures.cpp index 5c766965b9e2..1ce96c550ff7 100644 --- a/browser/components/shell/Windows11LimitedAccessFeatures.cpp +++ b/browser/components/shell/Windows11LimitedAccessFeatures.cpp @@ -9,6 +9,12 @@ */ #include "Windows11LimitedAccessFeatures.h" +#include "mozilla/Logging.h" + +static mozilla::LazyLogModule sLog("Windows11LimitedAccessFeatures"); + +#define LAF_LOG(level, msg, ...) MOZ_LOG(sLog, level, (msg, ##__VA_ARGS__)) + // MINGW32 is not supported for these features // Fall back function defined in the #else #ifndef __MINGW32__ @@ -30,11 +36,7 @@ using namespace ABI::Windows; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::ApplicationModel; -struct LimitedAccessFeatureInfo { - const WCHAR* feature; - const WCHAR* token; - const WCHAR* attestation; -}; +using namespace mozilla; /** * To unlock features, we need a feature identifier, a token, and an @@ -95,26 +97,36 @@ struct LimitedAccessFeatureInfo { * Windows 11 will then work. * */ + +struct LimitedAccessFeatureInfo { + const char* debugName; + const WCHAR* feature; + const WCHAR* token; + const WCHAR* attestation; +}; + static LimitedAccessFeatureInfo limitedAccessFeatureInfo[] = {{ - // Win11LimitedAccessFeatureType::Taskbar + "Win11LimitedAccessFeatureType::Taskbar", MOZ_WINDOWS_TASKBAR_PINNING_API_FEATURE, MOZ_WINDOWS_TASKBAR_PINNING_API_KEY, MOZ_WINDOWS_TASKBAR_PINNING_API_ATTRIBUTION, }}; +static_assert(mozilla::ArrayLength(limitedAccessFeatureInfo) == + kWin11LimitedAccessFeatureTypeCount); + /** Implementation of the Win11LimitedAccessFeaturesInterface. */ class Win11LimitedAccessFeatures : public Win11LimitedAccessFeaturesInterface { public: - using AtomicState = mozilla::Atomic; + using AtomicState = Atomic; - mozilla::Result Unlock( - Win11LimitedAccessFeatureType feature) override; + Result Unlock(Win11LimitedAccessFeatureType feature) override; private: AtomicState& GetState(Win11LimitedAccessFeatureType feature); - mozilla::Result UnlockImplementation( + Result UnlockImplementation( Win11LimitedAccessFeatureType feature); /** @@ -145,12 +157,20 @@ CreateWin11LimitedAccessFeaturesInterface() { return result; } -mozilla::Result Win11LimitedAccessFeatures::Unlock( +Result Win11LimitedAccessFeatures::Unlock( Win11LimitedAccessFeatureType feature) { AtomicState& atomicState = GetState(feature); + const auto& lafInfo = limitedAccessFeatureInfo[static_cast(feature)]; + + LAF_LOG( + LogLevel::Debug, "Limited Access Feature Info for %s. Feature %S, %S, %S", + lafInfo.debugName, lafInfo.feature, lafInfo.token, lafInfo.attestation); + int state = atomicState; if (state != Uninitialized) { + LAF_LOG(LogLevel::Debug, "%s already initialized! State = %s", + lafInfo.debugName, (state == Unlocked) ? "true" : "false"); return (state == Unlocked); } @@ -177,6 +197,8 @@ Win11LimitedAccessFeatures::AtomicState& Win11LimitedAccessFeatures::GetState( return mTaskbarState; default: + LAF_LOG(LogLevel::Debug, "Missing feature type for %d", + static_cast(feature)); MOZ_ASSERT(false, "Unhandled feature type! Add a new atomic state variable, add " "that entry to the switch statement above, and add the proper " @@ -185,11 +207,13 @@ Win11LimitedAccessFeatures::AtomicState& Win11LimitedAccessFeatures::GetState( } } -mozilla::Result Win11LimitedAccessFeatures::UnlockImplementation( +Result Win11LimitedAccessFeatures::UnlockImplementation( Win11LimitedAccessFeatureType feature) { ComPtr limitedAccessFeatures; ComPtr limitedAccessFeaturesResult; + const auto& lafInfo = limitedAccessFeatureInfo[static_cast(feature)]; + HRESULT hr = RoGetActivationFactory( HStringReference( RuntimeClass_Windows_ApplicationModel_LimitedAccessFeatures) @@ -197,29 +221,35 @@ mozilla::Result Win11LimitedAccessFeatures::UnlockImplementation( IID_ILimitedAccessFeaturesStatics, &limitedAccessFeatures); if (!SUCCEEDED(hr)) { - return mozilla::Err(hr); + LAF_LOG(LogLevel::Debug, "%s activation error. HRESULT = 0x%lx", + lafInfo.debugName, hr); + return Err(hr); } - const auto& lafInfo = limitedAccessFeatureInfo[static_cast(feature)]; - hr = limitedAccessFeatures->TryUnlockFeature( HStringReference(lafInfo.feature).Get(), HStringReference(lafInfo.token).Get(), HStringReference(lafInfo.attestation).Get(), &limitedAccessFeaturesResult); if (!SUCCEEDED(hr)) { - return mozilla::Err(hr); + LAF_LOG(LogLevel::Debug, "%s unlock error. HRESULT = 0x%lx", + lafInfo.debugName, hr); + return Err(hr); } LimitedAccessFeatureStatus status; hr = limitedAccessFeaturesResult->get_Status(&status); if (!SUCCEEDED(hr)) { - return mozilla::Err(hr); + LAF_LOG(LogLevel::Debug, "%s get status error. HRESULT = 0x%lx", + lafInfo.debugName, hr); + return Err(hr); } int state = Unlocked; if ((status != LimitedAccessFeatureStatus_Available) && (status != LimitedAccessFeatureStatus_AvailableWithoutToken)) { + LAF_LOG(LogLevel::Debug, "%s not available. HRESULT = 0x%lx", + lafInfo.debugName, hr); state = Locked; } diff --git a/browser/components/shell/Windows11LimitedAccessFeatures.h b/browser/components/shell/Windows11LimitedAccessFeatures.h index 21fbfd40ac5c..8e1ae5db7a5b 100644 --- a/browser/components/shell/Windows11LimitedAccessFeatures.h +++ b/browser/components/shell/Windows11LimitedAccessFeatures.h @@ -11,10 +11,10 @@ #include "mozilla/ResultVariant.h" #include #include // for HRESULT +#include "mozilla/DefineEnum.h" +#include -enum class Win11LimitedAccessFeatureType { - Taskbar, -}; +MOZ_DEFINE_ENUM_CLASS(Win11LimitedAccessFeatureType, (Taskbar)); /** * Class to manage unlocking limited access features on Windows 11. diff --git a/browser/components/shell/Windows11TaskbarPinning.cpp b/browser/components/shell/Windows11TaskbarPinning.cpp index d6d6833e6a61..350a58d59aa9 100644 --- a/browser/components/shell/Windows11TaskbarPinning.cpp +++ b/browser/components/shell/Windows11TaskbarPinning.cpp @@ -14,6 +14,13 @@ #include "mozilla/Result.h" #include "mozilla/ResultVariant.h" +#include "mozilla/Logging.h" + +static mozilla::LazyLogModule sLog("Windows11TaskbarPinning"); + +#define TASKBAR_PINNING_LOG(level, msg, ...) \ + MOZ_LOG(sLog, level, (msg, ##__VA_ARGS__)) + #ifndef __MINGW32__ // WinRT headers not yet supported by MinGW # include @@ -24,6 +31,8 @@ # include # include +using namespace mozilla; + /** * The Win32 SetEvent and WaitForSingleObject functions take HANDLE parameters * which are typedefs of void*. When using nsAutoHandle, that means if you @@ -54,30 +63,40 @@ using namespace ABI::Windows::UI::Shell; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::ApplicationModel; -static mozilla::Result, HRESULT> InitializeTaskbar() { +static Result, HRESULT> InitializeTaskbar() { ComPtr taskbarStaticsInspectable; + TASKBAR_PINNING_LOG(LogLevel::Debug, "Initializing taskbar"); + HRESULT hr = RoGetActivationFactory( HStringReference(RuntimeClass_Windows_UI_Shell_TaskbarManager).Get(), IID_ITaskbarManagerStatics, &taskbarStaticsInspectable); if (FAILED(hr)) { - return mozilla::Err(hr); + TASKBAR_PINNING_LOG(LogLevel::Debug, + "Taskbar: Failed to activate. HRESULT = 0x%lx", hr); + return Err(hr); } ComPtr taskbarStatics; hr = taskbarStaticsInspectable.As(&taskbarStatics); if (FAILED(hr)) { - return mozilla::Err(hr); + TASKBAR_PINNING_LOG(LogLevel::Debug, "Failed statistics. HRESULT = 0x%lx", + hr); + return Err(hr); } ComPtr taskbarManager; hr = taskbarStatics->GetDefault(&taskbarManager); if (FAILED(hr)) { - return mozilla::Err(hr); + TASKBAR_PINNING_LOG(LogLevel::Debug, + "Error getting TaskbarManager. HRESULT = 0x%lx", hr); + return Err(hr); } + TASKBAR_PINNING_LOG(LogLevel::Debug, + "TaskbarManager retrieved successfully!"); return taskbarManager; } @@ -95,10 +114,16 @@ Win11PinToTaskBarResult PinCurrentAppToTaskbarWin11( auto result = limitedAccessFeatures->Unlock(Win11LimitedAccessFeatureType::Taskbar); if (result.isErr()) { - return {result.unwrapErr(), Win11PinToTaskBarResultStatus::NotSupported}; + auto hr = result.unwrapErr(); + TASKBAR_PINNING_LOG(LogLevel::Debug, + "Taskbar unlock: Error. HRESULT = 0x%lx", hr); + return {hr, Win11PinToTaskBarResultStatus::NotSupported}; } if (result.unwrap() == false) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar unlock: failed. Not supported on this version of Windows."); return {S_OK, Win11PinToTaskBarResultStatus::NotSupported}; } } @@ -130,17 +155,38 @@ Win11PinToTaskBarResult PinCurrentAppToTaskbarWin11( boolean supported; hr = taskbar->get_IsSupported(&supported); if (FAILED(hr) || !supported) { + if (FAILED(hr)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: error checking if supported. HRESULT = 0x%lx", hr); + } else { + TASKBAR_PINNING_LOG(LogLevel::Debug, "Taskbar: not supported."); + } return CompletedOperations( Win11PinToTaskBarResultStatus::NotSupported); } if (aCheckOnly) { + TASKBAR_PINNING_LOG(LogLevel::Debug, "Taskbar: check succeeded."); return CompletedOperations(Win11PinToTaskBarResultStatus::Success); } boolean isAllowed = false; hr = taskbar->get_IsPinningAllowed(&isAllowed); if (FAILED(hr) || !isAllowed) { + if (FAILED(hr)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: error checking if pinning is allowed. HRESULT = " + "0x%lx", + hr); + } else { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: is pinning allowed error or isn't allowed right now. " + "It's not clear when it will be allowed. Possibly after a " + "reboot."); + } return CompletedOperations( Win11PinToTaskBarResultStatus::NotCurrentlyAllowed); } @@ -148,6 +194,11 @@ Win11PinToTaskBarResult PinCurrentAppToTaskbarWin11( ComPtr> isPinnedOperation = nullptr; hr = taskbar->IsCurrentAppPinnedAsync(&isPinnedOperation); if (FAILED(hr)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: is current app pinned operation failed. HRESULT = " + "0x%lx", + hr); return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); } @@ -157,84 +208,117 @@ Win11PinToTaskBarResult PinCurrentAppToTaskbarWin11( // resultStatus and event are not defined on the main thread and will // be alive until the async functions complete, so they can be used as // references. - auto isPinnedCallback = Callback>( - [taskbar, &event, &resultStatus, &hr]( - IAsyncOperation* asyncInfo, - AsyncStatus status) mutable -> HRESULT { - auto CompletedOperations = - [&event, &resultStatus]( - Win11PinToTaskBarResultStatus status) -> HRESULT { - resultStatus = status; - event.Set(); - return S_OK; - }; + auto isPinnedCallback = Callback>([taskbar, &event, &resultStatus, &hr]( + IAsyncOperation* asyncInfo, + AsyncStatus status) mutable -> HRESULT { + auto CompletedOperations = + [&event, + &resultStatus](Win11PinToTaskBarResultStatus status) -> HRESULT { + resultStatus = status; + event.Set(); + return S_OK; + }; - bool asyncOpSucceeded = status == AsyncStatus::Completed; - if (!asyncOpSucceeded) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); - } + bool asyncOpSucceeded = status == AsyncStatus::Completed; + if (!asyncOpSucceeded) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: is pinned operation failed to complete."); + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } - unsigned char isCurrentAppPinned = false; - hr = asyncInfo->GetResults(&isCurrentAppPinned); + unsigned char isCurrentAppPinned = false; + hr = asyncInfo->GetResults(&isCurrentAppPinned); + if (FAILED(hr)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: is current app pinned check failed. HRESULT = 0x%lx", + hr); + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } + + if (isCurrentAppPinned) { + TASKBAR_PINNING_LOG(LogLevel::Debug, + "Taskbar: current app is already pinned."); + return CompletedOperations( + Win11PinToTaskBarResultStatus::AlreadyPinned); + } + + ComPtr> requestPinOperation = nullptr; + hr = taskbar->RequestPinCurrentAppAsync(&requestPinOperation); + if (FAILED(hr)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin current app operation creation failed. " + "HRESULT = 0x%lx", + hr); + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } + + auto pinAppCallback = Callback>([CompletedOperations, &hr]( + IAsyncOperation* asyncInfo, + AsyncStatus status) -> HRESULT { + bool asyncOpSucceeded = status == AsyncStatus::Completed; + if (!asyncOpSucceeded) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin current app operation did not " + "complete."); + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } + + unsigned char successfullyPinned = 0; + hr = asyncInfo->GetResults(&successfullyPinned); + if (FAILED(hr) || !successfullyPinned) { if (FAILED(hr)) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin current app operation failed to pin " + "due to error. HRESULT = 0x%lx", + hr); + } else { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin current app operation failed to pin"); } + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } - if (isCurrentAppPinned) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::AlreadyPinned); - } + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin current app operation succeeded"); + return CompletedOperations(Win11PinToTaskBarResultStatus::Success); + }); - ComPtr> requestPinOperation = nullptr; - hr = taskbar->RequestPinCurrentAppAsync(&requestPinOperation); - if (FAILED(hr)) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); - } + HRESULT pinOperationHR = + requestPinOperation->put_Completed(pinAppCallback.Get()); + if (FAILED(pinOperationHR)) { + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: request pin operation failed when setting completion " + "callback. HRESULT = 0x%lx", + hr); + hr = pinOperationHR; + return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); + } - auto pinAppCallback = - Callback>( - [CompletedOperations, &hr]( - IAsyncOperation* asyncInfo, - AsyncStatus status) -> HRESULT { - bool asyncOpSucceeded = - status == AsyncStatus::Completed; - if (!asyncOpSucceeded) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); - } - - unsigned char successfullyPinned = 0; - hr = asyncInfo->GetResults(&successfullyPinned); - if (FAILED(hr) || !successfullyPinned) { - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); - } - - return CompletedOperations( - Win11PinToTaskBarResultStatus::Success); - }); - - HRESULT pinOperationHR = - requestPinOperation->put_Completed(pinAppCallback.Get()); - if (FAILED(pinOperationHR)) { - hr = pinOperationHR; - return CompletedOperations( - Win11PinToTaskBarResultStatus::Failed); - } - - // DO NOT SET event HERE. It will be set in the pin operation - // callback As in, operations are not completed, so don't call - // CompletedOperations - return S_OK; - }); + // DO NOT SET event HERE. It will be set in the pin operation + // callback As in, operations are not completed, so don't call + // CompletedOperations + return S_OK; + }); HRESULT isPinnedOperationHR = isPinnedOperation->put_Completed(isPinnedCallback.Get()); if (FAILED(isPinnedOperationHR)) { hr = isPinnedOperationHR; + TASKBAR_PINNING_LOG( + LogLevel::Debug, + "Taskbar: is pinned operation failed when setting completion " + "callback. HRESULT = 0x%lx", + hr); return CompletedOperations(Win11PinToTaskBarResultStatus::Failed); }