Show message center on lock screen

This patch does:
- Show the message center button on tray on the lock screen
- Show the message to encourage user to log in when user opens message center on lock screen
- Add SetLockedState(bool) and IsLockedState() method into MessageCenter class.
- Don't make notifications read when opening the message center on lock screen
- Add tests

And this patch also fixes the bug that this makes blocked notifications read wrongly.

BUG=599891
TEST=manually tested

Review-Url: https://codereview.chromium.org/1986493002
Cr-Commit-Position: refs/heads/master@{#396402}
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index a23bf89..e0cc6ba9 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -301,9 +301,8 @@
 // Private methods.
 
 bool WebNotificationTray::ShouldShowMessageCenter() {
-  return status_area_widget()->login_status() != user::LOGGED_IN_LOCKED &&
-      !(status_area_widget()->system_tray() &&
-        status_area_widget()->system_tray()->HasNotificationBubble());
+  return !(status_area_widget()->system_tray() &&
+           status_area_widget()->system_tray()->HasNotificationBubble());
 }
 
 bool WebNotificationTray::ShouldBlockShelfAutoHide() const {
@@ -326,6 +325,7 @@
 
 void WebNotificationTray::UpdateAfterLoginStatusChange(
     user::LoginStatus login_status) {
+  message_center()->SetLockedState(login_status == user::LOGGED_IN_LOCKED);
   OnMessageCenterTrayChanged();
 }
 
@@ -408,8 +408,7 @@
                                ->session_state_delegate()
                                ->IsInSecondaryLoginScreen();
 
-  return login_status != user::LOGGED_IN_NONE
-      && login_status != user::LOGGED_IN_LOCKED && !userAddingRunning;
+  return login_status != user::LOGGED_IN_NONE && !userAddingRunning;
 }
 
 message_center::MessageCenterTray* WebNotificationTray::GetMessageCenterTray() {
@@ -477,7 +476,6 @@
                                ->IsInSecondaryLoginScreen();
 
   SetVisible((status_area_widget()->login_status() != user::LOGGED_IN_NONE) &&
-             (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) &&
              !userAddingRunning);
   Layout();
   SchedulePaint();
diff --git a/ui/message_center/fake_message_center.cc b/ui/message_center/fake_message_center.cc
index acfe789..1900b0e 100644
--- a/ui/message_center/fake_message_center.cc
+++ b/ui/message_center/fake_message_center.cc
@@ -42,6 +42,10 @@
   return false;
 }
 
+bool FakeMessageCenter::IsLockedState() const {
+  return false;
+}
+
 bool FakeMessageCenter::HasClickedListener(const std::string& id) {
   return false;
 }
@@ -121,6 +125,8 @@
 void FakeMessageCenter::SetQuietMode(bool in_quiet_mode) {
 }
 
+void FakeMessageCenter::SetLockedState(bool locked) {}
+
 void FakeMessageCenter::EnterQuietModeWithExpire(
     const base::TimeDelta& expires_in) {
 }
diff --git a/ui/message_center/fake_message_center.h b/ui/message_center/fake_message_center.h
index 023df8e..6cee5da 100644
--- a/ui/message_center/fake_message_center.h
+++ b/ui/message_center/fake_message_center.h
@@ -30,6 +30,7 @@
   size_t UnreadNotificationCount() const override;
   bool HasPopupNotifications() const override;
   bool IsQuietMode() const override;
+  bool IsLockedState() const override;
   bool HasClickedListener(const std::string& id) override;
   message_center::Notification* FindVisibleNotificationById(
       const std::string& id) override;
@@ -63,6 +64,7 @@
   void SetNotifierSettingsProvider(NotifierSettingsProvider* provider) override;
   NotifierSettingsProvider* GetNotifierSettingsProvider() override;
   void SetQuietMode(bool in_quiet_mode) override;
+  void SetLockedState(bool locked) override;
   void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) override;
   void SetVisibility(Visibility visible) override;
   bool IsMessageCenterVisible() const override;
diff --git a/ui/message_center/message_center.h b/ui/message_center/message_center.h
index 038c7b7..6db00a2 100644
--- a/ui/message_center/message_center.h
+++ b/ui/message_center/message_center.h
@@ -76,6 +76,7 @@
   virtual size_t UnreadNotificationCount() const = 0;
   virtual bool HasPopupNotifications() const = 0;
   virtual bool IsQuietMode() const = 0;
+  virtual bool IsLockedState() const = 0;
   virtual bool HasClickedListener(const std::string& id) = 0;
 
   // Find the notification with the corresponding id. Returns NULL if not found.
