tray_sms.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/chromeos/network/tray_sms.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/fixed_sized_scroll_view.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_bubble.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_details_view.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_more.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_view.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_notification_view.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/bubble/tray_bubble_view.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Min height of the list of messages in the popup.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMessageListMinHeight = 200;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Top/bottom padding of the text items.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingVertical = 10;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetMessageFromDictionary(const base::DictionaryValue* message,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::string* number,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::string* text) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!message->GetStringWithoutPathExpansion(ash::kSmsNumberKey, number))
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!message->GetStringWithoutPathExpansion(ash::kSmsTextKey, text))
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TraySms::SmsDefaultView : public TrayItemMore {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SmsDefaultView(TraySms* owner)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemMore(owner, true) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetImage(ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_SMS));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Update();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SmsDefaultView() {}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Update() {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int message_count = static_cast<TraySms*>(owner())->messages().GetSize();
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 label = l10n_util::GetStringFUTF16(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDS_ASH_STATUS_TRAY_SMS_MESSAGES, base::IntToString16(message_count));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLabel(label);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetAccessibleName(label);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SmsDefaultView);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An entry (row) in SmsDetailedView or NotificationView.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TraySms::SmsMessageView : public views::View,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                public views::ButtonListener {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ViewType {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VIEW_DETAILED,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VIEW_NOTIFICATION
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SmsMessageView(TraySms* owner,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ViewType view_type,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 size_t index,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const std::string& number,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const std::string& message)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : owner_(owner),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        index_(index) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    number_label_ = new views::Label(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_SMS_NUMBER,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   UTF8ToUTF16(number)));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    number_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    number_label_->SetFont(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        number_label_->font().DeriveFont(0, gfx::Font::BOLD));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_label_ = new views::Label(UTF8ToUTF16(message));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_label_->SetMultiLine(true);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view_type == VIEW_DETAILED)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LayoutDetailedView();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LayoutNotificationView();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SmsMessageView() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ButtonListener.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    owner_->RemoveMessage(index_);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    owner_->Update(false);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LayoutDetailedView() {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::ImageButton* close_button = new views::ImageButton(this);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    close_button->SetImage(views::CustomButton::STATE_NORMAL,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IDR_AURA_WINDOW_CLOSE));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int msg_width = owner_->system_tray()->GetSystemBubble()->
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bubble_view()->GetPreferredSize().width() -
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            (kNotificationIconWidth + kTrayPopupPaddingHorizontal * 2);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_label_->SizeToFit(msg_width);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::GridLayout* layout = new views::GridLayout(this);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(layout);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::ColumnSet* columns = layout->AddColumnSet(0);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Message
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       0 /* resize percent */,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       views::GridLayout::FIXED, msg_width, msg_width);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Close button
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       0, /* resize percent */
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       views::GridLayout::FIXED,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kNotificationIconWidth, kNotificationIconWidth);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddPaddingRow(0, kPaddingVertical);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->StartRow(0, 0);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(number_label_);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(close_button, 1, 2);  // 2 rows for icon
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->StartRow(0, 0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(message_label_);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddPaddingRow(0, kPaddingVertical);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LayoutNotificationView() {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(number_label_);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_label_->SizeToFit(kTrayNotificationContentsWidth);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(message_label_);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TraySms* owner_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t index_;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* number_label_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* message_label_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SmsMessageView);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TraySms::SmsDetailedView : public TrayDetailsView,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 public ViewClickListener {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SmsDetailedView(TraySms* owner)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayDetailsView(owner) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Init();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Update();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SmsDetailedView() {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init() {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateScrollableList();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateSpecialRow(IDS_ASH_STATUS_TRAY_SMS, this);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Update() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateMessageList();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Layout();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SchedulePaint();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::View.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size preferred_size = TrayDetailsView::GetPreferredSize();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (preferred_size.height() < kMessageListMinHeight)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      preferred_size.set_height(kMessageListMinHeight);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return preferred_size;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateMessageList() {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue& messages =
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<TraySms*>(owner())->messages();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scroll_content()->RemoveAllChildViews(true);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t index = 0; index < messages.GetSize(); ++index) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::DictionaryValue* message = NULL;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!messages.GetDictionary(index, &message)) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "SMS message not a dictionary at: " << index;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string number, text;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!GetMessageFromDictionary(message, &number, &text)) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Error parsing SMS message";
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SmsMessageView* msgview = new SmsMessageView(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<TraySms*>(owner()), SmsMessageView::VIEW_DETAILED, index,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          number, text);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_content()->AddChildView(msgview);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scroller()->Layout();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ViewClickListener.
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnViewClicked(views::View* sender) OVERRIDE {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender == footer()->content())
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      owner()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SmsDetailedView);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TraySms::SmsNotificationView : public TrayNotificationView {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SmsNotificationView(TraySms* owner,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      size_t message_index,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& number,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& text)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayNotificationView(owner, IDR_AURA_UBER_TRAY_SMS),
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        message_index_(message_index) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SmsMessageView* message_view = new SmsMessageView(
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        owner, SmsMessageView::VIEW_NOTIFICATION, message_index_, number, text);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitView(message_view);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Update(size_t message_index,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const std::string& number,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const std::string& text) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SmsMessageView* message_view = new SmsMessageView(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tray_sms(), SmsMessageView::VIEW_NOTIFICATION,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        message_index_, number, text);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateView(message_view);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from TrayNotificationView:
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClose() OVERRIDE {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tray_sms()->RemoveMessage(message_index_);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClickAction() OVERRIDE {
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    owner()->PopupDetailedView(0, true);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraySms* tray_sms() {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return static_cast<TraySms*>(owner());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t message_index_;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SmsNotificationView);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TraySms::TraySms(SystemTray* system_tray)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_(NULL),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_(NULL) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->AddSmsObserver(this);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraySms::~TraySms() {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->RemoveSmsObserver(this);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TraySms::CreateDefaultView(user::LoginStatus status) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = new SmsDefaultView(this);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_->SetVisible(!messages_.empty());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TraySms::CreateDetailedView(user::LoginStatus status) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HideNotificationView();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (messages_.empty())
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = new SmsDetailedView(this);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TraySms::CreateNotificationView(user::LoginStatus status) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(notification_ == NULL);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t index;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string number, text;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetLatestMessage(&index, &number, &text))
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notification_ = new SmsNotificationView(this, index, number, text);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notification_;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::DestroyDefaultView() {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::DestroyDetailedView() {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::DestroyNotificationView() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_ = NULL;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::AddMessage(const base::DictionaryValue& message) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  messages_.Append(message.DeepCopy());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Update(true);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraySms::GetLatestMessage(size_t* index,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::string* number,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::string* text) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (messages_.empty())
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* message;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t message_index = messages_.GetSize() - 1;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!messages_.GetDictionary(message_index, &message))
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetMessageFromDictionary(message, number, text))
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *index = message_index;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::RemoveMessage(size_t index) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index < messages_.GetSize())
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    messages_.Remove(index, NULL);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraySms::Update(bool notify) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (messages_.empty()) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (default_)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_->SetVisible(false);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (detailed_)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HideDetailedView();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HideNotificationView();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (default_) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_->SetVisible(true);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_->Update();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (detailed_)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_->Update();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (notification_) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t index;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string number, text;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GetLatestMessage(&index, &number, &text))
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_->Update(index, number, text);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (notify) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShowNotificationView();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
382