Commit b3dda04b authored by stevenjb@google.com's avatar stevenjb@google.com

Add TraySms for SMS messages.

BUG=124724
TEST=Test SMS messages running Chrome with --aura-notify
TBR=ben for ash strings

Review URL: https://chromiumcodereview.appspot.com/10332152

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137671 0039d316-1c4b-4281-b951-d872f2087c98
parent 6ccf15c0
......@@ -135,6 +135,8 @@
'system/network/network_observer.h',
'system/network/tray_network.cc',
'system/network/tray_network.h',
'system/network/tray_sms.cc',
'system/network/tray_sms.h',
'system/power/power_status_observer.h',
'system/power/power_supply_status.cc',
'system/power/power_supply_status.h',
......
......@@ -234,6 +234,15 @@ This file contains the strings for ash.
<message name="IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS" desc="The label used in the proxy settings entry in the network dialog in the login screen.">
Proxy...
</message>
<message name="IDS_ASH_STATUS_TRAY_SMS" desc="The label used in the status tray for SMS.">
SMS
</message>
<message name="IDS_ASH_STATUS_TRAY_SMS_MESSAGES" desc="The label used in the default status tray view for SMS with the number of messages.">
SMS messages: <ph name="MESSAGE_COUNT">$1<ex>3</ex></ph>
</message>
<message name="IDS_ASH_STATUS_TRAY_SMS_NUMBER" desc="Sender for SMS messagees in the system tray.">
SMS from <ph name="PHONE_NUMBER">$1<ex>08700 776655</ex></ph>
</message>
<message name="IDS_ASH_STATUS_TRAY_AIRPLANE_MODE" desc="The label used in the network dialog to turn on airplane mode.">
Airplane mode
</message>
......
This diff is collapsed.
// 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.
#ifndef ASH_SYSTEM_NETWORK_TRAY_SMS_H
#define ASH_SYSTEM_NETWORK_TRAY_SMS_H
#pragma once
#include "ash/system/tray/tray_image_item.h"
#include "base/memory/scoped_ptr.h"
namespace ash {
namespace internal {
class TraySms : public TrayImageItem {
public:
TraySms();
virtual ~TraySms();
// Overridden from SystemTrayItem.
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE;
virtual views::View* CreateNotificationView(
user::LoginStatus status) OVERRIDE;
virtual void DestroyDefaultView() OVERRIDE;
virtual void DestroyDetailedView() OVERRIDE;
virtual void DestroyNotificationView() OVERRIDE;
// Overridden from TrayImageItem.
virtual bool GetInitialVisibility() OVERRIDE;
protected:
class SmsDefaultView;
class SmsDetailedView;
class SmsMessageView;
class SmsNotificationView;
class SmsObserver;
// Called when sms messages have changed (by tray::SmsObserver).
void Update(bool notify);
SmsObserver* sms_observer() const { return sms_observer_.get(); }
private:
SmsDefaultView* default_;
SmsDetailedView* detailed_;
SmsNotificationView* notification_;
scoped_ptr<SmsObserver> sms_observer_;
DISALLOW_COPY_AND_ASSIGN(TraySms);
};
} // namespace internal
} // namespace ash
#endif // ASH_SYSTEM_NETWORK_TRAY_SMS_H
......@@ -14,6 +14,7 @@
#include "ash/system/drive/tray_drive.h"
#include "ash/system/ime/tray_ime.h"
#include "ash/system/network/tray_network.h"
#include "ash/system/network/tray_sms.h"
#include "ash/system/power/power_status_observer.h"
#include "ash/system/power/power_supply_status.h"
#include "ash/system/power/tray_power.h"
......@@ -206,6 +207,7 @@ void SystemTray::CreateItems() {
internal::TrayDate* tray_date = new internal::TrayDate();
internal::TrayPower* tray_power = new internal::TrayPower();
internal::TrayNetwork* tray_network = new internal::TrayNetwork;
internal::TraySms* tray_sms = new internal::TraySms();
internal::TrayUser* tray_user = new internal::TrayUser;
internal::TrayAccessibility* tray_accessibility =
new internal::TrayAccessibility;
......@@ -231,6 +233,7 @@ void SystemTray::CreateItems() {
AddTrayItem(tray_power);
AddTrayItem(tray_network);
AddTrayItem(tray_bluetooth);
AddTrayItem(tray_sms);
AddTrayItem(tray_drive);
AddTrayItem(tray_ime);
AddTrayItem(tray_volume);
......@@ -299,6 +302,19 @@ void SystemTray::ShowDetailedView(SystemTrayItem* item,
bubble_->StartAutoCloseTimer(close_delay);
}
void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
if (bubble_.get() &&
bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED)
bubble_->StartAutoCloseTimer(close_delay);
}
void SystemTray::HideDetailedView(SystemTrayItem* item) {
if (item != detailed_item_)
return;
bubble_.reset();
UpdateNotificationBubble();
}
void SystemTray::ShowNotificationView(SystemTrayItem* item) {
if (std::find(notification_items_.begin(), notification_items_.end(), item)
!= notification_items_.end())
......@@ -313,13 +329,9 @@ void SystemTray::HideNotificationView(SystemTrayItem* item) {
if (found_iter == notification_items_.end())
return;
notification_items_.erase(found_iter);
UpdateNotificationBubble();
}
void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
if (bubble_.get() &&
bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DETAILED)
bubble_->StartAutoCloseTimer(close_delay);
// Only update the notification bubble if visible (i.e. don't create one).
if (notification_bubble_.get())
UpdateNotificationBubble();
}
void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
......@@ -416,6 +428,11 @@ void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
SystemTrayBubble::BubbleType bubble_type = detailed ?
SystemTrayBubble::BUBBLE_TYPE_DETAILED :
SystemTrayBubble::BUBBLE_TYPE_DEFAULT;
// Destroy the notification bubble here so that it doesn't get rebuilt
// while we add items to the main bubble_ (e.g. in HideNotificationView).
notification_bubble_.reset();
if (bubble_.get() && creation_type == BUBBLE_USE_EXISTING) {
bubble_->UpdateView(items, bubble_type);
} else {
......@@ -432,10 +449,17 @@ void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
init_params.arrow_offset = arrow_offset;
bubble_->InitView(init_params);
}
if (detailed && items.size() > 0)
detailed_item_ = items[0];
else
detailed_item_ = NULL;
// If we have focus the shelf should be visible and we need to continue
// showing the shelf when the popup is shown.
if (GetWidget()->IsActive())
should_show_launcher_ = true;
UpdateNotificationBubble(); // State changed, re-create notifications.
}
......
......@@ -80,6 +80,9 @@ class ASH_EXPORT SystemTray : public internal::ActionableView,
// seconds.
void SetDetailedViewCloseDelay(int close_delay);
// Hides the detailed view for |item|.
void HideDetailedView(SystemTrayItem* item);
// Shows the notification view for |item|.
void ShowNotificationView(SystemTrayItem* item);
......@@ -190,8 +193,11 @@ class ASH_EXPORT SystemTray : public internal::ActionableView,
// Overridden from internal::BackgroundAnimatorDelegate.
virtual void UpdateBackground(int alpha) OVERRIDE;
// Owned items.
ScopedVector<SystemTrayItem> items_;
// Pointers to members of |items_|.
SystemTrayItem* detailed_item_;
std::vector<SystemTrayItem*> notification_items_;
// The container for all the tray views of the items.
......
......@@ -377,6 +377,9 @@ void SystemTrayBubble::UpdateView(
bubble_type_ = bubble_type;
CreateItemViews(Shell::GetInstance()->tray_delegate()->GetUserLoginStatus());
bubble_widget_->GetContentsView()->Layout();
// Make sure that the bubble is large enough for the default view.
if (bubble_type_ == BUBBLE_TYPE_DEFAULT)
bubble_view_->SizeToContents();
}
void SystemTrayBubble::InitView(const InitParams& init_params) {
......
......@@ -38,6 +38,8 @@ class SystemTrayBubbleView : public views::BubbleDelegateView {
void reset_host() { host_ = NULL; }
private:
friend class SystemTrayBubble;
// Overridden from views::BubbleDelegateView.
virtual void Init() OVERRIDE;
virtual gfx::Rect GetAnchorRect() OVERRIDE;
......
......@@ -49,6 +49,9 @@ void SystemTrayItem::TransitionDetailedView() {
BUBBLE_USE_EXISTING);
}
void SystemTrayItem::UpdateAfterLoginStatusChange(user::LoginStatus status) {
}
void SystemTrayItem::PopupDetailedView(int for_seconds, bool activate) {
Shell::GetInstance()->tray()->ShowDetailedView(this, for_seconds, activate,
BUBBLE_CREATE_NEW);
......@@ -58,6 +61,10 @@ void SystemTrayItem::SetDetailedViewCloseDelay(int for_seconds) {
Shell::GetInstance()->tray()->SetDetailedViewCloseDelay(for_seconds);
}
void SystemTrayItem::HideDetailedView() {
Shell::GetInstance()->tray()->HideDetailedView(this);
}
void SystemTrayItem::ShowNotificationView() {
Shell::GetInstance()->tray()->ShowNotificationView(this);
}
......
......@@ -55,8 +55,9 @@ class ASH_EXPORT SystemTrayItem {
// Updates the tray view (if applicable) when the user's login status changes.
// It is not necessary the update the default or detailed view, since the
// default/detailed popup is closed when login status changes.
virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) = 0;
// default/detailed popup is closed when login status changes. The default
// implementation does nothing.
virtual void UpdateAfterLoginStatusChange(user::LoginStatus status);
// Shows the detailed view for this item. If the main popup for the tray is
// currently visible, then making this call would use the existing window to
......@@ -78,6 +79,9 @@ class ASH_EXPORT SystemTrayItem {
// currently-shown view is for this item.
void SetDetailedViewCloseDelay(int for_seconds);
// Hides the detailed view for this item.
void HideDetailedView();
// Shows a notification for this item.
void ShowNotificationView();
......
......@@ -37,5 +37,6 @@ const SkColor kHeaderTextColorNormal = SkColorSetARGB(0x7f, 0, 0, 0);
const SkColor kHeaderTextColorHover = SkColorSetARGB(0xd3, 0, 0, 0);
const int kTrayPopupWidth = 300;
const int kNotificationCloseButtonWidth = 60;
} // namespace ash
......@@ -39,6 +39,7 @@ extern const SkColor kHeaderTextColorNormal;
extern const SkColor kHeaderTextColorHover;
extern const int kTrayPopupWidth;
extern const int kNotificationCloseButtonWidth;
} // namespace ash
......
......@@ -59,23 +59,19 @@ void TrayDetailsView::Layout() {
scroller_->set_fixed_size(gfx::Size());
gfx::Size size = GetPreferredSize();
if (size.height() < height()) {
// The available size is larger than the requested size. In this case, do
// the normal layout, then make sure the footer element is bottom aligned.
views::View::Layout();
gfx::Rect fbounds = footer_->bounds();
fbounds.set_y(height() - footer_->height());
footer_->SetBoundsRect(fbounds);
} else {
if (size.height() > height()) {
// The available size is smaller than the requested size. Squeeze the
// scroller so that everything fits in the available size, and then do the
// normal layout.
// scroller so that everything fits in the available size.
gfx::Size scroller_size = scroll_content_->GetPreferredSize();
scroller_->set_fixed_size(gfx::Size(
width() + scroller_->GetScrollBarWidth(),
scroller_size.height() - (size.height() - height())));
views::View::Layout();
}
views::View::Layout();
// Always make sure the footer element is bottom aligned.
gfx::Rect fbounds = footer_->bounds();
fbounds.set_y(height() - footer_->height());
footer_->SetBoundsRect(fbounds);
}
} // namespace internal
......
......@@ -36,7 +36,6 @@ views::View* CreatePopupHeaderButtonsContainer() {
return view;
}
const int kNotificationCloseButtonWidth = 60;
}
////////////////////////////////////////////////////////////////////////////////
......@@ -470,13 +469,10 @@ void TrayNotificationView::InitView(views::View* contents) {
views::GridLayout* layout = new views::GridLayout(this);
SetLayoutManager(layout);
AddChildView(contents);
views::ImageButton* close_button = new views::ImageButton(this);
close_button->SetImage(views::CustomButton::BS_NORMAL,
ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_AURA_WINDOW_CLOSE));
AddChildView(close_button);
int contents_width = kTrayPopupWidth - kNotificationCloseButtonWidth;
views::ColumnSet* columns = layout->AddColumnSet(0);
......
......@@ -138,14 +138,17 @@ class FixedSizedScrollView : public views::ScrollView {
void set_fixed_size(gfx::Size size) { fixed_size_ = size; }
private:
// Overridden from views::View.
// views::View public method overrides.
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual void Layout() OVERRIDE;
virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
protected:
// views::View protected method overrides.
virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
private:
gfx::Size fixed_size_;
DISALLOW_COPY_AND_ASSIGN(FixedSizedScrollView);
......
......@@ -50,10 +50,13 @@ void ProfileStartup(Profile* profile, bool process_startup) {
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
AddUserActionObserver(network_message_observer);
static chromeos::SmsObserver* sms_observer =
new chromeos::SmsObserver(profile);
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
AddNetworkManagerObserver(sms_observer);
if (!CommandLine::ForCurrentProcess()->HasSwitch(
ash::switches::kAshNotify)) {
static chromeos::SmsObserver* sms_observer =
new chromeos::SmsObserver(profile);
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
AddNetworkManagerObserver(sms_observer);
}
profile->SetupChromeOSEnterpriseExtensionObserver();
}
......
......@@ -230,7 +230,7 @@ class GsmSMSClientImpl : public GsmSMSClient {
// A stub implementaion of GsmSMSClient.
class GsmSMSClientStubImpl : public GsmSMSClient {
public:
GsmSMSClientStubImpl() : test_index_(0), weak_ptr_factory_(this) {
GsmSMSClientStubImpl() : test_index_(-1), weak_ptr_factory_(this) {
test_messages_.push_back("Test Message 0");
test_messages_.push_back("Test Message 1");
test_messages_.push_back("Test a relatively long message 2");
......@@ -291,7 +291,15 @@ class GsmSMSClientStubImpl : public GsmSMSClient {
// GsmSMSClient override.
virtual void RequestUpdate(const std::string& service_name,
const dbus::ObjectPath& object_path) {
PushTestMessageChain();
if (test_index_ >= 0)
return;
test_index_ = 0;
// Call PushTestMessageChain asynchronously so that the handler_ callback
// does not get called from the update request.
MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GsmSMSClientStubImpl::PushTestMessageChain,
weak_ptr_factory_.GetWeakPtr()));
}
private:
......@@ -310,7 +318,7 @@ class GsmSMSClientStubImpl : public GsmSMSClient {
}
bool PushTestMessage() {
if (test_index_ >= test_messages_.size())
if (test_index_ >= static_cast<int>(test_messages_.size()))
return false;
base::DictionaryValue* message = new base::DictionaryValue;
message->SetString("number", "000-000-0000");
......@@ -324,7 +332,7 @@ class GsmSMSClientStubImpl : public GsmSMSClient {
return true;
}
size_t test_index_;
int test_index_;
std::vector<std::string> test_messages_;
base::ListValue message_list_;
SmsReceivedHandler handler_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment