1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/updater/win/ui/ui_displayed_event.h"
6 
7 #include "base/check.h"
8 #include "base/no_destructor.h"
9 #include "base/stl_util.h"
10 #include "chrome/updater/win/ui/constants.h"
11 #include "chrome/updater/win/util.h"
12 
13 namespace updater {
14 namespace ui {
15 
CreateEvent(bool is_machine)16 HRESULT UIDisplayedEventManager::CreateEvent(bool is_machine) {
17   DCHECK(!IsEventHandleInitialized());
18   return CreateUniqueEventInEnvironment(
19       kLegacyUiDisplayedEventEnvironmentVariableName, is_machine,
20       ScopedKernelHANDLE::Receiver(GetUIDisplayedEvent()).get());
21 }
22 
GetEvent(bool is_machine,HANDLE * ui_displayed_event)23 HRESULT UIDisplayedEventManager::GetEvent(bool is_machine,
24                                           HANDLE* ui_displayed_event) {
25   DCHECK(ui_displayed_event);
26   *ui_displayed_event = nullptr;
27   if (IsEventHandleInitialized()) {
28     *ui_displayed_event = GetUIDisplayedEvent().get();
29     return S_OK;
30   }
31 
32   HRESULT hr = OpenUniqueEventFromEnvironment(
33       kLegacyUiDisplayedEventEnvironmentVariableName, is_machine,
34       ScopedKernelHANDLE::Receiver(GetUIDisplayedEvent()).get());
35   if (FAILED(hr))
36     return hr;
37 
38   *ui_displayed_event = GetUIDisplayedEvent().get();
39   return S_OK;
40 }
41 
SignalEvent(bool is_machine)42 void UIDisplayedEventManager::SignalEvent(bool is_machine) {
43   if (!IsEventHandleInitialized()) {
44     HRESULT hr = GetEvent(
45         is_machine, ScopedKernelHANDLE::Receiver(GetUIDisplayedEvent()).get());
46     if (HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND) == hr)
47       hr = CreateEvent(is_machine);
48     if (FAILED(hr)) {
49       // We may display two UIs in this case.
50       GetUIDisplayedEvent().reset();
51       return;
52     }
53   }
54 
55   DCHECK(IsEventHandleInitialized());
56   ::SetEvent(GetUIDisplayedEvent().get());
57 }
58 
IsEventHandleInitialized()59 bool UIDisplayedEventManager::IsEventHandleInitialized() {
60   return GetUIDisplayedEvent().is_valid();
61 }
62 
GetUIDisplayedEvent()63 ScopedKernelHANDLE& UIDisplayedEventManager::GetUIDisplayedEvent() {
64   static base::NoDestructor<ScopedKernelHANDLE> ui_displayed_event;
65   return *ui_displayed_event;
66 }
67 
68 }  // namespace ui
69 }  // namespace updater
70