15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/ui/idle_app_name_notification_view.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_delegate.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_window_ids.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_animations.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/timer/timer.h" 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/canvas.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/controls/label.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/layout/box_layout.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/layout/fill_layout.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/view.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/widget/widget.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace ui { 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerAnimationSequence; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos { 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Color of the text of the warning message. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const SkColor kTextColor = SK_ColorBLACK; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Color of the text of the warning message. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const SkColor kErrorTextColor = SK_ColorRED; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Color of the window background. 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const SkColor kWindowBackgroundColor = SK_ColorWHITE; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Radius of the rounded corners of the window. 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kWindowCornerRadius = 4; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates and shows the message widget for |view| with |animation_time_ms|. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CreateAndShowWidgetWithContent(views::WidgetDelegate* delegate, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::View* view, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int animation_time_ms) { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* root_window = ash::Shell::GetTargetRootWindow(); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Size rs = root_window->bounds().size(); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Size ps = view->GetPreferredSize(); 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect bounds((rs.width() - ps.width()) / 2, 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) -ps.height(), 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ps.width(), 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ps.height()); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::Widget::InitParams params; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.type = views::Widget::InitParams::TYPE_POPUP; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.accept_events = false; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.keep_on_top = true; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.remove_standard_frame = true; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.delegate = delegate; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.bounds = bounds; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.parent = ash::Shell::GetContainer( 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_window, ash::kShellWindowId_SettingBubbleContainer); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::Widget* widget = new views::Widget; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget->Init(params); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget->SetContentsView(view); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::NativeView native_view = widget->GetNativeView(); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_view->SetName("KioskIdleAppNameNotification"); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note: We cannot use the Window show/hide animations since they are disabled 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // for kiosk by command line. 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::LayerAnimator* animator = new ui::LayerAnimator( 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(animation_time_ms)); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_view->layer()->SetAnimator(animator); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget->Show(); 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We don't care about the show animation since it is off screen, so stop the 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // started animation and move the message into view. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) animator->StopAnimating(); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds.set_y((rs.height() - ps.height()) / 20); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget->SetBounds(bounds); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allow to use the message for spoken feedback. 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) view->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The class which implements the content view for the message. 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class IdleAppNameNotificationDelegateView 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : public views::WidgetDelegateView, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public ui::ImplicitAnimationObserver { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // An idle message which will get shown from the caller and hides itself after 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a time, calling |owner->CloseMessage| to inform the owner that it got 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // destroyed. The |app_name| is a string which gets used as message and 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |error| is true if something is not correct. 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |message_visibility_time_in_ms| ms's after creation the message will start 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to remove itself from the screen. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IdleAppNameNotificationDelegateView(IdleAppNameNotificationView *owner, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& app_name, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool error, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int message_visibility_time_in_ms) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : owner_(owner), 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget_closed_(false) { 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add the application name label to the message. 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddLabel(app_name, 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rb.GetFontList(ui::ResourceBundle::BoldFont), 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error ? kErrorTextColor : kTextColor); 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) spoken_text_ = app_name; 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetLayoutManager(new views::FillLayout); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set a timer which will trigger to remove the message after the given 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // time. 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hide_timer_.Start( 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(message_visibility_time_in_ms), 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &IdleAppNameNotificationDelegateView::RemoveMessage); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~IdleAppNameNotificationDelegateView() { 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The widget is already closing, but the other cleanup items need to be 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // performed. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget_closed_ = true; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Close(); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Close the widget immediately. This can be called from the owner or from 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this class. 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Close() { 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Stop the timer (if it was running). 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hide_timer_.Stop(); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Inform our owner that we are going away. 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (owner_) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IdleAppNameNotificationView* owner = owner_; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) owner_ = NULL; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) owner->CloseMessage(); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Close the owning widget - if required. 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!widget_closed_) { 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget_closed_ = true; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetWidget()->Close(); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Animate the window away (and close once done). 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void RemoveMessage() { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* widget_view = GetWidget()->GetNativeView(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Layer* layer = widget_view->layer(); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) settings.AddObserver(this); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect rect = widget_view->bounds(); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.set_y(-GetPreferredSize().height()); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layer->SetBounds(rect); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkPaint paint; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) paint.setColor(kWindowBackgroundColor); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawRoundRect(GetLocalBounds(), kWindowCornerRadius, paint); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::WidgetDelegateView::OnPaint(canvas); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE { 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state->name = spoken_text_; 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_ALERT; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ImplicitAnimationObserver overrides 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnImplicitAnimationsCompleted() OVERRIDE { 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Close(); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Adds the label to the view, using |text| with a |font| and a |text_color|. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddLabel(const base::string16& text, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::FontList& font, 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkColor text_color) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::Label* label = new views::Label; 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetText(text); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetHorizontalAlignment(gfx::ALIGN_CENTER); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetFontList(font); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetEnabledColor(text_color); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetDisabledColor(text_color); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label->SetAutoColorReadabilityEnabled(false); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddChildView(label); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A timer which calls us to remove the message from the screen. 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::OneShotTimer<IdleAppNameNotificationDelegateView> hide_timer_; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The owner of this message which needs to get notified when the message 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // closes. 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IdleAppNameNotificationView* owner_; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The spoken text. 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 spoken_text_; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // True if the widget got already closed. 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool widget_closed_; 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IdleAppNameNotificationDelegateView); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IdleAppNameNotificationView::IdleAppNameNotificationView( 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int message_visibility_time_in_ms, 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int animation_time_ms, 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const extensions::Extension* extension) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : view_(NULL) { 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowMessage(message_visibility_time_in_ms, animation_time_ms, extension); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IdleAppNameNotificationView::~IdleAppNameNotificationView() { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseMessage(); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IdleAppNameNotificationView::CloseMessage() { 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_) { 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IdleAppNameNotificationDelegateView* view = view_; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_ = NULL; 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view->Close(); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IdleAppNameNotificationView::IsVisible() { 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return view_ != NULL; 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 IdleAppNameNotificationView::GetShownTextForTest() { 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::AXViewState state; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(view_); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->GetAccessibleState(&state); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return state.name; 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IdleAppNameNotificationView::ShowMessage( 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int message_visibility_time_in_ms, 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int animation_time_ms, 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const extensions::Extension* extension) { 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!view_); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 app_name; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool error = false; 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (extension && 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !base::ContainsOnlyChars(extension->name(), base::kWhitespaceASCII)) { 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_name = base::UTF8ToUTF16(extension->name()); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = true; 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_name = l10n_util::GetStringUTF16( 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_IDLE_APP_NAME_UNKNOWN_APPLICATION_NOTIFICATION); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_ = new IdleAppNameNotificationDelegateView( 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_name, 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error, 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_visibility_time_in_ms + animation_time_ms); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAndShowWidgetWithContent(view_, view_, animation_time_ms); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chromeos 277