kiosk_external_update_notification.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 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/browser/chromeos/ui/kiosk_external_update_notification.h"
6
7#include "ash/shell.h"
8#include "ash/shell_window_ids.h"
9#include "ui/aura/window.h"
10#include "ui/base/resource/resource_bundle.h"
11#include "ui/compositor/layer.h"
12#include "ui/compositor/scoped_layer_animation_settings.h"
13#include "ui/gfx/canvas.h"
14#include "ui/views/controls/label.h"
15#include "ui/views/layout/fill_layout.h"
16#include "ui/views/view.h"
17#include "ui/views/widget/widget.h"
18#include "ui/views/widget/widget_delegate.h"
19
20namespace chromeos {
21
22namespace {
23
24const SkColor kTextColor = SK_ColorBLACK;
25const SkColor kWindowBackgroundColor = SK_ColorWHITE;
26const int kWindowCornerRadius = 4;
27const int kPreferredWidth = 600;
28const int kPreferredHeight = 250;
29
30}  // namespace
31
32class KioskExternalUpdateNotificationView : public views::WidgetDelegateView {
33 public:
34  explicit KioskExternalUpdateNotificationView(
35      KioskExternalUpdateNotification* owner)
36      : owner_(owner), widget_closed_(false) {
37    AddLabel();
38    SetLayoutManager(new views::FillLayout);
39  }
40
41  virtual ~KioskExternalUpdateNotificationView() {
42    widget_closed_ = true;
43    InformOwnerForDismiss();
44  }
45
46  // Closes the widget immediately from |owner_|.
47  void CloseByOwner() {
48    owner_ = NULL;
49    if (!widget_closed_) {
50      widget_closed_ = true;
51      GetWidget()->Close();
52    }
53  }
54
55  void SetMessage(const base::string16& message) { label_->SetText(message); }
56
57  // views::WidgetDelegateView overrides:
58  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
59    SkPaint paint;
60    paint.setStyle(SkPaint::kFill_Style);
61    paint.setColor(kWindowBackgroundColor);
62    canvas->DrawRoundRect(GetLocalBounds(), kWindowCornerRadius, paint);
63    views::WidgetDelegateView::OnPaint(canvas);
64  }
65
66  virtual gfx::Size GetPreferredSize() const OVERRIDE {
67    return gfx::Size(kPreferredWidth, kPreferredHeight);
68  }
69
70 private:
71  void AddLabel() {
72    label_ = new views::Label;
73    label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
74    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
75    label_->SetFontList(rb.GetFontList(ui::ResourceBundle::BoldFont));
76    label_->SetEnabledColor(kTextColor);
77    label_->SetDisabledColor(kTextColor);
78    label_->SetAutoColorReadabilityEnabled(false);
79    label_->SetMultiLine(true);
80    AddChildView(label_);
81  }
82
83  void InformOwnerForDismiss() {
84    // Inform the |owner_| that we are going away.
85    if (owner_) {
86      KioskExternalUpdateNotification* owner = owner_;
87      owner_ = NULL;
88      owner->Dismiss();
89    }
90  }
91
92  // The owner of this message which needs to get notified when the message
93  // closes.
94  KioskExternalUpdateNotification* owner_;
95  views::Label* label_;  // owned by views hierarchy.
96
97  // True if the widget got already closed.
98  bool widget_closed_;
99
100  DISALLOW_COPY_AND_ASSIGN(KioskExternalUpdateNotificationView);
101};
102
103KioskExternalUpdateNotification::KioskExternalUpdateNotification(
104    const base::string16& message) {
105  CreateAndShowNotificationView(message);
106}
107
108KioskExternalUpdateNotification::~KioskExternalUpdateNotification() {
109  Dismiss();
110}
111
112void KioskExternalUpdateNotification::ShowMessage(
113    const base::string16& message) {
114  if (view_)
115    view_->SetMessage(message);
116}
117
118void KioskExternalUpdateNotification::CreateAndShowNotificationView(
119    const base::string16& message) {
120  view_ = new KioskExternalUpdateNotificationView(this);
121  view_->SetMessage(message);
122
123  aura::Window* root_window = ash::Shell::GetTargetRootWindow();
124  gfx::Size rs = root_window->bounds().size();
125  gfx::Size ps = view_->GetPreferredSize();
126  gfx::Rect bounds((rs.width() - ps.width()) / 2,
127                   (rs.height() - ps.height()) / 10,
128                   ps.width(),
129                   ps.height());
130  views::Widget::InitParams params;
131  params.type = views::Widget::InitParams::TYPE_POPUP;
132  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
133  params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
134  params.accept_events = false;
135  params.keep_on_top = true;
136  params.remove_standard_frame = true;
137  params.delegate = view_;
138  params.bounds = bounds;
139  params.parent = ash::Shell::GetContainer(
140      root_window, ash::kShellWindowId_SettingBubbleContainer);
141  views::Widget* widget = new views::Widget;
142  widget->Init(params);
143  widget->SetContentsView(view_);
144  gfx::NativeView native_view = widget->GetNativeView();
145  native_view->SetName("KioskExternalUpdateNotification");
146  widget->Show();
147}
148
149void KioskExternalUpdateNotification::Dismiss() {
150  if (view_) {
151    KioskExternalUpdateNotificationView* view = view_;
152    view_ = NULL;
153    view->CloseByOwner();
154  }
155}
156
157}  // namespace chromeos
158