Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Unified Diff: ash/system/network/tray_sms.cc

Issue 10332152: Add TraySms for SMS messages. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/system/network/tray_sms.cc
diff --git a/ash/system/network/tray_sms.cc b/ash/system/network/tray_sms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..12ac9eee68741425fe67431c999ad854caa263ba
--- /dev/null
+++ b/ash/system/network/tray_sms.cc
@@ -0,0 +1,473 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/network/tray_sms.h"
+
+#include "ash/shell.h"
+#include "ash/system/tray/system_tray.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_item_more.h"
+#include "ash/system/tray/tray_item_view.h"
+#include "ash/system/tray/tray_views.h"
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "grit/ash_strings.h"
+#include "grit/ui_resources.h"
+#include "grit/ui_resources_standard.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/grid_layout.h"
+#include "ui/views/view.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/network/network_sms_handler.h"
+#endif
+
+namespace {
+
+// Height of the list of messages in the popup.
+const int kMessageListHeight = 200;
+// Top/bottom padding of the text items.
+const int kPaddingVertical = 10;
+const int kSmsIconWidth = 50;
+
+} // namespace
+
+namespace ash {
+namespace internal {
+
+class SmsObserverBase {
+ public:
+ explicit SmsObserverBase(TraySms* tray) : tray_(tray) {}
+ virtual ~SmsObserverBase() {}
+
+ bool GetMessageFromDictionary(const base::DictionaryValue* message,
+ std::string* number,
+ std::string* text) {
+ if (!message->GetStringWithoutPathExpansion(
+ chromeos::NetworkSmsHandler::kNumberKey, number))
+ return false;
+ if (!message->GetStringWithoutPathExpansion(
+ chromeos::NetworkSmsHandler::kTextKey, text))
+ return false;
+ return true;
+ }
+
+ void RemoveMessage(size_t index) {
+ if (index < messages_.GetSize())
+ messages_.Remove(index, NULL);
+ }
+
+ const base::ListValue& messages() const { return messages_; }
+
+ protected:
+ base::ListValue messages_;
+ TraySms* tray_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SmsObserverBase);
+};
+
+#if defined(OS_CHROMEOS)
+
+class TraySms::SmsObserver : public SmsObserverBase,
+ public chromeos::NetworkSmsHandler::Observer {
+ public:
+ explicit SmsObserver(TraySms* tray) : SmsObserverBase(tray) {
+ sms_handler_.reset(new chromeos::NetworkSmsHandler());
+ sms_handler_->AddObserver(this);
+ sms_handler_->Init();
+ }
+
+ virtual ~SmsObserver() {
+ sms_handler_->RemoveObserver(this);
+ }
+
+ // Overridden from chromeos::NetworkSmsHandler::Observer
+ virtual void MessageReceived(const base::DictionaryValue& message) {
+ messages_.Append(message.DeepCopy());
+ tray_->Update(true);
+ }
+
+ private:
+ scoped_ptr<chromeos::NetworkSmsHandler> sms_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmsObserver);
+};
+
+#else
+
+class TraySms::SmsObserver : public SmsObserverBase {
+ public:
+ explicit SmsObserver(TraySms* tray) : SmsObserverBase(tray) {
+ }
+ virtual ~SmsObserver() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SmsObserver);
+};
+
+#endif // OS_CHROMEOS
+
+class TraySms::SmsDefaultView : public TrayItemMore {
+ public:
+ explicit SmsDefaultView(TraySms* tray)
+ : TrayItemMore(tray),
+ tray_(tray) {
+ SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_AURA_UBER_TRAY_SMS));
+ Update();
+ }
+
+ virtual ~SmsDefaultView() {}
+
+ void Update() {
+ int message_count =
+ static_cast<int>(tray_->sms_observer()->messages().GetSize());
+ string16 label = l10n_util::GetStringFUTF16(
+ IDS_ASH_STATUS_TRAY_SMS_MESSAGES, base::IntToString16(message_count));
+ SetLabel(label);
+ SetAccessibleName(label);
+ }
+
+ private:
+ TraySms* tray_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmsDefaultView);
+};
+
+class TraySms::SmsMessageView : public views::View,
+ public views::ButtonListener {
+ public:
+ enum ViewType {
+ VIEW_DETAILED,
+ VIEW_NOTIFICATION
+ };
+
+ SmsMessageView(TraySms* tray,
+ ViewType view_type,
+ size_t index,
+ const std::string& number,
+ const std::string& message)
+ : tray_(tray),
+ index_(index) {
+ number_label_ = new views::Label(
+ l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_SMS_NUMBER,
+ UTF8ToUTF16(number)));
+ number_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+
+ message_label_ = new views::Label(UTF8ToUTF16(message));
+ message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ message_label_->SetMultiLine(true);
+
+ int msg_width;
+ if (view_type == VIEW_DETAILED)
+ msg_width = LayoutDetailedView();
+ else
+ msg_width = LayoutNotificationView();
+
+ message_label_->SizeToFit(msg_width);
+ }
+
+ virtual ~SmsMessageView() {
+ }
+
+ // Overridden from ButtonListener.
+ virtual void ButtonPressed(views::Button* sender,
+ const views::Event& event) OVERRIDE {
+ tray_->sms_observer()->RemoveMessage(index_);
+ tray_->Update(false);
+ }
+
+ private:
+ int LayoutDetailedView() {
+ views::ImageButton* close_button = new views::ImageButton(this);
+ close_button->SetImage(views::CustomButton::BS_NORMAL,
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_AURA_WINDOW_CLOSE));
+
+ int msg_width = kTrayPopupWidth - kNotificationCloseButtonWidth -
+ kTrayPopupPaddingHorizontal * 2;
+
+ views::GridLayout* layout = new views::GridLayout(this);
+ SetLayoutManager(layout);
+
+ views::ColumnSet* columns = layout->AddColumnSet(0);
+
+ // Message
+ columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal);
+ columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
+ 0 /* resize percent */,
+ views::GridLayout::FIXED, msg_width, msg_width);
+
+ // Close button
+ columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
+ 0, /* resize percent */
+ views::GridLayout::FIXED,
+ kNotificationCloseButtonWidth,
+ kNotificationCloseButtonWidth);
+
+
+ layout->AddPaddingRow(0, kPaddingVertical);
+ layout->StartRow(0, 0);
+ layout->AddView(number_label_);
+ layout->AddView(close_button, 1, 2); // 2 rows for icon
+ layout->StartRow(0, 0);
+ layout->AddView(message_label_);
+
+ layout->AddPaddingRow(0, kPaddingVertical);
+
+ return msg_width;
+ }
+
+ int LayoutNotificationView() {
+ icon_ = new views::ImageView;
+ icon_->SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_AURA_UBER_TRAY_SMS));
+
+ int msg_width = kTrayPopupWidth - kNotificationCloseButtonWidth -
+ kTrayPopupPaddingHorizontal - kSmsIconWidth;
+
+ views::GridLayout* layout = new views::GridLayout(this);
+ SetLayoutManager(layout);
+
+ views::ColumnSet* columns = layout->AddColumnSet(0);
+
+ // Icon
+ columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
+ 0 /* resize percent */,
+ views::GridLayout::FIXED, kSmsIconWidth, kSmsIconWidth);
+
+ // Message
+ columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
+ 0 /* resize percent */,
+ views::GridLayout::FIXED, msg_width, msg_width);
+
+ layout->AddPaddingRow(0, kPaddingVertical);
+
+ layout->StartRow(0, 0);
+ layout->AddView(icon_, 1, 2); // 2 rows for icon
+ layout->AddView(number_label_);
+ layout->StartRow(0, 0);
+ layout->SkipColumns(1);
+ layout->AddView(message_label_);
+ layout->StartRow(0, 0);
+
+ layout->AddPaddingRow(0, kPaddingVertical);
+
+ return msg_width;
+ }
+
+ TraySms* tray_;
+ size_t index_;
+ views::Label* number_label_;
+ views::Label* message_label_;
+ views::ImageView* icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmsMessageView);
+};
+
+class TraySms::SmsDetailedView : public views::View,
+ public ViewClickListener {
+ public:
+ explicit SmsDetailedView(TraySms* tray)
+ : tray_(tray),
+ header_(NULL),
+ message_list_(NULL),
+ scroller_(NULL) {
+ SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, 0, 0));
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
+ Init();
+ Update();
+ }
+
+ virtual ~SmsDetailedView() {
+ }
+
+ void Init() {
+ message_list_ = new views::View;
+ message_list_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, 0, 1));
+
+ scroller_ = new FixedSizedScrollView;
+ scroller_->set_border(views::Border::CreateSolidSidedBorder(
+ 1, 0, 1, 0, SkColorSetARGB(25, 0, 0, 0)));
+ scroller_->set_fixed_size(
+ gfx::Size(message_list_->GetPreferredSize().width() +
+ scroller_->GetScrollBarWidth(),
+ kMessageListHeight));
+ scroller_->SetContentsView(message_list_);
+ AddChildView(scroller_);
+
+ header_ = new SpecialPopupRow();
+ header_->SetTextLabel(IDS_ASH_STATUS_TRAY_SMS, this);
+ AddChildView(header_);
+ }
+
+ void Update() {
+ UpdateMessageList();
+ scroller_->Layout();
+ SchedulePaint();
+ }
+
+ private:
+ void UpdateMessageList() {
+ const base::ListValue& messages = tray_->sms_observer()->messages();
+ message_list_->RemoveAllChildViews(true);
+
+ for (size_t index = 0; index < messages.GetSize(); ++index) {
+ base::DictionaryValue* message = NULL;
+ if (!messages.GetDictionary(index, &message)) {
+ LOG(ERROR) << "SMS message not a dictionary at: " << index;
+ continue;
+ }
+ std::string number, text;
+ if (!tray_->sms_observer()->GetMessageFromDictionary(
+ message, &number, &text)) {
+ LOG(ERROR) << "Error parsing SMS message";
+ continue;
+ }
+ SmsMessageView* msgview = new SmsMessageView(
+ tray_, SmsMessageView::VIEW_DETAILED, index, number, text);
+ message_list_->AddChildView(msgview);
+ }
+ message_list_->SizeToPreferredSize();
+ }
+
+ // Overridden from ViewClickListener.
+ virtual void ClickedOn(views::View* sender) OVERRIDE {
+ if (sender == header_->content())
+ Shell::GetInstance()->tray()->ShowDefaultView();
+ }
+
+ TraySms* tray_;
+ SpecialPopupRow* header_;
+ views::View* message_list_;
+ FixedSizedScrollView* scroller_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmsDetailedView);
+};
+
+class TraySms::SmsNotificationView : public TrayNotificationView {
+ public:
+ SmsNotificationView(TraySms* tray,
+ const std::string& number,
+ const std::string& text,
+ size_t message_index)
+ : tray_(tray),
+ message_index_(message_index) {
+ SmsMessageView* message_view_ = new SmsMessageView(
+ tray_, SmsMessageView::VIEW_NOTIFICATION, message_index, number, text);
+ InitView(message_view_);
+ }
+
+ // Overridden from views::View.
+ bool OnMousePressed(const views::MouseEvent& event) {
+ tray_->PopupDetailedView(0, true);
+ return true;
+ }
+
+ // Overridden from TrayNotificationView:
+ virtual void OnClose() OVERRIDE {
+ tray_->sms_observer()->RemoveMessage(message_index_);
+ tray_->HideNotificationView();
+ }
+
+ private:
+ TraySms* tray_;
+ SmsMessageView* message_view_;
+ size_t message_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmsNotificationView);
+};
+
+TraySms::TraySms()
+ : TrayImageItem(IDR_AURA_UBER_TRAY_SMS),
+ default_(NULL),
+ detailed_(NULL),
+ notification_(NULL) {
+ sms_observer_.reset(new SmsObserver(this));
+}
+
+TraySms::~TraySms() {
+}
+
+bool TraySms::GetInitialVisibility() {
+ return !sms_observer()->messages().empty();
+}
+
+views::View* TraySms::CreateDefaultView(user::LoginStatus status) {
+ CHECK(default_ == NULL);
+ default_ = new SmsDefaultView(this);
+ default_->SetVisible(!sms_observer()->messages().empty());
+ return default_;
+}
+
+views::View* TraySms::CreateDetailedView(user::LoginStatus status) {
+ CHECK(detailed_ == NULL);
+ HideNotificationView();
+ if (sms_observer()->messages().empty())
+ return NULL;
+ detailed_ = new SmsDetailedView(this);
+ return detailed_;
+}
+
+views::View* TraySms::CreateNotificationView(user::LoginStatus status) {
+ CHECK(notification_ == NULL);
+ const base::ListValue& messages = sms_observer()->messages();
+ if (messages.empty())
+ return NULL;
+ DictionaryValue* message;
+ size_t message_index = messages.GetSize() - 1;
+ if (!messages.GetDictionary(message_index, &message))
+ return NULL;
+ std::string number, text;
+ if (!sms_observer()->GetMessageFromDictionary(message, &number, &text))
+ return NULL;
+ notification_ = new SmsNotificationView(this, number, text, message_index);
+ return notification_;
+}
+
+void TraySms::DestroyDefaultView() {
+ default_ = NULL;
+}
+
+void TraySms::DestroyDetailedView() {
+ detailed_ = NULL;
+}
+
+void TraySms::DestroyNotificationView() {
+ notification_ = NULL;
+}
+
+void TraySms::Update(bool notify) {
+ HideNotificationView();
+ if (sms_observer()->messages().empty()) {
+ if (tray_view())
+ tray_view()->SetVisible(false);
+ if (default_)
+ default_->SetVisible(false);
+ if (detailed_)
+ HideDetailedView();
+ } else {
+ if (tray_view())
+ tray_view()->SetVisible(true);
+ if (default_) {
+ default_->SetVisible(true);
+ default_->Update();
+ }
+ if (detailed_)
+ detailed_->Update();
+ else if (notify)
+ ShowNotificationView();
+ }
+}
+
+} // namespace internal
+} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698