@@ -171,6 +172,9 @@
   // This can be called to change the quiet mode state (without a timeout).
   virtual void SetQuietMode(bool in_quiet_mode) = 0;
 
+  // This can be called to change the lock mode state.
+  virtual void SetLockedState(bool locked) = 0;
+
   // Temporarily enables quiet mode for |expires_in| time.
   virtual void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) = 0;
 
diff --git a/ui/message_center/message_center_impl.cc b/ui/message_center/message_center_impl.cc
index 06a0461..67d62d4 100644
--- a/ui/message_center/message_center_impl.cc
+++ b/ui/message_center/message_center_impl.cc
@@ -356,7 +356,7 @@
     : MessageCenter(),
       popup_timers_controller_(new PopupTimersController(this)),
       settings_provider_(NULL) {
-  notification_list_.reset(new NotificationList());
+  notification_list_.reset(new NotificationList(this));
 
   bool enable_message_center_changes_while_open = true;  // enable by default
   std::string arg = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
@@ -440,14 +440,17 @@
 }
 
 void MessageCenterImpl::SetVisibility(Visibility visibility) {
-  std::set<std::string> updated_ids;
-  notification_list_->SetMessageCenterVisible(
-      (visibility == VISIBILITY_MESSAGE_CENTER), &updated_ids);
-  notification_cache_.RecountUnread();
+  visible_ = (visibility == VISIBILITY_MESSAGE_CENTER);
 
-  for (const auto& id : updated_ids) {
-    FOR_EACH_OBSERVER(
-        MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
+  if (visible_ && !locked_) {
+    std::set<std::string> updated_ids;
+    notification_list_->SetNotificationsShown(blockers_, &updated_ids);
+    notification_cache_.RecountUnread();
+
+    for (const auto& id : updated_ids) {
+      FOR_EACH_OBSERVER(
+          MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
+    }
   }
 
   if (notification_queue_ &&
@@ -461,7 +464,7 @@
 }
 
 bool MessageCenterImpl::IsMessageCenterVisible() const {
-  return notification_list_->is_message_center_visible();
+  return visible_;
 }
 
 size_t MessageCenterImpl::NotificationCount() const {
@@ -481,6 +484,10 @@
   return notification_list_->quiet_mode();
 }
 
+bool MessageCenterImpl::IsLockedState() const {
+  return locked_;
+}
+
 bool MessageCenterImpl::HasClickedListener(const std::string& id) {
   scoped_refptr<NotificationDelegate> delegate =
       notification_list_->GetNotificationDelegate(id);
@@ -516,8 +523,7 @@
   for (size_t i = 0; i < blockers_.size(); ++i)
     blockers_[i]->CheckState();
 
-  if (notification_queue_ &&
-      notification_list_->is_message_center_visible()) {
+  if (notification_queue_ && visible_) {
     notification_queue_->AddNotification(std::move(notification));
     return;
   }
@@ -552,8 +558,7 @@
   for (size_t i = 0; i < blockers_.size(); ++i)
     blockers_[i]->CheckState();
 
-  if (notification_queue_ &&
-      notification_list_->is_message_center_visible()) {
+  if (notification_queue_ && visible_) {
     // We will allow notifications that are progress types (and stay progress
     // types) to be updated even if the message center is open.  There are 3
     // requirements here:
@@ -601,8 +606,7 @@
 
 void MessageCenterImpl::RemoveNotification(const std::string& id,
                                            bool by_user) {
-  if (notification_queue_ && !by_user &&
-      notification_list_->is_message_center_visible()) {
+  if (notification_queue_ && !by_user && visible_) {
     notification_queue_->EraseNotification(id, by_user);
     return;
   }
@@ -854,6 +858,14 @@
   quiet_mode_timer_.reset();
 }
 
+void MessageCenterImpl::SetLockedState(bool locked) {
+  if (locked != locked_) {
+    locked_ = locked;
+    FOR_EACH_OBSERVER(MessageCenterObserver, observer_list_,
+                      OnLockedStateChanged(locked));
+  }
+}
+
 void MessageCenterImpl::EnterQuietModeWithExpire(
     const base::TimeDelta& expires_in) {
   if (quiet_mode_timer_) {
diff --git a/ui/message_center/message_center_impl.h b/ui/message_center/message_center_impl.h
index bac09cb..46ff15e 100644
--- a/ui/message_center/message_center_impl.h
+++ b/ui/message_center/message_center_impl.h
@@ -49,6 +49,7 @@
   size_t UnreadNotificationCount() const override;
   bool HasPopupNotifications() const override;
   bool IsQuietMode() const override;
+  bool IsLockedState() const override;
   bool HasClickedListener(const std::string& id) override;
   message_center::Notification* FindVisibleNotificationById(
       const std::string& id) override;
@@ -79,6 +80,7 @@
   void SetNotifierSettingsProvider(NotifierSettingsProvider* provider) override;
   NotifierSettingsProvider* GetNotifierSettingsProvider() override;
   void SetQuietMode(bool in_quiet_mode) override;
+  void SetLockedState(bool locked) override;
   void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) override;
   void RestartPopupTimers() override;
   void PausePopupTimers() override;
@@ -126,6 +128,9 @@
   NotifierSettingsProvider* settings_provider_;
   std::vector<NotificationBlocker*> blockers_;
 
+  bool locked_ = false;
+  bool visible_ = false;
+
   // Queue for the notifications to delay the addition/updates when the message
   // center is visible.
   std::unique_ptr<internal::ChangeQueue> notification_queue_;
diff --git a/ui/message_center/message_center_observer.h b/ui/message_center/message_center_observer.h
index 5ab0722..e6315cc 100644
--- a/ui/message_center/message_center_observer.h
+++ b/ui/message_center/message_center_observer.h
@@ -56,6 +56,9 @@
   // quiet mode expires.
   virtual void OnQuietModeChanged(bool in_quiet_mode) {}
 
+  // Called when the user locks (or unlocks) the screen.
+  virtual void OnLockedStateChanged(bool locked) {}
+
   // Called when the blocking state of |blocker| is changed.
   virtual void OnBlockingStateChanged(NotificationBlocker* blocker) {}
 };
diff --git a/ui/message_center/notification_list.cc b/ui/message_center/notification_list.cc
index 14abd9b..0ac3b1c 100644
--- a/ui/message_center/notification_list.cc
+++ b/ui/message_center/notification_list.cc
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "ui/gfx/image/image.h"
+#include "ui/message_center/message_center.h"
 #include "ui/message_center/message_center_style.h"
 #include "ui/message_center/notification.h"
 #include "ui/message_center/notification_blocker.h"
@@ -54,8 +55,8 @@
   return false;
 }
 
-NotificationList::NotificationList()
-    : message_center_visible_(false),
+NotificationList::NotificationList(MessageCenter* message_center)
+    : message_center_(message_center),
       quiet_mode_(false) {
 }
 
@@ -63,19 +64,12 @@
   STLDeleteContainerPointers(notifications_.begin(), notifications_.end());
 }
 
-void NotificationList::SetMessageCenterVisible(
-    bool visible,
+void NotificationList::SetNotificationsShown(
+    const NotificationBlockers& blockers,
     std::set<std::string>* updated_ids) {
-  if (message_center_visible_ == visible)
-    return;
+  Notifications notifications = GetVisibleNotifications(blockers);
 
-  message_center_visible_ = visible;
-
-  if (!visible)
-    return;
-
-  for (Notifications::iterator iter = notifications_.begin();
-       iter != notifications_.end(); ++iter) {
+  for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
     Notification* notification = *iter;
     bool was_popup = notification->shown_as_popup();
     bool was_read = notification->IsRead();
@@ -346,7 +340,7 @@
     // TODO(mukai): needs to distinguish if a notification is dismissed by
     // the quiet mode or user operation.
     notification->set_is_read(false);
-    notification->set_shown_as_popup(message_center_visible_
+    notification->set_shown_as_popup(message_center_->IsMessageCenterVisible()
                                      || quiet_mode_
                                      || notification->shown_as_popup());
   }
diff --git a/ui/message_center/notification_list.h b/ui/message_center/notification_list.h
index 6b30a2e..f52217b0 100644
--- a/ui/message_center/notification_list.h
+++ b/ui/message_center/notification_list.h
@@ -56,14 +56,13 @@
   // toasts.
   typedef std::set<Notification*, CompareTimestampSerial> PopupNotifications;
 
-  explicit NotificationList();
+  explicit NotificationList(MessageCenter* message_center);
   virtual ~NotificationList();
 
-  // Affects whether or not a message has been "read". Collects the set of
-  // ids whose state have changed and set to |udpated_ids|. NULL if updated
-  // ids don't matter.
-  void SetMessageCenterVisible(bool visible,
-                               std::set<std::string>* updated_ids);
+  // Makes a message "read". Collects the set of ids whose state have changed
+  // and set to |udpated_ids|. NULL if updated ids don't matter.
+  void SetNotificationsShown(const NotificationBlockers& blockers,
+                             std::set<std::string>* updated_ids);
 
   void AddNotification(std::unique_ptr<Notification> notification);
 
@@ -137,8 +136,6 @@
   size_t NotificationCount(const NotificationBlockers& blockers) const;
   size_t UnreadCount(const NotificationBlockers& blockers) const;
 
-  bool is_message_center_visible() const { return message_center_visible_; }
-
  private:
   friend class NotificationListTest;
   FRIEND_TEST_ALL_PREFIXES(NotificationListTest,
@@ -151,8 +148,8 @@
 
   void PushNotification(std::unique_ptr<Notification> notification);
 
+  MessageCenter* message_center_;  // owner
   Notifications notifications_;
-  bool message_center_visible_;
   bool quiet_mode_;
 
   DISALLOW_COPY_AND_ASSIGN(NotificationList);
diff --git a/ui/message_center/notification_list_unittest.cc b/ui/message_center/notification_list_unittest.cc
index 4405339..8aaaa084 100644
--- a/ui/message_center/notification_list_unittest.cc
+++ b/ui/message_center/notification_list_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/message_center/fake_message_center.h"
 #include "ui/message_center/message_center_style.h"
 #include "ui/message_center/notification_blocker.h"
 #include "ui/message_center/notification_types.h"
@@ -29,7 +30,7 @@
   ~NotificationListTest() override {}
 
   void SetUp() override {
-    notification_list_.reset(new NotificationList());
+    notification_list_.reset(new NotificationList(new FakeMessageCenter()));
     counter_ = 0;
   }
 
@@ -162,9 +163,8 @@
   ASSERT_EQ(1u, notification_list()->UnreadCount(blockers()));
   ASSERT_EQ(1u, GetPopupCounts());
 
-  // Make the message center visible. It resets the unread count and popup
-  // counts.
-  notification_list()->SetMessageCenterVisible(true, NULL);
+  // Resets the unread count and popup counts.
+  notification_list()->SetNotificationsShown(blockers(), NULL);
   ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
   ASSERT_EQ(0u, GetPopupCounts());
 }
@@ -309,8 +309,7 @@
   EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts());
 
   // Low priority: not visible to popups.
-  notification_list()->SetMessageCenterVisible(true, NULL);
-  notification_list()->SetMessageCenterVisible(false, NULL);
+  notification_list()->SetNotificationsShown(blockers(), NULL);
   EXPECT_EQ(0u, notification_list()->UnreadCount(blockers()));
   AddPriorityNotification(LOW_PRIORITY);
   EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
@@ -368,8 +367,7 @@
   notification_list()->MarkSinglePopupAsShown(normal_id, false);
   notification_list()->MarkSinglePopupAsShown(system_id, false);
 
-  notification_list()->SetMessageCenterVisible(true, NULL);
-  notification_list()->SetMessageCenterVisible(false, NULL);
+  notification_list()->SetNotificationsShown(blockers(), NULL);
   EXPECT_EQ(1u, GetPopupCounts());
 
   // Mark as read -- emulation of mouse click.
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc
index a82de8e..3555b1a 100644
--- a/ui/message_center/views/message_center_view.cc
+++ b/ui/message_center/views/message_center_view.cc
@@ -41,6 +41,9 @@
 
 namespace message_center {
 
+// static
+bool MessageCenterView::disable_animation_for_testing = false;
+
 namespace {
 
 const int kDefaultAnimationDurationMs = 120;
@@ -73,8 +76,9 @@
       target_view_(NULL),
       target_height_(0),
       is_closing_(false),
-      mode_((!initially_settings_visible) ? Mode::BUTTONS_ONLY
-                                          : Mode::SETTINGS),
+      is_locked_(message_center_->IsLockedState()),
+      mode_((!initially_settings_visible || is_locked_) ? Mode::BUTTONS_ONLY
+                                                        : Mode::SETTINGS),
       context_menu_controller_(new MessageViewContextMenuController(this)) {
   message_center_->AddObserver(this);
   set_notify_enter_exit_on_child(true);
@@ -402,6 +406,12 @@
   }
 }
 
+void MessageCenterView::OnLockedStateChanged(bool locked) {
+  is_locked_ = locked;
+  UpdateButtonBarStatus();
+  Update(true /* animate */);
+}
+
 void MessageCenterView::ClickOnNotification(
     const std::string& notification_id) {
   message_center_->ClickOnNotification(notification_id);
@@ -488,8 +498,10 @@
 }
 
 base::string16 MessageCenterView::GetButtonBarTitle() const {
-  bool no_message_views = notification_views_.empty();
-  if (no_message_views && !settings_visible_)
+  if (is_locked_)
+    return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_LOCKSCREEN);
+
+  if (mode_ == Mode::BUTTONS_ONLY)
     return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_NO_MESSAGES);
 
   return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE);
@@ -507,7 +519,9 @@
   if (focus_manager)
     focused_view = focus_manager->GetFocusedView();
 
-  if (settings_visible_)
+  if (is_locked_)
+    SetVisibilityMode(Mode::BUTTONS_ONLY, animate);
+  else if (settings_visible_)
     SetVisibilityMode(Mode::SETTINGS, animate);
   else if (no_message_views)
     SetVisibilityMode(Mode::BUTTONS_ONLY, animate);
@@ -561,7 +575,7 @@
   source_height_ = source_view_ ? source_view_->GetHeightForWidth(width()) : 0;
   target_height_ = target_view_ ? target_view_->GetHeightForWidth(width()) : 0;
 
-  if (!animate) {
+  if (!animate || disable_animation_for_testing) {
     AnimationEnded(NULL);
     return;
   }
@@ -603,7 +617,7 @@
   }
 
   button_bar_->SetBackArrowVisible(mode_ == Mode::SETTINGS);
-  button_bar_->SetSettingsAndQuietModeButtonsEnabled(true);
+  button_bar_->SetSettingsAndQuietModeButtonsEnabled(!is_locked_);
   button_bar_->SetTitle(GetButtonBarTitle());
 
   if (mode_ == Mode::NOTIFICATIONS) {
diff --git a/ui/message_center/views/message_center_view.h b/ui/message_center/views/message_center_view.h
index 9a37ade..93bedd5 100644
--- a/ui/message_center/views/message_center_view.h
+++ b/ui/message_center/views/message_center_view.h
@@ -73,6 +73,7 @@
   void OnNotificationAdded(const std::string& id) override;
   void OnNotificationRemoved(const std::string& id, bool by_user) override;
   void OnNotificationUpdated(const std::string& id) override;
+  void OnLockedStateChanged(bool locked) override;
 
   // Overridden from MessageCenterController:
   void ClickOnNotification(const std::string& notification_id) override;
@@ -96,6 +97,8 @@
 
   enum class Mode { NOTIFICATIONS, SETTINGS, BUTTONS_ONLY };
 
+  static bool disable_animation_for_testing;
+
   void AddNotificationAt(const Notification& notification, int index);
   base::string16 GetButtonBarTitle() const;
   void Update(bool animate);
@@ -137,6 +140,7 @@
   bool is_closing_;
 
   bool is_clearing_ = false;
+  bool is_locked_ = false;
 
   // Current view mode. During animation, it is the target mode.
   Mode mode_ = Mode::BUTTONS_ONLY;
diff --git a/ui/message_center/views/message_center_view_unittest.cc b/ui/message_center/views/message_center_view_unittest.cc
index b60f144..7558b1b 100644
--- a/ui/message_center/views/message_center_view_unittest.cc
+++ b/ui/message_center/views/message_center_view_unittest.cc
@@ -107,8 +107,10 @@
     if (type == RemoveType::NON_PINNED)
       remove_all_closable_notification_called_ = true;
   }
+  bool IsLockedState() const override { return locked_; }
   bool remove_all_closable_notification_called_ = false;
   NotificationList::Notifications visible_notifications_;
+  bool locked_ = false;
 };
 
 /* Test fixture ***************************************************************/
@@ -134,6 +136,7 @@
   int GetNotificationCount();
   int GetCallCount(CallType type);
   int GetCalculatedMessageListViewHeight();
+  void SetLockedState(bool locked);
   Mode GetMessageCenterViewInternalMode();
   void AddNotification(std::unique_ptr<Notification> notification);
   void UpdateNotification(const std::string& notification_id,
@@ -166,6 +169,7 @@
   views::View* MakeParent(views::View* child1, views::View* child2);
 
   NotificationList::Notifications notifications_;
+  std::unique_ptr<views::Widget> widget_;
   std::unique_ptr<MessageCenterView> message_center_view_;
   std::unique_ptr<FakeMessageCenterImpl> message_center_;
   std::map<CallType,int> callCounts_;
@@ -181,6 +185,7 @@
 
 void MessageCenterViewTest::SetUp() {
   views::ViewsTestBase::SetUp();
+  MessageCenterView::disable_animation_for_testing = true;
   message_center_.reset(new FakeMessageCenterImpl());
 
   // Create a dummy notification.
@@ -209,6 +214,18 @@
   GetMessageListView()->quit_message_loop_after_animation_for_test_ = true;
   GetMessageCenterView()->SetBounds(0, 0, 380, 600);
   message_center_view_->SetNotifications(notifications_);
+  message_center_view_->set_owned_by_client();
+
+  widget_.reset(new views::Widget());
+  views::Widget::InitParams params =
+      CreateParams(views::Widget::InitParams::TYPE_POPUP);
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.bounds = gfx::Rect(50, 50, 650, 650);
+  widget_->Init(params);
+  views::View* root = widget_->GetRootView();
+  root->AddChildView(message_center_view_.get());
+  widget_->Show();
+  widget_->Activate();
 
   // Wait until the animation finishes if available.
   if (GetAnimator()->IsAnimating())
@@ -216,6 +233,8 @@
 }
 
 void MessageCenterViewTest::TearDown() {
+  widget_->CloseNow();
+  widget_.reset();
   message_center_view_.reset();
   STLDeleteElements(&notifications_);
   views::ViewsTestBase::TearDown();
@@ -258,6 +277,10 @@
   return callCounts_[type];
 }
 
+void MessageCenterViewTest::SetLockedState(bool locked) {
+  GetMessageCenterView()->OnLockedStateChanged(locked);
+}
+
 void MessageCenterViewTest::ClickOnNotification(
     const std::string& notification_id) {
   // For this test, this method should not be invoked.
@@ -707,4 +730,82 @@
   EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode());
 }
 
+TEST_F(MessageCenterViewTest, LockScreen) {
+  const int kLockedMessageCenterViewHeight = 50;
+
+  EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn());
+  EXPECT_TRUE(GetNotificationView(kNotificationId2)->IsDrawn());
+
+  // Lock!
+  SetLockedState(true);
+
+  EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn());
+  EXPECT_FALSE(GetNotificationView(kNotificationId2)->IsDrawn());
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  RemoveNotification(kNotificationId1, false);
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  RemoveNotification(kNotificationId2, false);
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  AddNotification(std::unique_ptr<Notification>(new Notification(
+      NOTIFICATION_TYPE_SIMPLE, std::string(kNotificationId1),
+      base::UTF8ToUTF16("title1"),
+      base::UTF8ToUTF16("message"),
+      gfx::Image(), base::UTF8ToUTF16("display source"), GURL(),
+      NotifierId(NotifierId::APPLICATION, "extension_id"),
+      message_center::RichNotificationData(), NULL)));
+  EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn());
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  // Unlock!
+  SetLockedState(false);
+
+  EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn());
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  // Lock!
+  SetLockedState(true);
+
+  EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn());
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height());
+}
+
+TEST_F(MessageCenterViewTest, NoNotification) {
+  const int kEmptyMessageCenterViewHeight = 50;
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height());
+  RemoveNotification(kNotificationId1, false);
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height());
+  RemoveNotification(kNotificationId2, false);
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_EQ(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height());
+
+  AddNotification(std::unique_ptr<Notification>(new Notification(
+      NOTIFICATION_TYPE_SIMPLE, std::string(kNotificationId1),
+      base::UTF8ToUTF16("title1"),
+      base::UTF8ToUTF16("message"),
+      gfx::Image(), base::UTF8ToUTF16("display source"), GURL(),
+      NotifierId(NotifierId::APPLICATION, "extension_id"),
+      message_center::RichNotificationData(), NULL)));
+
+  GetMessageCenterView()->SizeToPreferredSize();
+  EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height());
+}
+
 }  // namespace message_center
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
index bfe59ee3..5242982 100644
--- a/ui/strings/ui_strings.grd
+++ b/ui/strings/ui_strings.grd
@@ -605,6 +605,9 @@
       <message name="IDS_MESSAGE_CENTER_FOOTER_TITLE" desc="The label in the footer of the message center">
         Notifications
       </message>
+      <message name="IDS_MESSAGE_CENTER_FOOTER_LOCKSCREEN" desc="The label in the footer of the message center on lock screen">
+        Sign in to view your notifications
+      </message>
       <message name="IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL" desc="The button label for visiting the appropriate settings page in the footer of the message center.">
         Settings
       </message>