Commit 196ee3b6 authored by jamescook's avatar jamescook Committed by Commit bot

ash: Use system tray mojo interface to show system update tray icon

Change the flow so that Chrome explicitly asks ash to show the icon
rather than having ash ask Chrome whether there is an update available.

* Add ShowUpdateIcon to system_tray.mojom
* Introduce update.mojom
* Migrate ash to using ash::mojom::UpdateSeverity internally
* Migrate update methods from SystemTrayDelegate to SystemTrayClient
* Add a new SystemTrayClientTest and move existing Flash test there

Also add docs for SystemTrayItem (used by TrayUpdate) since tray view
vs. default view vs. detailed view always confuses me.

BUG=647412
TEST=chrome browser_tests, ash_unittests

Review-Url: https://codereview.chromium.org/2558043006
Cr-Commit-Position: refs/heads/master@{#438051}
parent 6c2cb1e4
......@@ -441,7 +441,6 @@ component("ash") {
"common/system/tray_accessibility.h",
"common/system/update/tray_update.cc",
"common/system/update/tray_update.h",
"common/system/update/update_observer.h",
"common/system/user/button_from_view.cc",
"common/system/user/button_from_view.h",
"common/system/user/login_status.cc",
......
......@@ -5,11 +5,6 @@
#include "ash/common/system/tray/default_system_tray_delegate.h"
#include <string>
#include <utility>
#include "ash/common/system/networking_config_delegate.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
namespace ash {
......@@ -32,13 +27,6 @@ bool DefaultSystemTrayDelegate::IsUserSupervised() const {
return GetUserLoginStatus() == LoginStatus::SUPERVISED;
}
void DefaultSystemTrayDelegate::GetSystemUpdateInfo(UpdateInfo* info) const {
DCHECK(info);
info->severity = UpdateInfo::UPDATE_NONE;
info->update_required = true;
info->factory_reset_required = false;
}
bool DefaultSystemTrayDelegate::ShouldShowSettings() const {
return true;
}
......
......@@ -20,7 +20,6 @@ class ASH_EXPORT DefaultSystemTrayDelegate : public SystemTrayDelegate {
LoginStatus GetUserLoginStatus() const override;
std::string GetSupervisedUserManager() const override;
bool IsUserSupervised() const override;
void GetSystemUpdateInfo(UpdateInfo* info) const override;
bool ShouldShowSettings() const override;
bool ShouldShowNotificationTray() const override;
void ToggleBluetooth() override;
......
......@@ -822,10 +822,6 @@ TrayTiles* SystemTray::GetTrayTilesForTesting() const {
return tray_tiles_;
}
TrayUpdate* SystemTray::GetTrayUpdateForTesting() const {
return tray_update_;
}
void SystemTray::CloseBubble(const ui::KeyEvent& key_event) {
CloseSystemBubble();
}
......
......@@ -47,6 +47,8 @@ class ASH_EXPORT SystemTray : public TrayBackgroundView,
explicit SystemTray(WmShelf* wm_shelf);
~SystemTray() override;
TrayUpdate* tray_update() { return tray_update_; }
// Calls TrayBackgroundView::Initialize(), creates the tray items, and
// adds them to SystemTrayNotifier.
void InitializeTrayItems(SystemTrayDelegate* delegate,
......@@ -168,7 +170,6 @@ class ASH_EXPORT SystemTray : public TrayBackgroundView,
TrayNetwork* GetTrayNetworkForTesting() const;
TraySystemInfo* GetTraySystemInfoForTesting() const;
TrayTiles* GetTrayTilesForTesting() const;
TrayUpdate* GetTrayUpdateForTesting() const;
// Activates the system tray bubble.
void ActivateBubble();
......
......@@ -4,8 +4,12 @@
#include "ash/common/system/tray/system_tray_controller.h"
#include "ash/common/system/tray/system_tray.h"
#include "ash/common/system/tray/system_tray_notifier.h"
#include "ash/common/system/update/tray_update.h"
#include "ash/common/wm_root_window_controller.h"
#include "ash/common/wm_shell.h"
#include "ash/common/wm_window.h"
namespace ash {
......@@ -128,4 +132,16 @@ void SystemTrayController::SetUse24HourClock(bool use_24_hour) {
WmShell::Get()->system_tray_notifier()->NotifyDateFormatChanged();
}
void SystemTrayController::ShowUpdateIcon(mojom::UpdateSeverity severity,
bool factory_reset_required) {
// Show the icon on all displays.
for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) {
ash::SystemTray* tray = root->GetRootWindowController()->GetSystemTray();
// External monitors might not have a tray yet.
if (!tray)
continue;
tray->tray_update()->ShowUpdateIcon(severity, factory_reset_required);
}
}
} // namespace ash
......@@ -56,11 +56,13 @@ class ASH_EXPORT SystemTrayController
// Binds the mojom::SystemTray interface to this object.
void BindRequest(mojom::SystemTrayRequest request);
private:
// mojom::SystemTray:
// mojom::SystemTray overrides. Public for testing.
void SetClient(mojom::SystemTrayClientPtr client) override;
void SetUse24HourClock(bool use_24_hour) override;
void ShowUpdateIcon(mojom::UpdateSeverity severity,
bool factory_reset_required) override;
private:
// Client interface in chrome browser. Only bound on Chrome OS.
mojom::SystemTrayClientPtr system_tray_client_;
......
......@@ -17,13 +17,6 @@ BluetoothDeviceInfo::BluetoothDeviceInfo(const BluetoothDeviceInfo& other) =
BluetoothDeviceInfo::~BluetoothDeviceInfo() {}
UpdateInfo::UpdateInfo()
: severity(UPDATE_NONE),
update_required(false),
factory_reset_required(false) {}
UpdateInfo::~UpdateInfo() {}
SystemTrayDelegate::SystemTrayDelegate() {}
SystemTrayDelegate::~SystemTrayDelegate() {}
......@@ -66,12 +59,6 @@ bool SystemTrayDelegate::IsUserChild() const {
return false;
}
void SystemTrayDelegate::GetSystemUpdateInfo(UpdateInfo* info) const {
info->severity = UpdateInfo::UPDATE_NONE;
info->update_required = false;
info->factory_reset_required = false;
}
bool SystemTrayDelegate::ShouldShowSettings() const {
return false;
}
......
......@@ -51,24 +51,6 @@ struct ASH_EXPORT BluetoothDeviceInfo {
using BluetoothDeviceList = std::vector<BluetoothDeviceInfo>;
struct ASH_EXPORT UpdateInfo {
enum UpdateSeverity {
UPDATE_NONE,
UPDATE_LOW,
UPDATE_ELEVATED,
UPDATE_HIGH,
UPDATE_SEVERE,
UPDATE_CRITICAL,
};
UpdateInfo();
~UpdateInfo();
UpdateSeverity severity;
bool update_required;
bool factory_reset_required;
};
class NetworkingConfigDelegate;
// SystemTrayDelegate is intended for delegating tasks in the System Tray to the
......@@ -123,9 +105,6 @@ class ASH_EXPORT SystemTrayDelegate {
// crbug.com/443119
virtual bool IsUserChild() const;
// Fills |info| structure (which must not be null) with current update info.
virtual void GetSystemUpdateInfo(UpdateInfo* info) const;
// Returns true if settings menu item should appear.
virtual bool ShouldShowSettings() const;
......
......@@ -25,6 +25,10 @@ class SystemTray;
class SystemTrayBubble;
class TrayItemView;
// Controller for an item in the system tray. Each item can create these views:
// Tray view - The icon in the status area in the shelf.
// Default view - The row in the top-level menu.
// Detailed view - The submenu shown when the top-level menu row is clicked.
class ASH_EXPORT SystemTrayItem {
public:
// The different types of SystemTrayItems.
......@@ -87,6 +91,7 @@ class ASH_EXPORT SystemTrayItem {
// Returns a notification view for the item. This view is displayed with
// other notifications and should be the same size as default views.
// DEPRECATED. Use the message center instead.
virtual views::View* CreateNotificationView(LoginStatus status);
// These functions are called when the corresponding view item is about to be
......
......@@ -7,7 +7,6 @@
#include "ash/common/system/accessibility_observer.h"
#include "ash/common/system/date/clock_observer.h"
#include "ash/common/system/ime/ime_observer.h"
#include "ash/common/system/update/update_observer.h"
#include "ash/common/system/user/user_observer.h"
#if defined(OS_CHROMEOS)
......@@ -92,19 +91,6 @@ void SystemTrayNotifier::NotifyRefreshIMEMenu(bool is_active) {
observer.OnIMEMenuActivationChanged(is_active);
}
void SystemTrayNotifier::AddUpdateObserver(UpdateObserver* observer) {
update_observers_.AddObserver(observer);
}
void SystemTrayNotifier::RemoveUpdateObserver(UpdateObserver* observer) {
update_observers_.RemoveObserver(observer);
}
void SystemTrayNotifier::NotifyUpdateRecommended(const UpdateInfo& info) {
for (auto& observer : update_observers_)
observer.OnUpdateRecommended(info);
}
void SystemTrayNotifier::AddUserObserver(UserObserver* observer) {
user_observers_.AddObserver(observer);
}
......
......@@ -22,8 +22,6 @@ namespace ash {
class AccessibilityObserver;
class ClockObserver;
class IMEObserver;
struct UpdateInfo;
class UpdateObserver;
class UserObserver;
#if defined(OS_CHROMEOS)
......@@ -40,6 +38,10 @@ class TracingObserver;
class VirtualKeyboardObserver;
#endif
namespace mojom {
enum class UpdateSeverity;
}
// Observer and notification manager for the ash system tray.
class ASH_EXPORT SystemTrayNotifier {
public:
......@@ -66,11 +68,6 @@ class ASH_EXPORT SystemTrayNotifier {
void NotifyRefreshIME();
void NotifyRefreshIMEMenu(bool is_active);
// OS updates.
void AddUpdateObserver(UpdateObserver* observer);
void RemoveUpdateObserver(UpdateObserver* observer);
void NotifyUpdateRecommended(const UpdateInfo& info);
// User.
void AddUserObserver(UserObserver* observer);
void RemoveUserObserver(UserObserver* observer);
......@@ -147,7 +144,6 @@ class ASH_EXPORT SystemTrayNotifier {
base::ObserverList<AccessibilityObserver> accessibility_observers_;
base::ObserverList<ClockObserver> clock_observers_;
base::ObserverList<IMEObserver> ime_observers_;
base::ObserverList<UpdateObserver> update_observers_;
base::ObserverList<UserObserver> user_observers_;
#if defined(OS_CHROMEOS)
......
......@@ -17,6 +17,7 @@ class ImageView;
namespace ash {
class TrayItemView;
// A system tray item that uses an image as its "tray view" in the status area.
class ASH_EXPORT TrayImageItem : public SystemTrayItem {
public:
TrayImageItem(SystemTray* system_tray, int resource_id, UmaType uma_type);
......@@ -57,6 +58,7 @@ class ASH_EXPORT TrayImageItem : public SystemTrayItem {
// The color of the material design icon in the tray.
SkColor icon_color_;
// The image view in the tray.
TrayItemView* tray_view_;
DISALLOW_COPY_AND_ASSIGN(TrayImageItem);
......
......@@ -10,11 +10,11 @@
#include "ash/common/system/tray/system_tray.h"
#include "ash/common/system/tray/system_tray_controller.h"
#include "ash/common/system/tray/system_tray_delegate.h"
#include "ash/common/system/tray/system_tray_notifier.h"
#include "ash/common/system/tray/tray_constants.h"
#include "ash/common/system/tray/tray_popup_item_style.h"
#include "ash/common/system/tray/tray_popup_utils.h"
#include "ash/common/wm_shell.h"
#include "ash/public/interfaces/update.mojom.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
......@@ -33,22 +33,22 @@ namespace {
// severity.
// TODO(tdanderson): This is only used for non-material design, so remove it
// when material design is the default. See crbug.com/625692.
int DecideResource(UpdateInfo::UpdateSeverity severity, bool dark) {
int DecideResource(mojom::UpdateSeverity severity, bool dark) {
switch (severity) {
case UpdateInfo::UPDATE_NONE:
case UpdateInfo::UPDATE_LOW:
case mojom::UpdateSeverity::NONE:
case mojom::UpdateSeverity::LOW:
return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK : IDR_AURA_UBER_TRAY_UPDATE;
case UpdateInfo::UPDATE_ELEVATED:
case mojom::UpdateSeverity::ELEVATED:
return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_GREEN
: IDR_AURA_UBER_TRAY_UPDATE_GREEN;
case UpdateInfo::UPDATE_HIGH:
case mojom::UpdateSeverity::HIGH:
return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_ORANGE
: IDR_AURA_UBER_TRAY_UPDATE_ORANGE;
case UpdateInfo::UPDATE_SEVERE:
case UpdateInfo::UPDATE_CRITICAL:
case mojom::UpdateSeverity::SEVERE:
case mojom::UpdateSeverity::CRITICAL:
return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_RED
: IDR_AURA_UBER_TRAY_UPDATE_RED;
}
......@@ -60,19 +60,19 @@ int DecideResource(UpdateInfo::UpdateSeverity severity, bool dark) {
// Returns the color to use for the material design update icon when the update
// severity is |severity|. If |for_menu| is true, the icon color for the system
// menu is given, otherwise the icon color for the system tray is given.
SkColor IconColorForUpdateSeverity(UpdateInfo::UpdateSeverity severity,
SkColor IconColorForUpdateSeverity(mojom::UpdateSeverity severity,
bool for_menu) {
const SkColor default_color = for_menu ? kMenuIconColor : kTrayIconColor;
switch (severity) {
case UpdateInfo::UPDATE_NONE:
case mojom::UpdateSeverity::NONE:
return default_color;
case UpdateInfo::UPDATE_LOW:
case mojom::UpdateSeverity::LOW:
return for_menu ? gfx::kGoogleGreen700 : kTrayIconColor;
case UpdateInfo::UPDATE_ELEVATED:
case mojom::UpdateSeverity::ELEVATED:
return for_menu ? gfx::kGoogleYellow700 : gfx::kGoogleYellow300;
case UpdateInfo::UPDATE_HIGH:
case UpdateInfo::UPDATE_SEVERE:
case UpdateInfo::UPDATE_CRITICAL:
case mojom::UpdateSeverity::HIGH:
case mojom::UpdateSeverity::SEVERE:
case mojom::UpdateSeverity::CRITICAL:
return for_menu ? gfx::kGoogleRed700 : gfx::kGoogleRed300;
default:
NOTREACHED();
......@@ -81,9 +81,19 @@ SkColor IconColorForUpdateSeverity(UpdateInfo::UpdateSeverity severity,
return default_color;
}
class UpdateView : public ActionableView {
} // namespace
// static
bool TrayUpdate::update_required_ = false;
// static
mojom::UpdateSeverity TrayUpdate::severity_ = mojom::UpdateSeverity::NONE;
// static
bool TrayUpdate::factory_reset_required_ = false;
// The "restart to update" item in the system tray menu.
class TrayUpdate::UpdateView : public ActionableView {
public:
UpdateView(SystemTrayItem* owner, const UpdateInfo& info)
explicit UpdateView(TrayUpdate* owner)
: ActionableView(owner, TrayPopupInkDropStyle::FILL_BOUNDS),
label_(nullptr) {
SetLayoutManager(new views::FillLayout);
......@@ -95,15 +105,16 @@ class UpdateView : public ActionableView {
if (MaterialDesignController::IsSystemTrayMenuMaterial()) {
image->SetImage(gfx::CreateVectorIcon(
kSystemMenuUpdateIcon,
IconColorForUpdateSeverity(info.severity, true)));
IconColorForUpdateSeverity(owner->severity_, true)));
} else {
image->SetImage(bundle.GetImageNamed(DecideResource(info.severity, true))
image->SetImage(
bundle.GetImageNamed(DecideResource(owner->severity_, true))
.ToImageSkia());
}
tri_view->AddView(TriView::Container::START, image);
base::string16 label_text =
info.factory_reset_required
owner->factory_reset_required_
? bundle.GetLocalizedString(
IDS_ASH_STATUS_TRAY_RESTART_AND_POWERWASH_TO_UPDATE)
: bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE);
......@@ -149,34 +160,33 @@ class UpdateView : public ActionableView {
DISALLOW_COPY_AND_ASSIGN(UpdateView);
};
} // namespace
TrayUpdate::TrayUpdate(SystemTray* system_tray)
: TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_UPDATE, UMA_UPDATE) {
WmShell::Get()->system_tray_notifier()->AddUpdateObserver(this);
}
: TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_UPDATE, UMA_UPDATE) {}
TrayUpdate::~TrayUpdate() {
WmShell::Get()->system_tray_notifier()->RemoveUpdateObserver(this);
}
TrayUpdate::~TrayUpdate() {}
bool TrayUpdate::GetInitialVisibility() {
UpdateInfo info;
WmShell::Get()->system_tray_delegate()->GetSystemUpdateInfo(&info);
return info.update_required;
// If chrome tells ash there is an update available before this item's system
// tray is constructed then show the icon.
return update_required_;
}
views::View* TrayUpdate::CreateDefaultView(LoginStatus status) {
UpdateInfo info;
WmShell::Get()->system_tray_delegate()->GetSystemUpdateInfo(&info);
return info.update_required ? new UpdateView(this, info) : nullptr;
return update_required_ ? new UpdateView(this) : nullptr;
}
void TrayUpdate::OnUpdateRecommended(const UpdateInfo& info) {
void TrayUpdate::ShowUpdateIcon(mojom::UpdateSeverity severity,
bool factory_reset_required) {
// Cache update info so we can create the default view when the menu opens.
update_required_ = true;
severity_ = severity;
factory_reset_required_ = factory_reset_required;
// Show the icon in the tray.
if (MaterialDesignController::UseMaterialDesignSystemIcons())
SetIconColor(IconColorForUpdateSeverity(info.severity, false));
SetIconColor(IconColorForUpdateSeverity(severity_, false));
else
SetImageFromResourceId(DecideResource(info.severity, false));
SetImageFromResourceId(DecideResource(severity_, false));
tray_view()->SetVisible(true);
}
......
......@@ -7,7 +7,6 @@
#include "ash/ash_export.h"
#include "ash/common/system/tray/tray_image_item.h"
#include "ash/common/system/update/update_observer.h"
#include "base/macros.h"
namespace views {
......@@ -16,19 +15,37 @@ class View;
namespace ash {
// The system update tray item. Exported for test.
class ASH_EXPORT TrayUpdate : public TrayImageItem, public UpdateObserver {
namespace mojom {
enum class UpdateSeverity;
}
// The system update tray item. The tray icon stays visible once an update
// notification is received. The icon only disappears after a reboot to apply
// the update. Exported for test.
class ASH_EXPORT TrayUpdate : public TrayImageItem {
public:
explicit TrayUpdate(SystemTray* system_tray);
~TrayUpdate() override;
// Shows an icon in the system tray indicating that a software update is
// available. Once shown the icon persists until reboot. |severity| and
// |factory_reset_required| are used to set the icon, color, and tooltip.
void ShowUpdateIcon(mojom::UpdateSeverity severity,
bool factory_reset_required);
private:
class UpdateView;
// Overridden from TrayImageItem.
bool GetInitialVisibility() override;
views::View* CreateDefaultView(LoginStatus status) override;
// Overridden from UpdateObserver.
void OnUpdateRecommended(const UpdateInfo& info) override;
// If an external monitor is connected then the system tray may be created
// after the update data is sent from chrome, so share the update info between
// all instances.
static bool update_required_;
static mojom::UpdateSeverity severity_;
static bool factory_reset_required_;
DISALLOW_COPY_AND_ASSIGN(TrayUpdate);
};
......
......@@ -5,10 +5,10 @@
#include "ash/common/system/update/tray_update.h"
#include "ash/common/system/tray/system_tray.h"
#include "ash/common/system/tray/system_tray_delegate.h"
#include "ash/common/system/tray/system_tray_notifier.h"
#include "ash/common/system/tray/system_tray_controller.h"
#include "ash/common/test/ash_test.h"
#include "ash/common/wm_shell.h"
#include "ash/public/interfaces/update.mojom.h"
namespace ash {
......@@ -17,20 +17,14 @@ using TrayUpdateTest = AshTest;
// Tests that the update icon becomes visible when an update becomes
// available.
TEST_F(TrayUpdateTest, VisibilityAfterUpdate) {
TrayUpdate* tray_update = GetPrimarySystemTray()->GetTrayUpdateForTesting();
TrayUpdate* tray_update = GetPrimarySystemTray()->tray_update();
// The system starts with no update pending.
UpdateInfo initial_info;
WmShell::Get()->system_tray_delegate()->GetSystemUpdateInfo(&initial_info);
EXPECT_FALSE(initial_info.update_required);
// When no update is pending, the item isn't visible.
// The system starts with no update pending, so the icon isn't visible.
EXPECT_FALSE(tray_update->tray_view()->visible());
// Simulate an update.
UpdateInfo info;
info.update_required = true;
WmShell::Get()->system_tray_notifier()->NotifyUpdateRecommended(info);
WmShell::Get()->system_tray_controller()->ShowUpdateIcon(
mojom::UpdateSeverity::LOW, false);
// Tray item is now visible.
EXPECT_TRUE(tray_update->tray_view()->visible());
......
// 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_COMMON_SYSTEM_UPDATE_UPDATE_OBSERVER_H_
#define ASH_COMMON_SYSTEM_UPDATE_UPDATE_OBSERVER_H_
#include "ash/ash_export.h"
namespace ash {
struct UpdateInfo;
class ASH_EXPORT UpdateObserver {
public:
virtual ~UpdateObserver() {}
virtual void OnUpdateRecommended(const UpdateInfo& info) = 0;
};
} // namespace ash
#endif // ASH_COMMON_SYSTEM_UPDATE_UPDATE_OBSERVER_H_
......@@ -16,7 +16,6 @@ namespace test {
namespace {
bool g_system_update_required = false;
LoginStatus g_initial_status = LoginStatus::USER;
} // namespace
......@@ -71,13 +70,6 @@ bool TestSystemTrayDelegate::IsUserSupervised() const {
return login_status_ == LoginStatus::SUPERVISED;
}
void TestSystemTrayDelegate::GetSystemUpdateInfo(UpdateInfo* info) const {
DCHECK(info);
info->severity = UpdateInfo::UPDATE_NONE;
info->update_required = g_system_update_required;
info->factory_reset_required = false;
}
bool TestSystemTrayDelegate::GetSessionStartTime(
base::TimeTicks* session_start_time) {
// Just returns TimeTicks::Now(), so the remaining time is always the
......
......@@ -41,7 +41,6 @@ class TestSystemTrayDelegate : public DefaultSystemTrayDelegate {
// Overridden from SystemTrayDelegate:
LoginStatus GetUserLoginStatus() const override;
bool IsUserSupervised() const override;
void GetSystemUpdateInfo(UpdateInfo* info) const override;
bool GetSessionStartTime(base::TimeTicks* session_start_time) override;
bool GetSessionLengthLimit(base::TimeDelta* session_length_limit) override;
void GetCurrentIME(IMEInfo* info) override;
......
......@@ -17,6 +17,7 @@ mojom("interfaces") {
"shutdown.mojom",
"system_tray.mojom",
"touch_view.mojom",
"update.mojom",
"volume.mojom",
"vpn_list.mojom",
"wallpaper.mojom",
......
......@@ -4,6 +4,8 @@
module ash.mojom;
import "ash/public/interfaces/update.mojom";
// Allows clients (e.g. Chrome browser) to control the ash system tray menu.
interface SystemTray {
// Sets the client interface.
......@@ -12,6 +14,11 @@ interface SystemTray {
// Sets the clock to use 24 hour time formatting if |use_24_hour| is true.
// Otherwise sets 12 hour time formatting.
SetUse24HourClock(bool use_24_hour);
// Shows an icon in the system tray indicating that a software update is
// available. Once shown the icon persists until reboot. |severity| and
// |factory_reset_required| are used to set the icon, color, and tooltip.
ShowUpdateIcon(UpdateSeverity severity, bool factory_reset_required);
};
// Allows ash system tray to control a client (e.g. Chrome browser). Requests
......
// Copyright 2016 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.
module ash.mojom;
// Urgency of a pending software update. Sets the system tray update icon color.
// TODO(jamescook): UpgradeDetector::UpgradeNotificationAnnoyanceLevel could be
// replaced with this if this moves into a component shared with non-ash chrome.
enum UpdateSeverity {
NONE,
LOW,
ELEVATED,
HIGH,
SEVERE,
CRITICAL,
};
......@@ -46,7 +46,7 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h"
#include "chrome/browser/ui/ash/system_tray_client.h"
#include "chrome/common/chrome_features.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/dbus_thread_manager.h"
......@@ -91,8 +91,7 @@ void LogRegistrationResult(chromeos::DBusMethodCallStatus call_status,
LOG(ERROR) << "Component flash registration failed";
return;
}
chromeos::SystemTrayDelegateChromeOS* tray =
chromeos::SystemTrayDelegateChromeOS::instance();
chromeos::SystemTrayClient* tray = chromeos::SystemTrayClient::Get();
if (tray) {
tray->SetFlashUpdateAvailable();
}
......
......@@ -1394,8 +1394,6 @@ split_static_library("ui") {
"ash/session_util.h",
"ash/system_tray_delegate_chromeos.cc",
"ash/system_tray_delegate_chromeos.h",
"ash/system_tray_delegate_utils.cc",
"ash/system_tray_delegate_utils.h",
"ash/volume_controller.cc",
"ash/volume_controller.h",
"ash/vpn_list_forwarder.cc",
......
......@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/accessibility/accessibility_util.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
......@@ -26,11 +27,13 @@
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/common/url_constants.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/login/login_state.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/service_manager_connection.h"
#include "extensions/browser/api/vpn_provider/vpn_service.h"
......@@ -59,6 +62,26 @@ void ShowSettingsSubPageForActiveUser(const std::string& sub_page) {
sub_page);
}
// Returns the severity of a pending Chrome / Chrome OS update.
ash::mojom::UpdateSeverity GetUpdateSeverity(UpgradeDetector* detector) {
switch (detector->upgrade_notification_stage()) {
case UpgradeDetector::UPGRADE_ANNOYANCE_NONE:
return ash::mojom::UpdateSeverity::NONE;
case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
return ash::mojom::UpdateSeverity::LOW;
case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
return ash::mojom::UpdateSeverity::ELEVATED;
case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
return ash::mojom::UpdateSeverity::HIGH;
case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
return ash::mojom::UpdateSeverity::SEVERE;
case UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL:
return ash::mojom::UpdateSeverity::CRITICAL;
}
NOTREACHED();
return ash::mojom::UpdateSeverity::CRITICAL;
}
} // namespace
SystemTrayClient::SystemTrayClient() : binding_(this) {
......@@ -72,6 +95,13 @@ SystemTrayClient::SystemTrayClient() : binding_(this) {
// be queued on |system_tray_|.
g_browser_process->platform_part()->GetSystemClock()->AddObserver(this);
registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
content::NotificationService::AllSources());
// If an upgrade is available at startup then tell ash about it.
if (UpgradeDetector::GetInstance()->notify_upgrade())
HandleUpdateAvailable();
DCHECK(!g_instance);
g_instance = this;
}
......@@ -167,6 +197,11 @@ Widget* SystemTrayClient::CreateUnownedDialogWidget(
return widget;
}
void SystemTrayClient::SetFlashUpdateAvailable() {
flash_update_available_ = true;
HandleUpdateAvailable();
}
////////////////////////////////////////////////////////////////////////////////
// ash::mojom::SystemTrayClient:
......@@ -309,19 +344,29 @@ void SystemTrayClient::SignOut() {
}
void SystemTrayClient::RequestRestartForUpdate() {
bool component_update = false;
chromeos::SystemTrayDelegateChromeOS* tray =
chromeos::SystemTrayDelegateChromeOS::instance();
if (tray)
component_update = tray->GetFlashUpdateAvailable();
chrome::RebootPolicy reboot_policy =
component_update ? chrome::RebootPolicy::kForceReboot
// Flash updates on Chrome OS require device reboot.
const chrome::RebootPolicy reboot_policy =
flash_update_available_ ? chrome::RebootPolicy::kForceReboot
: chrome::RebootPolicy::kOptionalReboot;
chrome::NotifyAndTerminate(true /* fast_path */, reboot_policy);
}
void SystemTrayClient::HandleUpdateAvailable() {
// Show an update icon for Chrome updates and Flash component updates.
UpgradeDetector* detector = UpgradeDetector::GetInstance();
DCHECK(detector->notify_upgrade() || flash_update_available_);
// Get the Chrome update severity.
ash::mojom::UpdateSeverity severity = GetUpdateSeverity(detector);
// Flash updates are elevated severity unless the Chrome severity is higher.
if (flash_update_available_)
severity = std::max(severity, ash::mojom::UpdateSeverity::ELEVATED);
system_tray_->ShowUpdateIcon(severity, detector->is_factory_reset_required());
}
////////////////////////////////////////////////////////////////////////////////
// chromeos::system::SystemClockObserver:
......@@ -329,3 +374,10 @@ void SystemTrayClient::OnSystemClockChanged(
chromeos::system::SystemClock* clock) {
system_tray_->SetUse24HourClock(clock->ShouldUse24HourClock());
}
void SystemTrayClient::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
HandleUpdateAvailable();
}
......@@ -8,6 +8,8 @@
#include "ash/public/interfaces/system_tray.mojom.h"
#include "base/macros.h"
#include "chrome/browser/chromeos/system/system_clock_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace ash {
......@@ -23,7 +25,8 @@ class WidgetDelegate;
// relevant state changes in chrome.
// TODO: Consider renaming this to SystemTrayClientChromeOS.
class SystemTrayClient : public ash::mojom::SystemTrayClient,
public chromeos::system::SystemClockObserver {
public chromeos::system::SystemClockObserver,
public content::NotificationObserver {
public:
SystemTrayClient();
~SystemTrayClient() override;
......@@ -43,6 +46,10 @@ class SystemTrayClient : public ash::mojom::SystemTrayClient,
static views::Widget* CreateUnownedDialogWidget(
views::WidgetDelegate* widget_delegate);
// Shows an update icon for an Adobe Flash update and forces a device reboot
// when the update is applied.
void SetFlashUpdateAvailable();
// ash::mojom::SystemTrayClient:
void ShowSettings() override;
void ShowDateSettings() override;
......@@ -66,15 +73,28 @@ class SystemTrayClient : public ash::mojom::SystemTrayClient,
void RequestRestartForUpdate() override;
private:
// Requests that ash show the update available icon.
void HandleUpdateAvailable();
// chromeos::system::SystemClockObserver:
void OnSystemClockChanged(chromeos::system::SystemClock* clock) override;
// content::NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// System tray mojo service in ash.
ash::mojom::SystemTrayPtr system_tray_;
// Binds this object to the client interface.
mojo::Binding<ash::mojom::SystemTrayClient> binding_;
// Whether an Adobe Flash component update is available.
bool flash_update_available_ = false;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(SystemTrayClient);
};
......
// Copyright 2016 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 "chrome/browser/ui/ash/system_tray_client.h"
#include "ash/common/system/tray/system_tray.h"
#include "ash/common/system/update/tray_update.h"
#include "ash/common/wm_root_window_controller.h"
#include "ash/common/wm_shell.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/test_utils.h"
ash::TrayUpdate* GetTrayUpdate() {
return ash::WmShell::Get()
->GetPrimaryRootWindowController()
->GetSystemTray()
->tray_update();
}
using SystemTrayClientTest = InProcessBrowserTest;
// Test that a chrome update shows the update icon in the system menu.
IN_PROC_BROWSER_TEST_F(SystemTrayClientTest, UpdateTrayIcon) {
ash::TrayUpdate* tray_update = GetTrayUpdate();
// When no update is pending, the icon isn't visible.
EXPECT_FALSE(tray_update->tray_view()->visible());
// Simulate an upgrade. This sends a mojo message to ash.
UpgradeDetector::GetInstance()->NotifyUpgradeRecommended();
content::RunAllPendingInMessageLoop();
// Tray icon is now visible.
EXPECT_TRUE(tray_update->tray_view()->visible());
}
// Test that a flash update causes the update UI to show in the system menu.
IN_PROC_BROWSER_TEST_F(SystemTrayClientTest, FlashUpdateTrayIcon) {
ash::TrayUpdate* tray_update = GetTrayUpdate();
// When no update is pending, the icon isn't visible.
EXPECT_FALSE(tray_update->tray_view()->visible());
// Simulate a Flash update. This sends a mojo message to ash.
SystemTrayClient::Get()->SetFlashUpdateAvailable();
content::RunAllPendingInMessageLoop();
// Tray icon is now visible.
EXPECT_TRUE(tray_update->tray_view()->visible());
}
......@@ -24,7 +24,6 @@
#include "ash/common/system/ime/ime_observer.h"
#include "ash/common/system/tray/system_tray_notifier.h"
#include "ash/common/system/tray_accessibility.h"
#include "ash/common/system/update/update_observer.h"
#include "ash/common/system/user/user_observer.h"
#include "ash/common/wm_shell.h"
#include "ash/system/chromeos/rotation/tray_rotation_lock.h"
......@@ -58,13 +57,11 @@
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/networking_config_delegate_chromeos.h"
#include "chrome/browser/ui/ash/system_tray_client.h"
#include "chrome/browser/ui/ash/system_tray_delegate_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/features.h"
#include "chrome/common/pref_names.h"
......@@ -109,9 +106,6 @@ const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
// The maximum session length limit that can be set.
const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
// A pointer so that callers can access the single class instance.
SystemTrayDelegateChromeOS* g_instance = nullptr;
void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime,
const input_method::InputMethodUtil& util,
ash::IMEInfo* info) {
......@@ -150,9 +144,6 @@ SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
// Register notifications on construction so that events such as
// PROFILE_CREATED do not get missed if they happen before Initialize().
registrar_.reset(new content::NotificationRegistrar);
registrar_->Add(this,
chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
content::NotificationService::AllSources());
registrar_->Add(this,
chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
content::NotificationService::AllSources());
......@@ -175,14 +166,6 @@ SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
base::Unretained(this)));
user_manager::UserManager::Get()->AddSessionStateObserver(this);
DCHECK(!g_instance);
g_instance = this;
}
// static
SystemTrayDelegateChromeOS* SystemTrayDelegateChromeOS::instance() {
return g_instance;
}
void SystemTrayDelegateChromeOS::Initialize() {
......@@ -232,9 +215,6 @@ void SystemTrayDelegateChromeOS::InitializeOnAdapterReady(
}
SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() {
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
// Unregister PrefChangeRegistrars.
local_state_registrar_.reset();
user_pref_registrar_.reset();
......@@ -325,15 +305,6 @@ bool SystemTrayDelegateChromeOS::IsUserChild() const {
return user_manager::UserManager::Get()->IsLoggedInAsChildUser();
}
void SystemTrayDelegateChromeOS::GetSystemUpdateInfo(
ash::UpdateInfo* info) const {
GetUpdateInfo(UpgradeDetector::GetInstance(), info);
// If a flash component update is available, force the tray to show the user
// the Restart to Update dialog.
if (flash_update_available_)
info->update_required = true;
}
bool SystemTrayDelegateChromeOS::ShouldShowSettings() const {
// Show setting button only when the user flow allows and it's not in the
// multi-profile login screen.
......@@ -624,18 +595,6 @@ void SystemTrayDelegateChromeOS::UserChangedChildStatus(
ash::WmShell::Get()->UpdateAfterLoginStatusChange(GetUserLoginStatus());
}
void SystemTrayDelegateChromeOS::SetFlashUpdateAvailable() {
flash_update_available_ = true;
ash::UpdateInfo info;
GetSystemUpdateInfo(&info);
GetSystemTrayNotifier()->NotifyUpdateRecommended(info);
}
bool SystemTrayDelegateChromeOS::GetFlashUpdateAvailable() {
return flash_update_available_;
}
ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() {
return ash::WmShell::Get()->system_tray_notifier();
}
......@@ -803,12 +762,6 @@ void SystemTrayDelegateChromeOS::Observe(
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
ash::UpdateInfo info;
GetUpdateInfo(content::Source<UpgradeDetector>(source).ptr(), &info);
GetSystemTrayNotifier()->NotifyUpdateRecommended(info);
break;
}
case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
// This notification is also sent on login screen when user avatar
// is loaded from file.
......
......@@ -70,10 +70,6 @@ class SystemTrayDelegateChromeOS
~SystemTrayDelegateChromeOS() override;
// Access a global pointer to the single instance of the
// SystemTrayDelegateChromeOS class.
static SystemTrayDelegateChromeOS* instance();
void InitializeOnAdapterReady(
scoped_refptr<device::BluetoothAdapter> adapter);
......@@ -88,7 +84,6 @@ class SystemTrayDelegateChromeOS
base::string16 GetSupervisedUserMessage() const override;
bool IsUserSupervised() const override;
bool IsUserChild() const override;
void GetSystemUpdateInfo(ash::UpdateInfo* info) const override;
bool ShouldShowSettings() const override;
bool ShouldShowNotificationTray() const override;
void ShowEnterpriseInfo() override;
......@@ -127,11 +122,6 @@ class SystemTrayDelegateChromeOS
void UserChangedChildStatus(user_manager::User* user) override;
// This notifies the system that a flash update is now available, and so the
// user should reboot.
void SetFlashUpdateAvailable();
bool GetFlashUpdateAvailable();
private:
ash::SystemTrayNotifier* GetSystemTrayNotifier();
......@@ -244,7 +234,6 @@ class SystemTrayDelegateChromeOS
std::string enterprise_realm_;
bool should_run_bluetooth_discovery_ = false;
bool session_started_ = false;
bool flash_update_available_ = false;
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
std::unique_ptr<device::BluetoothDiscoverySession>
......
......@@ -13,8 +13,6 @@
#include "ash/common/system/date/tray_date.h"
#include "ash/common/system/date/tray_system_info.h"
#include "ash/common/system/tray/system_tray.h"
#include "ash/common/system/update/tray_update.h"
#include "ash/common/wm_shell.h"
#include "ash/shell.h"
#include "base/macros.h"
#include "chrome/browser/chromeos/login/login_manager_test.h"
......@@ -131,29 +129,4 @@ IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest,
EXPECT_EQ(base::k24HourClock, GetHourType());
}
// Test that a flash update causes the update UI to show in the system menu.
IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest,
TestFlashUpdateTrayIcon) {
ash::TrayUpdate* tray_update = ash::Shell::GetInstance()
->GetPrimarySystemTray()
->GetTrayUpdateForTesting();
ash::UpdateInfo initial_info;
ash::WmShell::Get()->system_tray_delegate()->GetSystemUpdateInfo(
&initial_info);
EXPECT_FALSE(initial_info.update_required);
// When no update is pending, the item isn't visible.
EXPECT_FALSE(tray_update->tray_view()->visible());
chromeos::SystemTrayDelegateChromeOS::instance()->SetFlashUpdateAvailable();
ash::UpdateInfo post_info;
ash::WmShell::Get()->system_tray_delegate()->GetSystemUpdateInfo(&post_info);
EXPECT_TRUE(post_info.update_required);
// Tray item is now visible.
EXPECT_TRUE(tray_update->tray_view()->visible());
}
} // namespace chromeos
// Copyright 2014 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 "chrome/browser/ui/ash/system_tray_delegate_utils.h"
#include "ash/common/system/tray/system_tray_delegate.h"
#include "base/logging.h"
#include "chrome/browser/upgrade_detector.h"
void GetUpdateInfo(const UpgradeDetector* detector, ash::UpdateInfo* info) {
DCHECK(detector);
DCHECK(info);
switch (detector->upgrade_notification_stage()) {
case UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL:
info->severity = ash::UpdateInfo::UPDATE_CRITICAL;
break;
case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
info->severity = ash::UpdateInfo::UPDATE_SEVERE;
break;
case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
info->severity = ash::UpdateInfo::UPDATE_HIGH;
break;
case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
info->severity = ash::UpdateInfo::UPDATE_ELEVATED;
break;
case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
info->severity = ash::UpdateInfo::UPDATE_LOW;
break;
case UpgradeDetector::UPGRADE_ANNOYANCE_NONE:
info->severity = ash::UpdateInfo::UPDATE_NONE;
break;
}
info->update_required = detector->notify_upgrade();
info->factory_reset_required = detector->is_factory_reset_required();
}
// Copyright 2014 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 CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_UTILS_H_
#define CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_UTILS_H_
class UpgradeDetector;
namespace ash {
struct UpdateInfo;
}
// Fills |info| structure with data from |detector|.
void GetUpdateInfo(const UpgradeDetector* detector, ash::UpdateInfo* info);
#endif // CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_UTILS_H_
......@@ -135,6 +135,7 @@ class UpgradeDetector {
private:
FRIEND_TEST_ALL_PREFIXES(AppMenuModelTest, Basics);
FRIEND_TEST_ALL_PREFIXES(SystemTrayClientTest, UpdateTrayIcon);
// Initiates an Idle check. See IdleCallback below.
void CheckIdle();
......
......@@ -2090,6 +2090,7 @@ test("browser_tests") {
"../browser/ui/ash/multi_user/multi_user_window_manager_test.h",
"../browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc",
"../browser/ui/ash/shelf_browsertest.cc",
"../browser/ui/ash/system_tray_client_browsertest.cc",
"../browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc",
"../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc",
"../browser/ui/ash/volume_controller_browsertest.cc",
......
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