summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-02 18:30:50 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-02 18:30:50 +0000
commitf7f06ea18c6c20546b6dbcebd0b1cc4527b057c5 (patch)
tree1700be50abbbc6f32f29e8eb12edcdc251ef8d38 /ash
parent958068f9967b2b1a715030755ac175f467acea37 (diff)
downloadchromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.zip
chromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.tar.gz
chromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.tar.bz2
ash uber tray: Add entry for power and date.
BUG=110130 TEST=none Review URL: https://chromiumcodereview.appspot.com/9562008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124690 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/ash.gyp5
-rw-r--r--ash/shell.cc5
-rw-r--r--ash/shell.h7
-rw-r--r--ash/system/power/power_status_controller.h21
-rw-r--r--ash/system/power/power_supply_status.cc44
-rw-r--r--ash/system/power/power_supply_status.h33
-rw-r--r--ash/system/power/tray_power_date.cc296
-rw-r--r--ash/system/power/tray_power_date.h51
-rw-r--r--ash/system/tray/system_tray.cc6
9 files changed, 465 insertions, 3 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index a0116b6..7a7402b 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -111,6 +111,11 @@
'system/brightness/brightness_control_delegate.h',
'system/brightness/tray_brightness.cc',
'system/brightness/tray_brightness.h',
+ 'system/power/power_status_controller.h',
+ 'system/power/power_supply_status.cc',
+ 'system/power/power_supply_status.h',
+ 'system/power/tray_power_date.cc',
+ 'system/power/tray_power_date.h',
'system/settings/tray_settings.cc',
'system/settings/tray_settings.h',
'system/tray/system_tray.cc',
diff --git a/ash/shell.cc b/ash/shell.cc
index 651068f..519c9ee 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -18,6 +18,8 @@
#include "ash/system/audio/tray_volume.h"
#include "ash/system/brightness/tray_brightness.h"
#include "ash/system/settings/tray_settings.h"
+#include "ash/system/power/power_status_controller.h"
+#include "ash/system/power/tray_power_date.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray_user.h"
@@ -427,10 +429,13 @@ void Shell::Init() {
internal::TrayVolume* tray_volume = new internal::TrayVolume();
internal::TrayBrightness* tray_brightness = new internal::TrayBrightness();
+ internal::TrayPowerDate* tray_power_date = new internal::TrayPowerDate();
audio_controller_ = tray_volume;
brightness_controller_ = tray_brightness;
+ power_status_controller_ = tray_power_date;
tray_->AddTrayItem(new internal::TrayUser());
+ tray_->AddTrayItem(tray_power_date);
tray_->AddTrayItem(tray_volume);
tray_->AddTrayItem(tray_brightness);
tray_->AddTrayItem(new internal::TraySettings());
diff --git a/ash/shell.h b/ash/shell.h
index 40d5e20..1ef873cd 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -43,6 +43,7 @@ class BrightnessController;
class Launcher;
class NestedDispatcherController;
class PowerButtonController;
+class PowerStatusController;
class ShellDelegate;
class SystemTrayDelegate;
class SystemTray;
@@ -198,6 +199,9 @@ class ASH_EXPORT Shell {
BrightnessController* brightness_controller() const {
return brightness_controller_;
}
+ PowerStatusController* power_status_controller() const {
+ return power_status_controller_;
+ }
ShellDelegate* delegate() { return delegate_.get(); }
SystemTrayDelegate* tray_delegate() { return tray_delegate_.get(); }
@@ -284,9 +288,10 @@ class ASH_EXPORT Shell {
scoped_ptr<WindowCycleController> window_cycle_controller_;
scoped_ptr<internal::FocusCycler> focus_cycler_;
- // The audio and brightness controllers are not owner by the shell.
+ // These controllers are not owned by the shell.
AudioController* audio_controller_;
BrightnessController* brightness_controller_;
+ PowerStatusController* power_status_controller_;
// An event filter that pre-handles all key events to send them to an IME.
scoped_ptr<internal::InputMethodEventFilter> input_method_filter_;
diff --git a/ash/system/power/power_status_controller.h b/ash/system/power/power_status_controller.h
new file mode 100644
index 0000000..877349c
--- /dev/null
+++ b/ash/system/power/power_status_controller.h
@@ -0,0 +1,21 @@
+// 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_POWER_POWER_STATUS_CONTROLLER_H_
+#define ASH_SYSTEM_POWER_POWER_STATUS_CONTROLLER_H_
+
+namespace ash {
+
+struct PowerSupplyStatus;
+
+class PowerStatusController {
+ public:
+ virtual ~PowerStatusController() {}
+
+ virtual void OnPowerStatusChanged(const PowerSupplyStatus& status) = 0;
+};
+
+};
+
+#endif // ASH_SYSTEM_POWER_POWER_STATUS_CONTROLLER_H_
diff --git a/ash/system/power/power_supply_status.cc b/ash/system/power/power_supply_status.cc
new file mode 100644
index 0000000..d1ad5dc
--- /dev/null
+++ b/ash/system/power/power_supply_status.cc
@@ -0,0 +1,44 @@
+// 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/power/power_supply_status.h"
+
+#include "base/format_macros.h"
+#include "base/stringprintf.h"
+
+namespace ash {
+
+PowerSupplyStatus::PowerSupplyStatus()
+ : line_power_on(false),
+ battery_is_present(false),
+ battery_is_full(false),
+ battery_seconds_to_empty(0),
+ battery_seconds_to_full(0),
+ battery_percentage(0) {
+}
+
+std::string PowerSupplyStatus::ToString() const {
+ std::string result;
+ base::StringAppendF(&result,
+ "line_power_on = %s ",
+ line_power_on ? "true" : "false");
+ base::StringAppendF(&result,
+ "battery_is_present = %s ",
+ battery_is_present ? "true" : "false");
+ base::StringAppendF(&result,
+ "battery_is_full = %s ",
+ battery_is_full ? "true" : "false");
+ base::StringAppendF(&result,
+ "battery_percentage = %f ",
+ battery_percentage);
+ base::StringAppendF(&result,
+ "battery_seconds_to_empty = %"PRId64" ",
+ battery_seconds_to_empty);
+ base::StringAppendF(&result,
+ "battery_seconds_to_full = %"PRId64" ",
+ battery_seconds_to_full);
+ return result;
+}
+
+} // namespace ash
diff --git a/ash/system/power/power_supply_status.h b/ash/system/power/power_supply_status.h
new file mode 100644
index 0000000..c70101b
--- /dev/null
+++ b/ash/system/power/power_supply_status.h
@@ -0,0 +1,33 @@
+// 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_POWER_POWER_SUPPLY_STATUS_H_
+#define ASH_SYSTEM_POWER_POWER_SUPPLY_STATUS_H_
+
+#include <string>
+
+#include "ash/ash_export.h"
+#include "base/basictypes.h"
+
+namespace ash {
+
+struct ASH_EXPORT PowerSupplyStatus {
+ bool line_power_on;
+
+ bool battery_is_present;
+ bool battery_is_full;
+
+ // Time in seconds until the battery is empty or full, 0 for unknown.
+ int64 battery_seconds_to_empty;
+ int64 battery_seconds_to_full;
+
+ double battery_percentage;
+
+ PowerSupplyStatus();
+ std::string ToString() const;
+};
+
+} // namespace ash
+
+#endif // ASH_SYSTEM_POWER_POWER_SUPPLY_STATUS_H_
diff --git a/ash/system/power/tray_power_date.cc b/ash/system/power/tray_power_date.cc
new file mode 100644
index 0000000..15a0a22
--- /dev/null
+++ b/ash/system/power/tray_power_date.cc
@@ -0,0 +1,296 @@
+// 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/power/tray_power_date.h"
+
+#include "ash/shell.h"
+#include "ash/system/power/power_supply_status.h"
+#include "ash/system/tray/system_tray_delegate.h"
+#include "base/i18n/time_formatting.h"
+#include "base/stringprintf.h"
+#include "base/time.h"
+#include "base/timer.h"
+#include "base/utf_string_conversions.h"
+#include "grit/ui_resources.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/size.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/text_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/view.h"
+#include "unicode/datefmt.h"
+#include "unicode/fieldpos.h"
+#include "unicode/fmtable.h"
+
+namespace ash {
+namespace internal {
+
+namespace {
+// Width and height of battery images.
+const int kBatteryImageHeight = 26;
+const int kBatteryImageWidth = 24;
+// Number of different power states.
+const int kNumPowerImages = 20;
+// Amount of slop to add into the timer to make sure we're into the next minute
+// when the timer goes off.
+const int kTimerSlopSeconds = 1;
+
+string16 FormatNicely(const base::Time& time) {
+ icu::UnicodeString date_string;
+
+ scoped_ptr<icu::DateFormat> formatter(
+ icu::DateFormat::createDateInstance(icu::DateFormat::kFull));
+ icu::FieldPosition position;
+ position.setField(UDAT_DAY_OF_WEEK_FIELD);
+ formatter->format(static_cast<UDate>(time.ToDoubleT() * 1000),
+ date_string,
+ position);
+ icu::UnicodeString day = date_string.retainBetween(position.getBeginIndex(),
+ position.getEndIndex());
+
+ date_string.remove();
+ formatter.reset(
+ icu::DateFormat::createDateInstance(icu::DateFormat::kMedium));
+ formatter->format(static_cast<UDate>(time.ToDoubleT() * 1000), date_string);
+
+ date_string += "\n";
+ date_string += day;
+
+ return string16(date_string.getBuffer(),
+ static_cast<size_t>(date_string.length()));
+}
+
+}
+
+namespace tray {
+
+// This view is used for both the tray and the popup.
+class DateView : public views::Label {
+ public:
+ enum TimeType {
+ TIME,
+ DATE
+ };
+
+ DateView(base::HourClockType hour_type, TimeType type)
+ : hour_type_(hour_type),
+ type_(type) {
+ UpdateText();
+ }
+
+ virtual ~DateView() {
+ timer_.Stop();
+ }
+
+ private:
+ void UpdateText() {
+ base::Time now = base::Time::Now();
+ if (type_ == TIME) {
+ SetText(base::TimeFormatTimeOfDayWithHourClockType(now, hour_type_,
+ base::kDropAmPm));
+ } else {
+ SetText(FormatNicely(now));
+ }
+
+ SetTooltipText(base::TimeFormatFriendlyDate(now));
+ SchedulePaint();
+
+ // Try to set the timer to go off at the next change of the minute. We don't
+ // want to have the timer go off more than necessary since that will cause
+ // the CPU to wake up and consume power.
+ base::Time::Exploded exploded;
+ now.LocalExplode(&exploded);
+
+ // Often this will be called at minute boundaries, and we'll actually want
+ // 60 seconds from now.
+ int seconds_left = 60 - exploded.second;
+ if (seconds_left == 0)
+ seconds_left = 60;
+
+ // Make sure that the timer fires on the next minute. Without this, if it is
+ // called just a teeny bit early, then it will skip the next minute.
+ seconds_left += kTimerSlopSeconds;
+
+ timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(seconds_left), this,
+ &DateView::UpdateText);
+ }
+
+ // Overridden from views::View.
+ virtual void OnLocaleChanged() OVERRIDE {
+ UpdateText();
+ }
+
+ base::OneShotTimer<DateView> timer_;
+ base::HourClockType hour_type_;
+ TimeType type_;
+
+ DISALLOW_COPY_AND_ASSIGN(DateView);
+};
+
+// This view is used only for the tray.
+class PowerTrayView : public views::ImageView {
+ public:
+ PowerTrayView() {
+ UpdateImage();
+ }
+
+ virtual ~PowerTrayView() {
+ }
+
+ void UpdatePowerStatus(const PowerSupplyStatus& status) {
+ supply_status_ = status;
+ // Sanitize.
+ if (supply_status_.battery_is_full)
+ supply_status_.battery_percentage = 100.0;
+
+ UpdateImage();
+ }
+
+ private:
+ void UpdateImage() {
+ SkBitmap image;
+ gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+ IDR_AURA_UBER_TRAY_POWER_SMALL);
+
+ int image_index = 0;
+ if (supply_status_.battery_percentage >= 100) {
+ image_index = kNumPowerImages - 1;
+ } else if (!supply_status_.battery_is_present) {
+ image_index = kNumPowerImages;
+ } else {
+ image_index = static_cast<int> (
+ supply_status_.battery_percentage / 100.0 *
+ (kNumPowerImages - 1));
+ image_index =
+ std::max(std::min(image_index, kNumPowerImages - 2), 0);
+ }
+
+ SkIRect region = SkIRect::MakeXYWH(
+ image_index * kBatteryImageWidth,
+ supply_status_.line_power_on ? 0 : kBatteryImageHeight,
+ kBatteryImageWidth, kBatteryImageHeight);
+ all.ToSkBitmap()->extractSubset(&image, region);
+
+ SetImage(image);
+ }
+
+ PowerSupplyStatus supply_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
+};
+
+// This view is used only for the popup.
+class PowerPopupView : public views::Label {
+ public:
+ PowerPopupView() {
+ SetHorizontalAlignment(ALIGN_RIGHT);
+ UpdateText();
+ }
+
+ virtual ~PowerPopupView() {
+ }
+
+ void UpdatePowerStatus(const PowerSupplyStatus& status) {
+ supply_status_ = status;
+ // Sanitize.
+ if (supply_status_.battery_is_full)
+ supply_status_.battery_percentage = 100.0;
+
+ UpdateText();
+ }
+
+ private:
+ void UpdateText() {
+ base::TimeDelta time = base::TimeDelta::FromSeconds(
+ supply_status_.line_power_on ?
+ supply_status_.battery_seconds_to_full :
+ supply_status_.battery_seconds_to_empty);
+ int hour = time.InHours();
+ int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
+ // TODO: Translation
+ SetText(ASCIIToUTF16(base::StringPrintf("Battery: %.0lf%%\n%dh%02dm",
+ supply_status_.battery_percentage,
+ hour, min)));
+ }
+
+ PowerSupplyStatus supply_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerPopupView);
+};
+
+} // namespace tray
+
+TrayPowerDate::TrayPowerDate()
+ : power_(NULL),
+ power_tray_(NULL) {
+}
+
+TrayPowerDate::~TrayPowerDate() {
+}
+
+views::View* TrayPowerDate::CreateTrayView() {
+ date_tray_.reset(new tray::DateView(base::k24HourClock,
+ tray::DateView::TIME));
+ date_tray_->SetFont(date_tray_->font().DeriveFont(-1, gfx::Font::BOLD));
+ date_tray_->SetAutoColorReadabilityEnabled(false);
+ date_tray_->SetEnabledColor(SK_ColorWHITE);
+
+ power_tray_.reset(new tray::PowerTrayView());
+
+ views::View* container = new views::View;
+ container->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kHorizontal, 0, 0, 0));
+ container->AddChildView(power_tray_.get());
+ container->AddChildView(date_tray_.get());
+
+ return container;
+}
+
+views::View* TrayPowerDate::CreateDefaultView() {
+ date_.reset(new tray::DateView(base::k24HourClock,
+ tray::DateView::DATE));
+ power_.reset(new tray::PowerPopupView());
+
+ views::View* container = new views::View;
+ views::BoxLayout* layout = new
+ views::BoxLayout(views::BoxLayout::kHorizontal, 0, 10, 0);
+ layout->set_spread_blank_space(true);
+ container->SetLayoutManager(layout);
+ container->set_background(views::Background::CreateSolidBackground(
+ SkColorSetARGB(255, 240, 240, 240)));
+ container->AddChildView(date_.get());
+ container->AddChildView(power_.get());
+ return container;
+}
+
+views::View* TrayPowerDate::CreateDetailedView() {
+ return NULL;
+}
+
+void TrayPowerDate::DestroyTrayView() {
+ date_tray_.reset();
+ power_tray_.reset();
+}
+
+void TrayPowerDate::DestroyDefaultView() {
+ date_.reset();
+ power_.reset();
+}
+
+void TrayPowerDate::DestroyDetailedView() {
+}
+
+void TrayPowerDate::OnPowerStatusChanged(const PowerSupplyStatus& status) {
+ power_tray_->UpdatePowerStatus(status);
+ if (power_.get())
+ power_->UpdatePowerStatus(status);
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/system/power/tray_power_date.h b/ash/system/power/tray_power_date.h
new file mode 100644
index 0000000..5427149
--- /dev/null
+++ b/ash/system/power/tray_power_date.h
@@ -0,0 +1,51 @@
+// 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_POWER_TRAY_POWER_DATE_H_
+#define ASH_SYSTEM_POWER_TRAY_POWER_DATE_H_
+#pragma once
+
+#include "ash/system/power/power_status_controller.h"
+#include "ash/system/tray/system_tray_item.h"
+
+namespace ash {
+namespace internal {
+
+namespace tray {
+class DateView;
+class PowerPopupView;
+class PowerTrayView;
+}
+
+class TrayPowerDate : public SystemTrayItem,
+ public PowerStatusController {
+ public:
+ TrayPowerDate();
+ virtual ~TrayPowerDate();
+
+ private:
+ // Overridden from SystemTrayItem.
+ virtual views::View* CreateTrayView() OVERRIDE;
+ virtual views::View* CreateDefaultView() OVERRIDE;
+ virtual views::View* CreateDetailedView() OVERRIDE;
+ virtual void DestroyTrayView() OVERRIDE;
+ virtual void DestroyDefaultView() OVERRIDE;
+ virtual void DestroyDetailedView() OVERRIDE;
+
+ // Overridden from PowerStatusController.
+ virtual void OnPowerStatusChanged(const PowerSupplyStatus& status) OVERRIDE;
+
+ scoped_ptr<tray::DateView> date_;
+ scoped_ptr<tray::DateView> date_tray_;
+
+ scoped_ptr<tray::PowerPopupView> power_;
+ scoped_ptr<tray::PowerTrayView> power_tray_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrayPowerDate);
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif // ASH_SYSTEM_POWER_TRAY_POWER_DATE_H_
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index dc4b13f..341dbc6 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -30,7 +30,7 @@ class SystemTrayBubble : public views::BubbleDelegateView {
tray_(tray),
items_(items),
detailed_(detailed) {
- set_margin(1);
+ set_margin(0);
}
virtual ~SystemTrayBubble() {
@@ -77,7 +77,9 @@ SystemTray::SystemTray()
: items_(),
popup_(NULL) {
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
- 5, 10, 3));
+ 5, 0, 3));
+ set_background(views::Background::CreateSolidBackground(
+ SkColorSetARGB(127, 0, 0, 0)));
}
SystemTray::~SystemTray() {