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 "ash/login/ui/pin_request_widget.h"
6
7 #include <utility>
8
9 #include "ash/keyboard/keyboard_controller_impl.h"
10 #include "ash/public/cpp/shell_window_ids.h"
11 #include "ash/session/session_controller_impl.h"
12 #include "ash/shell.h"
13 #include "ash/wm/window_dimmer.h"
14 #include "base/no_destructor.h"
15 #include "components/session_manager/session_manager_types.h"
16 #include "ui/views/widget/widget.h"
17
18 namespace ash {
19
20 namespace {
21
22 PinRequestWidget* instance_ = nullptr;
23
GetOnShownCallback()24 base::RepeatingClosure& GetOnShownCallback() {
25 static base::NoDestructor<base::RepeatingClosure> on_shown;
26 return *on_shown;
27 }
28
29 } // namespace
30
TestApi(PinRequestWidget * widget)31 PinRequestWidget::TestApi::TestApi(PinRequestWidget* widget)
32 : pin_request_widget_(widget) {}
33
34 PinRequestWidget::TestApi::~TestApi() = default;
35
pin_request_view()36 PinRequestView* PinRequestWidget::TestApi::pin_request_view() {
37 return pin_request_widget_->GetView();
38 }
39
40 // static
Show(PinRequest request,PinRequestView::Delegate * delegate)41 void PinRequestWidget::Show(PinRequest request,
42 PinRequestView::Delegate* delegate) {
43 DCHECK(!instance_);
44 instance_ = new PinRequestWidget(std::move(request), delegate);
45 if (GetOnShownCallback())
46 GetOnShownCallback().Run();
47 }
48
49 // static
Get()50 PinRequestWidget* PinRequestWidget::Get() {
51 return instance_;
52 }
53
54 // static
SetShownCallbackForTesting(base::RepeatingClosure on_shown)55 void PinRequestWidget::SetShownCallbackForTesting(
56 base::RepeatingClosure on_shown) {
57 GetOnShownCallback() = std::move(on_shown);
58 }
59
UpdateState(PinRequestViewState state,const base::string16 & title,const base::string16 & description)60 void PinRequestWidget::UpdateState(PinRequestViewState state,
61 const base::string16& title,
62 const base::string16& description) {
63 DCHECK_EQ(instance_, this);
64 GetView()->UpdateState(state, title, description);
65 }
66
SetPinInputEnabled(bool enabled)67 void PinRequestWidget::SetPinInputEnabled(bool enabled) {
68 DCHECK_EQ(instance_, this);
69 GetView()->SetInputEnabled(enabled);
70 }
71
ClearInput()72 void PinRequestWidget::ClearInput() {
73 DCHECK_EQ(instance_, this);
74 GetView()->ClearInput();
75 }
76
Close(bool success)77 void PinRequestWidget::Close(bool success) {
78 DCHECK_EQ(instance_, this);
79 PinRequestWidget* instance = instance_;
80 instance_ = nullptr;
81 std::move(on_pin_request_done_).Run(success);
82 widget_->Close();
83 delete instance;
84 }
85
PinRequestWidget(PinRequest request,PinRequestView::Delegate * delegate)86 PinRequestWidget::PinRequestWidget(PinRequest request,
87 PinRequestView::Delegate* delegate)
88 : on_pin_request_done_(std::move(request.on_pin_request_done)) {
89 views::Widget::InitParams widget_params;
90 // Using window frameless to be able to get focus on the view input fields,
91 // which does not work with popup type.
92 widget_params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
93 widget_params.ownership =
94 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
95 widget_params.opacity =
96 views::Widget::InitParams::WindowOpacity::kTranslucent;
97 widget_params.accept_events = true;
98
99 ShellWindowId parent_window_id =
100 Shell::Get()->session_controller()->GetSessionState() ==
101 session_manager::SessionState::ACTIVE
102 ? kShellWindowId_SystemModalContainer
103 : kShellWindowId_LockSystemModalContainer;
104 widget_params.parent =
105 Shell::GetPrimaryRootWindow()->GetChildById(parent_window_id);
106 if (request.extra_dimmer)
107 dimmer_ = std::make_unique<WindowDimmer>(widget_params.parent);
108 request.on_pin_request_done =
109 base::BindOnce(&PinRequestWidget::Close, weak_factory_.GetWeakPtr());
110 widget_params.delegate = new PinRequestView(std::move(request), delegate);
111
112 widget_ = std::make_unique<views::Widget>();
113 widget_->Init(std::move(widget_params));
114
115 Show();
116 }
117
118 PinRequestWidget::~PinRequestWidget() = default;
119
Show()120 void PinRequestWidget::Show() {
121 if (dimmer_)
122 dimmer_->window()->Show();
123
124 DCHECK(widget_);
125 widget_->Show();
126
127 auto* keyboard_controller = Shell::Get()->keyboard_controller();
128 if (keyboard_controller && keyboard_controller->IsKeyboardEnabled())
129 keyboard_controller->HideKeyboard(HideReason::kSystem);
130 }
131
GetView()132 PinRequestView* PinRequestWidget::GetView() {
133 return static_cast<PinRequestView*>(widget_->widget_delegate());
134 }
135
136 } // namespace ash
137