Merge from Chromium at DEPS revision 278205
This commit was generated by merge_to_master.py.
Change-Id: I23f1e7ea8c154ba72e7fb594436216f861f868ab
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index b1b77cc..ed574b2 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -44,6 +44,7 @@
#include "ash/system/web_notification/web_notification_tray.h"
#include "ash/touch/touch_hud_debug.h"
#include "ash/volume_control_delegate.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/partial_screenshot_view.h"
@@ -71,7 +72,6 @@
#include "ui/views/widget/widget.h"
#if defined(OS_CHROMEOS)
-#include "ash/session/session_state_delegate.h"
#include "ash/system/chromeos/keyboard_brightness_controller.h"
#include "base/sys_info.h"
#include "chromeos/ime/ime_keyboard.h"
@@ -596,9 +596,10 @@
// TODO(skuhne): This is only temporary! Remove this!
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAshEnableTouchViewTesting)) {
- Shell* shell = Shell::GetInstance();
- shell->EnableMaximizeModeWindowManager(
- !shell->IsMaximizeModeWindowManagerEnabled());
+ MaximizeModeController* controller = Shell::GetInstance()->
+ maximize_mode_controller();
+ controller->EnableMaximizeModeWindowManager(
+ !controller->IsMaximizeModeWindowManagerEnabled());
return true;
}
return false;
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 51b6324..7fd9049 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -68,7 +68,7 @@
TOUCH_HUD_MODE_CHANGE },
{ true, ui::VKEY_I, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN,
TOUCH_HUD_CLEAR },
- { true, ui::VKEY_9, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+ { true, ui::VKEY_P, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
TOUCH_HUD_PROJECTION_TOGGLE },
// Accessibility: Spoken feedback shortcuts. The first one is to toggle
// spoken feedback on or off. The others are only valid when
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index ad3e9d1..e4a0c1e 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -113,14 +113,21 @@
}
void CursorWindowController::UpdateContainer() {
- display_ = Shell::GetScreen()->GetPrimaryDisplay();
if (is_cursor_compositing_enabled_) {
- SetDisplay(display_);
+ gfx::Screen* screen = Shell::GetScreen();
+ gfx::Display display = screen->GetDisplayNearestPoint(
+ screen->GetCursorScreenPoint());
+ DCHECK(display.is_valid());
+ if (display.is_valid())
+ SetDisplay(display);
} else {
- SetContainer(Shell::GetInstance()->
- display_controller()->
- mirror_window_controller()->
- GetWindow());
+ aura::Window* mirror_window = Shell::GetInstance()->
+ display_controller()->
+ mirror_window_controller()->
+ GetWindow();
+ if (mirror_window)
+ display_ = Shell::GetScreen()->GetPrimaryDisplay();
+ SetContainer(mirror_window);
}
}
@@ -142,7 +149,6 @@
void CursorWindowController::UpdateLocation() {
if (!cursor_window_)
return;
-
gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
if (!is_cursor_compositing_enabled_) {
Shell::GetPrimaryRootWindow()->GetHost()->ConvertPointToHost(&point);
@@ -181,20 +187,20 @@
void CursorWindowController::SetContainer(aura::Window* container) {
if (container_ == container)
return;
-
container_ = container;
if (!container) {
cursor_window_.reset();
return;
}
- if (!cursor_window_) {
- cursor_window_.reset(new aura::Window(delegate_.get()));
- cursor_window_->SetTransparent(true);
- cursor_window_->Init(aura::WINDOW_LAYER_TEXTURED);
- cursor_window_->set_ignore_events(true);
- cursor_window_->set_owned_by_parent(false);
- }
+ // Reusing the window does not work when the display is disconnected.
+ // Just creates a new one instead. crbug.com/384218.
+ cursor_window_.reset(new aura::Window(delegate_.get()));
+ cursor_window_->SetTransparent(true);
+ cursor_window_->Init(aura::WINDOW_LAYER_TEXTURED);
+ cursor_window_->set_ignore_events(true);
+ cursor_window_->set_owned_by_parent(false);
+ UpdateCursorImage();
container->AddChild(cursor_window_.get());
cursor_window_->Show();
diff --git a/ash/display/display_change_observer_chromeos.cc b/ash/display/display_change_observer_chromeos.cc
index 40a1a37..a7bb2e1 100644
--- a/ash/display/display_change_observer_chromeos.cc
+++ b/ash/display/display_change_observer_chromeos.cc
@@ -30,6 +30,13 @@
namespace {
+// The DPI threshold to detect high density screen.
+// Higher DPI than this will use device_scale_factor=2.
+const unsigned int kHighDensityDPIThreshold = 170;
+
+// 1 inch in mm.
+const float kInchInMm = 25.4f;
+
// Display mode list is sorted by (in descending priority):
// * the area in pixels.
// * refresh rate.
@@ -126,8 +133,12 @@
if (!mode_info)
continue;
- float device_scale_factor = ui::GetScaleFactor(
- state.display->physical_size(), mode_info->size());
+ float device_scale_factor = 1.0f;
+ if (!ui::IsDisplaySizeBlackListed(state.display->physical_size()) &&
+ (kInchInMm * mode_info->size().width() /
+ state.display->physical_size().width()) > kHighDensityDPIThreshold) {
+ device_scale_factor = 2.0f;
+ }
gfx::Rect display_bounds(state.display->origin(), mode_info->size());
std::vector<DisplayMode> display_modes = GetDisplayModeList(state);
diff --git a/ash/display/display_configurator_animation.cc b/ash/display/display_configurator_animation.cc
index 7398d27..300556b 100644
--- a/ash/display/display_configurator_animation.cc
+++ b/ash/display/display_configurator_animation.cc
@@ -97,7 +97,8 @@
} // namespace
-DisplayConfiguratorAnimation::DisplayConfiguratorAnimation() {
+DisplayConfiguratorAnimation::DisplayConfiguratorAnimation()
+ : weak_ptr_factory_(this) {
}
DisplayConfiguratorAnimation::~DisplayConfiguratorAnimation() {
@@ -154,7 +155,7 @@
// should be deleted eventually.
CallbackRunningObserver* observer = new CallbackRunningObserver(
base::Bind(&DisplayConfiguratorAnimation::ClearHidingLayers,
- base::Unretained(this)));
+ weak_ptr_factory_.GetWeakPtr()));
// Ensure that layers are not animating.
for (std::map<aura::Window*, ui::Layer*>::iterator it =
diff --git a/ash/display/display_configurator_animation.h b/ash/display/display_configurator_animation.h
index 98b54e5..b0f490a 100644
--- a/ash/display/display_configurator_animation.h
+++ b/ash/display/display_configurator_animation.h
@@ -9,6 +9,7 @@
#include "ash/ash_export.h"
#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/display/chromeos/display_configurator.h"
@@ -55,6 +56,7 @@
std::map<aura::Window*, ui::Layer*> hiding_layers_;
scoped_ptr<base::OneShotTimer<DisplayConfiguratorAnimation> > timer_;
+ base::WeakPtrFactory<DisplayConfiguratorAnimation> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorAnimation);
};
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index 79a5f29..f137277 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -137,6 +137,7 @@
}
aura::Window* GetWindow(AshWindowTreeHost* ash_host) {
+ CHECK(ash_host->AsWindowTreeHost());
return ash_host->AsWindowTreeHost()->window();
}
@@ -232,7 +233,8 @@
: primary_tree_host_for_replace_(NULL),
focus_activation_store_(new FocusActivationStore()),
cursor_window_controller_(new CursorWindowController()),
- mirror_window_controller_(new MirrorWindowController()) {
+ mirror_window_controller_(new MirrorWindowController()),
+ weak_ptr_factory_(this) {
#if defined(OS_CHROMEOS)
if (base::SysInfo::IsRunningOnChromeOS())
limiter_.reset(new DisplayChangeLimiter);
@@ -282,6 +284,7 @@
const gfx::Display& primary_candidate =
GetDisplayManager()->GetPrimaryDisplayCandidate();
primary_display_id = primary_candidate.id();
+ CHECK_NE(gfx::Display::kInvalidDisplayID, primary_display_id);
AddWindowTreeHostForDisplay(primary_candidate, init_params);
}
@@ -313,6 +316,7 @@
// static
int64 DisplayController::GetPrimaryDisplayId() {
+ CHECK_NE(gfx::Display::kInvalidDisplayID, primary_display_id);
return primary_display_id;
}
@@ -322,7 +326,9 @@
aura::Window* DisplayController::GetRootWindowForDisplayId(int64 id) {
DCHECK_EQ(1u, window_tree_hosts_.count(id));
- return GetWindow(window_tree_hosts_[id]);
+ AshWindowTreeHost* host = window_tree_hosts_[id];
+ CHECK(host);
+ return GetWindow(host);
}
void DisplayController::CloseChildWindows() {
@@ -392,8 +398,8 @@
DisplayConfiguratorAnimation* animation =
shell->display_configurator_animation();
animation->StartFadeOutAnimation(
- base::Bind(base::IgnoreResult(&DisplayManager::SetMirrorMode),
- base::Unretained(display_manager),
+ base::Bind(&DisplayController::SetMirrorModeAfterAnimation,
+ weak_ptr_factory_.GetWeakPtr(),
!display_manager->IsMirrored()));
#endif
}
@@ -412,7 +418,7 @@
if (animation) {
animation->StartFadeOutAnimation(base::Bind(
&DisplayController::OnFadeOutForSwapDisplayFinished,
- base::Unretained(this)));
+ weak_ptr_factory_.GetWeakPtr()));
} else {
SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay());
}
@@ -462,8 +468,8 @@
// Swap root windows between current and new primary display.
AshWindowTreeHost* primary_host = window_tree_hosts_[primary_display_id];
- DCHECK(primary_host);
- DCHECK_NE(primary_host, non_primary_host);
+ CHECK(primary_host);
+ CHECK_NE(primary_host, non_primary_host);
window_tree_hosts_[new_primary_display.id()] = primary_host;
GetRootWindowSettings(GetWindow(primary_host))->display_id =
@@ -575,7 +581,7 @@
void DisplayController::OnDisplayRemoved(const gfx::Display& display) {
AshWindowTreeHost* host_to_delete = window_tree_hosts_[display.id()];
- DCHECK(host_to_delete) << display.ToString();
+ CHECK(host_to_delete) << display.ToString();
// Display for root window will be deleted when the Primary RootWindow
// is deleted by the Shell.
@@ -754,6 +760,10 @@
#endif
}
+void DisplayController::SetMirrorModeAfterAnimation(bool mirror) {
+ GetDisplayManager()->SetMirrorMode(mirror);
+}
+
void DisplayController::UpdateHostWindowNames() {
#if defined(USE_X11)
// crbug.com/120229 - set the window title for the primary dislpay
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index dd92ab3..988f138 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -14,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "ui/aura/window.h"
@@ -177,6 +178,8 @@
void OnFadeOutForSwapDisplayFinished();
+ void SetMirrorModeAfterAnimation(bool mirror);
+
void UpdateHostWindowNames();
class DisplayChangeLimiter {
@@ -221,6 +224,8 @@
// changed.
gfx::Point cursor_location_in_native_coords_for_restore_;
+ base::WeakPtrFactory<DisplayController> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(DisplayController);
};
diff --git a/ash/display/resolution_notification_controller_unittest.cc b/ash/display/resolution_notification_controller_unittest.cc
index 4d1eedf..e351c86 100644
--- a/ash/display/resolution_notification_controller_unittest.cc
+++ b/ash/display/resolution_notification_controller_unittest.cc
@@ -123,7 +123,7 @@
}
static bool IsNotificationVisible() {
- return message_center::MessageCenter::Get()->HasNotification(
+ return message_center::MessageCenter::Get()->FindVisibleNotificationById(
ResolutionNotificationController::kNotificationId);
}
diff --git a/ash/display/virtual_keyboard_window_controller_unittest.cc b/ash/display/virtual_keyboard_window_controller_unittest.cc
index fdb01f0..e2538c1 100644
--- a/ash/display/virtual_keyboard_window_controller_unittest.cc
+++ b/ash/display/virtual_keyboard_window_controller_unittest.cc
@@ -10,6 +10,7 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "base/command_line.h"
#include "ui/keyboard/keyboard_switches.h"
#include "ui/keyboard/keyboard_util.h"
@@ -84,9 +85,11 @@
virtual_keyboard_window_controller());
ASSERT_FALSE(keyboard::IsKeyboardEnabled());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(keyboard::IsKeyboardEnabled());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(keyboard::IsKeyboardEnabled());
}
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 34bd1d3..ce4810e 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -81,8 +81,7 @@
gfx::ImageSkiaRep image_rep(gfx::Size(10, 20), 1.0f);
gfx::ImageSkia image_skia(image_rep);
- drag_utils::SetDragImageOnDataObject(
- image_skia, image_skia.size(), gfx::Vector2d(), data);
+ drag_utils::SetDragImageOnDataObject(image_skia, gfx::Vector2d(), data);
}
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
diff --git a/ash/frame/caption_buttons/frame_caption_button.cc b/ash/frame/caption_buttons/frame_caption_button.cc
index c8d71c3..df41fb4 100644
--- a/ash/frame/caption_buttons/frame_caption_button.cc
+++ b/ash/frame/caption_buttons/frame_caption_button.cc
@@ -5,9 +5,11 @@
#include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/compositor/layer.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
+#include "ui/views/widget/widget.h"
namespace ash {
@@ -37,6 +39,10 @@
swap_images_animation_(new gfx::SlideAnimation(this)) {
swap_images_animation_->Reset(1);
+ SetPaintToLayer(true);
+ SetFillsBoundsOpaquely(false);
+ set_layer_owner_delegate(this);
+
// Do not flip the gfx::Canvas passed to the OnPaint() method. The snap left
// and snap right button icons should not be flipped. The other icons are
// horizontally symmetrical.
@@ -174,4 +180,9 @@
paint);
}
+void FrameCaptionButton::OnLayerRecreated(ui::Layer* old_layer,
+ ui::Layer* new_layer) {
+ GetWidget()->UpdateRootLayers();
+}
+
} // namespace ash
diff --git a/ash/frame/caption_buttons/frame_caption_button.h b/ash/frame/caption_buttons/frame_caption_button.h
index 6fd9831..d42d791 100644
--- a/ash/frame/caption_buttons/frame_caption_button.h
+++ b/ash/frame/caption_buttons/frame_caption_button.h
@@ -8,6 +8,7 @@
#include "ash/ash_export.h"
#include "ash/frame/caption_buttons/caption_button_types.h"
#include "base/memory/scoped_ptr.h"
+#include "ui/compositor/layer_owner_delegate.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/custom_button.h"
@@ -19,7 +20,8 @@
// Base class for the window caption buttons (minimize, maximize, restore,
// close).
-class ASH_EXPORT FrameCaptionButton : public views::CustomButton {
+class ASH_EXPORT FrameCaptionButton : public views::CustomButton,
+ public ui::LayerOwnerDelegate {
public:
enum Animate {
ANIMATE_YES,
@@ -72,6 +74,10 @@
const gfx::ImageSkia& to_center,
int alpha);
+ // ui::LayerOwnerDelegate:
+ virtual void OnLayerRecreated(ui::Layer* old_layer,
+ ui::Layer* new_layer) OVERRIDE;
+
// The button's current icon.
CaptionButtonIcon icon_;
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view.cc b/ash/frame/caption_buttons/frame_caption_button_container_view.cc
index 12bbb71..643993e 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view.cc
@@ -5,16 +5,21 @@
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include <cmath>
+#include <map>
#include "ash/ash_switches.h"
#include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/frame/caption_buttons/frame_size_button.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/shell.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "grit/ui_strings.h" // Accessibility names
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/point.h"
@@ -25,6 +30,14 @@
namespace {
+// Visual design parameters for animating the transition to maximize mode.
+// When the size button hides we delay sliding the minimize button into its
+// location. Also used to delay showing the size button so that the minimize
+// button slides out of that position.
+const int kAnimationDelayMs = 100;
+const int kMinimizeSlideDurationMs = 500;
+const int kSizeFadeDurationMs = 250;
+
// Converts |point| from |src| to |dst| and hittests against |dst|.
bool ConvertPointToViewAndHitTest(const views::View* src,
const views::View* dst,
@@ -47,6 +60,10 @@
minimize_button_(NULL),
size_button_(NULL),
close_button_(NULL) {
+ SetPaintToLayer(true);
+ SetFillsBoundsOpaquely(false);
+ set_layer_owner_delegate(this);
+
// Insert the buttons left to right.
minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
minimize_button_->SetAccessibleName(
@@ -57,7 +74,7 @@
size_button_ = new FrameSizeButton(this, frame, this);
size_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
- UpdateSizeButtonVisibility(false);
+ UpdateSizeButtonVisibility();
AddChildView(size_button_);
close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE);
@@ -119,16 +136,48 @@
return HTNOWHERE;
}
-void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility(
- bool force_hidden) {
- // TODO(flackr): Refactor the Maximize Mode notifications. Currently
- // UpdateSizeButtonVisibilty requires a force_hidden parameter. This is
- // because Shell::IsMaximizeWindowManagerEnabled is still false at the
- // time when ShellObserver::OnMaximizeModeStarted is called. This prevents
- // this method from performing that check, and instead relies on the calling
- // code to tell it to force being hidden.
- size_button_->SetVisible(
- !force_hidden && frame_->widget_delegate()->CanMaximize());
+void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility() {
+ bool visible = !Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled() &&
+ frame_->widget_delegate()->CanMaximize();
+
+ // Turning visibility off prevents animations from rendering. Setting the
+ // size button visibility to false will occur after the animation.
+ if (visible) {
+ size_button_->SetVisible(true);
+ // Because we delay calling View::SetVisible(false) until the end of the
+ // animation, if SetVisible(true) is called mid-animation, the View still
+ // believes it is visible and will not update the target layer visibility.
+ size_button_->layer()->SetVisible(true);
+ }
+
+ ui::ScopedLayerAnimationSettings settings(
+ size_button_->layer()->GetAnimator());
+ settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kSizeFadeDurationMs));
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+
+ if (visible) {
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ // Delay fade in so that the minimize button has begun its sliding
+ // animation.
+ size_button_->layer()->GetAnimator()->SchedulePauseForProperties(
+ base::TimeDelta::FromMilliseconds(kAnimationDelayMs),
+ ui::LayerAnimationElement::OPACITY);
+ size_button_->layer()->SetOpacity(1.0f);
+ } else {
+ settings.SetTweenType(gfx::Tween::EASE_IN);
+ // Observer will call size_button_->SetVisible(false) upon completion of
+ // the animation.
+ // TODO(jonross): avoid the delayed SetVisible(false) call by acquring
+ // the size_button's layer before making it invisible. That layer can then
+ // be animated and deleted upon completion of the animation. See
+ // LayerOwner::RecreateLayer
+ settings.AddObserver(this);
+ size_button_->layer()->SetOpacity(0.0f);
+ size_button_->layer()->SetVisible(false);
+ }
}
gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() const {
@@ -142,15 +191,56 @@
}
void FrameCaptionButtonContainerView::Layout() {
- int x = 0;
- for (int i = 0; i < child_count(); ++i) {
+ int x = width();
+ // Offsets the initial position of a child, so that buttons slide into the
+ // place as other buttons are added/removed.
+ int offset_x = 0;
+ for (int i = child_count() - 1; i >= 0; --i) {
views::View* child = child_at(i);
- if (!child->visible())
+ ui::LayerAnimator* child_animator = child->layer()->GetAnimator();
+ bool child_animating = child_animator->is_animating();
+ // The actual property visibility is not being animated, otherwise the
+ // view does not render.
+ bool child_animating_opacity = child_animator->
+ IsAnimatingProperty(ui::LayerAnimationElement::OPACITY);
+ bool child_target_visibility = child->layer()->GetTargetVisibility();
+
+ if (child_animating_opacity) {
+ if (child_target_visibility)
+ offset_x += child->width();
+ else
+ offset_x -= child->width();
+ }
+
+ if (!child->visible() || !child_target_visibility)
continue;
+ scoped_ptr<ui::ScopedLayerAnimationSettings> animation;
gfx::Size size = child->GetPreferredSize();
+ x -= size.width();
+
+ // Animate the button if a previous button is currently animating
+ // its visibility.
+ if (offset_x != 0) {
+ if (!child_animating)
+ child->SetBounds(x + offset_x, 0, size.width(), size.height());
+ if (offset_x < 0) {
+ // Delay sliding to where the previous button was located.
+ child_animator->SchedulePauseForProperties(
+ base::TimeDelta::FromMilliseconds(kAnimationDelayMs),
+ ui::LayerAnimationElement::BOUNDS);
+ }
+
+ ui::ScopedLayerAnimationSettings* settings =
+ new ui::ScopedLayerAnimationSettings(child_animator);
+ settings->SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kMinimizeSlideDurationMs));
+ settings->SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings->SetTweenType(gfx::Tween::EASE_OUT);
+ animation.reset(settings);
+ }
child->SetBounds(x, 0, size.width(), size.height());
- x += size.width();
}
}
@@ -202,7 +292,7 @@
if (sender == minimize_button_) {
frame_->Minimize();
} else if (sender == size_button_) {
- if (frame_->IsFullscreen()) { // Can be clicked in immersive fullscreen.
+ if (frame_->IsFullscreen()) { // Can be clicked in immersive fullscreen.
frame_->SetFullscreen(false);
action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN;
} else if (frame_->IsMaximized()) {
@@ -212,7 +302,7 @@
frame_->Maximize();
action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE;
}
- } else if(sender == close_button_) {
+ } else if (sender == close_button_) {
frame_->Close();
action = ash::UMA_WINDOW_CLOSE_BUTTON_CLICK;
} else {
@@ -289,6 +379,29 @@
}
}
+void FrameCaptionButtonContainerView::OnImplicitAnimationsCompleted() {
+ // If there is another animation in the queue, the reverse animation was
+ // triggered before the completion of animating to invisible. Do not turn off
+ // the visibility so that the next animation may render.
+ if (!size_button_->layer()->GetAnimator()->is_animating() &&
+ !size_button_->layer()->GetTargetVisibility()) {
+ size_button_->SetVisible(false);
+ }
+ // TODO(jonross): currently we need to delay telling the parent about the
+ // size change from visibility. When the size changes this forces a relayout
+ // and we want to animate both the bounds of FrameCaptionButtonContainerView
+ // along with that of its children. However when the parent is currently
+ // having its bounds changed this leads to strange animations where this view
+ // renders outside of its parents. Create a more specific animation where
+ // height and y are immediately fixed, and where we only animate width and x.
+ PreferredSizeChanged();
+}
+
+void FrameCaptionButtonContainerView::OnLayerRecreated(ui::Layer* old_layer,
+ ui::Layer* new_layer) {
+ GetWidget()->UpdateRootLayers();
+}
+
FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds()
: icon_image_id(-1),
inactive_icon_image_id(-1),
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view.h b/ash/frame/caption_buttons/frame_caption_button_container_view.h
index 9e67b93..39191b2 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view.h
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view.h
@@ -5,8 +5,12 @@
#ifndef ASH_FRAME_CAPTION_BUTTONS_FRAME_CAPTION_BUTTON_CONTAINER_VIEW_H_
#define ASH_FRAME_CAPTION_BUTTONS_FRAME_CAPTION_BUTTON_CONTAINER_VIEW_H_
+#include <map>
+
#include "ash/ash_export.h"
#include "ash/frame/caption_buttons/frame_size_button_delegate.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/compositor/layer_owner_delegate.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"
@@ -21,7 +25,9 @@
class ASH_EXPORT FrameCaptionButtonContainerView
: public views::View,
public views::ButtonListener,
- public FrameSizeButtonDelegate {
+ public FrameSizeButtonDelegate,
+ public ui::ImplicitAnimationObserver,
+ public ui::LayerOwnerDelegate {
public:
static const char kViewClassName[];
@@ -86,9 +92,9 @@
int NonClientHitTest(const gfx::Point& point) const;
// Updates the size button's visibility based on whether |frame_| can be
- // maximized and |force_hidden|. A parent view should relayout to reflect the
- // change in visibility.
- void UpdateSizeButtonVisibility(bool force_hidden);
+ // maximized and if maximize mode is enabled. A parent view should relayout
+ // to reflect the change in visibility.
+ void UpdateSizeButtonVisibility();
// views::View:
virtual gfx::Size GetPreferredSize() const OVERRIDE;
@@ -136,6 +142,13 @@
const FrameCaptionButton* to_hover,
const FrameCaptionButton* to_press) OVERRIDE;
+ // ui::ImplicitAnimationObserver:
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
+
+ // ui::LayerOwnerDelegate:
+ virtual void OnLayerRecreated(ui::Layer* old_layer,
+ ui::Layer* new_layer) OVERRIDE;
+
// The widget that the buttons act on.
views::Widget* frame_;
@@ -152,6 +165,6 @@
DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerView);
};
-} // namesapace ash
+} // namespace ash
#endif // ASH_FRAME_CAPTION_BUTTONS_FRAME_CAPTION_BUTTON_CONTAINER_VIEW_H_
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
index acd72c8..30e3317 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -5,8 +5,12 @@
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/caption_buttons/frame_caption_button.h"
+#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "grit/ash_resources.h"
+#include "ui/compositor/layer.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
@@ -108,6 +112,7 @@
FrameCaptionButtonContainerView container1(widget_can_maximize.get(),
FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
SetMockImages(&container1);
+ container1.SetBoundsRect(gfx::Rect(container1.GetPreferredSize()));
container1.Layout();
FrameCaptionButtonContainerView::TestApi t1(&container1);
EXPECT_TRUE(t1.minimize_button()->visible());
@@ -123,6 +128,7 @@
FrameCaptionButtonContainerView container2(widget_cannot_maximize.get(),
FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
SetMockImages(&container2);
+ container2.SetBoundsRect(gfx::Rect(container2.GetPreferredSize()));
container2.Layout();
FrameCaptionButtonContainerView::TestApi t2(&container2);
EXPECT_TRUE(t2.minimize_button()->visible());
@@ -136,6 +142,7 @@
FrameCaptionButtonContainerView container3(widget_cannot_maximize.get(),
FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED);
SetMockImages(&container3);
+ container3.SetBoundsRect(gfx::Rect(container3.GetPreferredSize()));
container3.Layout();
FrameCaptionButtonContainerView::TestApi t3(&container3);
EXPECT_FALSE(t3.minimize_button()->visible());
@@ -145,4 +152,97 @@
&container3, *t3.close_button(), *t3.close_button()));
}
+// Tests that the layout animations trigered by button visibilty result in the
+// correct placement of the buttons.
+TEST_F(FrameCaptionButtonContainerViewTest,
+ TestUpdateSizeButtonVisibilityAnimation) {
+ scoped_ptr<views::Widget> widget_can_maximize(
+ CreateTestWidget(MAXIMIZE_ALLOWED));
+ FrameCaptionButtonContainerView container(widget_can_maximize.get(),
+ FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
+ SetMockImages(&container);
+ container.SetBoundsRect(gfx::Rect(container.GetPreferredSize()));
+ container.Layout();
+
+ FrameCaptionButtonContainerView::TestApi test(&container);
+ gfx::Rect initial_minimize_button_bounds = test.minimize_button()->bounds();
+ gfx::Rect initial_size_button_bounds = test.size_button()->bounds();
+ gfx::Rect initial_close_button_bounds = test.close_button()->bounds();
+ gfx::Rect initial_container_bounds = container.bounds();
+
+ ASSERT_EQ(initial_size_button_bounds.x(),
+ initial_minimize_button_bounds.right());
+ ASSERT_EQ(initial_close_button_bounds.x(),
+ initial_size_button_bounds.right());
+
+ // Hidden size button should result in minimize button animating to the
+ // right. The size button should not be visible, but should not have moved.
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
+ container.UpdateSizeButtonVisibility();
+ container.Layout();
+
+ EXPECT_TRUE(test.minimize_button()->visible());
+ EXPECT_FALSE(test.size_button()->visible());
+ EXPECT_TRUE(test.close_button()->visible());
+ gfx::Rect minimize_button_bounds = test.minimize_button()->bounds();
+ gfx::Rect close_button_bounds = test.close_button()->bounds();
+ EXPECT_EQ(close_button_bounds.x(), minimize_button_bounds.right());
+ EXPECT_EQ(initial_size_button_bounds, test.size_button()->bounds());
+ EXPECT_EQ(initial_close_button_bounds, close_button_bounds);
+ EXPECT_LT(container.GetPreferredSize().width(),
+ initial_container_bounds.width());
+
+ // Revealing the size button should cause the minimze button to return to its
+ // original position.
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
+ container.UpdateSizeButtonVisibility();
+ container.Layout();
+ EXPECT_TRUE(test.minimize_button()->visible());
+ EXPECT_TRUE(test.size_button()->visible());
+ EXPECT_TRUE(test.close_button()->visible());
+ EXPECT_EQ(initial_minimize_button_bounds, test.minimize_button()->bounds());
+ EXPECT_EQ(initial_size_button_bounds, test.size_button()->bounds());
+ EXPECT_EQ(initial_close_button_bounds, test.close_button()->bounds());
+ EXPECT_EQ(container.GetPreferredSize().width(),
+ initial_container_bounds.width());
+}
+
+// Tests that after an animation to maximized state, that the layer tree has
+// been updated to reflect the swapped layers.
+TEST_F(FrameCaptionButtonContainerViewTest, AnimationUpdatesLayerTree) {
+ scoped_ptr<views::Widget> widget_can_maximize(
+ CreateTestWidget(MAXIMIZE_ALLOWED));
+ FrameCaptionButtonContainerView container(widget_can_maximize.get(),
+ FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
+ SetMockImages(&container);
+ container.SetBoundsRect(gfx::Rect(container.GetPreferredSize()));
+ container.Layout();
+ ui::Layer* original_layer = container.layer();
+
+ // The container must be a child of the window to be affected by the
+ // animation.
+ widget_can_maximize->non_client_view()->AddChildView(&container);
+ widget_can_maximize->Show();
+ // The original cache of the layer tree must be created before the animation
+ widget_can_maximize->UpdateRootLayers();
+ widget_can_maximize->GetRootLayers();
+
+ // After the maximizing animation has completed, |original_layer| will have
+ // been deleted. Dereferencing it could cause a segfault.
+ widget_can_maximize->Maximize();
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(widget_can_maximize->IsMaximized());
+
+ std::vector<ui::Layer*> layers = widget_can_maximize->GetRootLayers();
+
+ EXPECT_GT(layers.size(), 0u);
+ EXPECT_NE(layers.end(),
+ std::find(layers.begin(), layers.end(), container.layer()));
+ EXPECT_EQ(layers.end(),
+ std::find(layers.begin(), layers.end(), original_layer));
+ EXPECT_NE(original_layer, container.layer());
+}
+
} // namespace ash
diff --git a/ash/frame/custom_frame_view_ash.cc b/ash/frame/custom_frame_view_ash.cc
index 85722ff..508f830 100644
--- a/ash/frame/custom_frame_view_ash.cc
+++ b/ash/frame/custom_frame_view_ash.cc
@@ -4,6 +4,9 @@
#include "ash/frame/custom_frame_view_ash.h"
+#include <algorithm>
+#include <vector>
+
#include "ash/ash_switches.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/default_header_painter.h"
@@ -150,6 +153,7 @@
// views::View:
virtual void Layout() OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+ virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
// ShellObserver:
virtual void OnMaximizeModeStarted() OVERRIDE;
@@ -203,8 +207,7 @@
FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED;
caption_button_container_ = new FrameCaptionButtonContainerView(frame_,
minimize_allowed);
- caption_button_container_->UpdateSizeButtonVisibility(Shell::GetInstance()->
- IsMaximizeModeWindowManagerEnabled());
+ caption_button_container_->UpdateSizeButtonVisibility();
AddChildView(caption_button_container_);
header_painter_->Init(frame_, this, NULL, caption_button_container_);
@@ -285,16 +288,27 @@
header_painter_->PaintHeader(canvas, header_mode);
}
+void CustomFrameViewAsh::HeaderView::
+ ChildPreferredSizeChanged(views::View* child) {
+ // FrameCaptionButtonContainerView animates the visibility changes in
+ // UpdateSizeButtonVisibility(false). Due to this a new size is not available
+ // until the completion of the animation. Layout it response to the preferred
+ // size changes.
+ if (child != caption_button_container_)
+ return;
+ parent()->Layout();
+}
+
///////////////////////////////////////////////////////////////////////////////
// CustomFrameViewAsh::HeaderView, ShellObserver overrides:
void CustomFrameViewAsh::HeaderView::OnMaximizeModeStarted() {
- caption_button_container_->UpdateSizeButtonVisibility(true);
+ caption_button_container_->UpdateSizeButtonVisibility();
parent()->Layout();
}
void CustomFrameViewAsh::HeaderView::OnMaximizeModeEnded() {
- caption_button_container_->UpdateSizeButtonVisibility(false);
+ caption_button_container_->UpdateSizeButtonVisibility();
parent()->Layout();
}
diff --git a/ash/frame/custom_frame_view_ash_unittest.cc b/ash/frame/custom_frame_view_ash_unittest.cc
index 527080e..5e20247 100644
--- a/ash/frame/custom_frame_view_ash_unittest.cc
+++ b/ash/frame/custom_frame_view_ash_unittest.cc
@@ -9,6 +9,7 @@
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_session_state_delegate.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "base/memory/scoped_ptr.h"
#include "grit/ash_resources.h"
#include "ui/base/resource/resource_bundle.h"
@@ -209,11 +210,13 @@
const gfx::Rect initial = delegate->
GetFrameCaptionButtonContainerViewBounds();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
const gfx::Rect maximize_mode_bounds = delegate->
GetFrameCaptionButtonContainerViewBounds();
EXPECT_GT(initial.width(), maximize_mode_bounds.width());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
const gfx::Rect after_restore = delegate->
GetFrameCaptionButtonContainerViewBounds();
EXPECT_EQ(initial, after_restore);
diff --git a/ash/frame/default_header_painter.cc b/ash/frame/default_header_painter.cc
index fd31d77..e8a46ef 100644
--- a/ash/frame/default_header_painter.cc
+++ b/ash/frame/default_header_painter.cc
@@ -200,8 +200,6 @@
}
void DefaultHeaderPainter::LayoutHeader() {
- caption_button_container_->Layout();
-
gfx::Size caption_button_container_size =
caption_button_container_->GetPreferredSize();
caption_button_container_->SetBounds(
@@ -209,7 +207,7 @@
0,
caption_button_container_size.width(),
caption_button_container_size.height());
-
+ caption_button_container_->Layout();
if (window_icon_) {
// Vertically center the window icon with respect to the caption button
// container.
diff --git a/ash/ime/infolist_window.cc b/ash/ime/infolist_window.cc
index 429cca5..d29ed2a 100644
--- a/ash/ime/infolist_window.cc
+++ b/ash/ime/infolist_window.cc
@@ -172,6 +172,8 @@
title_font_list_(gfx::Font(kJapaneseFontName, kFontSizeDelta + 15)),
description_font_list_(gfx::Font(kJapaneseFontName,
kFontSizeDelta + 11)) {
+ set_use_focusless(true);
+ set_accept_events(false);
set_margins(gfx::Insets());
set_background(
diff --git a/ash/keyboard_overlay/keyboard_overlay_delegate.cc b/ash/keyboard_overlay/keyboard_overlay_delegate.cc
index 266319a..877fe2a 100644
--- a/ash/keyboard_overlay/keyboard_overlay_delegate.cc
+++ b/ash/keyboard_overlay/keyboard_overlay_delegate.cc
@@ -50,7 +50,7 @@
void PaintMessageHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"didPaint",
- base::Bind(&PaintMessageHandler::DidPaint, base::Unretained(this)));
+ base::Bind(&PaintMessageHandler::DidPaint, AsWeakPtr()));
}
void PaintMessageHandler::DidPaint(const base::ListValue* args) {
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc
index 2ab9380..3775745 100644
--- a/ash/metrics/user_metrics_recorder.cc
+++ b/ash/metrics/user_metrics_recorder.cc
@@ -368,9 +368,13 @@
base::RecordAction(
base::UserMetricsAction("WindowSelector_Overview"));
break;
- case ash::UMA_WINDOW_SELECTION:
+ case ash::UMA_WINDOW_OVERVIEW_ENTER_KEY:
base::RecordAction(
- base::UserMetricsAction("WindowSelector_Selection"));
+ base::UserMetricsAction("WindowSelector_OverviewEnterKey"));
+ break;
+ case ash::UMA_WINDOW_CYCLE:
+ base::RecordAction(
+ base::UserMetricsAction("WindowCycleController_Cycle"));
break;
}
}
@@ -401,7 +405,7 @@
ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW;
wm::WindowState* active_window_state = ash::wm::GetActiveWindowState();
if (active_window_state) {
- switch(active_window_state->GetStateType()) {
+ switch (active_window_state->GetStateType()) {
case wm::WINDOW_STATE_TYPE_MAXIMIZED:
active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED;
break;
diff --git a/ash/metrics/user_metrics_recorder.h b/ash/metrics/user_metrics_recorder.h
index 98eb652..11d274a 100644
--- a/ash/metrics/user_metrics_recorder.h
+++ b/ash/metrics/user_metrics_recorder.h
@@ -100,14 +100,15 @@
UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT,
UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT,
- // Thumbnail sized overview of windows triggered. This is a subset of
- // UMA_WINDOW_SELECTION triggered by lingering during alt+tab cycles or
- // pressing the overview key.
+ // Thumbnail sized overview of windows triggered by pressing the overview key.
UMA_WINDOW_OVERVIEW,
- // Window selection started by beginning an alt+tab cycle or pressing the
- // overview key. This does not count each step through an alt+tab cycle.
- UMA_WINDOW_SELECTION,
+ // Selecting a window in overview mode by pressing the enter key.
+ UMA_WINDOW_OVERVIEW_ENTER_KEY,
+
+ // Window selection started by beginning an alt+tab cycle. This does not count
+ // each step through an alt+tab cycle.
+ UMA_WINDOW_CYCLE,
};
// User Metrics Recorder provides a repeating callback (RecordPeriodicMetrics)
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd
index be48b67..4f0be18 100644
--- a/ash/resources/ash_resources.grd
+++ b/ash/resources/ash_resources.grd
@@ -104,6 +104,7 @@
<!-- ChromeOS specific icons -->
<if expr="chromeos">
+ <structure type="chrome_scaled_image" name="IDR_AURA_NOTIFICATION_BLUETOOTH" file="cros/notification/notification_bluetooth_icon.png" />
<structure type="chrome_scaled_image" name="IDR_AURA_NOTIFICATION_DISPLAY" file="cros/notification/display_notification_icon.png" />
<structure type="chrome_scaled_image" name="IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER" file="cros/notification/notification_low_power_charger.png" />
<structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_AUDIO_BLUETOOTH" file="cros/status/status_audio_device_bluetooth.png" />
diff --git a/ash/resources/default_100_percent/cros/notification/notification_bluetooth_icon.png b/ash/resources/default_100_percent/cros/notification/notification_bluetooth_icon.png
new file mode 100644
index 0000000..28b497f
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/notification/notification_bluetooth_icon.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/notification/notification_bluetooth_icon.png b/ash/resources/default_200_percent/cros/notification/notification_bluetooth_icon.png
new file mode 100644
index 0000000..14e740e
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/notification/notification_bluetooth_icon.png
Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 5763b3d..aafe0ba 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -307,7 +307,7 @@
DISALLOW_COPY_AND_ASSIGN(CrosAccessibilityObserver);
};
-#endif // OS_CHROMEOS
+#endif // OS_CHROMEOS
} // namespace
@@ -330,7 +330,8 @@
}
// static
-RootWindowController* RootWindowController::ForShelf(aura::Window* window) {
+RootWindowController* RootWindowController::ForShelf(
+ const aura::Window* window) {
return GetRootWindowController(window->GetRootWindow());
}
@@ -527,6 +528,11 @@
void RootWindowController::CloseChildWindows() {
mouse_event_target_.reset();
+ // Remove observer as deactivating keyboard causes |docked_layout_manager_|
+ // to fire notifications.
+ if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
+ docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
+
// Deactivate keyboard container before closing child windows and shutting
// down associated layout managers.
DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
@@ -538,8 +544,6 @@
}
// docked_layout_manager_ needs to be shut down before windows are destroyed.
if (docked_layout_manager_) {
- if (shelf_ && shelf_->shelf_layout_manager())
- docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
docked_layout_manager_->Shutdown();
docked_layout_manager_ = NULL;
}
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index b7a059f..5c91f56 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -80,7 +80,6 @@
// |GetRootWindowController(aura::WindowEventDispatcher*)| function.
class ASH_EXPORT RootWindowController : public ShellObserver {
public:
-
// Creates and Initialize the RootWindowController for primary display.
static void CreateForPrimaryDisplay(AshWindowTreeHost* host);
@@ -95,7 +94,7 @@
// |window|. This returns the RootWindowController for the |window|'s
// root window when multiple shelf mode is enabled, or the primary
// RootWindowController otherwise.
- static RootWindowController* ForShelf(aura::Window* window);
+ static RootWindowController* ForShelf(const aura::Window* window);
// Returns a RootWindowController of the window's root window.
static RootWindowController* ForWindow(const aura::Window* window);
@@ -326,6 +325,6 @@
ASH_EXPORT RootWindowController* GetRootWindowController(
const aura::Window* root_window);
-} // ash
+} // namespace ash
-#endif // ASH_ROOT_WINDOW_CONTROLLER_H_
+#endif // ASH_ROOT_WINDOW_CONTROLLER_H_
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 9f0112a..9e959c5 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -28,6 +28,8 @@
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/events/test/test_event_handler.h"
#include "ui/keyboard/keyboard_controller_proxy.h"
#include "ui/keyboard/keyboard_switches.h"
@@ -805,7 +807,12 @@
MockTextInputClient text_input_client;
ui::InputMethod* input_method = proxy->GetInputMethod();
ASSERT_TRUE(input_method);
- input_method->SetFocusedTextInputClient(&text_input_client);
+ if (switches::IsTextInputFocusManagerEnabled()) {
+ ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
+ &text_input_client);
+ } else {
+ input_method->SetFocusedTextInputClient(&text_input_client);
+ }
aura::Window* root_window = Shell::GetPrimaryRootWindow();
aura::Window* keyboard_container =
@@ -825,6 +832,13 @@
text_input_client.visible_rect().width());
ASSERT_EQ(keyboard_container->bounds().height() - keyboard_height,
text_input_client.visible_rect().height());
+
+ if (switches::IsTextInputFocusManagerEnabled()) {
+ ui::TextInputFocusManager::GetInstance()->BlurTextInputClient(
+ &text_input_client);
+ } else {
+ input_method->SetFocusedTextInputClient(NULL);
+ }
}
} // namespace test
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc
index 2d988fc..f9d3704 100644
--- a/ash/shelf/shelf.cc
+++ b/ash/shelf/shelf.cc
@@ -80,7 +80,8 @@
// ShelfLayoutManager will resize the shelf.
}
-gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(aura::Window* window) {
+gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(
+ const aura::Window* window) {
ShelfID id = GetShelfIDForWindow(window);
gfx::Rect bounds(shelf_view_->GetIdealBoundsOfItemIcon(id));
gfx::Point screen_origin;
diff --git a/ash/shelf/shelf.h b/ash/shelf/shelf.h
index 2b06d82..88cd060 100644
--- a/ash/shelf/shelf.h
+++ b/ash/shelf/shelf.h
@@ -63,7 +63,7 @@
// Returns the screen bounds of the item for the specified window. If there is
// no item for the specified window an empty rect is returned.
- gfx::Rect GetScreenBoundsOfItemIconForWindow(aura::Window* window);
+ gfx::Rect GetScreenBoundsOfItemIconForWindow(const aura::Window* window);
// Updates the icon position given the current window bounds. This is used
// when dragging panels to reposition them with respect to the other panels.
diff --git a/ash/shelf/shelf_util.cc b/ash/shelf/shelf_util.cc
index 2d008ff..af773b4 100644
--- a/ash/shelf/shelf_util.cc
+++ b/ash/shelf/shelf_util.cc
@@ -27,7 +27,7 @@
window->SetProperty(kShelfID, id);
}
-ShelfID GetShelfIDForWindow(aura::Window* window) {
+ShelfID GetShelfIDForWindow(const aura::Window* window) {
DCHECK(window);
return window->GetProperty(kShelfID);
}
diff --git a/ash/shelf/shelf_util.h b/ash/shelf/shelf_util.h
index 7e5dae1..f93f42e 100644
--- a/ash/shelf/shelf_util.h
+++ b/ash/shelf/shelf_util.h
@@ -30,7 +30,7 @@
// or 0 if there isn't one.
// Note: Window of a tabbed browser will return the |ShelfID| of the
// currently active tab.
-ASH_EXPORT ShelfID GetShelfIDForWindow(aura::Window* window);
+ASH_EXPORT ShelfID GetShelfIDForWindow(const aura::Window* window);
// Sets ShelfItemDetails for |window|.
ASH_EXPORT void SetShelfItemDetailsForWindow(aura::Window* window,
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc
index 0ef9b40..972afa7 100644
--- a/ash/shelf/shelf_view.cc
+++ b/ash/shelf/shelf_view.cc
@@ -259,8 +259,7 @@
// AnimationDelegate used when inserting a new item. This steadily increases the
// opacity of the layer as the animation progress.
-class FadeInAnimationDelegate
- : public views::BoundsAnimator::OwnedAnimationDelegate {
+class FadeInAnimationDelegate : public gfx::AnimationDelegate {
public:
explicit FadeInAnimationDelegate(views::View* view) : view_(view) {}
virtual ~FadeInAnimationDelegate() {}
@@ -314,8 +313,7 @@
// AnimationDelegate used when deleting an item. This steadily decreased the
// opacity of the layer as the animation progress.
-class ShelfView::FadeOutAnimationDelegate
- : public views::BoundsAnimator::OwnedAnimationDelegate {
+class ShelfView::FadeOutAnimationDelegate : public gfx::AnimationDelegate {
public:
FadeOutAnimationDelegate(ShelfView* host, views::View* view)
: shelf_view_(host),
@@ -343,8 +341,7 @@
// AnimationDelegate used to trigger fading an element in. When an item is
// inserted this delegate is attached to the animation that expands the size of
// the item. When done it kicks off another animation to fade the item in.
-class ShelfView::StartFadeAnimationDelegate
- : public views::BoundsAnimator::OwnedAnimationDelegate {
+class ShelfView::StartFadeAnimationDelegate : public gfx::AnimationDelegate {
public:
StartFadeAnimationDelegate(ShelfView* host,
views::View* view)
@@ -379,7 +376,6 @@
owner_overflow_bubble_(NULL),
drag_pointer_(NONE),
drag_view_(NULL),
- drag_offset_(0),
start_drag_index_(-1),
context_menu_id_(0),
leading_inset_(kDefaultLeadingInset),
@@ -904,7 +900,8 @@
view->layer()->SetOpacity(0);
AnimateToIdealBounds();
bounds_animator_->SetAnimationDelegate(
- view, new FadeInAnimationDelegate(view), true);
+ view,
+ scoped_ptr<gfx::AnimationDelegate>(new FadeInAnimationDelegate(view)));
}
void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) {
@@ -970,7 +967,7 @@
int x = 0, y = 0;
if (layout_manager_->IsHorizontalAlignment()) {
x = std::max(view_model_->ideal_bounds(indices.first).x(),
- drag_point.x() - drag_offset_);
+ drag_point.x() - drag_origin_.x());
x = std::min(view_model_->ideal_bounds(last_drag_index).right() -
view_model_->ideal_bounds(current_index).width(),
x);
@@ -979,7 +976,7 @@
drag_view_->SetX(x);
} else {
y = std::max(view_model_->ideal_bounds(indices.first).y(),
- drag_point.y() - drag_offset_);
+ drag_point.y() - drag_origin_.y());
y = std::min(view_model_->ideal_bounds(last_drag_index).bottom() -
view_model_->ideal_bounds(current_index).height(),
y);
@@ -1255,8 +1252,8 @@
last_visible_view->layer()->SetOpacity(0);
bounds_animator_->SetAnimationDelegate(
last_visible_view,
- new ShelfView::StartFadeAnimationDelegate(this, last_visible_view),
- true);
+ scoped_ptr<gfx::AnimationDelegate>(
+ new StartFadeAnimationDelegate(this, last_visible_view)));
}
}
@@ -1452,7 +1449,9 @@
if (model_index <= last_visible_index_ ||
model_index >= model_->FirstPanelIndex()) {
bounds_animator_->SetAnimationDelegate(
- view, new StartFadeAnimationDelegate(this, view), true);
+ view,
+ scoped_ptr<gfx::AnimationDelegate>(
+ new StartFadeAnimationDelegate(this, view)));
} else {
// Undo the hiding if animation does not run.
view->layer()->SetOpacity(1.0f);
@@ -1486,7 +1485,9 @@
// of the views to their target location.
bounds_animator_->AnimateViewTo(view, view->bounds());
bounds_animator_->SetAnimationDelegate(
- view, new FadeOutAnimationDelegate(this, view), true);
+ view,
+ scoped_ptr<gfx::AnimationDelegate>(
+ new FadeOutAnimationDelegate(this, view)));
} else {
// We don't need to show a fade out animation for invisible |view|. When an
// item is ripped out from the shelf, its |view| is already invisible.
@@ -1574,7 +1575,7 @@
return; // View is being deleted or not draggable, ignore request.
drag_view_ = view;
- drag_offset_ = layout_manager_->PrimaryAxisValue(event.x(), event.y());
+ drag_origin_ = gfx::Point(event.x(), event.y());
UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage",
layout_manager_->SelectValueForShelfAlignment(
SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
@@ -1590,8 +1591,8 @@
// To prepare all drag types (moving an item in the shelf and dragging off),
// we should check the x-axis and y-axis offset.
if (!dragging() && drag_view_ &&
- ((std::abs(event.x() - drag_offset_) >= kMinimumDragDistance) ||
- (std::abs(event.y() - drag_offset_) >= kMinimumDragDistance))) {
+ ((std::abs(event.x() - drag_origin_.x()) >= kMinimumDragDistance) ||
+ (std::abs(event.y() - drag_origin_.y()) >= kMinimumDragDistance))) {
PrepareForDrag(pointer, event);
}
if (drag_pointer_ == pointer)
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h
index c3fb39f..f68e959 100644
--- a/ash/shelf/shelf_view.h
+++ b/ash/shelf/shelf_view.h
@@ -358,8 +358,8 @@
// |dragging_| is set only if the mouse is dragged far enough.
views::View* drag_view_;
- // X coordinate of the mouse down event in |drag_view_|s coordinates.
- int drag_offset_;
+ // Position of the mouse down event in |drag_view_|'s coordinates.
+ gfx::Point drag_origin_;
// Index |drag_view_| was initially at.
int start_drag_index_;
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index d57e23e..fb5c1db 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -120,6 +120,32 @@
DISALLOW_COPY_AND_ASSIGN(ShelfViewIconObserverTest);
};
+// TestShelfItemDelegate which tracks whether it gets selected.
+class ShelfItemSelectionTracker : public TestShelfItemDelegate {
+ public:
+ ShelfItemSelectionTracker() : TestShelfItemDelegate(NULL), selected_(false) {
+ }
+
+ virtual ~ShelfItemSelectionTracker() {
+ }
+
+ // Returns true if the delegate was selected.
+ bool WasSelected() {
+ return selected_;
+ }
+
+ // TestShelfItemDelegate:
+ virtual bool ItemSelected(const ui::Event& event) OVERRIDE {
+ selected_ = true;
+ return false;
+ }
+
+ private:
+ bool selected_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShelfItemSelectionTracker);
+};
+
TEST_F(ShelfViewIconObserverTest, AddRemove) {
TestShelfDelegate* shelf_delegate = TestShelfDelegate::instance();
ASSERT_TRUE(shelf_delegate);
@@ -398,7 +424,7 @@
ShelfButtonHost* button_host = shelf_view_;
views::View* button = test_api_->GetButton(button_index);
ui::MouseEvent click_event(ui::ET_MOUSE_PRESSED,
- button->bounds().origin(),
+ gfx::Point(),
button->GetBoundsInScreen().origin(), 0, 0);
button_host->PointerPressedOnButton(button, pointer, click_event);
return button;
@@ -421,7 +447,8 @@
// Drag.
views::View* destination = test_api_->GetButton(destination_index);
ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED,
- destination->bounds().origin(),
+ gfx::Point(destination->x() - button->x(),
+ destination->y() - button->y()),
destination->GetBoundsInScreen().origin(), 0, 0);
button_host->PointerDraggedOnButton(button, pointer, drag_event);
return button;
@@ -1030,6 +1057,54 @@
EXPECT_TRUE(model_->items()[3].type == TYPE_BROWSER_SHORTCUT);
}
+// Check that clicking an item and jittering the mouse a bit still selects the
+// item.
+TEST_F(ShelfViewTest, ClickAndMoveSlightly) {
+ std::vector<std::pair<ShelfID, views::View*> > id_map;
+ SetupForDragTest(&id_map);
+
+ ShelfID shelf_id = (id_map.begin() + 1)->first;
+ views::View* button = (id_map.begin() + 1)->second;
+
+ // Replace the ShelfItemDelegate for |shelf_id| with one which tracks whether
+ // the shelf item gets selected.
+ ShelfItemSelectionTracker* selection_tracker = new ShelfItemSelectionTracker;
+ item_manager_->SetShelfItemDelegate(
+ shelf_id,
+ scoped_ptr<ShelfItemDelegate>(selection_tracker).Pass());
+
+ gfx::Vector2d press_offset(5, 30);
+ gfx::Point press_location = gfx::Point() + press_offset;
+ gfx::Point press_location_in_screen =
+ button->GetBoundsInScreen().origin() + press_offset;
+
+ ui::MouseEvent click_event(ui::ET_MOUSE_PRESSED,
+ press_location,
+ press_location_in_screen,
+ ui::EF_LEFT_MOUSE_BUTTON, 0);
+ button->OnMousePressed(click_event);
+
+ ui::MouseEvent drag_event1(ui::ET_MOUSE_DRAGGED,
+ press_location + gfx::Vector2d(0, 1),
+ press_location_in_screen + gfx::Vector2d(0, 1),
+ ui::EF_LEFT_MOUSE_BUTTON, 0);
+ button->OnMouseDragged(drag_event1);
+
+ ui::MouseEvent drag_event2(ui::ET_MOUSE_DRAGGED,
+ press_location + gfx::Vector2d(-1, 0),
+ press_location_in_screen + gfx::Vector2d(-1, 0),
+ ui::EF_LEFT_MOUSE_BUTTON, 0);
+ button->OnMouseDragged(drag_event2);
+
+ ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED,
+ press_location + gfx::Vector2d(-1, 0),
+ press_location_in_screen + gfx::Vector2d(-1, 0),
+ ui::EF_LEFT_MOUSE_BUTTON, 0);
+ button->OnMouseReleased(release_event);
+
+ EXPECT_TRUE(selection_tracker->WasSelected());
+}
+
// Confirm that item status changes are reflected in the buttons.
TEST_F(ShelfViewTest, ShelfItemStatus) {
// All buttons should be visible.
diff --git a/ash/shell.cc b/ash/shell.cc
index c8d5da4..c8b3279 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -467,21 +467,9 @@
observers_.RemoveObserver(observer);
}
-void Shell::EnableMaximizeModeWindowManager(bool enable) {
- if (enable && !maximize_mode_window_manager_.get()) {
- maximize_mode_window_manager_.reset(new MaximizeModeWindowManager());
- } else if (!enable && maximize_mode_window_manager_.get()) {
- maximize_mode_window_manager_.reset();
- }
-}
-
-bool Shell::IsMaximizeModeWindowManagerEnabled() {
- return maximize_mode_window_manager_.get() != NULL;
-}
-
#if defined(OS_CHROMEOS)
bool Shell::ShouldSaveDisplaySettings() {
- return !((IsMaximizeModeWindowManagerEnabled() &&
+ return !((maximize_mode_controller_->IsMaximizeModeWindowManagerEnabled() &&
maximize_mode_controller_->in_set_screen_rotation()) ||
resolution_notification_controller_->DoesNotificationTimeout());
}
@@ -513,7 +501,7 @@
}
}
-ShelfAlignment Shell::GetShelfAlignment(aura::Window* root_window) {
+ShelfAlignment Shell::GetShelfAlignment(const aura::Window* root_window) {
return GetRootWindowController(root_window)
->GetShelfLayoutManager()
->GetAlignment();
@@ -691,10 +679,10 @@
// TooltipController is deleted with the Shell so removing its references.
RemovePreTargetHandler(tooltip_controller_.get());
- // Destroy maximize window manager early on since it has some observers which
+ // Destroy maximize mode controller early on since it has some observers which
// need to be removed.
+ maximize_mode_controller_->Shutdown();
maximize_mode_controller_.reset();
- maximize_mode_window_manager_.reset();
// AppList needs to be released before shelf layout manager, which is
// destroyed with shelf container in the loop below. However, app list
diff --git a/ash/shell.h b/ash/shell.h
index 1518ea6..14e1f91 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -326,12 +326,6 @@
void AddShellObserver(ShellObserver* observer);
void RemoveShellObserver(ShellObserver* observer);
- // Turn the always maximize mode window manager on or off.
- void EnableMaximizeModeWindowManager(bool enable);
-
- // Test if the MaximizeModeWindowManager is enabled or not.
- bool IsMaximizeModeWindowManagerEnabled();
-
#if defined(OS_CHROMEOS)
// Test if MaximizeModeWindowManager is not enabled, and if
// MaximizeModeController is not currently setting a display rotation. Or if
@@ -457,7 +451,7 @@
// Sets/gets shelf's alignment on |root_window|.
void SetShelfAlignment(ShelfAlignment alignment,
aura::Window* root_window);
- ShelfAlignment GetShelfAlignment(aura::Window* root_window);
+ ShelfAlignment GetShelfAlignment(const aura::Window* root_window);
// Dims or undims the screen.
void SetDimming(bool should_dim);
@@ -704,9 +698,6 @@
scoped_ptr<LocaleNotificationController> locale_notification_controller_;
- // The maximized window manager (if enabled).
- scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
-
scoped_ptr<AccelerometerController> accelerometer_controller_;
#if defined(OS_CHROMEOS)
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb
index b76aac4..d96db71 100644
--- a/ash/strings/ash_strings_am.xtb
+++ b/ash/strings/ash_strings_am.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">ምንም የአውታረ መረብ መረጃ አይገኝም</translation>
<translation id="4625920103690741805">ማሽከርከር ተቆልፏል (ለመለወጥ እዚህ ጋር መታ ያድርጉ)</translation>
<translation id="3799026279081545374">መጥፎ የኃይል መሙያ ሊኖርዎት ይችላል። በአሜሪካ ውስጥ የሚኖሩ ከሆኑ እርዳታን እና መተኪያን ለማግኘት እባክዎ ወደ 866-628-1371 ይደውሉ። በዩኬ ውስጥ የሚኖሩ ከሆኑ እባክዎ ወደ 0800-026-0613 ይደውሉ። በአየርላንድ ውስጥ የሚሆኑ ከሆኑ እባክዎ ወደ 1-800-832-664 ይደውሉ። በካናዳ ውስጥ የሚኖሩ ከሆኑ እባክዎ ወደ 866-628-1372 ይደውሉ። በአውስትራሊያ ውስጥ የሚኖሩ ከሆኑ እባክዎ ወደ 1-800-067-460 ይደውሉ።</translation>
+<translation id="3026237328237090306">የተንቀሳቃሽ ስልክ ውሂብ ያዋቅሩ</translation>
<translation id="5871632337994001636">መሳሪያዎችን ያስተዳድሩ...</translation>
<translation id="785750925697875037">የተንቀሳቃሽ መለያ ይመልከቱ</translation>
<translation id="153454903766751181">ተንቀሳቃሽ ሞደምን በማስጀመር ላይ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (የቃል ግብረመልስ)</translation>
<translation id="6981982820502123353">ተደራሽነት</translation>
<translation id="4274292172790327596">ያልታወቀ ስህተት</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ጆሮ ማዳጀጫ</translation>
<translation id="225680501294068881">መሣሪያዎችን በመቃኘት ላይ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>፣ <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">ተጨማሪ ለመረዳት</translation>
<translation id="9046895021617826162">ማገናኘት አልተሳካም</translation>
<translation id="7168224885072002358">በ<ph name="TIMEOUT_SECONDS"/> ውስጥ ወደ ቀድሞው ጥራት በመመለስ ላይ</translation>
+<translation id="973896785707726617">ይህ ክፍለ ጊዜ በ<ph name="SESSION_TIME_REMAINING"/> ጊዜ ውስጥ ያልቃል። በራስ-ሰር እንዲወጡ ይደረጋሉ።</translation>
<translation id="743058460480092004">ካሜራና ማይክራፎን ስራ ላይ ናቸው።</translation>
<translation id="8372369524088641025">መጥፎ የWEP ቁልፍ</translation>
<translation id="6636709850131805001">ያልታወቀ ሁኔታ</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index 57ec9e5..53418f3 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">لا توجد معلومات متاحة حول الشبكة</translation>
<translation id="4625920103690741805">قفل التناوب (انقر هنا للتغيير)</translation>
<translation id="3799026279081545374">قد يكون الشاحن غير صالح. إذا كنت مقيمًا في الولايات المتحدة، فالرجاء الاتصال بالرقم 866-628-1371 للحصول على مساعدة واستبدال الشاحن. وإذا كنت مقيمًا في المملكة المتحدة، فالرجاء الاتصال بالرقم 0800-026-0613. وإذا كنت مقيمًا في أيرلندا، فالرجاء الاتصال بالرقم 1-800-832-664. وإذا كنت مقيمًا في كندا، فالرجاء الاتصال بالرقم 866-628-1372. وإذا كنت مقيمًا في أستراليا، فالرجاء الاتصال بالرقم 1-800-067-460.</translation>
+<translation id="3026237328237090306">إعداد بيانات الجوال</translation>
<translation id="5871632337994001636">إدارة الأجهزة...</translation>
<translation id="785750925697875037">عرض حساب الجوال</translation>
<translation id="153454903766751181">جارٍ تهيئة المودم الخلوي...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (التعليق المنطوق)</translation>
<translation id="6981982820502123353">إمكانية الدخول</translation>
<translation id="4274292172790327596">خطأ غير معروف</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">سماعة رأس</translation>
<translation id="225680501294068881">جارٍ البحث عن أجهزة...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>، <ph name="DATE"/></translation>
@@ -225,6 +227,7 @@
<translation id="6165508094623778733">مزيد من المعلومات</translation>
<translation id="9046895021617826162">أخفق الاتصال</translation>
<translation id="7168224885072002358">سيتم الرجوع إلى درجة الدقة القديمة في غضون <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">ستنتهي هذه الجلسة في <ph name="SESSION_TIME_REMAINING"/>. سيتم الخروج تلقائيًا.</translation>
<translation id="743058460480092004">الكاميرا والميكروفون قيد الاستخدام.</translation>
<translation id="8372369524088641025">مفتاح WEP غير صالح</translation>
<translation id="6636709850131805001">حالة غير معروفة</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb
index bf0671e..4653285 100644
--- a/ash/strings/ash_strings_bg.xtb
+++ b/ash/strings/ash_strings_bg.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Не е налице информация за мрежата</translation>
<translation id="4625920103690741805">Завъртането е заключено (докоснете тук за промяна)</translation>
<translation id="3799026279081545374">Възможно е зарядното ви устройство да е дефектно. За да получите помощ и да го замените, моля, обадете се на номера за държавата, в която живеете – 866-628-1371 за САЩ, 0800-026-0613 за Великобритания, 1-800-832-664 за Ирландия, 866-628-1372 за Канада и 1-800-067-460 за Австралия.</translation>
+<translation id="3026237328237090306">Настройка на мобилните данни</translation>
<translation id="5871632337994001636">Управление на устройствата...</translation>
<translation id="785750925697875037">Преглед на мобилния профил</translation>
<translation id="153454903766751181">Клетъчният модем се подготвя за работа...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (обратна връзка с говор)</translation>
<translation id="6981982820502123353">Достъпност</translation>
<translation id="4274292172790327596">Неразпозната грешка</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Слушалки</translation>
<translation id="225680501294068881">Сканира се за устройства...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416">„<ph name="DISPLAY_NAME"/>“ е обществена сесия, управлявана от <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Свързването с мрежата не бе успешно: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Изход от сесията</translation>
-<translation id="479989351350248267">търсете</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi е включен.</translation>
<translation id="4872237917498892622">„Alt + търсене“ или „Shift“</translation>
<translation id="2429753432712299108">Устройството с Bluetooth „<ph name="DEVICE_NAME"/>“ иска разрешение за сдвояване. Преди да приемете, моля, уверете се, че на него се показва следният ключ за достъп: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Научете повече</translation>
<translation id="9046895021617826162">Свързването не бе успешно</translation>
<translation id="7168224885072002358">Старата разделителна способност ще се възстанови след <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Тази сесия ще приключи след <ph name="SESSION_TIME_REMAINING"/>. Ще излезете автоматично от нея.</translation>
<translation id="743058460480092004">Камерата и микрофонът се използват.</translation>
<translation id="8372369524088641025">Ключът за WEP е неправилен</translation>
<translation id="6636709850131805001">Неразпознато състояние</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb
index 200628d..4e718bd 100644
--- a/ash/strings/ash_strings_bn.xtb
+++ b/ash/strings/ash_strings_bn.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">কোনো নেটওয়ার্ক সংক্রান্ত তথ্য উপলব্ধ নেই</translation>
<translation id="4625920103690741805">ঘূর্ণন লক করা আছে (পরিবর্তন করতে এখানে আলতো চাপুন)</translation>
<translation id="3799026279081545374">আপনার কাছে একটি খারাপ চার্জার থাকতে পারে৷ যদি আপনি মার্কিন যুক্তরাষ্ট্রে বাস করেন তবে সহায়তা পেতে এবং একটি প্রতিস্থাপনের জন্য দয়া করে ৮৬৬-৬২৮-১৩৭১ এ কল করুন৷ যদি আপনি যুক্তরাজ্য বাস করেন তবে দয়া করে ০৮০০-০২৬-০৬১৩ এ কল করুন৷ যদি আপনি আয়ারল্যান্ডে বাস করেন তবে দয়া করে ১-৮০০-৮৩২-৬৬৪ এ কল করুন৷ যদি আপনি কানাডায় বাস করেন তবে দয়া করে ৮৬৬-৬২৮-১৩৭২ এ কল করুন৷ যদি আপনি অস্ট্রেলিয়ায় বাস করেন তবে দয়া করে ১-৮০০-০৬৭-৪৬০ এ কল করুন৷</translation>
+<translation id="3026237328237090306">মোবাইল ডেটা সেটআপ করুন</translation>
<translation id="5871632337994001636">ডিভাইসগুলি পরিচালন করুন...</translation>
<translation id="785750925697875037">মোবাইল অ্যাকাউন্ট দেখুন</translation>
<translation id="153454903766751181">সেলুলার মোডেম আরম্ভ করা হচ্ছে...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (কথ্য প্রতিক্রিয়া)</translation>
<translation id="6981982820502123353">অ্যাক্সেযোগ্যতা</translation>
<translation id="4274292172790327596">অস্বীকৃত ত্রুটি</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">হেডফোন</translation>
<translation id="225680501294068881">ডিভাইসগুলির জন্য স্ক্যান করা হচ্ছে...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> হল <ph name="DOMAIN"/> এর দ্বারা পরিচালিত একটি সর্বজনীন সেশন</translation>
<translation id="9044646465488564462">নেটওয়ার্কের সাথে সংযোগ করতে ব্যর্থ: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">সেশন থেকে প্রস্থান</translation>
-<translation id="479989351350248267">অনুসন্ধান</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi চালু আছে৷</translation>
<translation id="4872237917498892622">Alt+Search অথবা Shift</translation>
<translation id="2429753432712299108">Bluetooth ডিভাইস "<ph name="DEVICE_NAME"/>" যুক্ত করার অনুমতি চাইছে। স্বীকার করার আগে, দয়া করে এই পাস কীটি যে ডিভাইসে প্রদর্শিত হয়েছে তা নিশ্চিত করুন: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">আরো জানুন</translation>
<translation id="9046895021617826162">সংযোগ ব্যর্থ হয়েছে</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> এ পুরানো রেসুলিউশানে ফেরানো হচ্ছে</translation>
+<translation id="973896785707726617">এই সেশনটি <ph name="SESSION_TIME_REMAINING"/> এর মধ্যে সমাপ্ত হবে৷ আপনি স্বয়ংক্রিয়ভাবে সাইন আউট হয়ে যাবেন৷</translation>
<translation id="743058460480092004">ক্যামেরা এবং মাইক্রোফোন ব্যবহার করা হচ্ছে।</translation>
<translation id="8372369524088641025">খারাপ WEP কী</translation>
<translation id="6636709850131805001">অস্বীকৃত স্থিতি</translation>
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb
index 15955e7..efa0c0e 100644
--- a/ash/strings/ash_strings_ca.xtb
+++ b/ash/strings/ash_strings_ca.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">No hi ha informació de xarxa disponible</translation>
<translation id="4625920103690741805">Rotació bloquejada (toqueu aquí per canviar)</translation>
<translation id="3799026279081545374">Pot ser que el carregador s'hagi espatllat. Si residiu als EUA, truqueu al 866-628-1371 per rebre ajuda i un carregador de recanvi. Si residiu al Regne Unit, truqueu al 0800-026-0613. Si residiu a Irlanda, truqueu al 1-800-832-664. Si residiu al Canadà, truqueu al 866-628-1372. Si residiu a Austràlia, truqueu al 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configura les dades mòbils</translation>
<translation id="5871632337994001636">Gestiona els dispositius...</translation>
<translation id="785750925697875037">Mostra el compte mòbil</translation>
<translation id="153454903766751181">S'està inicialitzant el mòdem mòbil...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (comentaris de veu)</translation>
<translation id="6981982820502123353">Accessibilitat</translation>
<translation id="4274292172790327596">Error no reconegut</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Auricular</translation>
<translation id="225680501294068881">S'estan cercant dispositius...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,10 +229,11 @@
<translation id="6165508094623778733">Més informació</translation>
<translation id="9046895021617826162">S'ha produït un error en la connexió</translation>
<translation id="7168224885072002358">Es revertirà a la resolució anterior d'aquí a <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">La sessió finalitzarà d'aquí a <ph name="SESSION_TIME_REMAINING"/>. Es tancarà la sessió automàticament.</translation>
<translation id="743058460480092004">La càmera i el micròfon s'estan utilitzant.</translation>
<translation id="8372369524088641025">Clau WEP no vàlida</translation>
<translation id="6636709850131805001">Estat no reconegut</translation>
-<translation id="6406704438230478924">altgr</translation>
+<translation id="6406704438230478924">AltGr</translation>
<translation id="3573179567135747900">Torna a canviar a "<ph name="FROM_LOCALE"/>" (requereix reiniciar)</translation>
<translation id="8103386449138765447">Missatges SMS: <ph name="MESSAGE_COUNT"/></translation>
<translation id="7097613348211027502">ChromeVox (comentaris de veu) està activat.
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb
index 98b879a..2ad798c 100644
--- a/ash/strings/ash_strings_cs.xtb
+++ b/ash/strings/ash_strings_cs.xtb
@@ -48,6 +48,7 @@
<translation id="3846575436967432996">Informace o síti nejsou k dispozici</translation>
<translation id="4625920103690741805">Otáčení je uzamčeno (klepnutím sem toto nastavení změníte)</translation>
<translation id="3799026279081545374">Je možné, že máte vadnou nabíječku. Pokud žijete v USA, požádejte o pomoc a výměnu na čísle 866-628-1371. Pokud žijete ve Spojeném království, volejte na číslo 0800-026-0613. Pokud žijete v Irsku, volejte na číslo 1-800-832-664. Pokud žijete v Kanadě, volejte na číslo 866-628-1372. Pokud žijete v Austrálii, volejte na číslo 1-800-067-460.</translation>
+<translation id="3026237328237090306">Nastavení mobilního datového připojení</translation>
<translation id="5871632337994001636">Spravovat zařízení...</translation>
<translation id="785750925697875037">Zobrazit mobilní účet</translation>
<translation id="153454903766751181">Inicializace mobilního modemu...</translation>
@@ -173,6 +174,7 @@
<translation id="68610848741840742">ChromeVox (hlasová odezva)</translation>
<translation id="6981982820502123353">Usnadnění</translation>
<translation id="4274292172790327596">Neznámá chyba</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Sluchátka</translation>
<translation id="225680501294068881">Vyhledávání zařízení…</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -186,7 +188,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je veřejná relace spravovaná doménou <ph name="DOMAIN"/>.</translation>
<translation id="9044646465488564462">Připojení k síti se nezdařilo: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Ukončit relaci</translation>
-<translation id="479989351350248267">vyhledat</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Připojení Wi-Fi je zapnuto.</translation>
<translation id="4872237917498892622">Alt + Vyhledávání nebo Shift</translation>
<translation id="2429753432712299108">Zařízení Bluetooth „<ph name="DEVICE_NAME"/>“ žádá o povolení ke spárování. Než toto povolení schválíte, zkontrolujte si, zda je na zařízení zobrazen následující přístupový klíč: <ph name="PASSKEY"/></translation>
@@ -224,6 +226,7 @@
<translation id="6165508094623778733">Další informace</translation>
<translation id="9046895021617826162">Připojení selhalo</translation>
<translation id="7168224885072002358">Původní rozlišení bude obnoveno za <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Relace bude ukončena za <ph name="SESSION_TIME_REMAINING"/>. Poté budete automaticky odhlášeni.</translation>
<translation id="743058460480092004">Kamera a mikrofon jsou používány.</translation>
<translation id="8372369524088641025">Chybný klíč WEP</translation>
<translation id="6636709850131805001">Neznámý stav</translation>
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb
index 3f01c0d..34773e7 100644
--- a/ash/strings/ash_strings_da.xtb
+++ b/ash/strings/ash_strings_da.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Der er ingen tilgængelige netværksoplysninger</translation>
<translation id="4625920103690741805">Rotation er låst (tryk her for at ændre indstillingen)</translation>
<translation id="3799026279081545374">Din oplader er muligvis beskadiget. Hvis du er bosiddende i USA, skal du ringe på 866-628-1371 for at få hjælp og en ny oplader. Hvis du er bosiddende i Storbritannien, skal du ringe på 0800-026-0613. Hvis du er bosiddende i Irland, skal du ringe på 1-800-832-664. Hvis du er bosiddende i Canada, skal du ringe på 866-628-1372. Hvis du er bosiddende i Australien, skal du ringe på 1-800-067-460.</translation>
+<translation id="3026237328237090306">Konfigurer mobildata</translation>
<translation id="5871632337994001636">Administrer enheder...</translation>
<translation id="785750925697875037">Vis mobilkonto</translation>
<translation id="153454903766751181">Initialiserer mobilmodem...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (talefeedback)</translation>
<translation id="6981982820502123353">Hjælpefunktioner</translation>
<translation id="4274292172790327596">Fejlen genkendes ikke</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Hovedtelefon</translation>
<translation id="225680501294068881">Scanner efter enheder...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> d. <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Flere oplysninger</translation>
<translation id="9046895021617826162">Forbindelsen mislykkedes</translation>
<translation id="7168224885072002358">Fortryder og vender tilbage til den gamle opløsning om <ph name="TIMEOUT_SECONDS"/> sekunder.</translation>
+<translation id="973896785707726617">Denne session afsluttes om <ph name="SESSION_TIME_REMAINING"/>. Du logges automatisk ud.</translation>
<translation id="743058460480092004">Kamera og mikrofon er i brug.</translation>
<translation id="8372369524088641025">Ugyldig WEP-nøgle</translation>
<translation id="6636709850131805001">Tilstanden genkendes ikke</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb
index c707be5..e24bd09 100644
--- a/ash/strings/ash_strings_de.xtb
+++ b/ash/strings/ash_strings_de.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Keine Netzwerkinformationen verfügbar</translation>
<translation id="4625920103690741805">Rotation gesperrt – zum Ändern hier tippen</translation>
<translation id="3799026279081545374">Möglicherweise ist Ihr Ladegerät fehlerhaft. Wenn Sie in den USA leben, erhalten Sie unter der Telefonnummer 866-628-1371 Hilfe und ein Ersatzgerät. Wählen Sie in Großbritannien die Nummer 0800-026-0613, in Irland die Nummer 1-800-832-664, in Kanada die Nummer 866-628-1372 und in Australien die Nummer 1-800-067-460.</translation>
+<translation id="3026237328237090306">Mobilfunk einrichten</translation>
<translation id="5871632337994001636">Geräte verwalten...</translation>
<translation id="785750925697875037">Mobiles Konto aufrufen</translation>
<translation id="153454903766751181">Mobilfunkmodem wird initialisiert...</translation>
@@ -71,7 +72,7 @@
<translation id="7170041865419449892">Außerhalb des Bereichs</translation>
<translation id="4804818685124855865">Verbindung trennen</translation>
<translation id="2544853746127077729">Ablehnung des Authentifizierungszertifikats durch das Netzwerk</translation>
-<translation id="2963773877003373896">mod3</translation>
+<translation id="2963773877003373896">Mod3</translation>
<translation id="5222676887888702881">Abmelden</translation>
<translation id="2391579633712104609">180°</translation>
<translation id="2688477613306174402">Konfiguration</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (gesprochenes Feedback)</translation>
<translation id="6981982820502123353">Bedienungshilfen</translation>
<translation id="4274292172790327596">Unbekannter Fehler</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Kopfhörer</translation>
<translation id="225680501294068881">Nach Geräten wird gesucht...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ist eine öffentliche Sitzung, die von <ph name="DOMAIN"/> verwaltet wird.</translation>
<translation id="9044646465488564462">Fehler beim Herstellen einer Verbindung mit dem Netzwerk: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Sitzung beenden</translation>
-<translation id="479989351350248267">Suchbegriff eingeben</translation>
+<translation id="479989351350248267">Suchen</translation>
<translation id="8454013096329229812">WLAN ist aktiviert.</translation>
<translation id="4872237917498892622">Alt+Suchen oder Shift</translation>
<translation id="2429753432712299108">Das Bluetooth-Gerät "<ph name="DEVICE_NAME"/>" bittet um Erlaubnis für das Pairing. Bevor Sie akzeptieren, überprüfen Sie, ob folgender Passkey auf dem Gerät angezeigt wird: <ph name="PASSKEY"/>.</translation>
@@ -227,10 +229,11 @@
<translation id="6165508094623778733">Weitere Informationen</translation>
<translation id="9046895021617826162">Verbindungsaufbau fehlgeschlagen</translation>
<translation id="7168224885072002358">Alte Auflösung wird in <ph name="TIMEOUT_SECONDS"/> wiederhergestellt.</translation>
+<translation id="973896785707726617">Die Sitzung wird in <ph name="SESSION_TIME_REMAINING"/> beendet. Sie werden dann automatisch abgemeldet.</translation>
<translation id="743058460480092004">Kamera und Mikrofon werden verwendet.</translation>
<translation id="8372369524088641025">Ungültiger WEP-Schlüssel</translation>
<translation id="6636709850131805001">Unbekannter Status</translation>
-<translation id="6406704438230478924">alt gr</translation>
+<translation id="6406704438230478924">AltGr</translation>
<translation id="3573179567135747900">Zurücksetzen auf "<ph name="FROM_LOCALE"/>" (Neustart erforderlich)</translation>
<translation id="8103386449138765447">SMS: <ph name="MESSAGE_COUNT"/></translation>
<translation id="7097613348211027502">ChromeVox (gesprochenes Feedback) ist aktiviert.
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb
index 733bb12..8d3af7c 100644
--- a/ash/strings/ash_strings_el.xtb
+++ b/ash/strings/ash_strings_el.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Δεν υπάρχουν διαθέσιμες πληροφορίες δικτύου</translation>
<translation id="4625920103690741805">Κλείδωμα περιστροφής (Πατήστε εδώ για να αλλάξετε την επιλογή)</translation>
<translation id="3799026279081545374">Ενδέχεται ο φορτιστής σας να έχει κάποια βλάβη. Εάν διαμένετε στις ΗΠΑ, καλέστε στο 866-628-1371 για να λάβετε βοήθεια και υλικό αντικατάστασης. Εάν διαμένετε στο ΗΒ, καλέστε στο 0800-026-0613. Εάν διαμένετε στην Ιρλανδία, καλέστε στο 1-800-832-664. Εάν διαμένετε στον Καναδά, καλέστε στο 866-628-1372. Εάν διαμένετε στην Αυστραλία, καλέστε στο 1-800-067-460.</translation>
+<translation id="3026237328237090306">Ρύθμιση δεδομένων κινητής τηλεφωνίας</translation>
<translation id="5871632337994001636">Διαχείριση συσκευών…</translation>
<translation id="785750925697875037">Προβολή λογαριασμού κινητής τηλεφωνίας</translation>
<translation id="153454903766751181">Εκκίνηση μόντεμ δικτύου κινητής τηλεφωνίας…</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (προφορικά σχόλια)</translation>
<translation id="6981982820502123353">Προσβασιμότητα</translation>
<translation id="4274292172790327596">Μη αναγνωρίσιμο σφάλμα</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Ακουστικά</translation>
<translation id="225680501294068881">Σάρωση για συσκευές…</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -187,7 +189,7 @@
<translation id="2999742336789313416">Το <ph name="DISPLAY_NAME"/> είναι μια δημόσια περίοδος σύνδεσης που διαχειρίζεται το <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Η σύνδεση στο δίκτυο απέτυχε: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Έξοδος από συνεδρία</translation>
-<translation id="479989351350248267">αναζήτηση</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Το Wi-Fi έχει ενεργοποιηθεί.</translation>
<translation id="4872237917498892622">Alt+Search ή Shift</translation>
<translation id="2429753432712299108">Η συσκευή Bluetooth "<ph name="DEVICE_NAME"/>" ζητά δικαιώματα σύζευξης. Προτού αποδεχτείτε, επιβεβαιώστε ότι αυτό το κλειδί πρόσβασης εμφανίζεται στη συγκεκριμένη συσκευή: <ph name="PASSKEY"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">Μάθετε περισσότερα</translation>
<translation id="9046895021617826162">Η σύνδεση απέτυχε</translation>
<translation id="7168224885072002358">Επαναφορά στην προηγούμενη ανάλυση σε <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Αυτή η περίοδος σύνδεσης θα λήξει αυτόματα σε <ph name="SESSION_TIME_REMAINING"/>. Θα αποσυνδεθείτε αυτόματα.</translation>
<translation id="743058460480092004">Η κάμερα και το μικρόφωνο χρησιμοποιούνται.</translation>
<translation id="8372369524088641025">Εσφαλμένο κλειδί WEP</translation>
<translation id="6636709850131805001">Μη αναγνωρίσιμη κατάσταση</translation>
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb
index b5c0695..f173d69 100644
--- a/ash/strings/ash_strings_en-GB.xtb
+++ b/ash/strings/ash_strings_en-GB.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">No network information available</translation>
<translation id="4625920103690741805">Rotation locked (Tap here to change)</translation>
<translation id="3799026279081545374">You may have a bad charger. If you live in the US, please call 866-628-1371 in order to receive help and a replacement. If you live in the UK, please call 0800-026-0613. If you live in Ireland, please call 1-800-832-664. If you live in Canada, please call 866-628-1372. If you live in Australia, please call 1-800-067-460.</translation>
+<translation id="3026237328237090306">Set up mobile data</translation>
<translation id="5871632337994001636">Manage devices...</translation>
<translation id="785750925697875037">View mobile account</translation>
<translation id="153454903766751181">Initialising mobile modem...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Spoken feedback)</translation>
<translation id="6981982820502123353">Accessibility</translation>
<translation id="4274292172790327596">Unrecognised error</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Headphone</translation>
<translation id="225680501294068881">Scanning for devices...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Learn more</translation>
<translation id="9046895021617826162">Connection failed</translation>
<translation id="7168224885072002358">Reverting to old resolution in <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">This session will end in <ph name="SESSION_TIME_REMAINING"/>. You will be automatically signed out.</translation>
<translation id="743058460480092004">Camera and microphone are in use.</translation>
<translation id="8372369524088641025">Bad WEP key</translation>
<translation id="6636709850131805001">Unrecognised state</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb
index f3bfb83..7b7e752 100644
--- a/ash/strings/ash_strings_es-419.xtb
+++ b/ash/strings/ash_strings_es-419.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">No hay información de red disponible.</translation>
<translation id="4625920103690741805">Rotación bloqueada (presiona aquí para modificar)</translation>
<translation id="3799026279081545374">Es posible que el cargador esté fallado. Si vives en Estados Unidos, comunícate al 866-628-1371 para recibir ayuda y un reemplazo. Si vives en el Reino Unido, comunícate al 0800-026-0613. Si vives en Irlanda, comunícate al 1-800-832-664. Si vives en Canadá, comunícate al 866-628-1372. Si vives en Australia, comunícate al 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configurar datos de dispositivos móviles</translation>
<translation id="5871632337994001636">Administrar dispositivos…</translation>
<translation id="785750925697875037">Ver cuenta móvil</translation>
<translation id="153454903766751181">Iniciando módem celular...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (comentarios por voz)</translation>
<translation id="6981982820502123353">Accesibilidad</translation>
<translation id="4274292172790327596">Error no reconocido</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Auriculares</translation>
<translation id="225680501294068881">Buscando dispositivos...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> es una sesión pública administrada por <ph name="DOMAIN"/>.</translation>
<translation id="9044646465488564462">Error al establecer conexión con la red: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Salir de la sesión</translation>
-<translation id="479989351350248267">buscar</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi activada</translation>
<translation id="4872237917498892622">Alt+tecla de búsqueda o Mayús</translation>
<translation id="2429753432712299108">El dispositivo Bluetooth "<ph name="DEVICE_NAME"/>" solicita permiso para sincronizarse. Antes de aceptar, debes confirmar que aparece la siguiente clave de contraseña en el dispositivo: <ph name="PASSKEY"/>.</translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Más información</translation>
<translation id="9046895021617826162">No se pudo conectar</translation>
<translation id="7168224885072002358">Se revertirá a la resolución anterior en <ph name="TIMEOUT_SECONDS"/>.</translation>
+<translation id="973896785707726617">Esta sesión finalizará en <ph name="SESSION_TIME_REMAINING"/>. Saldrás automáticamente.</translation>
<translation id="743058460480092004">Cámara y micrófono en uso</translation>
<translation id="8372369524088641025">Clave de WEP no válida</translation>
<translation id="6636709850131805001">Estado no reconocido</translation>
@@ -249,7 +252,7 @@
<translation id="3678715477168044796"><ph name="DISPLAY_NAME"/>: <ph name="ANNOTATION"/></translation>
<translation id="2563856802393254086">Se activó tu servicio de datos "<ph name="NAME"/>" y está listo para que lo uses.</translation>
<translation id="412065659894267608"><ph name="HOUR"/>h <ph name="MINUTE"/>min para completar la carga</translation>
-<translation id="3077734595579995578">mayúscula</translation>
+<translation id="3077734595579995578">shift</translation>
<translation id="7297443947353982503">Nombre de usuario o contraseña incorrectos o error de autenticación EAP</translation>
<translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
<translation id="1244147615850840081">Proveedor de servicio celular</translation>
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb
index 2216db0..b896188 100644
--- a/ash/strings/ash_strings_es.xtb
+++ b/ash/strings/ash_strings_es.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">No hay información de red disponible.</translation>
<translation id="4625920103690741805">Rotación bloqueada (toca aquí para cambiar esta opción)</translation>
<translation id="3799026279081545374">Es posible que tu cargador esté defectuoso. Si vives en Estados Unidos, llama al teléfono 866-628-1371 para obtener ayuda y recibir un cargador de sustitución. Si vives en el Reino Unido, llama al teléfono 0800-026-0613. Si vives en Irlanda, llama al teléfono 1-800-832-664. Si vives en Canadá, llama al teléfono 866-628-1372. Si vives en Australia, llama al teléfono 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configurar datos móviles</translation>
<translation id="5871632337994001636">Administrar dispositivos...</translation>
<translation id="785750925697875037">Ver cuenta móvil</translation>
<translation id="153454903766751181">Iniciando módem móvil...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (mensajes de voz)</translation>
<translation id="6981982820502123353">Accesibilidad</translation>
<translation id="4274292172790327596">Error desconocido</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Auriculares</translation>
<translation id="225680501294068881">Buscando dispositivos...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Más información</translation>
<translation id="9046895021617826162">Error de conexión</translation>
<translation id="7168224885072002358">Restableciendo la resolución anterior en <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Esta sesión finalizará en <ph name="SESSION_TIME_REMAINING"/>. La sesión se cerrará automáticamente.</translation>
<translation id="743058460480092004">La cámara y el micrófono se están utilizando.</translation>
<translation id="8372369524088641025">Clave WEP incorrecta</translation>
<translation id="6636709850131805001">Estado desconocido</translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb
index b5fb431..b25bfb1 100644
--- a/ash/strings/ash_strings_et.xtb
+++ b/ash/strings/ash_strings_et.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Võrguteave ei ole saadaval</translation>
<translation id="4625920103690741805">Pööramine on lukustatud (muutmiseks puudutage siin)</translation>
<translation id="3799026279081545374">Teil võib olla halb laadija. Kui elate Ameerika Ühendriikides, helistage abi saamiseks ja laadija asendamiseks numbril 866-628-1371. Kui elate Ühendkuningriigis, helistage numbril 0800-026-0613. Kui elate Iirimaal, helistage numbril 1-800-832-664. Kui elate Kanadas, helistage numbril 866-628-1372. Kui elate Austraalias, helistage numbril 1-800-067-460.täis</translation>
+<translation id="3026237328237090306">Seadista mobiilne andmeside</translation>
<translation id="5871632337994001636">Seadmete haldamine ...</translation>
<translation id="785750925697875037">Kuva mobiilikonto</translation>
<translation id="153454903766751181">Mobiilimodemi lähtestamine ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (kõnena esitatud tagasiside)</translation>
<translation id="6981982820502123353">Juurdepääsetavus</translation>
<translation id="4274292172790327596">Tundmatu viga</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Kõrvaklapid</translation>
<translation id="225680501294068881">Seadmete skannimine ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Lisateave</translation>
<translation id="9046895021617826162">Ühendamine nurjus</translation>
<translation id="7168224885072002358">Ekraan ennistatakse vanale eraldusvõimele <ph name="TIMEOUT_SECONDS"/> pärast</translation>
+<translation id="973896785707726617">Selle seansi lõpuni on jäänud <ph name="SESSION_TIME_REMAINING"/>. Teid logitakse automaatselt välja.</translation>
<translation id="743058460480092004">Kaamera ja mikrofon on kasutusel.</translation>
<translation id="8372369524088641025">Halb WEP-võti</translation>
<translation id="6636709850131805001">Tundmatu olek</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb
index 5bc42e8..6dde9e8 100644
--- a/ash/strings/ash_strings_fa.xtb
+++ b/ash/strings/ash_strings_fa.xtb
@@ -48,6 +48,7 @@
<translation id="3846575436967432996">اطلاعات شبکه در دسترس نیست</translation>
<translation id="4625920103690741805">چرخش قفل شد (برای تغییر اینجا ضربه بزنید)</translation>
<translation id="3799026279081545374">ممکن است شارژرتان بد باشد. اگر در ایالات متحده زندگی میکنید، لطفاً با شماره ۱۳۷۱-۶۲۸-۸۶۶ تماس بگیرید تا راهنمایی شوید و جایگزین را دریافت کنید. اگر دربریتانیا زندگی میکنید، لطفاً با شماره ۰۶۱۳-۰۲۶-۰۸۰۰ تماس بگیرید. اگر در ایرلند زندگی میکنید، لطفاً با شماره ۶۶۴-۸۳۲-۸۰۰-۱ تماس بگیرید. اگر در کانادا زندگی میکنید، لطفاً با شماره ۱۳۷۲-۶۲۸-۸۶۶ تماس بگیرید. اگر در استرالیا زندگی میکنید، لطفاً با شماره ۴۶۰-۰۶۷-۸۰۰-۱ تماس بگیرید.</translation>
+<translation id="3026237328237090306">تنظیم اطلاعات تلفن همراه</translation>
<translation id="5871632337994001636">مدیریت دستگاهها...</translation>
<translation id="785750925697875037">مشاهده حساب تلفن همراه</translation>
<translation id="153454903766751181">در حال راهاندازی مودم سلولی...</translation>
@@ -120,7 +121,7 @@
<translation id="1621499497873603021">زمان باقیمانده تا خالیشدن شارژ باتری، <ph name="TIME_LEFT"/></translation>
<translation id="5980301590375426705">خروج از مهمان</translation>
<translation id="8308637677604853869">منوی قبلی</translation>
-<translation id="4321179778687042513">ctrl (مهار)</translation>
+<translation id="4321179778687042513">مهار</translation>
<translation id="3625258641415618104">عکس از صفحهنمایش غیرفعال است</translation>
<translation id="1346748346194534595">راست</translation>
<translation id="1773212559869067373">گواهینامه تأیید اعتبار به صورت محلی رد شد</translation>
@@ -173,6 +174,7 @@
<translation id="68610848741840742">ChromeVox (بازخورد گفتاری)</translation>
<translation id="6981982820502123353">قابلیت دسترسی</translation>
<translation id="4274292172790327596">خطای ناشناس</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">هدفون</translation>
<translation id="225680501294068881">درحال جستجو برای دستگاهها...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>، <ph name="DATE"/></translation>
@@ -181,7 +183,7 @@
<translation id="8401662262483418323">اتصال به «<ph name="NAME"/>» ناموفق بود: <ph name="DETAILS"/>
پیام سرور: <ph name="SERVER_MSG"/></translation>
<translation id="2475982808118771221">یک خطا روی داد</translation>
-<translation id="3783640748446814672">alt (دگرساز)</translation>
+<translation id="3783640748446814672">دگرساز</translation>
<translation id="7229570126336867161">EVDO مورد نیاز است</translation>
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> یک جلسه عمومی مدیریتشده توسط <ph name="DOMAIN"/> است</translation>
<translation id="9044646465488564462">اتصال به شبکه انجام نشد: <ph name="DETAILS"/></translation>
@@ -225,10 +227,11 @@
<translation id="6165508094623778733">بیشتر بیاموزید</translation>
<translation id="9046895021617826162">اتصال برقرار نشد</translation>
<translation id="7168224885072002358">برگرداندن به وضوح قدیمی در <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">این جلسه در <ph name="SESSION_TIME_REMAINING"/> به اتمام خواهد رسید. به طور خودکار از سیستم خارج خواهید شد.</translation>
<translation id="743058460480092004">دوربین و میکروفن در حال استفاده هستند.</translation>
<translation id="8372369524088641025">کلید WEP نادرست</translation>
<translation id="6636709850131805001">حالت ناشناس</translation>
-<translation id="6406704438230478924">altgr</translation>
+<translation id="6406704438230478924">دگرساز راست</translation>
<translation id="3573179567135747900">به "<ph name="FROM_LOCALE"/>" تغییر دهید (به راهاندازی دوباره نیاز دارد)</translation>
<translation id="8103386449138765447">پیامکها: <ph name="MESSAGE_COUNT"/></translation>
<translation id="7097613348211027502">ChromeVox (بازخورد گفتاری) فعال است.
@@ -248,7 +251,7 @@
<translation id="3678715477168044796"><ph name="DISPLAY_NAME"/>: <ph name="ANNOTATION"/></translation>
<translation id="2563856802393254086">تبریک میگوییم! خدمات داده «<ph name="NAME"/>» شما فعال شده است و آماده استفاده است.</translation>
<translation id="412065659894267608"><ph name="HOUR"/>ساعت <ph name="MINUTE"/>دقیقه مانده تا باتری شارژ شود</translation>
-<translation id="3077734595579995578">shift (تبدیل)</translation>
+<translation id="3077734595579995578">تبدیل</translation>
<translation id="7297443947353982503">نام کاربری/گذرواژه نادرست است یا احراز هویت EAP ناموفق بود</translation>
<translation id="6359806961507272919">پیامک از <ph name="PHONE_NUMBER"/></translation>
<translation id="1244147615850840081">شرکت مخابراتی</translation>
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb
index 42df4fe..475fbba 100644
--- a/ash/strings/ash_strings_fi.xtb
+++ b/ash/strings/ash_strings_fi.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Verkon tietoja ei saatavilla</translation>
<translation id="4625920103690741805">Kiertäminen lukittu (muuta napauttamalla tätä)</translation>
<translation id="3799026279081545374">Laturisi voi olla virheellinen. Jos asut Yhdysvalloissa, saat ohjeita ja voit tilata uuden laturin soittamalla numeroon 866 628 1371. Jos asut Isossa-Britanniassa, soita numeroon 0800 026 0613. Jos asut Irlannissa, soita numeroon 1 800 832 664. Jos asut Kanadassa, soita numeroon 866 628 1372. Jos asut Australiassa, soita numeroon 1 800 067 460.</translation>
+<translation id="3026237328237090306">Määritä mobiilitiedonsiirron asetukset</translation>
<translation id="5871632337994001636">Hallinnoi laitteita…</translation>
<translation id="785750925697875037">Näytä mobiilitili</translation>
<translation id="153454903766751181">Alustetaan matkapuhelinmodeemia…</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (äänipalaute)</translation>
<translation id="6981982820502123353">Esteettömyys</translation>
<translation id="4274292172790327596">Tunnistamaton virhe</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>.<ph name="MINUTES"/>.<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Kuulokkeet</translation>
<translation id="225680501294068881">Etsitään laitteita...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">Lisätietoja</translation>
<translation id="9046895021617826162">Yhdistäminen epäonnistui</translation>
<translation id="7168224885072002358">Palautetaan vanha tarkkuus, aikaa palautukseen <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Istunnon loppumiseen on <ph name="SESSION_TIME_REMAINING"/>. Sinut kirjataan automaattisesti ulos.</translation>
<translation id="743058460480092004">Kamera ja mikrofoni ovat käytössä.</translation>
<translation id="8372369524088641025">Väärä WEP-avain</translation>
<translation id="6636709850131805001">Tunnistamaton tila</translation>
@@ -247,7 +250,7 @@
<translation id="3678715477168044796"><ph name="DISPLAY_NAME"/>: <ph name="ANNOTATION"/></translation>
<translation id="2563856802393254086">Onnittelut! Tiedonsiirtopalvelusi <ph name="NAME"/> on aktivoitu ja käyttövalmis.</translation>
<translation id="412065659894267608">Akku täynnä <ph name="HOUR"/> t <ph name="MINUTE"/> min kuluttua</translation>
-<translation id="3077734595579995578">vaihto</translation>
+<translation id="3077734595579995578">shift</translation>
<translation id="7297443947353982503">Käyttäjänimi/salasana on virheellinen tai EAP-todennus epäonnistui</translation>
<translation id="6359806961507272919">Tekstiviesti lähettäjältä <ph name="PHONE_NUMBER"/></translation>
<translation id="1244147615850840081">Operaattori</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb
index 2cb961d..771fff4 100644
--- a/ash/strings/ash_strings_fil.xtb
+++ b/ash/strings/ash_strings_fil.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Walang available na impormasyon sa network</translation>
<translation id="4625920103690741805">Naka-lock ang Pag-rotate (Mag-tap dito upang baguhin)</translation>
<translation id="3799026279081545374">Maaaring mayroon kang hindi magandang charger. Kung nakatira ka sa US, mangyaring tumawag sa 866-628-1371 upang makatanggap ng tulong at ng kapalit. Kung nakatira ka sa UK, mangyaring tumawag sa 0800-026-0613. Kung nakatira ka sa Ireland, mangyaring tumawag sa 1-800-832-664. Kung nakatira ka sa Canada, mangyaring tumawag sa 866-628-1372. Kung nakatira ka sa Australia, mangyaring tumawag sa 1-800-067-460.</translation>
+<translation id="3026237328237090306">I-setup ang mobile data</translation>
<translation id="5871632337994001636">Pamahalaan ang mga device...</translation>
<translation id="785750925697875037">Tingnan ang account sa mobile</translation>
<translation id="153454903766751181">Sinisimulan ang cellular na modem...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (pasalitang feedback)</translation>
<translation id="6981982820502123353">Accessibility</translation>
<translation id="4274292172790327596">Di-kilalang error</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Headphone</translation>
<translation id="225680501294068881">Nag-i-scan para sa mga device...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416">Ang <ph name="DISPLAY_NAME"/> ay isang pampublikong session na pinamamahalaan ng <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Nabigong kumonekta sa network: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Lumabas sa session</translation>
-<translation id="479989351350248267">maghanap</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Naka-on ang Wi-Fi.</translation>
<translation id="4872237917498892622">Alt+Search o Shift</translation>
<translation id="2429753432712299108">Gusto ng bluetooth device na "<ph name="DEVICE_NAME"/>" ng pahintulot na magpares . Bago tanggapin, pakikumpirma na ipinapakita ang passkey na ito sa device na iyon: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Matuto nang higit pa</translation>
<translation id="9046895021617826162">Nabigo ang pagkonekta</translation>
<translation id="7168224885072002358">Magre-revert sa lumang resolution sa loob ng <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Magtatapos ang session na ito sa <ph name="SESSION_TIME_REMAINING"/>. Awtomatiko kang masa-sign out.</translation>
<translation id="743058460480092004">Ginagamit ang camera at mikropono.</translation>
<translation id="8372369524088641025">Mahinang WEP key</translation>
<translation id="6636709850131805001">Di-kilalang katayuan</translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb
index 445104a..523b16d 100644
--- a/ash/strings/ash_strings_fr.xtb
+++ b/ash/strings/ash_strings_fr.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Aucune information disponible concernant le réseau</translation>
<translation id="4625920103690741805">Rotation verrouillée (appuyer ici pour changer)</translation>
<translation id="3799026279081545374">Votre chargeur est peut-être défaillant. Si vous résidez aux États-Unis, veuillez appeler le 866 628 1371 pour obtenir de l'aide et recevoir un chargeur de substitution. Si vous résidez au Royaume-Uni, veuillez appeler le 0800 026 0613. Si vous résidez en Irlande, veuillez appeler le 1 800 832 664. Si vous résidez au Canada, veuillez appeler le 866 628 1372. Si vous résidez en Australie, veuillez appeler le 1 800 067 460.</translation>
+<translation id="3026237328237090306">Configurer les données mobiles</translation>
<translation id="5871632337994001636">Gérer les appareils…</translation>
<translation id="785750925697875037">Afficher le compte mobile</translation>
<translation id="153454903766751181">Initialisation du modem cellulaire en cours…</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (commentaires audio)</translation>
<translation id="6981982820502123353">Accessibilité</translation>
<translation id="4274292172790327596">Erreur non reconnue</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Casque</translation>
<translation id="225680501294068881">Recherche d'appareils en cours…</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">En savoir plus</translation>
<translation id="9046895021617826162">Échec de la connexion</translation>
<translation id="7168224885072002358">Rétablissement de la résolution précédente dans <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Cette session se terminera dans <ph name="SESSION_TIME_REMAINING"/>. Vous serez automatiquement déconnecté.</translation>
<translation id="743058460480092004">La caméra et le micro sont en cours d'utilisation.</translation>
<translation id="8372369524088641025">Clé WEP incorrecte</translation>
<translation id="6636709850131805001">État non reconnu</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb
index 2eb5967..b5cdbd3 100644
--- a/ash/strings/ash_strings_gu.xtb
+++ b/ash/strings/ash_strings_gu.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">કોઈ નેટવર્ક માહિતી ઉપલબ્ધ નથી</translation>
<translation id="4625920103690741805">પરિભ્રમણ લૉક કર્યું (બદલવા માટે અહીં ટેપ કરો)</translation>
<translation id="3799026279081545374">તમારી પાસે ખરાબ ચાર્જર હોઈ શકે છે. જો તમે યુએસમાં રહો છો, તો સહાય અને અવેજી પ્રાપ્ત કરવા માટે કૃપા કરીને 866-628-1371 પર કૉલ કરો. જો તમે યુકેમાં રહો છો, તો કૃપા કરીને 0800-026-0613 પર કૉલ કરો. જો તમે આયરલેન્ડમાં રહો છો, તો કૃપા કરીને 1-800-832-664 પર કૉલ કરો. જો તમે કેનેડામાં રહો છો, તો કૃપા કરીને 866-628-1372 પર કૉલ કરો. જો તમે ઑસ્ટ્રેલિયામાં રહો છો, તો કૃપા કરીને 1-800-067-460 પર કૉલ કરો.</translation>
+<translation id="3026237328237090306">મોબાઇલ ડેટા સેટ કરો</translation>
<translation id="5871632337994001636">ઉપકરણોનું સંચાલન કરો...</translation>
<translation id="785750925697875037">મોબાઇલ એકાઉન્ટ જુઓ</translation>
<translation id="153454903766751181">સેલ્યુલર મોડેમનો પ્રારંભ કરી રહ્યાં છે...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (બોલાયેલ પ્રતિસાદ)</translation>
<translation id="6981982820502123353">ઍક્સેસિબિલિટી</translation>
<translation id="4274292172790327596">અપરિચિત ભૂલ</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/> : <ph name="MINUTES"/> : <ph name="SECONDS"/></translation>
<translation id="5977415296283489383">હેડફોન</translation>
<translation id="225680501294068881">ઉપકરણો માટે સ્કેન કરી રહ્યું છે...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> એ <ph name="DOMAIN"/> દ્વારા સંચાલિત સાર્વજનિક સત્ર છે</translation>
<translation id="9044646465488564462">નેટવર્કથી કનેક્ટ કરવામાં નિષ્ફળ: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">સત્રમાંથી બહાર નીકળો</translation>
-<translation id="479989351350248267">શોધ</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi ચાલુ છે.</translation>
<translation id="4872237917498892622">Alt+Search અથવા Shift</translation>
<translation id="2429753432712299108">Bluetooth ઉપકરણ "<ph name="DEVICE_NAME"/>" ને જોડી બનાવવા માટે પરવાનગી જોઈએ છે. સ્વીકારતાં પહેલાં, કૃપા કરીને તે ઉપકરણ પર બતાવેલ આ પાસકીની પુષ્ટિ કરો: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">વધુ જાણો</translation>
<translation id="9046895021617826162">કનેક્ટ કરવું નિષ્ફળ</translation>
<translation id="7168224885072002358">જૂના રિઝોલ્યુશન પર પાછા ફરી રહ્યાં છે <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">આ સત્ર <ph name="SESSION_TIME_REMAINING"/> માં સમાપ્ત થશે. તમને આપમેળે સાઇન આઉટ કરવામાં આવશે.</translation>
<translation id="743058460480092004">કૅમેરો અને માઇક્રોફોન ઉપયોગમાં છે.</translation>
<translation id="8372369524088641025">ખરાબ WEP કી</translation>
<translation id="6636709850131805001">અપરિચિત સ્થિતિ</translation>
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb
index e1a8453..5319776 100644
--- a/ash/strings/ash_strings_hi.xtb
+++ b/ash/strings/ash_strings_hi.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">कोई नेटवर्क जानकारी उपलब्ध नहीं</translation>
<translation id="4625920103690741805">घूर्णन लॉक किया गया (बदलने के लिए यहां टैप करें)</translation>
<translation id="3799026279081545374">आपका चार्जर खराब हो सकता है. यदि आप यूएस में रहते हैं, तो कृपया सहायता प्राप्त करने और रिप्लेसमेंट के लिए 866-628-1371 पर कॉल करें. यदि आप यूके में रहते हैं, तो कृपया 0800-026-0613 पर कॉल करें. यदि आप आयरलैंड में रहते हैं, तो कृपया 1-800-832-664 पर कॉल करें. यदि आप कनाडा में रहते हैं, तो कृपया 866-628-1372 पर कॉल करें. यदि आप ऑस्ट्रेलिया में रहते हैं, तो कृपया 1-800-067-460 पर कॉल करें.</translation>
+<translation id="3026237328237090306">मोबाइल डेटा सेट करें</translation>
<translation id="5871632337994001636">उपकरणों को प्रबंधित करें...</translation>
<translation id="785750925697875037">मोबाइल खाते देखें</translation>
<translation id="153454903766751181">सेल्युलर मॉडम प्रारंभ हो रहा है...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (बोला गया फ़ीडबैक)</translation>
<translation id="6981982820502123353">पहुंच क्षमता</translation>
<translation id="4274292172790327596">अपरिचित त्रुटि</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">हेडफ़ोन</translation>
<translation id="225680501294068881">उपकरण स्कैन किए जा रहे हैं...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>, <ph name="DOMAIN"/> के द्वारा प्रबंधित एक सार्वजनिक सत्र है</translation>
<translation id="9044646465488564462">नेटवर्क से कनेक्ट करने में विफल रहा: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">सत्र से बाहर निकलें</translation>
-<translation id="479989351350248267">खोजें</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi चालू है.</translation>
<translation id="4872237917498892622">Alt+Search या Shift</translation>
<translation id="2429753432712299108">Bluetooth उपकरण "<ph name="DEVICE_NAME"/>" युग्मित करने की अनुमति चाहता है. स्वीकार करने से पहले, कृपया पुष्टि करें कि यह पासकुंजी उस उपकरण पर दिखाई जा रही है: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">अधिक जानें</translation>
<translation id="9046895021617826162">कनेक्ट करना विफल</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> में पुराने रिज़ॉल्यूशन में वापस लौट रहा है</translation>
+<translation id="973896785707726617">यह सत्र <ph name="SESSION_TIME_REMAINING"/> में समाप्त हो जाएगा. आपको स्वचालित रूप से प्रस्थान कर दिया जाएगा.</translation>
<translation id="743058460480092004">कैमरे और माइक्रोफ़ोन का उपयोग हो रहा है.</translation>
<translation id="8372369524088641025">ख़राब WEP कुंजी</translation>
<translation id="6636709850131805001">अपरिचित अवस्था</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb
index 88a3e4f..c7cecf8 100644
--- a/ash/strings/ash_strings_hr.xtb
+++ b/ash/strings/ash_strings_hr.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Informacije o mreži nisu dostupne</translation>
<translation id="4625920103690741805">Rotacija je zaključana (dodirnite ovdje za promjenu)</translation>
<translation id="3799026279081545374">Možda imate neispravan punjač. Ako živite u SAD-u, nazovite 866-628-1371 da biste dobili pomoć i zamjenski punjač. Ako živite u Velikoj Britaniji, nazovite 0800-026-0613. Ako živite u Irskoj, nazovite 1-800-832-664. Ako živite u Kanadi, nazovite 866-628-1372. Ako živite u Australiji, nazovite 1-800-067-460.</translation>
+<translation id="3026237328237090306">Postavi mobilne podatke</translation>
<translation id="5871632337994001636">Upravljanje uređajima...</translation>
<translation id="785750925697875037">Prikaz mobilnog računa</translation>
<translation id="153454903766751181">Inicijaliziranje modema mobilne mreže...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (govorne povratne informacije)</translation>
<translation id="6981982820502123353">Dostupnost</translation>
<translation id="4274292172790327596">Neprepoznata pogreška</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Slušalice</translation>
<translation id="225680501294068881">Pretraživanje uređaja...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> predstavlja javnu sesiju kojom upravlja domena <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Povezivanje s mrežom nije uspjelo: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Izlazak iz sesije</translation>
-<translation id="479989351350248267">pretraživanje</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi je uključen.</translation>
<translation id="4872237917498892622">Alt + Pretraživanje ili Shift</translation>
<translation id="2429753432712299108">Bluetooth uređaj "<ph name="DEVICE_NAME"/>" traži dopuštenje za uparivanje. Prije prihvaćanja provjerite prikazuje li se na njemu ovaj pristupni ključ: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Saznajte više</translation>
<translation id="9046895021617826162">Neuspjelo povezivanje</translation>
<translation id="7168224885072002358">Vraćanje na staru razlučivost za <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Sesija će završiti za <ph name="SESSION_TIME_REMAINING"/>. Bit ćete automatski odjavljeni.</translation>
<translation id="743058460480092004">Fotoaparat i mikrofon su aktivni.</translation>
<translation id="8372369524088641025">Neispravan WEP ključ</translation>
<translation id="6636709850131805001">Neprepoznato stanje</translation>
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb
index ae1374b..b17a722 100644
--- a/ash/strings/ash_strings_hu.xtb
+++ b/ash/strings/ash_strings_hu.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Nem áll rendelkezésre hálózati információ</translation>
<translation id="4625920103690741805">Forgatás zárolva (Koppintson ide a módosításhoz)</translation>
<translation id="3799026279081545374">Lehet, hogy rossz a töltője. Ha az Amerikai Egyesült Államokban él, segítség és csere ügyében hívja a következő telefonszámot: 866-628-1371. Ha az Egyesült Királyságban él, hívja a következő telefonszámot: 0800-026-0613. Ha Írországban él, hívja a következő telefonszámot: 1-800-832-664. Ha Kanadában él, hívja a következő telefonszámot: 866-628-1372. Ha Ausztráliában él, hívja a következő telefonszámot: 1-800-067-460.</translation>
+<translation id="3026237328237090306">Mobiladatok beállítása</translation>
<translation id="5871632337994001636">Eszközök kezelése...</translation>
<translation id="785750925697875037">Mobil fiók megtekintése</translation>
<translation id="153454903766751181">Mobilmodem inicializálása...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (beszélt visszajelzés)</translation>
<translation id="6981982820502123353">Kisegítő lehetőségek</translation>
<translation id="4274292172790327596">Azonosítatlan hiba</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Fülhallgató</translation>
<translation id="225680501294068881">Eszközök keresése...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416">A(z) <ph name="DISPLAY_NAME"/> egy <ph name="DOMAIN"/> által kezelt nyilvános munkamenet</translation>
<translation id="9044646465488564462">Nem sikerült csatlakozni a hálózathoz: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Kilépés a munkamenetből</translation>
-<translation id="479989351350248267">keresés</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi bekapcsolva.</translation>
<translation id="4872237917498892622">Alt + Keresés vagy Shift</translation>
<translation id="2429753432712299108">A(z) „<ph name="DEVICE_NAME"/>” Bluetooth-eszköz engedélyt kér a párosításra. Mielőtt elfogadná, ellenőrizze, hogy ez a biztonsági kód látható-e azon az eszközön is: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">További információ</translation>
<translation id="9046895021617826162">Csatlakozás sikertelen</translation>
<translation id="7168224885072002358">Visszaállítás a régi felbontásra <ph name="TIMEOUT_SECONDS"/> mp múlva</translation>
+<translation id="973896785707726617">A munkamenet <ph name="SESSION_TIME_REMAINING"/> múlva véget ér. Ekkor a rendszer automatikusan kijelentkezteti.</translation>
<translation id="743058460480092004">A kamera és a mikrofon épp használatban van.</translation>
<translation id="8372369524088641025">Hibás WEP kulcs</translation>
<translation id="6636709850131805001">Azonosítatlan állam</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb
index a79baee..705225a 100644
--- a/ash/strings/ash_strings_id.xtb
+++ b/ash/strings/ash_strings_id.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Tidak tersedia informasi jaringan</translation>
<translation id="4625920103690741805">Rotasi terkunci (Ketuk di sini untuk mengubah)</translation>
<translation id="3799026279081545374">Mungkin Anda memiliki pengisi daya yang tidak bagus. Apabila Anda tinggal di AS, hubungi 866-628-1371 untuk mendapatkan bantuan dan pengganti. Apabila Anda tinggal di Inggris, hubungi 0800-026-0613. Apabila Anda tinggal di Irlandia, hubungi 1-800-832-664. Apabila Anda tinggal di Kanada, hubungi 866-628-1372. Apabila Anda tinggal di Australia, hubungi 1-800-067-460.</translation>
+<translation id="3026237328237090306">Siapkan data seluler</translation>
<translation id="5871632337994001636">Mengelola perangkat...</translation>
<translation id="785750925697875037">Lihat akun seluler</translation>
<translation id="153454903766751181">Memulai modem seluler...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Masukan lisan)</translation>
<translation id="6981982820502123353">Aksesibilitas</translation>
<translation id="4274292172790327596">Kesalahan tak dikenal</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>.<ph name="MINUTES"/>.<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Headphone</translation>
<translation id="225680501294068881">Memindai perangkat...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> adalah sesi publik yang dikelola oleh <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Gagal menyambung ke jaringan: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Keluar dari sesi</translation>
-<translation id="479989351350248267">telusuri</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi diaktifkan.</translation>
<translation id="4872237917498892622">Alt+Telusuri atau Shift</translation>
<translation id="2429753432712299108">Perangkat Bluetooth "<ph name="DEVICE_NAME"/>" meminta izin untuk bersanding. Sebelum menerima, konfirmasikan bahwa kunci sandi ini ditampilkan pada perangkat tersebut: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Pelajari lebih lanjut</translation>
<translation id="9046895021617826162">Gagal menyambung</translation>
<translation id="7168224885072002358">Mengembalikan ke resolusi lama dalam <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Sesi ini akan berakhir dalam <ph name="SESSION_TIME_REMAINING"/>. Anda akan otomatis dikeluarkan.</translation>
<translation id="743058460480092004">Kamera dan mikrofon sedang digunakan.</translation>
<translation id="8372369524088641025">Kunci WEP yang buruk</translation>
<translation id="6636709850131805001">Keadaan yang tidak dikenal</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb
index 4037120..6bb92a0 100644
--- a/ash/strings/ash_strings_it.xtb
+++ b/ash/strings/ash_strings_it.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Nessuna informazione di rete disponibile</translation>
<translation id="4625920103690741805">Rotazione bloccata (tocca qui per cambiare l'impostazione)</translation>
<translation id="3799026279081545374">Probabilmente il tuo caricabatterie non è valido. Se risiedi negli Stati Uniti, chiama il numero 866-628-1371, per ricevere assistenza e un caricabatterie sostitutivo. Se risiedi nel Regno Unito, chiama il numero 0800-026-0613. Se risiedi in Irlanda, chiama il numero 1-800-832-664. Se risiedi in Canada, chiama il numero 866-628-1372. Se risiedi in Australia, chiama il numero 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configura dati mobili</translation>
<translation id="5871632337994001636">Gestisci dispositivi...</translation>
<translation id="785750925697875037">Visualizza account per cellulari</translation>
<translation id="153454903766751181">Inizializzazione del modem per cellulari...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (feedback vocale)</translation>
<translation id="6981982820502123353">Accessibilità</translation>
<translation id="4274292172790327596">Errore non riconosciuto</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Cuffia</translation>
<translation id="225680501294068881">Ricerca dispositivi in corso...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Ulteriori informazioni</translation>
<translation id="9046895021617826162">Connessione non riuscita</translation>
<translation id="7168224885072002358">Ripristino della risoluzione precedente tra <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Questa sessione terminerà fra <ph name="SESSION_TIME_REMAINING"/>. Verrà eseguita automaticamente la disconnessione.</translation>
<translation id="743058460480092004">Videocamera e microfono sono in uso.</translation>
<translation id="8372369524088641025">Chiave WEP non valida</translation>
<translation id="6636709850131805001">Stato non riconosciuto</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb
index 4625a4e..8d7fe4d 100644
--- a/ash/strings/ash_strings_iw.xtb
+++ b/ash/strings/ash_strings_iw.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">אין מידע רשת זמין</translation>
<translation id="4625920103690741805">סיבוב נעול (הקש כאן כדי לשנות)</translation>
<translation id="3799026279081545374">ייתכן שהמטען שברשותך פגום. אם אתה מתגורר בארה"ב, התקשר למספר 866-628-1371 כדי לקבל עזרה ומטען חלופי. אם אתה מתגורר בבריטניה, התקשר למספר 0800-026-0613. אם אתה מתגורר באירלנד, התקשר למספר 1-800-832-664. אם אתה מתגורר בקנדה, התקשר למספר 866-628-1372. אם אתה מתגורר באוסטרליה, התקשר למספר 1-800-067-460.</translation>
+<translation id="3026237328237090306">הגדר נתונים לנייד</translation>
<translation id="5871632337994001636">נהל מכשירים...</translation>
<translation id="785750925697875037">הצג את חשבון הנייד</translation>
<translation id="153454903766751181">מאתחל מודם סלולרי...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (משוב קולי)</translation>
<translation id="6981982820502123353">נגישות</translation>
<translation id="4274292172790327596">שגיאה לא מזוהה</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">אוזניות</translation>
<translation id="225680501294068881">סורק לאיתור מכשירים...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> היא הפעלה ציבורית המנוהלת על ידי <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">ההתחברות לרשת נכשלה: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">צא מההפעלה</translation>
-<translation id="479989351350248267">חפש</translation>
+<translation id="479989351350248267">Search</translation>
<translation id="8454013096329229812">Wi-Fi מופעל.</translation>
<translation id="4872237917498892622">Alt + חיפוש או Shift</translation>
<translation id="2429753432712299108">מכשיר ה-Bluetooth "<ph name="DEVICE_NAME"/>" מבקש הרשאה לבצע התאמה. לפני שתאשר, ודא שמפתח הסיסמה הבא מוצג במכשיר הזה: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">למידע נוסף</translation>
<translation id="9046895021617826162">החיבור נכשל</translation>
<translation id="7168224885072002358">חוזר לרזולוציה הקודמת בעוד <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">הפעילות הזו באתר תסתיים בעוד <ph name="SESSION_TIME_REMAINING"/>. תנותק אוטומטית.</translation>
<translation id="743058460480092004">המצלמה והמיקרופון נמצאים בשימוש.</translation>
<translation id="8372369524088641025">מקש WEP גרוע</translation>
<translation id="6636709850131805001">מצב לא מזוהה</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb
index 4eb48b1..dbac9c6 100644
--- a/ash/strings/ash_strings_ja.xtb
+++ b/ash/strings/ash_strings_ja.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">利用可能なネットワーク情報がありません</translation>
<translation id="4625920103690741805">回転しない(タップして変更)</translation>
<translation id="3799026279081545374">充電器に問題がある可能性があります。お住まいの国に応じて、それぞれのサポート/交換対応窓口までお問い合わせください。米国にお住まいの場合は 866-628-1371 までお電話ください。英国にお住まいの場合は 0800-026-0613 までお電話ください。アイルランドにお住まいの場合は 1-800-832-664 までお電話ください。カナダにお住まいの場合は 866-628-1372 までお電話ください。オーストラリアにお住まいの場合は 1-800-067-460 までお電話ください。</translation>
+<translation id="3026237328237090306">モバイル データをセットアップ</translation>
<translation id="5871632337994001636">デバイスを管理...</translation>
<translation id="785750925697875037">モバイル アカウントを表示</translation>
<translation id="153454903766751181">セルラー モデムを初期化しています...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox(音声フィードバック)</translation>
<translation id="6981982820502123353">アクセシビリティ</translation>
<translation id="4274292172790327596">不明なエラー</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ヘッドホン</translation>
<translation id="225680501294068881">デバイスをスキャンしています...</translation>
<translation id="5597451508971090205"><ph name="DATE"/> (<ph name="SHORT_WEEKDAY"/>)</translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">詳しく見る</translation>
<translation id="9046895021617826162">接続に失敗しました</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> 秒後に元の解像度に戻ります</translation>
+<translation id="973896785707726617">このセッションはあと <ph name="SESSION_TIME_REMAINING"/>で終了します。終了すると、自動的にログアウトします。</translation>
<translation id="743058460480092004">カメラとマイクが使用中です。</translation>
<translation id="8372369524088641025">WEP キーが正しくありません</translation>
<translation id="6636709850131805001">不明な状態</translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb
index 7537c8d..4d4bfa8 100644
--- a/ash/strings/ash_strings_kn.xtb
+++ b/ash/strings/ash_strings_kn.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">ನೆಟ್ವರ್ಕ್ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ</translation>
<translation id="4625920103690741805">ತಿರುಗುವಿಕೆ ಲಾಕ್ ಆಗಿದೆ (ಬದಲಾಯಿಸಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ)</translation>
<translation id="3799026279081545374">ನೀವು ತಪ್ಪಾದ ಚಾರ್ಜರ್ ಅನ್ನು ಹೊಂದಿರಬಹುದು. ನೀವು US ನಲ್ಲಿ ನೆಲೆಸಿದ್ದರೇ, ಕ್ರಮವಾಗಿ ಸಹಾಯ ಪಡೆಯಲು ಮತ್ತು ಬದಲಾವಣೆಯನ್ನು ಪಡೆಯಲು ದಯವಿಟ್ಟು 866-628-1371 ಗೆ ಕರೆ ಮಾಡಿ. ನೀವು UK ಯಲ್ಲಿ ನೆಲೆಸಿದ್ದರೆ, ದಯವಿಟ್ಟು 0800-026-0613 ಗೆ ಕರೆ ಮಾಡಿ. ನೀವು ಐರ್ಲೆಂಡ್ನಲ್ಲಿ ನೆಲೆಸಿದ್ದರೆ, ದಯವಿಟ್ಟು 1-800-832-664 ಗೆ ಕರೆ ಮಾಡಿ. ನೀವು ಕೆನಡಾದಲ್ಲಿ ನೆಲೆಸಿದ್ದರೆ, ದಯವಿಟ್ಟು 866-628-1372 ಗೆ ಕರೆ ಮಾಡಿ. ನೀವು ಆಸ್ಟ್ರೇಲಿಯಾದಲ್ಲಿ ನೆಲೆಸಿದ್ದರೆ, ದಯವಿಟ್ಟು 1-800-067-460 ಗೆ ಕರೆ ಮಾಡಿ.</translation>
+<translation id="3026237328237090306">ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ಹೊಂದಿಸಿ</translation>
<translation id="5871632337994001636">ಸಾಧನಗಳನ್ನು ನಿರ್ವಹಿಸಿ...</translation>
<translation id="785750925697875037">ಮೊಬೈಲ್ ಖಾತೆಯನ್ನು ವೀಕ್ಷಿಸಿ</translation>
<translation id="153454903766751181">ಸೆಲ್ಯುಲಾರ್ ಮೋಡೆಮ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (ಮಾತನಾಡುವ ಪ್ರತಿಕ್ರಿಯೆ)</translation>
<translation id="6981982820502123353">ಪ್ರವೇಶಿಸುವಿಕೆ</translation>
<translation id="4274292172790327596">ಗುರುತಿಸದೆ ಇರುವ ದೋಷ</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ಹೆಡ್ಫೋನ್</translation>
<translation id="225680501294068881">ಸಾಧನಗಳಿಗಾಗಿ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DOMAIN"/> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾದ ಸಾರ್ವಜನಿಕ ಸೆಶನ್ <ph name="DISPLAY_NAME"/> ಆಗಿದೆ</translation>
<translation id="9044646465488564462">ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲು ವಿಫಲವಾಗಿದೆ: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">ಸೆಶನ್ನಿಂದ ನಿರ್ಗಮಿಸು</translation>
-<translation id="479989351350248267">ಹುಡುಕಿ</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi ಆನ್ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="4872237917498892622">Alt+ಹುಡುಕಾಟ ಅಥವಾ Shift</translation>
<translation id="2429753432712299108">ಬ್ಲೂಟೂತ್ ಸಾಧನವು "<ph name="DEVICE_NAME"/>" ಜೋಡಣೆಗಾಗಿ ಅನುಮತಿಯನ್ನು ಬಯಸುತ್ತದೆ. ಸಮ್ಮತಿಸುವುದಕ್ಕೂ ಮೊದಲು, ದಯವಿಟ್ಟು ಆ ಸಾಧನದಲ್ಲಿ ಈ ಪಾಸ್ಕೀಲಿಯನ್ನು ತೋರಿಸಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಾತರಿಪಡಿಸಿಕೊಳ್ಳಿ: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ</translation>
<translation id="9046895021617826162">ಸಂಪರ್ಕವು ವಿಫಲವಾಗಿದೆ</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> ನಲ್ಲಿ ಹಳೆಯ ರೆಸಲ್ಯೂಷನ್ಗೆ ಹಿಂತಿರುಗಿಸಲಾಗುತ್ತಿದೆ</translation>
+<translation id="973896785707726617">ಈ ಸೆಷನ್ <ph name="SESSION_TIME_REMAINING"/> ರಲ್ಲಿ ಮುಕ್ತಾಯಗೊಳ್ಳುತ್ತದೆ. ನಿಮ್ಮನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೈನ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತದೆ.</translation>
<translation id="743058460480092004">ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ಬಳಕೆಯಲ್ಲಿವೆ.</translation>
<translation id="8372369524088641025">ಕೆಟ್ಟ WEP ಕೀ</translation>
<translation id="6636709850131805001">ಅಂಗೀಕಾರವಲ್ಲದ ರಾಜ್ಯ</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb
index 725113a..5ec6278 100644
--- a/ash/strings/ash_strings_ko.xtb
+++ b/ash/strings/ash_strings_ko.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">네트워크 정보 없음</translation>
<translation id="4625920103690741805">회전 잠금(변경하려면 여기를 탭)</translation>
<translation id="3799026279081545374">충전기에 문제가 있을 수 있습니다. 미국에 거주하는 경우 866-628-1371에 전화하여 문의하고 교체받으세요. 영국에 거주하는 경우 0800-026-0613에 문의하세요. 아일랜드에 거주하는 경우 1-800-832-664에 문의하세요. 캐나다에 거주하는 경우 866-628-1372에 문의하세요. 오스트레일리아에 거주하는 경우 1-800-067-460에 문의하세요.</translation>
+<translation id="3026237328237090306">모바일 데이터 설정</translation>
<translation id="5871632337994001636">기기 관리...</translation>
<translation id="785750925697875037">모바일 계정 표시</translation>
<translation id="153454903766751181">휴대전화 모뎀 초기화하는 중...</translation>
@@ -122,7 +123,7 @@
<translation id="1621499497873603021">남은 배터리 사용 시간은 <ph name="TIME_LEFT"/>입니다.</translation>
<translation id="5980301590375426705">손님 세션 종료</translation>
<translation id="8308637677604853869">이전 메뉴</translation>
-<translation id="4321179778687042513">Ctrl</translation>
+<translation id="4321179778687042513">ctrl</translation>
<translation id="3625258641415618104">스크린샷 캡쳐 사용 중지됨</translation>
<translation id="1346748346194534595">오른쪽</translation>
<translation id="1773212559869067373">인증서가 로컬로 거부됨</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox(음성 피드백)</translation>
<translation id="6981982820502123353">접근성</translation>
<translation id="4274292172790327596">인식할 수 없는 오류</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">헤드폰</translation>
<translation id="225680501294068881">기기 검색 중...</translation>
<translation id="5597451508971090205"><ph name="DATE"/> <ph name="SHORT_WEEKDAY"/></translation>
@@ -183,7 +185,7 @@
<translation id="8401662262483418323">'<ph name="NAME"/>'에 연결하지 못함: <ph name="DETAILS"/>
서버 메시지: <ph name="SERVER_MSG"/></translation>
<translation id="2475982808118771221">오류가 발생했습니다.</translation>
-<translation id="3783640748446814672">Alt</translation>
+<translation id="3783640748446814672">alt</translation>
<translation id="7229570126336867161">EVDO가 필요합니다.</translation>
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>은(는) <ph name="DOMAIN"/>에서 관리하는 공개 세션입니다.</translation>
<translation id="9044646465488564462">네트워크 연결 실패: <ph name="DETAILS"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">자세히 알아보기</translation>
<translation id="9046895021617826162">연결 실패</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/>초 후 기존 해상도로 돌아갑니다.</translation>
+<translation id="973896785707726617">이 세션은 <ph name="SESSION_TIME_REMAINING"/> 후에 종료되어 자동으로 로그아웃됩니다.</translation>
<translation id="743058460480092004">카메라와 마이크가 사용 중입니다.</translation>
<translation id="8372369524088641025">잘못된 WEP 키</translation>
<translation id="6636709850131805001">인식할 수 없는 상태</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb
index bcb2ea9..efe6241 100644
--- a/ash/strings/ash_strings_lt.xtb
+++ b/ash/strings/ash_strings_lt.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Nėra tinklo informacijos</translation>
<translation id="4625920103690741805">Kaitaliojimas užrakintas (palieskite čia, kad pakeistumėte)</translation>
<translation id="3799026279081545374">Turbūt jūsų kroviklis yra netinkamas. Jei gyvenate JAV, skambinkite numeriu 866-628-1371, kad gautumėte pagalbos ir būtų pakeistas kroviklis. Jei gyvenate JK, skambinkite numeriu 0800-026-0613. Jei gyvenate Airijoje, skambinkite numeriu 1-800-832-664. Jei gyvenate Kanadoje, skambinkite numeriu 866-628-1372. Jei gyvenate Australijoje, skambinkite numeriu 1-800-067-460.</translation>
+<translation id="3026237328237090306">Nustatyti duomenis mobiliesiems</translation>
<translation id="5871632337994001636">Valdyti įrenginius...</translation>
<translation id="785750925697875037">Žiūrėti paskyrą mobiliesiems</translation>
<translation id="153454903766751181">Inicijuojamas korinio ryšio modemas...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">„ChromeVox“ (žodiniai atsiliepimai)</translation>
<translation id="6981982820502123353">Pritaikymas neįgaliesiems</translation>
<translation id="4274292172790327596">Neatpažįstama klaida</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Ausinės</translation>
<translation id="225680501294068881">Ieškoma įrenginių...</translation>
<translation id="5597451508971090205"><ph name="DATE"/>, <ph name="SHORT_WEEKDAY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Sužinokite daugiau</translation>
<translation id="9046895021617826162">Nepavyko prisijungti</translation>
<translation id="7168224885072002358">Po <ph name="TIMEOUT_SECONDS"/> bus grąžinta sena skyra</translation>
+<translation id="973896785707726617">Ši sesija baigsis po <ph name="SESSION_TIME_REMAINING"/>. Būsite automatiškai atjungti.</translation>
<translation id="743058460480092004">Kamera ir mikrofonas naudojami.</translation>
<translation id="8372369524088641025">Netinkamas WEP raktas</translation>
<translation id="6636709850131805001">Neatpažinta būsena</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb
index 7058731..3f23bce 100644
--- a/ash/strings/ash_strings_lv.xtb
+++ b/ash/strings/ash_strings_lv.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Tīkla informācija nav pieejama.</translation>
<translation id="4625920103690741805">Pagriešana ir bloķēta (pieskarieties šeit, lai mainītu)</translation>
<translation id="3799026279081545374">Iespējams, uzlādes ierīce ir bojāta. Ja dzīvojat ASV, lūdzu, zvaniet 866-628-1371, lai saņemtu palīdzību vai pieprasītu ierīces aizstāšanu. Ja dzīvojat Lielbritānijā, lūdzu, zvaniet 0800-026-0613. Ja dzīvojat Īrijā, lūdzu, zvaniet 1-800-832-664. Ja dzīvojat Kanādā, lūdzu, zvaniet 866-628-1372. Ja dzīvojat Austrālijā, lūdzu, zvaniet 1-800-067-460.</translation>
+<translation id="3026237328237090306">Iestatīt mobilo datu pārraidi</translation>
<translation id="5871632337994001636">Pārvaldīt ierīces...</translation>
<translation id="785750925697875037">Skatīt mobilo kontu</translation>
<translation id="153454903766751181">Notiek mobilā modema inicializēšana...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (balss komentāri)</translation>
<translation id="6981982820502123353">Pieejamība</translation>
<translation id="4274292172790327596">Neatpazīta kļūda</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Austiņas</translation>
<translation id="225680501294068881">Notiek ierīču meklēšana...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Uzziniet vairāk</translation>
<translation id="9046895021617826162">Savienojums neizdevās</translation>
<translation id="7168224885072002358">Iepriekšējā izšķirtspēja tiks atgriezta pēc <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Atlikušais laiks līdz šīs sesijas beigām: <ph name="SESSION_TIME_REMAINING"/>. Jūs tiksiet automātiski izrakstīts.</translation>
<translation id="743058460480092004">Kamera un mikrofons tiek lietoti.</translation>
<translation id="8372369524088641025">Neatbilstoša WEP atslēga</translation>
<translation id="6636709850131805001">Neatpazīts stāvoklis</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb
index e19b290..5ff3f2e 100644
--- a/ash/strings/ash_strings_ml.xtb
+++ b/ash/strings/ash_strings_ml.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">നെറ്റ്വർക്ക് വിവരങ്ങളൊന്നും ലഭ്യമല്ല</translation>
<translation id="4625920103690741805">റൊട്ടേഷൻ ലോക്കുചെയ്തു (മാറ്റാൻ ഇവിടെ ടാപ്പുചെയ്യുക)</translation>
<translation id="3799026279081545374">നിങ്ങളുടെ ചാർജർ മോശമായിരിക്കാം. നിങ്ങൾ യു.എസിലാണ് താമസിക്കുന്നതെങ്കിൽ, സഹായത്തിനും മാറ്റിവാങ്ങുന്നതിനുമായി 866-628-1371 എന്ന നമ്പറിൽ വിളിക്കുക. നിങ്ങൾ യു.കെയിലാണ് താമസിക്കുന്നതെങ്കിൽ, 0800-026-0613 എന്ന നമ്പറിൽ വിളിക്കുക. നിങ്ങൾ അയർലൻഡിലാണ് താമസിക്കുന്നതെങ്കിൽ, 1-800-832-664 എന്ന നമ്പറിൽ വിളിക്കുക. നിങ്ങൾ കാനഡയിലാണ് താമസിക്കുന്നതെങ്കിൽ, 866-628-1372 എന്ന നമ്പറിൽ വിളിക്കുക. നിങ്ങൾ ഓസ്ട്രേലിയയിലാണ് താമസിക്കുന്നതെങ്കിൽ, 1-800-067-460 എന്ന നമ്പറിൽ വിളിക്കുക.</translation>
+<translation id="3026237328237090306">മൊബൈൽ ഡാറ്റ സജ്ജമാക്കുക</translation>
<translation id="5871632337994001636">ഉപകരണങ്ങൾ നിയന്ത്രിക്കുക...</translation>
<translation id="785750925697875037">മൊബൈൽ അക്കൗണ്ട് കാണുക</translation>
<translation id="153454903766751181">സെല്ലുലാർ മോഡം സമാരംഭിക്കുന്നു...</translation>
@@ -174,6 +175,7 @@
<translation id="68610848741840742">ChromeVox (സ്പോക്കൺ ഫീഡ്ബാക്ക്)</translation>
<translation id="6981982820502123353">പ്രവേശനക്ഷമത</translation>
<translation id="4274292172790327596">തിരിച്ചറിയാത്ത പിശക്</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ഹെഡ്ഫോൺ</translation>
<translation id="225680501294068881">ഉപകരണങ്ങൾക്കായി സ്കാൻ ചെയ്യുന്നു...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -187,7 +189,7 @@
<translation id="2999742336789313416"><ph name="DOMAIN"/> നിയന്ത്രിക്കുന്ന എല്ലാവർക്കുമുള്ള ഒരു സെഷനാണ് <ph name="DISPLAY_NAME"/></translation>
<translation id="9044646465488564462">നെറ്റ്വര്ക്കിലേക്ക് കണക്റ്റുചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">സെഷനിൽ നിന്ന് പുറത്തുകടക്കുക</translation>
-<translation id="479989351350248267">തിരയൽ</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi ഓൺ ചെയ്തു.</translation>
<translation id="4872237917498892622">Alt+തിരയൽ അല്ലെങ്കിൽ Shift</translation>
<translation id="2429753432712299108">"<ph name="DEVICE_NAME"/>" എന്ന Bluetooth ഉപകരണം ജോടിയാക്കുന്നതിനുള്ള അനുമതി ആവശ്യപ്പെടുന്നു. അനുമതി നൽകുന്നതിനുമുമ്പ്, ആ ഉപകരണത്തിൽ ഈ പാസ്കീ കാണിച്ചിരിക്കുന്നുവെന്ന് സ്ഥിരീകരിക്കുക: <ph name="PASSKEY"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">കൂടുതല് മനസിലാക്കുക</translation>
<translation id="9046895021617826162">ബന്ധിപ്പിക്കല് പരാജയപ്പെട്ടു</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/>-ൽ പഴയ മിഴിവിലേക്ക് പഴയപടിയാക്കുന്നു</translation>
+<translation id="973896785707726617"><ph name="SESSION_TIME_REMAINING"/> ആകുമ്പോൾ ഈ സെഷൻ അവസാനിക്കും. നിങ്ങൾ യാന്ത്രികമായി സൈൻ ഔട്ടാകും.</translation>
<translation id="743058460480092004">ക്യാമറയും മൈക്രോഫോണും ഉപയോഗത്തിലാണ്.</translation>
<translation id="8372369524088641025">മോശം WEP കീ</translation>
<translation id="6636709850131805001">തിരിച്ചറിയാത്ത അവസ്ഥ</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb
index 617400c..7c4fd2e 100644
--- a/ash/strings/ash_strings_mr.xtb
+++ b/ash/strings/ash_strings_mr.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">कोणतीही नेटवर्क माहिती उपलब्ध नाही</translation>
<translation id="4625920103690741805">फिरवणे लॉक केले (बदलण्यासाठी येथे टॅप करा)</translation>
<translation id="3799026279081545374">आपल्याकडे खराब चार्जर असू शकतो. आपण यूएस मध्ये रहात असल्यास, कृपया मदत आणि दुसरा चार्जर प्राप्त करण्यासाठी 866-628-1371 वर कॉल करा. आपण यूके मध्ये रहात असल्यास, कृपया 0800-026-0613 वर कॉल करा. आपण आयर्लंडमध्ये रहात असल्यास, कृपया 1-800-832-664 वर कॉल करा. आपण कॅनडामध्ये रहात असल्यास, कृपया 866-628-1372 वर कॉल करा. आपण ऑस्ट्रेलियामध्ये रहात असल्यास, कृपया 1-800-067-460 वर कॉल करा.</translation>
+<translation id="3026237328237090306">मोबाइल डेटा सेटअप करा</translation>
<translation id="5871632337994001636">डिव्हाइस व्यवस्थापित करा...</translation>
<translation id="785750925697875037">मोबाइल खाते पहा</translation>
<translation id="153454903766751181">सेल्युलर मोडेम आरंभ करत आहे...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (बोललेला अभिप्राय)</translation>
<translation id="6981982820502123353">प्रवेशयोग्यता</translation>
<translation id="4274292172790327596">अपरिचित त्रुटी</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">हेडफोन</translation>
<translation id="225680501294068881">डिव्हाइसेससाठी स्कॅन करत आहे...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> हे <ph name="DOMAIN"/> द्वारे व्यवस्थापित कलेले एक सावर्जनिक सत्र आहे</translation>
<translation id="9044646465488564462">नेटवर्कशी कनेक्ट करण्यात अयशस्वी: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">सत्र निर्गमन करा</translation>
-<translation id="479989351350248267">शोध</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi चालू आहे.</translation>
<translation id="4872237917498892622">Alt+Search किंवा Shift</translation>
<translation id="2429753432712299108">"<ph name="DEVICE_NAME"/>" Bluetooth डिव्हाइस जोडण्यासाठी परवानगी घेऊ इच्छिते. स्वीकार करण्यापूर्वी, कृपया त्या डिव्हाइसवर ही पासकी दर्शविली असल्याची पुष्टी करा: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">अधिक जाणून घ्या</translation>
<translation id="9046895021617826162">कनेक्ट करण्यात अयशस्वी</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> मध्ये जुन्या रिजोल्यूशनवर परत करत आहे</translation>
+<translation id="973896785707726617">हे सत्र <ph name="SESSION_TIME_REMAINING"/> मध्ये समाप्त होईल. आपल्याला स्वयंचलितपणे साइन आउट केले जाईल.</translation>
<translation id="743058460480092004">कॅमेरा आणि मायक्रोफोन वापरात आहेत.</translation>
<translation id="8372369524088641025">खराब WEP की</translation>
<translation id="6636709850131805001">अपरिचित राज्य</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 99afb81..15c58fa 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Tiada maklumat rangkaian tersedia</translation>
<translation id="4625920103690741805">Putaran dikunci (Ketik di sini untuk menukar)</translation>
<translation id="3799026279081545374">Anda mungkin mempunyai pengecas yang rosak. Jika anda tinggal di AS, sila hubungi 866-628-1371866-628-1371 untuk mendapatkan bantuan dan pengecas ganti. Jika anda tinggal di UK, sila hubungi 0800-026-06130800-026-0613. Jika anda tinggal di Ireland, sila hubungi 1-800-832-664. Jika anda tinggal di Kanada, sila hubungi 866-628-1372866-628-1372. Jika anda tinggal di Australia, sila hubungi 1-800-067-460.</translation>
+<translation id="3026237328237090306">Sediakan data mudah alih</translation>
<translation id="5871632337994001636">Uruskan peranti...</translation>
<translation id="785750925697875037">Lihat akaun mudah alih</translation>
<translation id="153454903766751181">Memulakan modem selular...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Maklum balas pertuturan)</translation>
<translation id="6981982820502123353">Kebolehcapaian</translation>
<translation id="4274292172790327596">Ralat tidak dikenali</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Fon kepala</translation>
<translation id="225680501294068881">Mengimbas untuk peranti...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ialah sesi awam yang diurus oleh <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Gagal bersambung ke rangkaian: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Keluar dari sesi</translation>
-<translation id="479989351350248267">cari</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi dihidupkan.</translation>
<translation id="4872237917498892622">Alt+Search atau Shift</translation>
<translation id="2429753432712299108">Peranti Bluetooth "<ph name="DEVICE_NAME"/>" ingin kebenaran untuk berpasangan. Sebelum menerimanya, sila sahkan bahawa kekunci laluan ini dipaparkan pada peranti tersebut: <ph name="PASSKEY"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">Ketahui lebih lanjut</translation>
<translation id="9046895021617826162">Gagal disambungkan</translation>
<translation id="7168224885072002358">Kembali kepada peleraian lama dalam <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Sesi ini akan berakhir dalam <ph name="SESSION_TIME_REMAINING"/>. Anda akan dilog keluar secara automatik.</translation>
<translation id="743058460480092004">Kamera dan mikrofon sedang digunakan.</translation>
<translation id="8372369524088641025">Kekunci WEP teruk</translation>
<translation id="6636709850131805001">Keadaan tidak dikenali</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index 86afabc..e6b029a 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Geen netwerkinformatie beschikbaar</translation>
<translation id="4625920103690741805">Rotatie vergrendeld (Tik hier om te wijzigen)</translation>
<translation id="3799026279081545374">Je hebt mogelijk een slechte oplader. Als je in de Verenigde Staten woont, bel je 866-628-1371 om ondersteuning en een vervangende lader te ontvangen. Als je in het Verenigd Koninkrijk woont, bel je 0800-026-0613. Als je in Ierland woont, bel je 1-800-832-664. Als je in Canada woont, bel je 866-628-1372. Als je in Australië woont, bel je 1-800-067-460.</translation>
+<translation id="3026237328237090306">Mobiele gegevens instellen</translation>
<translation id="5871632337994001636">Apparaten beheren...</translation>
<translation id="785750925697875037">Mobiel account weergeven</translation>
<translation id="153454903766751181">Mobiele modem initialiseren...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (gesproken feedback)</translation>
<translation id="6981982820502123353">Toegankelijkheid</translation>
<translation id="4274292172790327596">Onbekende fout</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Hoofdtelefoon</translation>
<translation id="225680501294068881">Scannen naar apparaten...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Meer informatie</translation>
<translation id="9046895021617826162">Verbinding mislukt</translation>
<translation id="7168224885072002358">Terugzetten naar oude resolutie over <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Deze sessie loopt af over <ph name="SESSION_TIME_REMAINING"/>. Je wordt automatisch uitgelogd.</translation>
<translation id="743058460480092004">Camera en microfoon zijn in gebruik.</translation>
<translation id="8372369524088641025">Slechte WEP-sleutel</translation>
<translation id="6636709850131805001">Niet-herkende staat</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb
index 3bef45f..919bf61 100644
--- a/ash/strings/ash_strings_no.xtb
+++ b/ash/strings/ash_strings_no.xtb
@@ -50,6 +50,7 @@
<translation id="4625920103690741805">Rotasjon låst (trykk her for å endre)</translation>
<translation id="3799026279081545374">Det kan hende laderen din fungerer dårlig. Hvis du bor i USA, kan du ringe 866-628-1371 for å få hjelp og erstatning. Hvis du bor i Storbritannia, kan du ringe 0800-026-0613. Hvis du bor i Irland, kan du ringe 1-800-832-664. Hvis du bor i Canada, kan du ringe
866-628-1372. Hvis du bor i Australia, kan du ringe 1-800-067-460.</translation>
+<translation id="3026237328237090306">Konfigurer mobildata</translation>
<translation id="5871632337994001636">Administrer enheter</translation>
<translation id="785750925697875037">Se mobilkontoen</translation>
<translation id="153454903766751181">Starter mobilmodemet ...</translation>
@@ -176,6 +177,7 @@
<translation id="68610848741840742">ChromeVox (muntlig tilbakemelding)</translation>
<translation id="6981982820502123353">Tilgjengelighet</translation>
<translation id="4274292172790327596">Ukjent feil</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Hodetelefon</translation>
<translation id="225680501294068881">Leter etter enheter ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
@@ -228,6 +230,7 @@
<translation id="6165508094623778733">Les mer</translation>
<translation id="9046895021617826162">Tilkoblingen mislyktes</translation>
<translation id="7168224885072002358">Går tilbake til den gamle oppløsningen om <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Denne økten slutter om <ph name="SESSION_TIME_REMAINING"/>. Du logges ut automatisk.</translation>
<translation id="743058460480092004">Kameraet og mikrofonen er i bruk.</translation>
<translation id="8372369524088641025">Feil WEP-nøkkel</translation>
<translation id="6636709850131805001">Ikke gjenkjent tilstand</translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb
index ea43c15..b1dee3b 100644
--- a/ash/strings/ash_strings_pl.xtb
+++ b/ash/strings/ash_strings_pl.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Brak informacji o sieciach</translation>
<translation id="4625920103690741805">Obracanie zablokowane (kliknij tutaj, by to zmienić)</translation>
<translation id="3799026279081545374">Możesz mieć niewłaściwą ładowarkę. Jeśli mieszkasz w Stanach Zjednoczonych, aby uzyskać pomoc i zamówić ładowarkę zastępczą, zadzwoń pod numer 866-628-1371. W Wielkiej Brytanii – pod numer 0800-026-0613. W Irlandii – pod numer 1-800-832-664. W Kanadzie – pod numer 866-628-1372. W Australii – pod numer 1-800-067-460.</translation>
+<translation id="3026237328237090306">Skonfiguruj komórkową transmisję danych</translation>
<translation id="5871632337994001636">Zarządzaj urządzeniami...</translation>
<translation id="785750925697875037">Wyświetl konto dla telefonów komórkowych</translation>
<translation id="153454903766751181">Inicjuję modem komórkowy...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (potwierdzenia głosowe)</translation>
<translation id="6981982820502123353">Ułatwienia dostępu</translation>
<translation id="4274292172790327596">Nierozpoznany błąd</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Słuchawki</translation>
<translation id="225680501294068881">Skanowanie w poszukiwaniu urządzeń...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> jest publiczną sesją zarządzaną przez <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Nie udało się połączyć z siecią: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Zakończ sesję</translation>
-<translation id="479989351350248267">szukaj</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi włączone.</translation>
<translation id="4872237917498892622">Alt+Szukaj lub Shift</translation>
<translation id="2429753432712299108">Urządzenie Bluetooth „<ph name="DEVICE_NAME"/>” chce się sparować. Zanim to zaakceptujesz, sprawdź, czy na tym urządzeniu wyświetla się klucz: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Więcej informacji</translation>
<translation id="9046895021617826162">Łączenie nie powiodło się</translation>
<translation id="7168224885072002358">Powrót do wcześniejszej rozdzielczości za <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Ta sesja zakończy się za <ph name="SESSION_TIME_REMAINING"/>. Nastąpi automatyczne wylogowanie.</translation>
<translation id="743058460480092004">Aparat i mikrofon są używane.</translation>
<translation id="8372369524088641025">Błędny klucz WEP</translation>
<translation id="6636709850131805001">Nierozpoznany stan</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb
index 6c12133..8cbbd60 100644
--- a/ash/strings/ash_strings_pt-BR.xtb
+++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Não há informações de rede disponíveis</translation>
<translation id="4625920103690741805">Rotação bloqueada (toque aqui para alterar)</translation>
<translation id="3799026279081545374">Seu carregador pode estar com defeito. Se você mora nos EUA, ligue para 866-628-1371 para receber ajuda e uma substituição. Se você mora no Reino Unido, ligue para 0800-026-0613. Se você mora na Irlanda, ligue para 1-800-832-664. Se você mora no Canadá, ligue para 866-628-1372. Se você mora na Austrália, ligue para 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configurar dados móveis</translation>
<translation id="5871632337994001636">Gerenciar dispositivos...</translation>
<translation id="785750925697875037">Exibir conta de celular</translation>
<translation id="153454903766751181">Inicializando modem celular...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (feedback falado)</translation>
<translation id="6981982820502123353">Acessibilidade</translation>
<translation id="4274292172790327596">Erro desconhecido</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Fone de ouvido</translation>
<translation id="225680501294068881">Procurando dispositivos...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">Saiba mais</translation>
<translation id="9046895021617826162">Falha na conexão</translation>
<translation id="7168224885072002358">Revertendo para resolução anterior em <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Esta sessão terminará em <ph name="SESSION_TIME_REMAINING"/>. Você será automaticamente desconectado.</translation>
<translation id="743058460480092004">A câmera e o microfone estão em uso.</translation>
<translation id="8372369524088641025">Chave WEP incorreta</translation>
<translation id="6636709850131805001">Estado não reconhecido</translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb
index ab49566..f273f3b 100644
--- a/ash/strings/ash_strings_pt-PT.xtb
+++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Não existem informações de rede disponíveis</translation>
<translation id="4625920103690741805">Rotação bloqueada (toque aqui para alterar)</translation>
<translation id="3799026279081545374">Pode ter um carregador defeituoso. Se vive nos EUA, ligue para 866-628-1371 para receber ajuda e uma substituição. Se vive no Reino Unido, ligue para 0800-026-0613. Se vive na Irlanda, ligue para 1-800-832-664. Se vive no Canadá, ligue para 866-628-1372. Se vive na Austrália, ligue para 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configurar dados móveis</translation>
<translation id="5871632337994001636">Gerir dispositivos...</translation>
<translation id="785750925697875037">Ver conta do telemóvel</translation>
<translation id="153454903766751181">A inicializar o modem celular...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (respostas faladas)</translation>
<translation id="6981982820502123353">Acessibilidade</translation>
<translation id="4274292172790327596">Erro não reconhecido</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Auscultador</translation>
<translation id="225680501294068881">A procurar dispositivos...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> é uma sessão pública gerida por <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Não foi possível ligar à rede: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Sair da sessão</translation>
-<translation id="479989351350248267">pesquisar</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">A ligação Wi-Fi está ativada.</translation>
<translation id="4872237917498892622">Alt + Pesquisar ou Shift</translation>
<translation id="2429753432712299108">O dispositivo Bluetooth "<ph name="DEVICE_NAME"/>" necessita de autorização para sincronizar. Antes de aceitar, confirme que esta chave está indicada nesse dispositivo: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Saiba mais</translation>
<translation id="9046895021617826162">A ligação falhou</translation>
<translation id="7168224885072002358">A reverter para a resolução antiga dentro de <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Esta sessão irá terminar em <ph name="SESSION_TIME_REMAINING"/>. A sua sessão será automaticamente terminada.</translation>
<translation id="743058460480092004">A câmara e o microfone estão a ser utilizados.</translation>
<translation id="8372369524088641025">Chave WEP incorrecta</translation>
<translation id="6636709850131805001">Estado não reconhecido</translation>
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb
index 63e0c0e..f770ca6 100644
--- a/ash/strings/ash_strings_ro.xtb
+++ b/ash/strings/ash_strings_ro.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Nu sunt disponibile informații despre rețele</translation>
<translation id="4625920103690741805">Rotire blocată (atingeți aici pentru a schimba)</translation>
<translation id="3799026279081545374">Este posibil să aveți un încărcător defect. Dacă locuiți în S.U.A., sunați la 866-628-1371 pentru a primi asistență și un încărcător de schimb. Dacă locuiți în Regatul Unit, sunați la 0800-026-0613. Dacă locuiți în Irlanda, sunați la 1-800-832-664. Dacă locuiți în Canada, sunați la 866-628-1372. Dacă locuiți în Australia, sunați la 1-800-067-460.</translation>
+<translation id="3026237328237090306">Configurați datele mobile</translation>
<translation id="5871632337994001636">Gestionați dispozitivele...</translation>
<translation id="785750925697875037">Afișați contul mobil</translation>
<translation id="153454903766751181">Se inițializează modemul mobil...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (feedback rostit)</translation>
<translation id="6981982820502123353">Accesibilitate</translation>
<translation id="4274292172790327596">Eroare nerecunoscută</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Căști</translation>
<translation id="225680501294068881">Se caută gadgeturi...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Aflați mai multe</translation>
<translation id="9046895021617826162">Conectarea a eșuat</translation>
<translation id="7168224885072002358">Se revine la rezoluția anterioară în <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Această sesiune se va încheia în <ph name="SESSION_TIME_REMAINING"/>. Veți fi deconectat(ă) automat.</translation>
<translation id="743058460480092004">Camera foto și microfonul sunt în uz.</translation>
<translation id="8372369524088641025">Cheie WEP greșită</translation>
<translation id="6636709850131805001">Stare nerecunoscută</translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb
index a386008..31953dc 100644
--- a/ash/strings/ash_strings_ru.xtb
+++ b/ash/strings/ash_strings_ru.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Информация о сетях недоступна</translation>
<translation id="4625920103690741805">Поворот заблокирован (нажмите, чтобы изменить)</translation>
<translation id="3799026279081545374">Возможно, ваше зарядное устройство требует замены. Для получения подробной информации позвоните по телефону: в США – 866-628-1371, в Великобритании – 0800-026-0613, в Ирландии – 1-800-832-664, в Канаде – 866-628-1372, в Австралии – 1-800-067-460.</translation>
+<translation id="3026237328237090306">Настроить мобильную передачу данных</translation>
<translation id="5871632337994001636">Управление устройствами...</translation>
<translation id="785750925697875037">Просмотр мобильного аккаунта</translation>
<translation id="153454903766751181">Инициализация сотового модема…</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (голосовое сопровождение)</translation>
<translation id="6981982820502123353">Специальные возможности</translation>
<translation id="4274292172790327596">Нераспознанная ошибка</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Наушники</translation>
<translation id="225680501294068881">Поиск устройств…</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Подробнее...</translation>
<translation id="9046895021617826162">Сбой подключения</translation>
<translation id="7168224885072002358">Возврат к предыдущему разрешению через <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Сеанс будет завершен через <ph name="SESSION_TIME_REMAINING"/>. Произойдет автоматический выход из системы.</translation>
<translation id="743058460480092004">Камера и микрофон используются.</translation>
<translation id="8372369524088641025">Недопустимый ключ WEP</translation>
<translation id="6636709850131805001">Нераспознанное состояние</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb
index 62dd005..43eb636 100644
--- a/ash/strings/ash_strings_sk.xtb
+++ b/ash/strings/ash_strings_sk.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Informácie o sieti nie sú k dispozícii</translation>
<translation id="4625920103690741805">Otáčanie je uzamknuté (klepnutím tu to zmeníte)</translation>
<translation id="3799026279081545374">Je možné, že máte chybnú nabíjačku. Ak žijete v USA, požiadajte o pomoc a výmenu na čísle 866-628-1371. Ak žijete v Spojenom kráľovstve, volajte na číslo 0800-026-0613. Ak žijete v Írsku, volajte na číslo 1-800-832-664. Ak žijete v Kanade, volajte na číslo 866-628-1372. Ak žijete v Austrálii, volajte na číslo 1-800-067-460.</translation>
+<translation id="3026237328237090306">Nastavenie mobilného dátového pripojenia</translation>
<translation id="5871632337994001636">Spravovať zariadenia...</translation>
<translation id="785750925697875037">Zobraziť mobilný účet</translation>
<translation id="153454903766751181">Inicializácia mobilného modemu...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (hlasová spätná väzba)</translation>
<translation id="6981982820502123353">Dostupnosť</translation>
<translation id="4274292172790327596">Nerozpoznaná chyba</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Slúchadlo</translation>
<translation id="225680501294068881">Hľadajú sa zariadenia...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je verejná relácia spravovaná stránkami <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Nepodarilo sa pripojiť k sieti: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Ukončiť reláciu</translation>
-<translation id="479989351350248267">hľadať</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Pripojenie Wi-Fi je zapnuté.</translation>
<translation id="4872237917498892622">Alt + Hľadať alebo Shift</translation>
<translation id="2429753432712299108">Zariadenie Bluetooth s názvom <ph name="DEVICE_NAME"/> žiada o povolenie párovania. Skôr ako žiadosti vyhoviete, overte, či sa na danom zariadení zobrazuje nasledujúci prístupový kľúč: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Viac informácií</translation>
<translation id="9046895021617826162">Zlyhanie pripojenia</translation>
<translation id="7168224885072002358">Vrátenie starého rozlíšenia prebehne o <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Relácia sa ukončí o <ph name="SESSION_TIME_REMAINING"/>. Automaticky dôjde k odhláseniu.</translation>
<translation id="743058460480092004">Fotoaparát a mikrofón sa používajú.</translation>
<translation id="8372369524088641025">Zlý kľúč WEP</translation>
<translation id="6636709850131805001">Nerozpoznaný stav</translation>
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb
index 1d7fe0c..c0011ab 100644
--- a/ash/strings/ash_strings_sl.xtb
+++ b/ash/strings/ash_strings_sl.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Ni podatkov o omrežju</translation>
<translation id="4625920103690741805">Sukanje je zaklenjeno (dotaknite se tu, če želite to spremeniti)</translation>
<translation id="3799026279081545374">Morda je vaš polnilnik okvarjen. Če živite v Združenih državah, pokličite 866-628-1371 za pomoč in zamenjavo. Če živite v Združenem kraljestvu, pokličite 0800-026-0613. Če živite na Irskem, pokličite 1-800-832-664. Če živite v Kanadi, pokličite 866-628-1372. Če živite v Avstraliji, pokličite 1-800-067-460.</translation>
+<translation id="3026237328237090306">Nastavitev mobilne podatkovne povezave</translation>
<translation id="5871632337994001636">Upravljanje naprav ...</translation>
<translation id="785750925697875037">Prikaz mobilnega računa</translation>
<translation id="153454903766751181">Inicializacija modema za mobilno omrežje ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (izgovorjava povratnih informacij)</translation>
<translation id="6981982820502123353">Pripomočki za osebe s posebnimi potrebami</translation>
<translation id="4274292172790327596">Neprepoznana napaka</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Slušalke</translation>
<translation id="225680501294068881">Iskanje naprav ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je javna seja, ki jo upravlja <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Z omrežjem se ni bilo mogoče povezati: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Zapusti sejo</translation>
-<translation id="479989351350248267">iskanje</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi je vklopljen.</translation>
<translation id="4872237917498892622">Alt + iskanje ali Shift</translation>
<translation id="2429753432712299108">Naprava Bluetooth »<ph name="DEVICE_NAME"/>« želi dovoljenje za seznanjanje. Preden sprejmete, se prepričajte, da je na napravi prikazano to geslo: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Več o tem</translation>
<translation id="9046895021617826162">Vzpostavljanje povezave ni uspelo</translation>
<translation id="7168224885072002358">Ponastavitev na prejšnjo ločljivost čez <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Ta seja se bo končala čez <ph name="SESSION_TIME_REMAINING"/>. Samodejno boste odjavljeni.</translation>
<translation id="743058460480092004">Kamera in mikrofon sta v uporabi.</translation>
<translation id="8372369524088641025">Napačen ključ WEP</translation>
<translation id="6636709850131805001">Neprepoznano stanje</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb
index ff9bfe2..13ded8f 100644
--- a/ash/strings/ash_strings_sr.xtb
+++ b/ash/strings/ash_strings_sr.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Нису доступне информације о мрежи</translation>
<translation id="4625920103690741805">Ротација је закључана (додирните овде да бисте променили то)</translation>
<translation id="3799026279081545374">Можда имате неисправан пуњач. Ако живите у САД, позовите 866 628 1371 да бисте добили помоћ и нов пуњач. Ако живите у УК, позовите 0800 026 0613. Ако живите у Ирској, позовите 1 800 832 664. Ако живите у Канади, позовите 866 628 1372. Ако живите у Аустралији, позовите 1 800 067 460.</translation>
+<translation id="3026237328237090306">Подеси податке за мобилне уређаје</translation>
<translation id="5871632337994001636">Управљај уређајима...</translation>
<translation id="785750925697875037">Прикажи налог за мобилне уређаје</translation>
<translation id="153454903766751181">Покретање модема за мобилну мрежу...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (говорне повратне информације)</translation>
<translation id="6981982820502123353">Приступачност</translation>
<translation id="4274292172790327596">Непозната грешка</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Слушалице</translation>
<translation id="225680501294068881">Скенирање уређаја...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> је јавна сесија којом управља <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Повезивање са мрежом није успело: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Изађи из сесије</translation>
-<translation id="479989351350248267">претражите</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi је укључен.</translation>
<translation id="4872237917498892622">Alt + тастер за претрагу или Shift</translation>
<translation id="2429753432712299108">Bluetooth уређај „<ph name="DEVICE_NAME"/>“ жели дозволу за упаривање. Пре него што му је дате, уверите се да је ова шифра приказана на том уређају: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Сазнајте више</translation>
<translation id="9046895021617826162">Повезивање није успело</translation>
<translation id="7168224885072002358">Враћање на стару резолуцију за <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Ова сесија ће се завршити за <ph name="SESSION_TIME_REMAINING"/>. Бићете аутоматски одјављени.</translation>
<translation id="743058460480092004">Камера и микрофон се користе.</translation>
<translation id="8372369524088641025">Неисправна WEP шифра</translation>
<translation id="6636709850131805001">Непознато стање</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb
index eebabab..91f2253 100644
--- a/ash/strings/ash_strings_sv.xtb
+++ b/ash/strings/ash_strings_sv.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Det finns ingen nätverksinformation</translation>
<translation id="4625920103690741805">Rotation har låsts (tryck här om du vill ändra inställningen)</translation>
<translation id="3799026279081545374">Du har kanske fått en dålig laddare. Ring 866-628-1371 för att få hjälp om du bor i USA. Ring 0800-026-0613 om du bor i Storbritannien. Ring 1-800-832-664 om du bor i Irland. Ring 866-628-1372 om du bor i Kanada. Ring 1-800-067-460 om du bor i Australien.</translation>
+<translation id="3026237328237090306">Konfigurera mobildata</translation>
<translation id="5871632337994001636">Hantera enheter ...</translation>
<translation id="785750925697875037">Visa mobilkonto</translation>
<translation id="153454903766751181">Mobilt modem initieras ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (talad feedback)</translation>
<translation id="6981982820502123353">Tillgänglighet</translation>
<translation id="4274292172790327596">Okänt fel</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Hörlurar</translation>
<translation id="225680501294068881">Söker efter enheter ...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -226,6 +228,7 @@
<translation id="6165508094623778733">Läs mer</translation>
<translation id="9046895021617826162">Kunde inte ansluta</translation>
<translation id="7168224885072002358">Återgår till den gamla upplösningen om <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Sessionen avslutas om <ph name="SESSION_TIME_REMAINING"/>. Du kommer att loggas ut automatiskt.</translation>
<translation id="743058460480092004">Kameran och mikrofonen används.</translation>
<translation id="8372369524088641025">Felaktig WEP-nyckel</translation>
<translation id="6636709850131805001">Okänt tillstånd</translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb
index 5229f04..f68fd3e 100644
--- a/ash/strings/ash_strings_sw.xtb
+++ b/ash/strings/ash_strings_sw.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Hakuna maelezo ya mtandao yanayopatikana</translation>
<translation id="4625920103690741805">Mzunguko umefungwa (Gonga hapa ili ubadilishe)</translation>
<translation id="3799026279081545374">Huenda una chaja mbaya. Kama unaishi Marekani, tafadhali piga simu 866-628-1371 ili upata usaidizi na chaja nyingine. Kama unaishi nchini Uingereza, tafadhali piga simu 0800-026-0613. Kama unaishi Ayalandi, tafadhali piga simu 1-800-832-664. Kama unaishi Kanada, tafadhali piga simu 866-628-1372. Kama unaishi Australia, tafadhali piga simu 1-800-067-460.</translation>
+<translation id="3026237328237090306">Sanidi data ya simu</translation>
<translation id="5871632337994001636">Simamia vifaa...</translation>
<translation id="785750925697875037">Ona akaunti ya simu ya mkononi</translation>
<translation id="153454903766751181">Inaanzisha modemu ya simu za mkononi...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Maoni Yaliyotamkwa)</translation>
<translation id="6981982820502123353">Ufikiaji</translation>
<translation id="4274292172790327596">Hitilafu Isiyotambulika</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Vipokea sauti</translation>
<translation id="225680501294068881">Inatambazaa vifaa...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Pata maelezo zaidi</translation>
<translation id="9046895021617826162">Muunganisho umeshindikana</translation>
<translation id="7168224885072002358">Inarejesha katika ubora wa zamani baada ya <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Kipindi hiki kitaisha katika <ph name="SESSION_TIME_REMAINING"/>. Utaondolewa kiotomatiki.</translation>
<translation id="743058460480092004">Kamera na maikrofoni zinatumiwa.</translation>
<translation id="8372369524088641025">Kitufe kibovu cha WEP</translation>
<translation id="6636709850131805001">Hali isiyotambulika</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb
index 009bc6b..32c23cf 100644
--- a/ash/strings/ash_strings_ta.xtb
+++ b/ash/strings/ash_strings_ta.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">நெட்வொர்க் தகவல் எதுவும் இல்லை</translation>
<translation id="4625920103690741805">சுழற்றுவது பூட்டப்பட்டது (மாற்ற, இங்கு தட்டவும்)</translation>
<translation id="3799026279081545374">உங்களிடம் நல்ல நிலையில் இல்லாத சார்ஜர் இருக்கலாம். நீங்கள் US இல் வசிக்கிறீர்கள் எனில், உதவி மற்றும் மாற்று சார்ஜரைப் பெறுவதற்கு 866-628-1371 ஐ அழைக்கவும். நீங்கள் UK இல் வசிக்கிறீர்கள் எனில், 0800-026-0613 ஐ அழைக்கவும். நீங்கள் அயர்லாந்தில் வசிக்கிறீர்கள் எனில், 1-800-832-664 ஐ அழைக்கவும். நீங்கள் கனடாவில் வசிக்கிறீர்கள் எனில், 866-628-1372 ஐ அழைக்கவும். நீங்கள் ஆஸ்திரேலியாவில் வசிக்கிறீர்கள் எனில், 1-800-067-460 ஐ அழைக்கவும்.</translation>
+<translation id="3026237328237090306">மொபைல் தரவை அமை</translation>
<translation id="5871632337994001636">சாதனங்களை நிர்வகி...</translation>
<translation id="785750925697875037">மொபைல் கணக்கைப் பார்க்கவும்</translation>
<translation id="153454903766751181">செல்லுலார் பயன்முறையைத் துவக்குகிறது...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (பேச்சுவடிவ கருத்து)</translation>
<translation id="6981982820502123353">அணுகல்தன்மை</translation>
<translation id="4274292172790327596">அறியப்படாத பிழை</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ஹெட்ஃபோன்</translation>
<translation id="225680501294068881">சாதனங்களைக் கண்டறிகிறது...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ஆனது <ph name="DOMAIN"/> ஆல் நிர்வகிக்கப்படும் பொது அமர்வாகும்</translation>
<translation id="9044646465488564462">பிணையத்துடன் இணைப்பதில் தோல்வி: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">அமர்விலிருந்து வெளியேறவும்</translation>
-<translation id="479989351350248267">தேடு</translation>
+<translation id="479989351350248267">Search</translation>
<translation id="8454013096329229812">Wi-Fi இயக்கத்தில் உள்ளது.</translation>
<translation id="4872237917498892622">Alt+Search அல்லது Shift</translation>
<translation id="2429753432712299108">Bluetooth சாதனம் "<ph name="DEVICE_NAME"/>", இணைப்பதற்கான அனுமதியை விரும்புகிறது. ஏற்றுக்கொள்வதற்கு முன்னர், இந்தக் கடவுச்சொல் அந்தச் சாதனத்தில் காண்பிக்கப்பட்டது என்பதை உறுதிப்படுத்தவும்: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">மேலும் அறிக</translation>
<translation id="9046895021617826162">இணைப்பு தோல்வியடைந்தது</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> வினாடிகளில் பழைய தெளிவுதிறனுக்கு மாற்றியமைக்கப்படும்</translation>
+<translation id="973896785707726617">இந்த அமர்வு <ph name="SESSION_TIME_REMAINING"/> நிமிடங்களில் முடியும். நீங்கள் தானாகவே வெளியேற்றப்படுவீர்கள்.</translation>
<translation id="743058460480092004">கேமராவும் மைக்ரோஃபோனும் பயன்பாட்டில் உள்ளன.</translation>
<translation id="8372369524088641025">மோசமான WEP விசை</translation>
<translation id="6636709850131805001">அறியப்படாத நிலை</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb
index 459761f..aa9ec69 100644
--- a/ash/strings/ash_strings_te.xtb
+++ b/ash/strings/ash_strings_te.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">నెట్వర్క్ సమాచారం అందుబాటులో లేదు</translation>
<translation id="4625920103690741805">తిప్పడం లాక్ చేయబడింది (మార్చడానికి ఇక్కడ నొక్కండి)</translation>
<translation id="3799026279081545374">మీరు పని చేయని ఛార్జర్ను కలిగి ఉండవచ్చు. మీరు USలో నివసిస్తుంటే, దయచేసి సహాయం పొందడానికి మరియు భర్తీ అభ్యర్థించడానికి 866-628-1371కి కాల్ చేయండి. మీరు UKలో నివసిస్తుంటే, దయచేసి 0800-026-0613కి కాల్ చేయండి. మీరు ఐర్లాండ్లో నివసిస్తుంటే, దయచేసి 1-800-832-664కి కాల్ చేయండి. మీరు కెనడాలో నివసిస్తుంటే, దయచేసి 866-628-1372కి కాల్ చేయండి. మీరు ఆస్ట్రేలియాలో నివసిస్తుంటే, దయచేసి 1-800-067-460కి కాల్ చేయండి.</translation>
+<translation id="3026237328237090306">మొబైల్ డేటాను సెటప్ చేయి</translation>
<translation id="5871632337994001636">పరికరాలను నిర్వహించండి...</translation>
<translation id="785750925697875037">మొబైల్ ఖాతాని వీక్షించండి</translation>
<translation id="153454903766751181">సెల్యులార్ మోడెమ్ను ప్రారంభిస్తోంది...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (చదవబడే అభిప్రాయం)</translation>
<translation id="6981982820502123353">ప్రాప్యత</translation>
<translation id="4274292172790327596">గుర్తించబడని లోపం</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">హెడ్ఫోన్</translation>
<translation id="225680501294068881">పరికరాల కోసం స్కాన్ చేస్తోంది...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> అనేది <ph name="DOMAIN"/> ద్వారా నిర్వహించబడుతున్న పబ్లిక్ సెషన్</translation>
<translation id="9044646465488564462">నెట్వర్క్కు కనెక్ట్ చేయడంలో విఫలమైంది: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">సెషన్ని నిష్క్రమించు</translation>
-<translation id="479989351350248267">శోధించండి</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi ప్రారంభించబడింది.</translation>
<translation id="4872237917498892622">Alt+Search లేదా Shift</translation>
<translation id="2429753432712299108">బ్లూటూత్ పరికరం "<ph name="DEVICE_NAME"/>" జత కావడానికి అనుమతి కోరుతోంది. ఆమోదించడానికి ముందు, దయచేసి ఆ పరికరంలో ఈ పాస్కీ చూపబడుతోందని నిర్ధారించుకోండి: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">మరింత తెలుసుకోండి</translation>
<translation id="9046895021617826162">కనెక్ట్ విఫలమైంది</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/>లో తిరిగి పాత రిజల్యూషన్కి మార్చబడుతోంది</translation>
+<translation id="973896785707726617">ఈ సెషన్ <ph name="SESSION_TIME_REMAINING"/> తర్వాత ముగుస్తుంది. మీరు స్వయంచాలకంగా సైన్ అవుట్ చేయబడతారు.</translation>
<translation id="743058460480092004">కెమెరా మరియు మైక్రోఫోన్ ఉపయోగంలో ఉన్నాయి.</translation>
<translation id="8372369524088641025">తప్పుడు WEP కీ</translation>
<translation id="6636709850131805001">గుర్తించబడని రాష్ట్రం</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb
index bf36986..3a71134 100644
--- a/ash/strings/ash_strings_th.xtb
+++ b/ash/strings/ash_strings_th.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">ไม่มีข้อมูลเครือข่ายที่สามารถใช้งานได้</translation>
<translation id="4625920103690741805">ล็อกการหมุนแล้ว (แตะที่นี่เพื่อเปลี่ยนแปลง)</translation>
<translation id="3799026279081545374">ที่ชาร์จของคุณอาจเสีย หากคุณอาศัยในสหรัฐอเมริกา โปรดโทรไปที่ 866-628-1371 เพื่อขอความช่วยเหลือหรือขอเปลี่ยนสินค้า หากคุณอาศัยในสหราชอาณาจักร โปรดโทรไปที่ 0800-026-0613 หากคุณอาศัยในไอร์แลนด์ โปรดโทรไปที่ 1-800-832-664 หากคุณอาศัยในแคนาดา โปรดโทรไปที่ 866-628-1372 หากคุณอาศัยในออสเตรเลีย โปรดโทรไปที่ 1-800-067-460</translation>
+<translation id="3026237328237090306">ตั้งค่าข้อมูลมือถือ</translation>
<translation id="5871632337994001636">จัดการอุปกรณ์...</translation>
<translation id="785750925697875037">ดูบัญชีมือถือ</translation>
<translation id="153454903766751181">กำลังเริ่มต้นโมเด็มมือถือ...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (การตอบสนองด้วยเสียง)</translation>
<translation id="6981982820502123353">การเข้าถึง</translation>
<translation id="4274292172790327596">ข้อผิดพลาดที่ไม่รู้จัก</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">ชุดหูฟัง</translation>
<translation id="225680501294068881">กำลังสแกนหาอุปกรณ์...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">เรียนรู้เพิ่มเติม</translation>
<translation id="9046895021617826162">การเชื่อมต่อล้มเหลว</translation>
<translation id="7168224885072002358">เปลี่ยนกลับไปเป็นความละเอียดเดิมภายใน <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">เซสชันนี้จะสิ้นสุดใน <ph name="SESSION_TIME_REMAINING"/> ระบบจะลงชื่อออกให้คุณโดยอัตโนมัติ</translation>
<translation id="743058460480092004">ใช้กล้องถ่ายรูปและไมโครโฟนอยู่</translation>
<translation id="8372369524088641025">คีย์ WEP ไม่ถูกต้อง</translation>
<translation id="6636709850131805001">สถานะที่ไม่รู้จัก</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb
index 4a54078..a50683a 100644
--- a/ash/strings/ash_strings_tr.xtb
+++ b/ash/strings/ash_strings_tr.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Hiçbir ağ bilgisi yok</translation>
<translation id="4625920103690741805">Döndürme kilitli (Değiştirmek için buraya hafifçe vurun)</translation>
<translation id="3799026279081545374">Şarj cihazınız sorunlu olabilir. ABD'de yaşıyorsanız yardım almak ve cihazı yenisiyle değiştirmek için lütfen 866-628-1371 numaralı telefonu arayın. İngiltere'de yaşıyorsanız 0800-026-0613 numaralı telefonu, İrlanda'da yaşıyorsanız 1-800-832-664 numaralı telefonu, Kanada'da yaşıyorsanız 866-628-1372 numaralı telefonu, Avustralya'da yaşıyorsanız lütfen 1-800-067-460 numaralı telefonu arayın.</translation>
+<translation id="3026237328237090306">Mobil verileri ayarla</translation>
<translation id="5871632337994001636">Cihazları yönet...</translation>
<translation id="785750925697875037">Mobil hesabı görüntüle</translation>
<translation id="153454903766751181">Hücresel modem başlatılıyor...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Sesli geri bildirim)</translation>
<translation id="6981982820502123353">Erişilebilirlik</translation>
<translation id="4274292172790327596">Tanınmayan hata</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Kulaklık</translation>
<translation id="225680501294068881">Cihazlar taranıyor...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>, <ph name="DOMAIN"/> tarafından yönetilen herkese açık bir oturumdur</translation>
<translation id="9044646465488564462">Şu ağa bağlanamadı: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Oturumdan çık</translation>
-<translation id="479989351350248267">arama yapın</translation>
+<translation id="479989351350248267">ara</translation>
<translation id="8454013096329229812">Kablosuz açık.</translation>
<translation id="4872237917498892622">Alt+Arama veya Üst Karakter</translation>
<translation id="2429753432712299108">"<ph name="DEVICE_NAME"/>" adlı Bluetooth cihaz eşleme izni istiyor. Kabul etmeden önce şu cihazda gösterilen bu parola anahtarının gösterildiğini onaylayın: <ph name="PASSKEY"/></translation>
@@ -228,6 +230,7 @@
<translation id="6165508094623778733">Daha fazla bilgi edinin</translation>
<translation id="9046895021617826162">Bağlantı başarısız oldu</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/> saniye içinde eski çözünürlüğe dönülüyor</translation>
+<translation id="973896785707726617">Bu oturum <ph name="SESSION_TIME_REMAINING"/> içinde sona erecek. Oturumunuz otomatik olarak kapatılacaktır.</translation>
<translation id="743058460480092004">Kamera ve mikrofon kullanımda.</translation>
<translation id="8372369524088641025">Hatalı WEP anahtarı</translation>
<translation id="6636709850131805001">Tanınmayan durum</translation>
@@ -251,7 +254,7 @@
<translation id="3678715477168044796"><ph name="DISPLAY_NAME"/>: <ph name="ANNOTATION"/></translation>
<translation id="2563856802393254086">Tebrikler! '<ph name="NAME"/>' veri hizmetiniz etkinleştirildi ve kullanıma hazır.</translation>
<translation id="412065659894267608">Tam dolana kadar <ph name="HOUR"/> sa <ph name="MINUTE"/> dk var</translation>
-<translation id="3077734595579995578">üst karakter</translation>
+<translation id="3077734595579995578">üstkrktr</translation>
<translation id="7297443947353982503">Kullanıcı adı/şifre yanlış veya EAP yetkilendirmesi başarısız oldu</translation>
<translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> numaradan SMS alındı</translation>
<translation id="1244147615850840081">Operatör</translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb
index 6edfb5b..b1a382f 100644
--- a/ash/strings/ash_strings_uk.xtb
+++ b/ash/strings/ash_strings_uk.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Інформація про мережу не доступна</translation>
<translation id="4625920103690741805">Обертання заблоковано (торкніться тут, щоб змінити)</translation>
<translation id="3799026279081545374">Можливо, у вас несправний зарядний пристрій. Якщо ви проживаєте в США, зателефонуйте за номером 866-628-1371, щоб отримати допомогу та інший зарядний пристрій. Якщо ви проживаєте у Великобританії, зателефонуйте за номером 0800-026-0613. Якщо ви проживаєте в Ірландії, зателефонуйте за номером 1-800-832-664. Якщо ви проживаєте в Канаді, зателефонуйте за номером 866-628-1372. Якщо ви проживаєте в Австралії, зателефонуйте за номером 1-800-067-460.</translation>
+<translation id="3026237328237090306">Налаштувати передавання мобільних даних</translation>
<translation id="5871632337994001636">Керування пристроями…</translation>
<translation id="785750925697875037">Переглянути обліковий запис для мобільних пристроїв</translation>
<translation id="153454903766751181">Ініціалізація мобільного модема…</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (голосові підказки)</translation>
<translation id="6981982820502123353">Доступність</translation>
<translation id="4274292172790327596">Нерозпізнана помилка</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Навушники</translation>
<translation id="225680501294068881">Пошук пристроїв...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Докладніше</translation>
<translation id="9046895021617826162">Помилка з'єднання</translation>
<translation id="7168224885072002358">Попередня роздільна здатність повернеться через <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Сеанс закінчиться за <ph name="SESSION_TIME_REMAINING"/>. Ви вийдете автоматично.</translation>
<translation id="743058460480092004">Камера та мікрофон використовуються.</translation>
<translation id="8372369524088641025">Поганий WEP-ключ</translation>
<translation id="6636709850131805001">Нерозпізнаний стан</translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb
index 5a372eb..27833a3 100644
--- a/ash/strings/ash_strings_vi.xtb
+++ b/ash/strings/ash_strings_vi.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">Không có thông tin mạng</translation>
<translation id="4625920103690741805">Đã khóa tính năng xoay (Nhấn vào đây để thay đổi)</translation>
<translation id="3799026279081545374">Bộ sạc của bạn có thể bị hỏng. Nếu bạn sống ở Hoa Kỳ, hãy gọi đến số 866-628-1371 để nhận trợ giúp và được thay thế. Nếu bạn sống ở Vương quốc Anh, hãy gọi đến số 0800-026-0613. Nếu bạn sống ở Ireland, hãy gọi đến số 1-800-832-664. Nếu bạn sống ở Canada, hãy gọi đến số 866-628-1372. Nếu bạn sống ở Úc, hãy gọi đến số 1-800-067-460.</translation>
+<translation id="3026237328237090306">Thiết lập dữ liệu di động</translation>
<translation id="5871632337994001636">Quản lý thiết bị...</translation>
<translation id="785750925697875037">Xem tài khoản di động</translation>
<translation id="153454903766751181">Đang chạy modem di động...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (Phản hồi bằng giọng nói)</translation>
<translation id="6981982820502123353">Khả năng truy cập</translation>
<translation id="4274292172790327596">Lỗi chưa được xác định</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">Tai nghe</translation>
<translation id="225680501294068881">Đang quét tìm thiết bị...</translation>
<translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
@@ -188,7 +190,7 @@
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> là phiên công khai được quản lý bởi <ph name="DOMAIN"/></translation>
<translation id="9044646465488564462">Không kết nối được với mạng: <ph name="DETAILS"/></translation>
<translation id="7029814467594812963">Thoát khỏi phiên</translation>
-<translation id="479989351350248267">tìm kiếm</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi đang bật.</translation>
<translation id="4872237917498892622">Alt+Search hoặc Shift</translation>
<translation id="2429753432712299108">Thiết bị Bluetooth "<ph name="DEVICE_NAME"/>" muốn được phép ghép nối. Trước khi chấp nhận, vui lòng xác nhận rằng mã xác nhận này đã hiển thị trên thiết bị đó: <ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">Tìm hiểu thêm</translation>
<translation id="9046895021617826162">Kết nối không thành công</translation>
<translation id="7168224885072002358">Sẽ hoàn nguyên về độ phân giải cũ sau <ph name="TIMEOUT_SECONDS"/></translation>
+<translation id="973896785707726617">Phiên này sẽ kết thúc sau <ph name="SESSION_TIME_REMAINING"/>. Bạn sẽ tự động bị đăng xuất.</translation>
<translation id="743058460480092004">Máy ảnh và micrô đang được sử dụng.</translation>
<translation id="8372369524088641025">Khóa WEP sai</translation>
<translation id="6636709850131805001">Trạng thái không xác định</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb
index e4448a4..032484c 100644
--- a/ash/strings/ash_strings_zh-CN.xtb
+++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">没有可用的网络信息</translation>
<translation id="4625920103690741805">旋转功能已锁定(点按此处可进行更改)</translation>
<translation id="3799026279081545374">您的充电器可能有问题。如果您居住在美国,请拨打866-628-1371寻求帮助并申请更换充电器。如果您居住在英国,请拨打0800-026-0613。如果您居住在爱尔兰,请拨打1-800-832-664。如果您居住在加拿大,请拨打866-628-1372。如果您居住在澳大利亚,请拨打1-800-067-460。</translation>
+<translation id="3026237328237090306">设置移动数据</translation>
<translation id="5871632337994001636">管理设备…</translation>
<translation id="785750925697875037">查看移动帐户</translation>
<translation id="153454903766751181">正在初始化蜂窝调制解调器...</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox(语音反馈)</translation>
<translation id="6981982820502123353">辅助功能</translation>
<translation id="4274292172790327596">未识别的错误</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">耳机</translation>
<translation id="225680501294068881">正在查找设备...</translation>
<translation id="5597451508971090205"><ph name="DATE"/><ph name="SHORT_WEEKDAY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">了解详情</translation>
<translation id="9046895021617826162">连接失败</translation>
<translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS"/>秒后恢复到原分辨率</translation>
+<translation id="973896785707726617">该会话将在 <ph name="SESSION_TIME_REMAINING"/>后结束,到时您将自动退出。</translation>
<translation id="743058460480092004">摄像头和麦克风处于使用状态。</translation>
<translation id="8372369524088641025">WEP 密钥错误</translation>
<translation id="6636709850131805001">未知状态</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb
index 3fa1a9b..9506e45 100644
--- a/ash/strings/ash_strings_zh-TW.xtb
+++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -49,6 +49,7 @@
<translation id="3846575436967432996">沒有可用的網路資訊</translation>
<translation id="4625920103690741805">已鎖定旋轉功能 (輕按此處即可變更)</translation>
<translation id="3799026279081545374">您的充電器可能有問題。如需相關協助或索取新的充電器,請致電 866-628-1371 (美國)、0800-026-0613 (英國)、1-800-832-664 (愛爾蘭)、866-628-1372 (加拿大) 或 1-800-067-460 (澳洲)。</translation>
+<translation id="3026237328237090306">設定行動數據</translation>
<translation id="5871632337994001636">管理裝置...</translation>
<translation id="785750925697875037">查看行動帳戶</translation>
<translation id="153454903766751181">正在初始化行動數據機...</translation>
@@ -122,7 +123,7 @@
<translation id="1621499497873603021">電池剩餘使用時間:<ph name="TIME_LEFT"/></translation>
<translation id="5980301590375426705">結束訪客工作階段</translation>
<translation id="8308637677604853869">前一個選單</translation>
-<translation id="4321179778687042513">ctrl</translation>
+<translation id="4321179778687042513">Ctrl</translation>
<translation id="3625258641415618104">已停用螢幕擷取畫面</translation>
<translation id="1346748346194534595">向右</translation>
<translation id="1773212559869067373">本機已拒絕驗證憑證</translation>
@@ -175,6 +176,7 @@
<translation id="68610848741840742">ChromeVox (互動朗讀)</translation>
<translation id="6981982820502123353">協助工具</translation>
<translation id="4274292172790327596">不明錯誤</translation>
+<translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
<translation id="5977415296283489383">耳機</translation>
<translation id="225680501294068881">正在掃描裝置...</translation>
<translation id="5597451508971090205"><ph name="DATE"/><ph name="SHORT_WEEKDAY"/></translation>
@@ -183,12 +185,12 @@
<translation id="8401662262483418323">無法連線至「<ph name="NAME"/>」:<ph name="DETAILS"/>
伺服器訊息:<ph name="SERVER_MSG"/></translation>
<translation id="2475982808118771221">發生錯誤</translation>
-<translation id="3783640748446814672">alt</translation>
+<translation id="3783640748446814672">Alt</translation>
<translation id="7229570126336867161">需要 EVDO</translation>
<translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> 是受 <ph name="DOMAIN"/> 管理的公開工作階段</translation>
<translation id="9044646465488564462">無法連線至網路:<ph name="DETAILS"/></translation>
<translation id="7029814467594812963">結束工作階段</translation>
-<translation id="479989351350248267">搜尋</translation>
+<translation id="479989351350248267">search</translation>
<translation id="8454013096329229812">Wi-Fi 已開啟。</translation>
<translation id="4872237917498892622">Alt + 搜尋鍵或 Shift 鍵</translation>
<translation id="2429753432712299108">藍牙裝置「<ph name="DEVICE_NAME"/>」要求配對權限。接受要求前,請確認裝置顯示以下密碼金鑰:<ph name="PASSKEY"/></translation>
@@ -227,6 +229,7 @@
<translation id="6165508094623778733">瞭解詳情</translation>
<translation id="9046895021617826162">連線失敗</translation>
<translation id="7168224885072002358">系統將在 <ph name="TIMEOUT_SECONDS"/> 秒後還原成原來的解析度</translation>
+<translation id="973896785707726617">這個工作階段將在 <ph name="SESSION_TIME_REMAINING"/>後結束,系統會自動將您登出。</translation>
<translation id="743058460480092004">攝影機和麥克風正在使用中。</translation>
<translation id="8372369524088641025">WEP 金鑰有誤</translation>
<translation id="6636709850131805001">不明狀態</translation>
@@ -250,7 +253,7 @@
<translation id="3678715477168044796"><ph name="DISPLAY_NAME"/>:<ph name="ANNOTATION"/></translation>
<translation id="2563856802393254086">恭喜您!您的「<ph name="NAME"/>」數據服務已啟用,隨時可供使用。</translation>
<translation id="412065659894267608">尚需 <ph name="HOUR"/> 小時 <ph name="MINUTE"/> 分鐘才能充滿電</translation>
-<translation id="3077734595579995578">shift</translation>
+<translation id="3077734595579995578">Shift</translation>
<translation id="7297443947353982503">使用者名稱/密碼錯誤或 EAP 驗證失敗</translation>
<translation id="6359806961507272919">來自 <ph name="PHONE_NUMBER"/> 的簡訊</translation>
<translation id="1244147615850840081">通訊業者</translation>
diff --git a/ash/system/chromeos/bluetooth/bluetooth_notification_controller.cc b/ash/system/chromeos/bluetooth/bluetooth_notification_controller.cc
index 1965ac2..d6b38f4 100644
--- a/ash/system/chromeos/bluetooth/bluetooth_notification_controller.cc
+++ b/ash/system/chromeos/bluetooth/bluetooth_notification_controller.cc
@@ -297,7 +297,7 @@
IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERABLE,
base::UTF8ToUTF16(adapter_->GetName()),
base::UTF8ToUTF16(adapter_->GetAddress())),
- bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH),
+ bundle.GetImageNamed(IDR_AURA_NOTIFICATION_BLUETOOTH),
base::string16() /* display source */,
message_center::NotifierId(
message_center::NotifierId::SYSTEM_COMPONENT,
@@ -328,7 +328,7 @@
kBluetoothDevicePairingNotificationId,
base::string16() /* title */,
message,
- bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH),
+ bundle.GetImageNamed(IDR_AURA_NOTIFICATION_BLUETOOTH),
base::string16() /* display source */,
message_center::NotifierId(
message_center::NotifierId::SYSTEM_COMPONENT,
@@ -357,7 +357,7 @@
base::string16() /* title */,
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED, device->GetName()),
- bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH),
+ bundle.GetImageNamed(IDR_AURA_NOTIFICATION_BLUETOOTH),
base::string16() /* display source */,
message_center::NotifierId(
message_center::NotifierId::SYSTEM_COMPONENT,
diff --git a/ash/system/chromeos/brightness/tray_brightness.cc b/ash/system/chromeos/brightness/tray_brightness.cc
index 901b0aa..ee511ea 100644
--- a/ash/system/chromeos/brightness/tray_brightness.cc
+++ b/ash/system/chromeos/brightness/tray_brightness.cc
@@ -4,6 +4,8 @@
#include "ash/system/chromeos/brightness/tray_brightness.h"
+#include <algorithm>
+
#include "ash/accelerators/accelerator_controller.h"
#include "ash/ash_constants.h"
#include "ash/display/display_manager.h"
@@ -15,6 +17,7 @@
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/system/tray/tray_constants.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -113,7 +116,8 @@
if (is_default_view_) {
Shell::GetInstance()->AddShellObserver(this);
- SetVisible(Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled());
+ SetVisible(Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled());
}
}
diff --git a/ash/system/chromeos/brightness/tray_brightness_unittest.cc b/ash/system/chromeos/brightness/tray_brightness_unittest.cc
index 9f641db..00c290f 100644
--- a/ash/system/chromeos/brightness/tray_brightness_unittest.cc
+++ b/ash/system/chromeos/brightness/tray_brightness_unittest.cc
@@ -9,6 +9,7 @@
#include "ash/system/tray/system_tray_item.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/status_area_widget_test_helper.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ui/views/view.h"
namespace ash {
@@ -45,19 +46,23 @@
// Tests the construction of the default view while MaximizeMode is active.
// The BrightnessView should be visible.
TEST_F(TrayBrightnessTest, CreateDefaultViewDuringMaximizeMode) {
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
scoped_ptr<views::View> tray(CreateDefaultView());
EXPECT_TRUE(tray->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests that the enabling of MaximizeMode affects a previously created
// BrightnessView, changing the visibility.
TEST_F(TrayBrightnessTest, DefaultViewVisibilityChangesDuringMaximizeMode) {
scoped_ptr<views::View> tray(CreateDefaultView());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(tray->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(tray->visible());
}
@@ -72,19 +77,23 @@
// Tests that when the detailed view is created during MaximizeMode that its
// BrightnessView is visible.
TEST_F(TrayBrightnessTest, CreateDetailedViewDuringMaximizeMode) {
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
scoped_ptr<views::View> tray(CreateDetailedView());
EXPECT_TRUE(tray->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests that the enabling of MaximizeMode has no affect on the visibility of a
// previously created BrightnessView that belongs to a detailed view.
TEST_F(TrayBrightnessTest, DetailedViewVisibilityChangesDuringMaximizeMode) {
scoped_ptr<views::View> tray(CreateDetailedView());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(tray->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_TRUE(tray->visible());
}
diff --git a/ash/system/chromeos/managed/tray_locally_managed_user.cc b/ash/system/chromeos/managed/tray_locally_managed_user.cc
index 2758879..7c22016 100644
--- a/ash/system/chromeos/managed/tray_locally_managed_user.cc
+++ b/ash/system/chromeos/managed/tray_locally_managed_user.cc
@@ -39,7 +39,8 @@
GetLocallyManagedUserMessage();
if (tray_view_)
tray_view_->SetMessage(message);
- if (message_center::MessageCenter::Get()->HasNotification(kNotificationId))
+ if (message_center::MessageCenter::Get()->FindVisibleNotificationById(
+ kNotificationId))
CreateOrUpdateNotification(message);
}
diff --git a/ash/system/chromeos/network/network_icon.cc b/ash/system/chromeos/network/network_icon.cc
index a732385..e14f15d 100644
--- a/ash/system/chromeos/network/network_icon.cc
+++ b/ash/system/chromeos/network/network_icon.cc
@@ -364,26 +364,6 @@
return GetImageForIndex(image_type, icon_type, disconnected_index);
}
-const std::string& GetDisconnectedImageUrl(IconType icon_type,
- const std::string& network_type,
- float scale_factor) {
- static ImageIdUrlMap* s_image_url_map = NULL;
- if (s_image_url_map == NULL)
- s_image_url_map = new ImageIdUrlMap;
-
- ImageIdForNetworkType key(icon_type, network_type, scale_factor);
- ImageIdUrlMap::iterator iter = s_image_url_map->find(key);
- if (iter != s_image_url_map->end())
- return iter->second;
-
- VLOG(2) << "Generating disconnected bitmap URL for: " << network_type;
- gfx::ImageSkia image = GetDisconnectedImage(icon_type, network_type);
- gfx::ImageSkiaRep image_rep = image.GetRepresentation(scale_factor);
- iter = s_image_url_map->insert(std::make_pair(
- key, webui::GetBitmapDataUrl(image_rep.sk_bitmap()))).first;
- return iter->second;
-}
-
gfx::ImageSkia* ConnectingWirelessImage(ImageType image_type,
IconType icon_type,
double animation) {
@@ -783,7 +763,9 @@
gfx::ImageSkia GetImageForNetwork(const NetworkState* network,
IconType icon_type) {
DCHECK(network);
- // Handle connecting icons.
+ if (!network->visible())
+ return GetDisconnectedImage(icon_type, network->type());
+
if (network->IsConnectingState())
return GetConnectingImage(icon_type, network->type());
@@ -818,12 +800,6 @@
return GetDisconnectedImage(icon_type, network_type);
}
-std::string GetImageUrlForDisconnectedNetwork(IconType icon_type,
- const std::string& network_type,
- float scale_factor) {
- return GetDisconnectedImageUrl(icon_type, network_type, scale_factor);
-}
-
base::string16 GetLabelForNetwork(const chromeos::NetworkState* network,
IconType icon_type) {
DCHECK(network);
@@ -970,7 +946,8 @@
void PurgeNetworkIconCache() {
NetworkStateHandler::NetworkStateList networks;
- NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
+ NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList(
+ &networks);
std::set<std::string> network_paths;
for (NetworkStateHandler::NetworkStateList::iterator iter = networks.begin();
iter != networks.end(); ++iter) {
diff --git a/ash/system/chromeos/network/network_icon.h b/ash/system/chromeos/network/network_icon.h
index 4974de7..7497930 100644
--- a/ash/system/chromeos/network/network_icon.h
+++ b/ash/system/chromeos/network/network_icon.h
@@ -56,12 +56,6 @@
IconType icon_type,
const std::string& network_type);
-// Gets a url representing the image for a disconnected network type.
-ASH_EXPORT std::string GetImageUrlForDisconnectedNetwork(
- IconType icon_type,
- const std::string& network_type,
- float scale_factor);
-
// Returns the label for |network| based on |icon_type|. |network| can be NULL.
ASH_EXPORT base::string16 GetLabelForNetwork(
const chromeos::NetworkState* network,
diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.cc b/ash/system/chromeos/network/network_state_list_detailed_view.cc
index de571bd..616dc27 100644
--- a/ash/system/chromeos/network/network_state_list_detailed_view.cc
+++ b/ash/system/chromeos/network/network_state_list_detailed_view.cc
@@ -182,7 +182,7 @@
void NetworkStateListDetailedView::NetworkListChanged() {
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
NetworkStateHandler::NetworkStateList network_list;
- handler->GetNetworkList(&network_list);
+ handler->GetVisibleNetworkList(&network_list);
UpdateNetworks(network_list);
UpdateNetworkList();
UpdateHeaderButtons();
diff --git a/ash/system/chromeos/network/network_state_notifier_unittest.cc b/ash/system/chromeos/network/network_state_notifier_unittest.cc
index 945bca3..56fed05 100644
--- a/ash/system/chromeos/network/network_state_notifier_unittest.cc
+++ b/ash/system/chromeos/network/network_state_notifier_unittest.cc
@@ -98,7 +98,7 @@
// Failure should spawn a notification.
message_center::MessageCenter* message_center =
message_center::MessageCenter::Get();
- EXPECT_TRUE(message_center->HasNotification(
+ EXPECT_TRUE(message_center->FindVisibleNotificationById(
network_connect::kNetworkConnectNotificationId));
}
diff --git a/ash/system/chromeos/power/power_status_unittest.cc b/ash/system/chromeos/power/power_status_unittest.cc
index f983f26..2884d35 100644
--- a/ash/system/chromeos/power/power_status_unittest.cc
+++ b/ash/system/chromeos/power/power_status_unittest.cc
@@ -4,10 +4,6 @@
#include "ash/system/chromeos/power/power_status.h"
-#include <set>
-#include <string>
-
-#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/ash/system/chromeos/rotation/tray_rotation_lock.cc b/ash/system/chromeos/rotation/tray_rotation_lock.cc
index 293299a..35cc017 100644
--- a/ash/system/chromeos/rotation/tray_rotation_lock.cc
+++ b/ash/system/chromeos/rotation/tray_rotation_lock.cc
@@ -44,7 +44,8 @@
RotationLockDefaultView::RotationLockDefaultView(SystemTrayItem* owner)
: TrayItemMore(owner, false) {
UpdateImage();
- SetVisible(Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled());
+ SetVisible(Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled());
Shell::GetInstance()->AddShellObserver(this);
}
@@ -55,16 +56,9 @@
bool RotationLockDefaultView::PerformAction(const ui::Event& event) {
MaximizeModeController* maximize_mode_controller = Shell::GetInstance()->
maximize_mode_controller();
- bool rotation_locked = !maximize_mode_controller->rotation_locked();
- maximize_mode_controller->set_rotation_locked(rotation_locked);
-
+ maximize_mode_controller->SetRotationLocked(
+ !maximize_mode_controller->rotation_locked());
UpdateImage();
-
- // RotationLockDefaultView can only be created by a TrayRotationLock. The
- // owner needs to be told of the action so that it can update its visibility.
- static_cast<TrayRotationLock*>(owner())->tray_view()->
- SetVisible(rotation_locked);
-
return true;
}
@@ -115,6 +109,10 @@
Shell::GetInstance()->RemoveShellObserver(this);
}
+void TrayRotationLock::OnRotationLockChanged(bool rotation_locked) {
+ tray_view()->SetVisible(ShouldBeVisible());
+}
+
views::View* TrayRotationLock::CreateDefaultView(user::LoginStatus status) {
if (on_primary_display_)
return new tray::RotationLockDefaultView(this);
@@ -124,16 +122,24 @@
void TrayRotationLock::OnMaximizeModeStarted() {
tray_view()->SetVisible(
Shell::GetInstance()->maximize_mode_controller()->rotation_locked());
+ Shell::GetInstance()->maximize_mode_controller()->AddObserver(this);
}
void TrayRotationLock::OnMaximizeModeEnded() {
tray_view()->SetVisible(false);
+ Shell::GetInstance()->maximize_mode_controller()->RemoveObserver(this);
}
bool TrayRotationLock::GetInitialVisibility() {
+ return ShouldBeVisible();
+}
+
+bool TrayRotationLock::ShouldBeVisible() {
+ MaximizeModeController* controller = Shell::GetInstance()->
+ maximize_mode_controller();
return on_primary_display_ &&
- Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled() &&
- Shell::GetInstance()->maximize_mode_controller()->rotation_locked();
+ controller->IsMaximizeModeWindowManagerEnabled() &&
+ controller->rotation_locked();
}
} // namespace ash
diff --git a/ash/system/chromeos/rotation/tray_rotation_lock.h b/ash/system/chromeos/rotation/tray_rotation_lock.h
index 9c53e6e..2a134d0 100644
--- a/ash/system/chromeos/rotation/tray_rotation_lock.h
+++ b/ash/system/chromeos/rotation/tray_rotation_lock.h
@@ -7,6 +7,7 @@
#include "ash/shell_observer.h"
#include "ash/system/tray/tray_image_item.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
namespace ash {
@@ -20,11 +21,15 @@
// be interacted with, it toggles the state of the rotation lock.
// TrayRotationLock is only available on the primary display.
class ASH_EXPORT TrayRotationLock : public TrayImageItem,
+ public MaximizeModeController::Observer,
public ShellObserver {
public:
explicit TrayRotationLock(SystemTray* system_tray);
virtual ~TrayRotationLock();
+ // MaximizeModeController::Observer:
+ virtual void OnRotationLockChanged(bool rotation_locked) OVERRIDE;
+
// SystemTrayItem:
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
@@ -39,6 +44,10 @@
private:
friend class TrayRotationLockTest;
+ // True if |on_primary_display_|, maximize mode is enabled, and rotation is
+ // locked.
+ bool ShouldBeVisible();
+
// True if this has been created by a SystemTray on the primary display.
bool on_primary_display_;
diff --git a/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc b/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc
index 347499f..3b0eb86 100644
--- a/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc
+++ b/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc
@@ -104,32 +104,38 @@
// it is not visible.
TEST_F(TrayRotationLockTest, CreateTrayViewDuringMaximizeMode) {
TearDownViews();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget());
EXPECT_FALSE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests that when the tray view is created, while MaximizeMode is active, and
// rotation is locked, that it is visible.
TEST_F(TrayRotationLockTest, CreateTrayViewDuringMaximizeModeAndRotationLock) {
TearDownViews();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
- Shell::GetInstance()-> maximize_mode_controller()->set_rotation_locked(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()-> maximize_mode_controller()->SetRotationLocked(true);
SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget());
EXPECT_TRUE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
+ EXPECT_FALSE(tray_view()->visible());
}
// Tests that the enabling of MaximizeMode affects a previously created tray
// view, changing the visibility.
TEST_F(TrayRotationLockTest, TrayViewVisibilityChangesDuringMaximizeMode) {
- TearDownViews();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
- Shell::GetInstance()-> maximize_mode_controller()->set_rotation_locked(true);
- SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget());
+ ASSERT_FALSE(tray_view()->visible());
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->SetRotationLocked(true);
EXPECT_TRUE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(tray_view()->visible());
}
@@ -143,9 +149,11 @@
SetUpForStatusAreaWidget(
StatusAreaWidgetTestHelper::GetSecondaryStatusAreaWidget());
EXPECT_FALSE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_FALSE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(tray_view()->visible());
}
@@ -159,18 +167,22 @@
// that it is visible.
TEST_F(TrayRotationLockTest, CreateDefaultViewDuringMaximizeMode) {
TearDownViews();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget());
EXPECT_TRUE(default_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests that the enabling of MaximizeMode affects a previously created default
// view, changing the visibility.
TEST_F(TrayRotationLockTest, DefaultViewVisibilityChangesDuringMaximizeMode) {
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(default_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(default_view()->visible());
}
@@ -193,7 +205,8 @@
MaximizeModeController* maximize_mode_controller = Shell::GetInstance()->
maximize_mode_controller();
ASSERT_FALSE(maximize_mode_controller->rotation_locked());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
ASSERT_FALSE(tray_view()->visible());
ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
@@ -202,7 +215,8 @@
EXPECT_TRUE(maximize_mode_controller->rotation_locked());
EXPECT_TRUE(tray_view()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
} // namespace ash
diff --git a/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc b/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
index 027d81c..1566ba8 100644
--- a/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
+++ b/ash/system/chromeos/screen_security/screen_tray_item_unittest.cc
@@ -181,7 +181,8 @@
test->StartSession();
message_center::MessageCenter* message_center =
message_center::MessageCenter::Get();
- EXPECT_TRUE(message_center->HasNotification(tray_item->GetNotificationId()));
+ EXPECT_TRUE(message_center->FindVisibleNotificationById(
+ tray_item->GetNotificationId()));
test->StopSession();
}
diff --git a/ash/system/chromeos/session/tray_session_length_limit.cc b/ash/system/chromeos/session/tray_session_length_limit.cc
index 6666c02..d608400 100644
--- a/ash/system/chromeos/session/tray_session_length_limit.cc
+++ b/ash/system/chromeos/session/tray_session_length_limit.cc
@@ -123,7 +123,7 @@
// If state hasn't changed and the notification has already been acknowledged,
// we won't re-create it.
if (limit_state_ == last_limit_state_ &&
- !message_center->HasNotification(kNotificationId)) {
+ !message_center->FindVisibleNotificationById(kNotificationId)) {
return;
}
@@ -132,7 +132,7 @@
// (and in the rare case of state change towards LIMIT_NONE to make the
// notification disappear).
if (limit_state_ != last_limit_state_ &&
- message_center->HasNotification(kNotificationId)) {
+ message_center->FindVisibleNotificationById(kNotificationId)) {
message_center::MessageCenter::Get()->RemoveNotification(
kNotificationId, false /* by_user */);
}
@@ -162,7 +162,7 @@
data,
NULL /* delegate */));
notification->SetSystemPriority();
- if (message_center->HasNotification(kNotificationId))
+ if (message_center->FindVisibleNotificationById(kNotificationId))
message_center->UpdateNotification(kNotificationId, notification.Pass());
else
message_center->AddNotification(notification.Pass());
diff --git a/ash/system/chromeos/tray_caps_lock.cc b/ash/system/chromeos/tray_caps_lock.cc
index 7c9925d..0c83ea4 100644
--- a/ash/system/chromeos/tray_caps_lock.cc
+++ b/ash/system/chromeos/tray_caps_lock.cc
@@ -111,11 +111,13 @@
virtual bool PerformAction(const ui::Event& event) OVERRIDE {
chromeos::input_method::ImeKeyboard* keyboard =
chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
- Shell::GetInstance()->metrics()->RecordUserMetricsAction(
- keyboard->CapsLockIsEnabled() ?
- ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK :
- ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK);
- keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
+ if (keyboard) {
+ Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+ keyboard->CapsLockIsEnabled() ?
+ ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK :
+ ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK);
+ keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
+ }
return true;
}
@@ -131,27 +133,17 @@
detailed_(NULL),
caps_lock_enabled_(CapsLockIsEnabled()),
message_shown_(false) {
- // Since keyboard handling differs between ChromeOS and Linux we need to
- // use different observers depending on the two platforms.
- if (base::SysInfo::IsRunningOnChromeOS()) {
- chromeos::input_method::ImeKeyboard* keyboard =
- chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
- keyboard->AddObserver(this);
- } else {
- Shell::GetInstance()->PrependPreTargetHandler(this);
- }
+ chromeos::input_method::InputMethodManager* ime =
+ chromeos::input_method::InputMethodManager::Get();
+ if (ime && ime->GetImeKeyboard())
+ ime->GetImeKeyboard()->AddObserver(this);
}
TrayCapsLock::~TrayCapsLock() {
- // Since keyboard handling differs between ChromeOS and Linux we need to
- // use different observers depending on the two platforms.
- if (base::SysInfo::IsRunningOnChromeOS()) {
- chromeos::input_method::ImeKeyboard* keyboard =
- chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
- keyboard->RemoveObserver(this);
- } else {
- Shell::GetInstance()->RemovePreTargetHandler(this);
- }
+ chromeos::input_method::InputMethodManager* ime =
+ chromeos::input_method::InputMethodManager::Get();
+ if (ime && ime->GetImeKeyboard())
+ ime->GetImeKeyboard()->RemoveObserver(this);
}
void TrayCapsLock::OnCapsLockChanged(bool enabled) {
@@ -176,11 +168,6 @@
}
}
-void TrayCapsLock::OnKeyEvent(ui::KeyEvent* key) {
- if (key->type() == ui::ET_KEY_PRESSED && key->key_code() == ui::VKEY_CAPITAL)
- OnCapsLockChanged(!caps_lock_enabled_);
-}
-
bool TrayCapsLock::GetInitialVisibility() {
return CapsLockIsEnabled();
}
diff --git a/ash/system/chromeos/tray_caps_lock.h b/ash/system/chromeos/tray_caps_lock.h
index 74eea29b..0343126 100644
--- a/ash/system/chromeos/tray_caps_lock.h
+++ b/ash/system/chromeos/tray_caps_lock.h
@@ -18,7 +18,6 @@
class CapsLockDefaultView;
class TrayCapsLock : public TrayImageItem,
- public ui::EventHandler,
public chromeos::input_method::ImeKeyboard::Observer {
public:
explicit TrayCapsLock(SystemTray* system_tray);
@@ -28,9 +27,6 @@
// Overriden from chromeos::input_method::ImeKeyboard::Observer:
virtual void OnCapsLockChanged(bool enabled) OVERRIDE;
- // ui::EventHandler:
- virtual void OnKeyEvent(ui::KeyEvent* key) OVERRIDE;
-
// Overridden from TrayImageItem.
virtual bool GetInitialVisibility() OVERRIDE;
virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
diff --git a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
index 88d74c4..63eadf1 100644
--- a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
+++ b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
@@ -64,7 +64,6 @@
tray_container()->AddChildView(button_);
SetContentsBackground();
- SetVisible(false);
// The Shell may not exist in some unit tests.
if (Shell::HasInstance()) {
Shell::GetInstance()->system_tray_notifier()->
diff --git a/ash/system/date/date_view.cc b/ash/system/date/date_view.cc
index 6bdd83e..9f45011 100644
--- a/ash/system/date/date_view.cc
+++ b/ash/system/date/date_view.cc
@@ -143,6 +143,14 @@
}
void DateView::SetAction(TrayDate::DateAction action) {
+ if (action == action_)
+ return;
+ if (IsMouseHovered()) {
+ date_label_->SetEnabledColor(
+ action == TrayDate::NONE ? kHeaderTextColorNormal :
+ kHeaderTextColorHover);
+ SchedulePaint();
+ }
action_ = action;
SetFocusable(action_ != TrayDate::NONE);
}
diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc
index b18ee1a..b56efa9 100644
--- a/ash/system/overview/overview_button_tray.cc
+++ b/ash/system/overview/overview_button_tray.cc
@@ -8,6 +8,7 @@
#include "ash/shell.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_utils.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
@@ -40,9 +41,6 @@
SetIconBorderForShelfAlignment();
tray_container()->AddChildView(icon_);
- UpdateIconVisibility(Shell::GetInstance()->
- IsMaximizeModeWindowManagerEnabled());
-
Shell::GetInstance()->AddShellObserver(this);
}
@@ -52,8 +50,7 @@
void OverviewButtonTray::UpdateAfterLoginStatusChange(
user::LoginStatus status) {
- UpdateIconVisibility(Shell::GetInstance()->
- IsMaximizeModeWindowManagerEnabled());
+ UpdateIconVisibility();
}
bool OverviewButtonTray::PerformAction(const ui::Event& event) {
@@ -62,13 +59,11 @@
}
void OverviewButtonTray::OnMaximizeModeStarted() {
- // TODO(flackr): once maximize mode has been refactored remove this so that
- // UpdateIconVisibility polls Shell for the status directly
- UpdateIconVisibility(/* maximize_mode_enabled */ true);
+ UpdateIconVisibility();
}
void OverviewButtonTray::OnMaximizeModeEnded() {
- UpdateIconVisibility(/* maximize_mode_enabled */ false);
+ UpdateIconVisibility();
}
bool OverviewButtonTray::ClickedOutsideBubble() {
@@ -111,8 +106,9 @@
}
}
-void OverviewButtonTray::UpdateIconVisibility(bool maximize_mode_enabled) {
- SetVisible(maximize_mode_enabled &&
+void OverviewButtonTray::UpdateIconVisibility() {
+ SetVisible(Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled() &&
Shell::GetInstance()->window_selector_controller()->CanSelect());
}
diff --git a/ash/system/overview/overview_button_tray.h b/ash/system/overview/overview_button_tray.h
index d988626..32feb0c 100644
--- a/ash/system/overview/overview_button_tray.h
+++ b/ash/system/overview/overview_button_tray.h
@@ -51,9 +51,9 @@
// alignment of the shelf.
void SetIconBorderForShelfAlignment();
- // Sets the icon to visible if |maximize_mode_enabled| and
+ // Sets the icon to visible if maximize mode is enabled and
// WindowSelectorController::CanSelect.
- void UpdateIconVisibility(bool maximize_mode_enabled);
+ void UpdateIconVisibility();
// Weak pointer, will be parented by TrayContainer for its lifetime.
views::ImageView* icon_;
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc
index bc3fd69..0bf495c 100644
--- a/ash/system/overview/overview_button_tray_unittest.cc
+++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -13,6 +13,7 @@
#include "ash/system/user/login_status.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/status_area_widget_test_helper.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "base/time/time.h"
#include "ui/events/event.h"
@@ -60,10 +61,12 @@
// By default the system should not have MaximizeMode enabled.
TEST_F(OverviewButtonTrayTest, MaximizeModeObserverOnMaximizeModeToggled) {
ASSERT_FALSE(GetTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(GetTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(GetTray()->visible());
}
@@ -92,10 +95,12 @@
UpdateDisplay("400x400,200x200");
EXPECT_FALSE(GetTray()->visible());
EXPECT_FALSE(GetSecondaryTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(GetTray()->visible());
EXPECT_TRUE(GetSecondaryTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests if Maximize Mode is enabled before a secondary display is attached
@@ -104,16 +109,19 @@
if (!SupportsMultipleDisplays())
return;
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
UpdateDisplay("400x400,200x200");
EXPECT_TRUE(GetSecondaryTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
// Tests that the tray loses visibility when a user logs out, and that it
// regains visibility when a user logs back in.
TEST_F(OverviewButtonTrayTest, VisibilityChangesForLoginStatus) {
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
SetUserLoggedIn(false);
Shell::GetInstance()->UpdateAfterLoginStatusChange(user::LOGGED_IN_NONE);
EXPECT_FALSE(GetTray()->visible());
@@ -121,7 +129,8 @@
SetSessionStarted(true);
Shell::GetInstance()->UpdateAfterLoginStatusChange(user::LOGGED_IN_USER);
EXPECT_TRUE(GetTray()->visible());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
}
} // namespace ash
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index 1de8045..5c6af2c 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -26,7 +26,6 @@
#include "ash/system/user/tray_user.h"
#include "ash/system/user/tray_user_separator.h"
#include "ash/system/web_notification/web_notification_tray.h"
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/timer/timer.h"
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index a166da3..bcf04a2 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -323,6 +323,8 @@
SetPaintToLayer(true);
SetFillsBoundsOpaquely(false);
+ // Start the tray items not visible, because visibility changes are animated.
+ views::View::SetVisible(false);
}
TrayBackgroundView::~TrayBackgroundView() {
diff --git a/ash/system/tray/tray_utils.cc b/ash/system/tray/tray_utils.cc
index 2153117..00a68fb 100644
--- a/ash/system/tray/tray_utils.cc
+++ b/ash/system/tray/tray_utils.cc
@@ -13,17 +13,12 @@
namespace ash {
void SetupLabelForTray(views::Label* label) {
- // Making label_font static to avoid the time penalty of Derive for all but
- // the first call.
- static const gfx::FontList label_font_list(
- gfx::FontList().Derive(1, gfx::Font::BOLD));
- label->SetFontList(label_font_list);
+ label->SetFontList(gfx::FontList().Derive(1, gfx::Font::BOLD));
label->SetAutoColorReadabilityEnabled(false);
label->SetEnabledColor(SK_ColorWHITE);
label->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
- label->SetShadowColors(SkColorSetARGB(64, 0, 0, 0),
- SkColorSetARGB(64, 0, 0, 0));
- label->SetShadowOffset(0, 1);
+ label->set_shadows(gfx::ShadowValues(1,
+ gfx::ShadowValue(gfx::Point(0, 1), 0, SkColorSetARGB(64, 0, 0, 0))));
}
void SetTrayImageItemBorder(views::View* tray_view,
diff --git a/ash/system/user/tray_user_unittest.cc b/ash/system/user/tray_user_unittest.cc
index 3205666..0135054 100644
--- a/ash/system/user/tray_user_unittest.cc
+++ b/ash/system/user/tray_user_unittest.cc
@@ -4,7 +4,6 @@
#include <vector>
-#include "ash/ash_switches.h"
#include "ash/root_window_controller.h"
#include "ash/session/user_info.h"
#include "ash/shelf/shelf_layout_manager.h"
@@ -17,7 +16,6 @@
#include "ash/test/ash_test_base.h"
#include "ash/test/test_session_state_delegate.h"
#include "ash/test/test_shell_delegate.h"
-#include "base/command_line.h"
#include "ui/aura/test/event_generator.h"
#include "ui/gfx/animation/animation_container_element.h"
#include "ui/views/view.h"
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index 45280f9..de999e9 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -305,7 +305,6 @@
tray_container()->AddChildView(button_);
SetContentsBackground();
tray_container()->SetBorder(views::Border::NullBorder());
- SetVisible(false);
message_center_tray_.reset(new message_center::MessageCenterTray(
this,
message_center::MessageCenter::Get()));
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index eaf9d06..ff7666c 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -157,27 +157,27 @@
// Add a notification.
AddNotification("test_id1");
EXPECT_EQ(1u, GetMessageCenter()->NotificationCount());
- EXPECT_TRUE(GetMessageCenter()->HasNotification("test_id1"));
+ EXPECT_TRUE(GetMessageCenter()->FindVisibleNotificationById("test_id1"));
AddNotification("test_id2");
AddNotification("test_id2");
EXPECT_EQ(2u, GetMessageCenter()->NotificationCount());
- EXPECT_TRUE(GetMessageCenter()->HasNotification("test_id2"));
+ EXPECT_TRUE(GetMessageCenter()->FindVisibleNotificationById("test_id2"));
// Ensure that updating a notification does not affect the count.
UpdateNotification("test_id2", "test_id3");
UpdateNotification("test_id3", "test_id3");
EXPECT_EQ(2u, GetMessageCenter()->NotificationCount());
- EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id2"));
+ EXPECT_FALSE(GetMessageCenter()->FindVisibleNotificationById("test_id2"));
// Ensure that Removing the first notification removes it from the tray.
RemoveNotification("test_id1");
- EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id1"));
+ EXPECT_FALSE(GetMessageCenter()->FindVisibleNotificationById("test_id1"));
EXPECT_EQ(1u, GetMessageCenter()->NotificationCount());
// Remove the remianing notification.
RemoveNotification("test_id3");
EXPECT_EQ(0u, GetMessageCenter()->NotificationCount());
- EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id3"));
+ EXPECT_FALSE(GetMessageCenter()->FindVisibleNotificationById("test_id3"));
}
TEST_F(WebNotificationTrayTest, WebNotificationPopupBubble) {
diff --git a/ash/test/shell_test_api.cc b/ash/test/shell_test_api.cc
index 0a7d4fd..94d93e5 100644
--- a/ash/test/shell_test_api.cc
+++ b/ash/test/shell_test_api.cc
@@ -55,10 +55,6 @@
return shell_->app_list_controller_.get();
}
-MaximizeModeWindowManager* ShellTestApi::maximize_mode_window_manager() {
- return shell_->maximize_mode_window_manager_.get();
-}
-
void ShellTestApi::DisableDisplayConfiguratorAnimation() {
#if defined(OS_CHROMEOS)
if (shell_->display_configurator_animation_) {
diff --git a/ash/touch/touch_hud_debug.cc b/ash/touch/touch_hud_debug.cc
index 20fab48..f516426 100644
--- a/ash/touch/touch_hud_debug.cc
+++ b/ash/touch/touch_hud_debug.cc
@@ -352,9 +352,8 @@
for (int i = 0; i < kMaxTouchPoints; ++i) {
touch_labels_[i] = new views::Label;
touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
- touch_labels_[i]->SetShadowColors(SK_ColorWHITE,
- SK_ColorWHITE);
- touch_labels_[i]->SetShadowOffset(1, 1);
+ touch_labels_[i]->set_shadows(gfx::ShadowValues(1,
+ gfx::ShadowValue(gfx::Point(1, 1), 0, SK_ColorWHITE)));
label_container_->AddChildView(touch_labels_[i]);
}
label_container_->SetX(0);
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc
index 0b42e24..a32812a 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -11,8 +11,10 @@
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "ash/wm/maximize_mode/maximize_mode_event_blocker.h"
+#include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
+#include "base/metrics/histogram.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
@@ -137,14 +139,33 @@
: rotation_locked_(false),
have_seen_accelerometer_data_(false),
in_set_screen_rotation_(false),
- user_rotation_(gfx::Display::ROTATE_0) {
+ user_rotation_(gfx::Display::ROTATE_0),
+ last_touchview_transition_time_(base::Time::Now()) {
Shell::GetInstance()->accelerometer_controller()->AddObserver(this);
+ Shell::GetInstance()->AddShellObserver(this);
}
MaximizeModeController::~MaximizeModeController() {
+ Shell::GetInstance()->RemoveShellObserver(this);
Shell::GetInstance()->accelerometer_controller()->RemoveObserver(this);
}
+void MaximizeModeController::SetRotationLocked(bool rotation_locked) {
+ if (rotation_locked_ == rotation_locked)
+ return;
+ rotation_locked_ = rotation_locked;
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnRotationLockChanged(rotation_locked_));
+}
+
+void MaximizeModeController::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void MaximizeModeController::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
bool MaximizeModeController::CanEnterMaximizeMode() {
// If we have ever seen accelerometer data, then HandleHingeRotation may
// trigger maximize mode at some point in the future.
@@ -155,6 +176,27 @@
switches::kAshEnableTouchViewTesting);
}
+void MaximizeModeController::EnableMaximizeModeWindowManager(bool enable) {
+ if (enable && !maximize_mode_window_manager_.get()) {
+ maximize_mode_window_manager_.reset(new MaximizeModeWindowManager());
+ // TODO(jonross): Move the maximize mode notifications from ShellObserver
+ // to MaximizeModeController::Observer
+ Shell::GetInstance()->OnMaximizeModeStarted();
+ } else if (!enable && maximize_mode_window_manager_.get()) {
+ maximize_mode_window_manager_.reset();
+ Shell::GetInstance()->OnMaximizeModeEnded();
+ }
+}
+
+bool MaximizeModeController::IsMaximizeModeWindowManagerEnabled() const {
+ return maximize_mode_window_manager_.get() != NULL;
+}
+
+void MaximizeModeController::Shutdown() {
+ maximize_mode_window_manager_.reset();
+ Shell::GetInstance()->OnMaximizeModeEnded();
+}
+
void MaximizeModeController::OnAccelerometerUpdated(
const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) {
@@ -177,11 +219,26 @@
HandleScreenRotation(lid);
}
+void MaximizeModeController::OnDisplayConfigurationChanged() {
+ if (in_set_screen_rotation_)
+ return;
+ DisplayManager* display_manager = Shell::GetInstance()->display_manager();
+ gfx::Display::Rotation user_rotation = display_manager->
+ GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
+ if (user_rotation != current_rotation_) {
+ // A user may change other display configuration settings. When the user
+ // does change the rotation setting, then lock rotation to prevent the
+ // accelerometer from erasing their change.
+ SetRotationLocked(true);
+ user_rotation_ = user_rotation;
+ current_rotation_ = user_rotation;
+ }
+}
+
void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) {
static const gfx::Vector3dF hinge_vector(0.0f, 1.0f, 0.0f);
- bool maximize_mode_engaged =
- Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled();
+ bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled();
// Ignore the component of acceleration parallel to the hinge for the purposes
// of hinge angle calculation.
gfx::Vector3dF base_flattened(base);
@@ -216,9 +273,11 @@
}
void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) {
- bool maximize_mode_engaged =
- Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled();
+ bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled();
+ // TODO(jonross): track the updated rotation angle even when locked. So that
+ // when rotation lock is removed the accelerometer rotation can be applied
+ // without waiting for the next update.
if (!maximize_mode_engaged || rotation_locked_)
return;
@@ -281,35 +340,86 @@
gfx::Display::Rotation rotation) {
base::AutoReset<bool> auto_in_set_screen_rotation(
&in_set_screen_rotation_, true);
+ current_rotation_ = rotation;
display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
rotation);
}
void MaximizeModeController::EnterMaximizeMode() {
- // TODO(jonross): Listen for display configuration changes. If the user
- // causes a rotation change a rotation lock should be applied.
- // https://crbug.com/369505
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
- user_rotation_ = display_manager->
+ current_rotation_ = user_rotation_ = display_manager->
GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ EnableMaximizeModeWindowManager(true);
event_blocker_.reset(new MaximizeModeEventBlocker);
#if defined(OS_CHROMEOS)
event_handler_.reset(new ScreenshotActionHandler);
#endif
+ Shell::GetInstance()->display_controller()->AddObserver(this);
}
void MaximizeModeController::LeaveMaximizeMode() {
DisplayManager* display_manager = Shell::GetInstance()->display_manager();
- DisplayInfo info = display_manager->
- GetDisplayInfo(gfx::Display::InternalDisplayId());
- gfx::Display::Rotation current_rotation = info.rotation();
+ gfx::Display::Rotation current_rotation = display_manager->
+ GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
if (current_rotation != user_rotation_)
SetDisplayRotation(display_manager, user_rotation_);
rotation_locked_ = false;
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ EnableMaximizeModeWindowManager(false);
event_blocker_.reset();
event_handler_.reset();
}
+void MaximizeModeController::OnSuspend() {
+ RecordTouchViewStateTransition();
+}
+
+void MaximizeModeController::OnResume() {
+ last_touchview_transition_time_ = base::Time::Now();
+}
+
+// Called after maximize mode has started, windows might still animate though.
+void MaximizeModeController::OnMaximizeModeStarted() {
+ RecordTouchViewStateTransition();
+}
+
+// Called after maximize mode has ended, windows might still be returning to
+// their original position.
+void MaximizeModeController::OnMaximizeModeEnded() {
+ RecordTouchViewStateTransition();
+}
+
+void MaximizeModeController::RecordTouchViewStateTransition() {
+ if (CanEnterMaximizeMode()) {
+ base::Time current_time = base::Time::Now();
+ base::TimeDelta delta = current_time - last_touchview_transition_time_;
+ if (IsMaximizeModeWindowManagerEnabled()) {
+ UMA_HISTOGRAM_LONG_TIMES("Ash.TouchView.TouchViewInactive", delta);
+ total_non_touchview_time_ += delta;
+ } else {
+ UMA_HISTOGRAM_LONG_TIMES("Ash.TouchView.TouchViewActive", delta);
+ total_touchview_time_ += delta;
+ }
+ last_touchview_transition_time_ = current_time;
+ }
+}
+
+void MaximizeModeController::OnAppTerminating() {
+ if (CanEnterMaximizeMode()) {
+ RecordTouchViewStateTransition();
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchView.TouchViewActiveTotal",
+ total_touchview_time_.InMinutes(),
+ 1, base::TimeDelta::FromDays(7).InMinutes(), 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchView.TouchViewInactiveTotal",
+ total_non_touchview_time_.InMinutes(),
+ 1, base::TimeDelta::FromDays(7).InMinutes(), 50);
+ base::TimeDelta total_runtime = total_touchview_time_ +
+ total_non_touchview_time_;
+ if (total_runtime.InSeconds() > 0) {
+ UMA_HISTOGRAM_PERCENTAGE("Ash.TouchView.TouchViewActivePercentage",
+ 100 * total_touchview_time_.InSeconds() / total_runtime.InSeconds());
+ }
+ }
+ Shell::GetInstance()->display_controller()->RemoveObserver(this);
+}
+
} // namespace ash
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h
index fd2efe5..8445bfa 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.h
+++ b/ash/wm/maximize_mode/maximize_mode_controller.h
@@ -7,9 +7,13 @@
#include "ash/accelerometer/accelerometer_observer.h"
#include "ash/ash_export.h"
+#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
+#include "ash/shell_observer.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "base/power_monitor/power_observer.h"
#include "ui/gfx/display.h"
namespace ui {
@@ -20,12 +24,28 @@
class MaximizeModeControllerTest;
class MaximizeModeEventBlocker;
+class MaximizeModeWindowManager;
+class MaximizeModeWindowManagerTest;
// MaximizeModeController listens to accelerometer events and automatically
// enters and exits maximize mode when the lid is opened beyond the triggering
// angle and rotates the display to match the device when in maximize mode.
-class ASH_EXPORT MaximizeModeController : public AccelerometerObserver {
+class ASH_EXPORT MaximizeModeController : public AccelerometerObserver,
+ public base::PowerObserver,
+ public ShellObserver,
+ public DisplayController::Observer {
public:
+ // Observer that reports changes to the state of MaximizeModeController's
+ // rotation lock.
+ class Observer {
+ public:
+ // Invoked whenever |rotation_locked_| is changed.
+ virtual void OnRotationLockChanged(bool rotation_locked) {}
+
+ protected:
+ virtual ~Observer() {}
+ };
+
MaximizeModeController();
virtual ~MaximizeModeController();
@@ -41,21 +61,53 @@
// If |rotation_locked| future calls to OnAccelerometerUpdated will not
// change the display rotation.
- void set_rotation_locked(bool rotation_locked) {
- rotation_locked_ = rotation_locked;
- }
+ void SetRotationLocked(bool rotation_locked);
+
+ // Add/Remove observers.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
// True if it is possible to enter maximize mode in the current
// configuration. If this returns false, it should never be the case that
// maximize mode becomes enabled.
bool CanEnterMaximizeMode();
+ // TODO(jonross): Merge this with EnterMaximizeMode. Currently these are
+ // separate for several reasons: there is no internal display when running
+ // unittests; the event blocker prevents keyboard input when running ChromeOS
+ // on linux. http://crbug.com/362881
+ // Turn the always maximize mode window manager on or off.
+ void EnableMaximizeModeWindowManager(bool enable);
+
+ // Test if the MaximizeModeWindowManager is enabled or not.
+ bool IsMaximizeModeWindowManagerEnabled() const;
+
+ // TODO(jonross): move this into the destructor. Currently separated as
+ // ShellOberver notifies of maximize mode ending, and the observers end up
+ // attempting to access MaximizeModeController via the Shell. If done in
+ // destructor the controller is null, and the observers segfault.
+ // Shuts down down the MaximizeModeWindowManager and notifies all observers.
+ void Shutdown();
+
// AccelerometerObserver:
virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) OVERRIDE;
+ // ShellObserver:
+ virtual void OnAppTerminating() OVERRIDE;
+ virtual void OnMaximizeModeStarted() OVERRIDE;
+ virtual void OnMaximizeModeEnded() OVERRIDE;
+
+ // base::PowerObserver:
+ virtual void OnSuspend() OVERRIDE;
+ virtual void OnResume() OVERRIDE;
+
+ // DisplayController::Observer:
+ virtual void OnDisplayConfigurationChanged() OVERRIDE;
+
private:
friend class MaximizeModeControllerTest;
+ friend class MaximizeModeWindowManagerTest;
// Detect hinge rotation from |base| and |lid| accelerometers and
// automatically start / stop maximize mode.
@@ -78,6 +130,12 @@
// is no rotation lock.
void LeaveMaximizeMode();
+ // Record UMA stats tracking touchview usage.
+ void RecordTouchViewStateTransition();
+
+ // The maximized window manager (if enabled).
+ scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
+
// An event targeter controller which traps mouse and keyboard events while
// maximize mode is engaged.
scoped_ptr<MaximizeModeEventBlocker> event_blocker_;
@@ -98,6 +156,19 @@
// restored upon exiting maximize mode.
gfx::Display::Rotation user_rotation_;
+ // The current rotation set by MaximizeModeController for the internal
+ // display. Compared in OnDisplayConfigurationChanged to determine user
+ // display setting changes.
+ gfx::Display::Rotation current_rotation_;
+
+ // Rotation Lock observers.
+ ObserverList<Observer> observers_;
+
+ // Tracks time spent in (and out of) touchview mode.
+ base::Time last_touchview_transition_time_;
+ base::TimeDelta total_touchview_time_;
+ base::TimeDelta total_non_touchview_time_;
+
DISALLOW_COPY_AND_ASSIGN(MaximizeModeController);
};
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index b3724c8..8afb9e3 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -126,8 +126,8 @@
maximize_mode_controller()->OnAccelerometerUpdated(base, lid);
}
- bool IsMaximizeModeStarted() const {
- return Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled();
+ bool IsMaximizeModeStarted() {
+ return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled();
}
// Overrides the internal input device list for the current event targeters
@@ -526,7 +526,7 @@
gfx::Vector3dF gravity(-1.0f, 0.0f, 0.0f);
- maximize_mode_controller()->set_rotation_locked(true);
+ maximize_mode_controller()->SetRotationLocked(true);
// Turn past the threshold for rotation.
float degrees = 90.0;
@@ -535,7 +535,7 @@
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
- maximize_mode_controller()->set_rotation_locked(false);
+ maximize_mode_controller()->SetRotationLocked(false);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
}
@@ -551,7 +551,7 @@
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
- maximize_mode_controller()->set_rotation_locked(true);
+ maximize_mode_controller()->SetRotationLocked(true);
// Open 90 degrees.
TriggerAccelerometerUpdate(base, gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
@@ -602,6 +602,7 @@
// adjusting the screen rotation directly when in maximize mode
ASSERT_NE(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
SetInternalDisplayRotation(gfx::Display::ROTATE_270);
+ maximize_mode_controller()->SetRotationLocked(false);
EXPECT_EQ(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
EXPECT_EQ(1u, message_center->NotificationCount());
EXPECT_TRUE(message_center->HasPopupNotifications());
@@ -646,4 +647,33 @@
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
}
+// Tests that if a user sets a display rotation that accelerometer rotation
+// becomes locked.
+TEST_F(MaximizeModeControllerTest,
+ NonAccelerometerRotationChangesLockRotation) {
+ // Trigger maximize mode by opening to 270.
+ TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
+ gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
+ ASSERT_FALSE(maximize_mode_controller()->rotation_locked());
+ SetInternalDisplayRotation(gfx::Display::ROTATE_270);
+ EXPECT_TRUE(maximize_mode_controller()->rotation_locked());
+}
+
+// Tests that if a user changes the display rotation, while rotation is locked,
+// that the updates are recorded. Upon exiting maximize mode the latest user
+// rotation should be applied.
+TEST_F(MaximizeModeControllerTest, UpdateUserRotationWhileRotationLocked) {
+ // Trigger maximize mode by opening to 270.
+ TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
+ gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
+ SetInternalDisplayRotation(gfx::Display::ROTATE_270);
+ // User sets rotation to the same rotation that the display was at when
+ // maximize mode was activated.
+ SetInternalDisplayRotation(gfx::Display::ROTATE_0);
+ // Exit maximize mode
+ TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f),
+ gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
+ EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
+}
+
} // namespace ash
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.cc b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
index aac09b7..e434cba 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
@@ -48,7 +48,6 @@
EnableBackdropBehindTopWindowOnEachDisplay(false);
RemoveWindowCreationObservers();
RestoreAllWindows();
- Shell::GetInstance()->OnMaximizeModeEnded();
}
int MaximizeModeWindowManager::GetNumberOfManagedWindows() {
@@ -163,7 +162,6 @@
MaximizeAllWindows();
AddWindowCreationObservers();
EnableBackdropBehindTopWindowOnEachDisplay(true);
- Shell::GetInstance()->OnMaximizeModeStarted();
Shell::GetScreen()->AddObserver(this);
Shell::GetInstance()->AddShellObserver(this);
Shell::GetInstance()->AddPreTargetHandler(this);
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.h b/ash/wm/maximize_mode/maximize_mode_window_manager.h
index 8bc851a..78e4405 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager.h
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager.h
@@ -22,8 +22,8 @@
}
namespace ash {
+class MaximizeModeController;
class MaximizeModeWindowState;
-class Shell;
// A window manager which - when created - will force all windows into maximized
// mode. Exception are panels and windows which cannot be maximized.
@@ -66,7 +66,7 @@
virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
protected:
- friend class ash::Shell;
+ friend class MaximizeModeController;
// The object should only be created by the ash::Shell.
MaximizeModeWindowManager();
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
index 9c59aa6..8dc5575 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
@@ -4,6 +4,8 @@
#include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
+#include <string>
+
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shelf/shelf_layout_manager.h"
@@ -11,6 +13,7 @@
#include "ash/switchable_windows.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/shell_test_api.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_properties.h"
@@ -79,20 +82,22 @@
// Create the Maximized mode window manager.
ash::MaximizeModeWindowManager* CreateMaximizeModeWindowManager() {
EXPECT_FALSE(maximize_mode_window_manager());
- Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
return maximize_mode_window_manager();
}
// Destroy the maximized mode window manager.
void DestroyMaximizeModeWindowManager() {
- Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(maximize_mode_window_manager());
}
// Get the maximze window manager.
ash::MaximizeModeWindowManager* maximize_mode_window_manager() {
- test::ShellTestApi test_api(Shell::GetInstance());
- return test_api.maximize_mode_window_manager();
+ return Shell::GetInstance()->maximize_mode_controller()->
+ maximize_mode_window_manager_.get();
}
// Resize our desktop.
@@ -735,7 +740,8 @@
rect));
wm::WindowState* window_state = wm::GetWindowState(window.get());
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
- ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ ash::Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
EXPECT_TRUE(window_state->IsMaximized());
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
@@ -750,7 +756,8 @@
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
- ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ ash::Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
EXPECT_FALSE(window_state->IsMaximized());
EXPECT_FALSE(window_state->IsMinimized());
EXPECT_TRUE(window->IsVisible());
@@ -950,7 +957,8 @@
// 2. Check that turning on the manager will stop allowing the window from
// dragging.
- ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
+ ash::Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(true);
gfx::Rect center_bounds(window->bounds());
EXPECT_NE(rect.origin().ToString(), center_bounds.origin().ToString());
generator.MoveMouseTo(gfx::Point(center_bounds.x() + 1,
@@ -961,7 +969,8 @@
generator.ReleaseLeftButton();
EXPECT_EQ(center_bounds.x(), window->bounds().x());
EXPECT_EQ(center_bounds.y(), window->bounds().y());
- ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
+ ash::Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(false);
// 3. Releasing the mazimize manager again will restore the window to its
// previous bounds and
diff --git a/ash/wm/maximize_mode/workspace_backdrop_delegate.cc b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc
index afa7005..14c5daf 100644
--- a/ash/wm/maximize_mode/workspace_backdrop_delegate.cc
+++ b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc
@@ -91,6 +91,10 @@
RestackBackdrop();
}
+void WorkspaceBackdropDelegate::OnDisplayWorkAreaInsetsChanged() {
+ AdjustToContainerBounds();
+}
+
void WorkspaceBackdropDelegate::RestackBackdrop() {
// Avoid recursive calls.
if (in_restacking_)
diff --git a/ash/wm/maximize_mode/workspace_backdrop_delegate.h b/ash/wm/maximize_mode/workspace_backdrop_delegate.h
index 27768ac..e9c495d 100644
--- a/ash/wm/maximize_mode/workspace_backdrop_delegate.h
+++ b/ash/wm/maximize_mode/workspace_backdrop_delegate.h
@@ -45,6 +45,7 @@
virtual void OnPostWindowStateTypeChange(
wm::WindowState* window_state,
wm::WindowStateType old_type) OVERRIDE;
+ virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE;
private:
// Restack the backdrop relatively to the other windows in the container.
diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc
index e59d078..7966849 100644
--- a/ash/wm/overview/window_grid.cc
+++ b/ash/wm/overview/window_grid.cc
@@ -143,7 +143,7 @@
// Attached panel windows are grouped into a single overview item per
// grid.
if (!panels_item) {
- panels_item = new WindowSelectorPanels();
+ panels_item = new WindowSelectorPanels(root_window_);
window_list_.push_back(panels_item);
}
panels_item->AddWindow(*iter);
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc
index 593df59..467aca6 100644
--- a/ash/wm/overview/window_selector.cc
+++ b/ash/wm/overview/window_selector.cc
@@ -95,7 +95,10 @@
restore_focus_window_(aura::client::GetFocusClient(
Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
ignore_activations_(false),
- selected_grid_index_(0) {
+ selected_grid_index_(0),
+ overview_start_time_(base::Time::Now()),
+ num_key_presses_(0),
+ num_items_(0) {
DCHECK(delegate_);
Shell* shell = Shell::GetInstance();
shell->OnOverviewModeStarting();
@@ -104,7 +107,6 @@
restore_focus_window_->AddObserver(this);
const aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- size_t items = 0;
for (aura::Window::Windows::const_iterator iter = root_windows.begin();
iter != root_windows.end(); iter++) {
// Observed switchable containers for newly created windows on all root
@@ -118,12 +120,12 @@
scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this));
if (grid->empty())
continue;
+ num_items_ += grid->size();
grid_list_.push_back(grid.release());
- items += grid_list_.size();
}
DCHECK(!grid_list_.empty());
- UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", items);
+ UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_);
shell->activation_client()->AddObserver(this);
@@ -168,9 +170,18 @@
shell->RemovePreTargetHandler(this);
shell->GetScreen()->RemoveObserver(this);
- UMA_HISTOGRAM_MEDIUM_TIMES(
- "Ash.WindowSelector.TimeInOverview",
- base::Time::Now() - overview_start_time_);
+
+ size_t remaining_items = 0;
+ for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin();
+ iter != grid_list_.end(); iter++) {
+ remaining_items += (*iter)->size();
+ }
+
+ DCHECK(num_items_ >= remaining_items);
+ UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems",
+ num_items_ - remaining_items);
+ UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowSelector.TimeInOverview",
+ base::Time::Now() - overview_start_time_);
// TODO(nsatragno): Change this to OnOverviewModeEnded and move it to when
// everything is done.
@@ -200,35 +211,45 @@
if (event->type() != ui::ET_KEY_PRESSED)
return;
- bool handled = true;
switch (event->key_code()) {
case ui::VKEY_ESCAPE:
CancelSelection();
break;
case ui::VKEY_UP:
+ num_key_presses_++;
Move(WindowSelector::UP);
break;
case ui::VKEY_DOWN:
+ num_key_presses_++;
Move(WindowSelector::DOWN);
break;
case ui::VKEY_RIGHT:
+ num_key_presses_++;
Move(WindowSelector::RIGHT);
break;
case ui::VKEY_LEFT:
+ num_key_presses_++;
Move(WindowSelector::LEFT);
break;
case ui::VKEY_RETURN:
- wm::GetWindowState(
- grid_list_[selected_grid_index_]->
- SelectedWindow()->SelectionWindow())->Activate();
+ // Ignore if no item is selected.
+ if (!grid_list_[selected_grid_index_]->is_selecting())
+ return;
+ UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses",
+ num_key_presses_);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Ash.WindowSelector.KeyPressesOverItemsRatio",
+ (num_key_presses_ * 100) / num_items_, 1, 300, 30);
+ Shell::GetInstance()->metrics()->RecordUserMetricsAction(
+ UMA_WINDOW_OVERVIEW_ENTER_KEY);
+ wm::GetWindowState(grid_list_[selected_grid_index_]->
+ SelectedWindow()->SelectionWindow())->Activate();
break;
default:
// Not a key we are interested in.
- handled = false;
- break;
+ return;
}
- if (handled)
- event->SetHandled();
+ event->StopPropagation();
}
void WindowSelector::OnDisplayAdded(const gfx::Display& display) {
diff --git a/ash/wm/overview/window_selector.h b/ash/wm/overview/window_selector.h
index d6c8519..f9ca51a 100644
--- a/ash/wm/overview/window_selector.h
+++ b/ash/wm/overview/window_selector.h
@@ -124,9 +124,6 @@
// List of all the window overview grids, one for each root window.
ScopedVector<WindowGrid> grid_list_;
- // The time when overview was started.
- base::Time overview_start_time_;
-
// Tracks windows which were hidden because they were not part of the
// overview.
aura::WindowTracker hidden_windows_;
@@ -134,6 +131,17 @@
// Tracks the index of the root window the selection widget is in.
size_t selected_grid_index_;
+ // The following variables are used for metric collection purposes. All of
+ // them refer to this particular overview session and are not cumulative:
+ // The time when overview was started.
+ base::Time overview_start_time_;
+
+ // The number of arrow key presses.
+ size_t num_key_presses_;
+
+ // The number of items in the overview.
+ size_t num_items_;
+
DISALLOW_COPY_AND_ASSIGN(WindowSelector);
};
diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc
index ea74ff0..02e2f59 100644
--- a/ash/wm/overview/window_selector_controller.cc
+++ b/ash/wm/overview/window_selector_controller.cc
@@ -67,8 +67,6 @@
}
void WindowSelectorController::OnSelectionStarted() {
- Shell* shell = Shell::GetInstance();
- shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_SELECTION);
if (!last_selection_time_.is_null()) {
UMA_HISTOGRAM_LONG_TIMES(
"Ash.WindowSelector.TimeBetweenUse",
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc
index 71a6f14..7b0d872 100644
--- a/ash/wm/overview/window_selector_item.cc
+++ b/ash/wm/overview/window_selector_item.cc
@@ -10,16 +10,46 @@
#include "ash/wm/overview/scoped_transform_overview_window.h"
#include "ash/wm/overview/transparent_activate_window_button.h"
#include "base/auto_reset.h"
-#include "third_party/skia/include/core/SkColor.h"
+#include "grit/ash_resources.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"
namespace ash {
+namespace {
+
+views::Widget* CreateCloseWindowButton(aura::Window* root_window,
+ views::ButtonListener* listener) {
+ views::Widget* widget = new views::Widget;
+ views::Widget::InitParams params;
+ params.type = views::Widget::InitParams::TYPE_POPUP;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
+ params.parent =
+ Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer);
+ widget->set_focus_on_creation(false);
+ widget->Init(params);
+ views::ImageButton* button = new views::ImageButton(listener);
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ button->SetImage(views::CustomButton::STATE_NORMAL,
+ rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE));
+ button->SetImage(views::CustomButton::STATE_HOVERED,
+ rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H));
+ button->SetImage(views::CustomButton::STATE_PRESSED,
+ rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P));
+ widget->SetContentsView(button);
+ widget->SetSize(rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE)->size());
+ widget->Show();
+ return widget;
+}
+
+} // namespace
+
// In the conceptual overview table, the window margin is the space reserved
// around the window within the cell. This margin does not overlap so the
// closest distance between adjacent windows will be twice this amount.
@@ -59,9 +89,8 @@
views::Label* label = new views::Label;
label->SetEnabledColor(kLabelColor);
label->SetBackgroundColor(kLabelBackground);
- label->SetShadowColors(kLabelShadow, kLabelShadow);
- label->SetShadowOffset(0, kVerticalShadowOffset);
- label->set_shadow_blur(kShadowBlur);
+ label->set_shadows(gfx::ShadowValues(1, gfx::ShadowValue(
+ gfx::Point(0, kVerticalShadowOffset), kShadowBlur, kLabelShadow)));
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
label->SetFontList(bundle.GetFontList(ui::ResourceBundle::BoldFont));
label->SetText(title);
@@ -85,6 +114,16 @@
WindowSelectorItem::~WindowSelectorItem() {
}
+void WindowSelectorItem::RemoveWindow(const aura::Window* window) {
+ // If empty WindowSelectorItem will be destroyed immediately after this by
+ // its owner.
+ if (empty())
+ return;
+ window_label_.reset();
+ UpdateWindowLabels(target_bounds_, root_window_, false);
+ UpdateCloseButtonBounds(root_window_, false);
+}
+
void WindowSelectorItem::SetBounds(aura::Window* root_window,
const gfx::Rect& target_bounds,
bool animate) {
@@ -108,6 +147,7 @@
gfx::Rect inset_bounds(target_bounds);
inset_bounds.Inset(kWindowMargin, kWindowMargin);
SetItemBounds(root_window, inset_bounds, animate);
+ UpdateCloseButtonBounds(root_window, animate);
}
void WindowSelectorItem::RecomputeWindowTransforms() {
@@ -118,12 +158,82 @@
gfx::Rect inset_bounds(target_bounds_);
inset_bounds.Inset(kWindowMargin, kWindowMargin);
SetItemBounds(root_window_, inset_bounds, false);
+ UpdateCloseButtonBounds(root_window_, false);
}
void WindowSelectorItem::SendFocusAlert() const {
activate_window_button_->SendFocusAlert();
}
+void WindowSelectorItem::ButtonPressed(views::Button* sender,
+ const ui::Event& event) {
+ views::Widget::GetWidgetForNativeView(SelectionWindow())->Close();
+}
+
+void WindowSelectorItem::UpdateCloseButtonBounds(aura::Window* root_window,
+ bool animate) {
+ gfx::RectF align_bounds(ScreenUtil::ConvertRectFromScreen(
+ root_window, SelectionWindow()->layer()->bounds()));
+ gfx::Transform window_transform;
+ window_transform.Translate(align_bounds.x(), align_bounds.y());
+ window_transform.PreconcatTransform(SelectionWindow()->layer()->
+ GetTargetTransform());
+ window_transform.Translate(-align_bounds.x(), -align_bounds.y());
+ window_transform.TransformRect(&align_bounds);
+ gfx::Rect target_bounds = ToEnclosingRect(align_bounds);
+
+ gfx::Transform close_button_transform;
+ close_button_transform.Translate(target_bounds.right(), target_bounds.y());
+
+ // If the root window has changed, force the close button to be recreated
+ // and faded in on the new root window.
+ if (close_button_ &&
+ close_button_->GetNativeWindow()->GetRootWindow() != root_window) {
+ close_button_.reset();
+ }
+
+ if (!close_button_) {
+ close_button_.reset(CreateCloseWindowButton(root_window, this));
+ gfx::Rect close_button_rect(close_button_->GetNativeWindow()->bounds());
+ // Align the center of the button with position (0, 0) so that the
+ // translate transform does not need to take the button dimensions into
+ // account.
+ close_button_rect.set_x(-close_button_rect.width() / 2);
+ close_button_rect.set_y(-close_button_rect.height() / 2);
+ close_button_->GetNativeWindow()->SetBounds(close_button_rect);
+ close_button_->GetNativeWindow()->SetTransform(close_button_transform);
+ // The close button is initialized when entering overview, fade the button
+ // in after the window should be in place.
+ ui::Layer* layer = close_button_->GetNativeWindow()->layer();
+ layer->SetOpacity(0);
+ layer->GetAnimator()->StopAnimating();
+ layer->GetAnimator()->SchedulePauseForProperties(
+ base::TimeDelta::FromMilliseconds(
+ ScopedTransformOverviewWindow::kTransitionMilliseconds),
+ ui::LayerAnimationElement::OPACITY);
+ {
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
+ settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
+ WindowSelectorItem::kFadeInMilliseconds));
+ layer->SetOpacity(1);
+ }
+ } else {
+ if (animate) {
+ ui::ScopedLayerAnimationSettings settings(
+ close_button_->GetNativeWindow()->layer()->GetAnimator());
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
+ ScopedTransformOverviewWindow::kTransitionMilliseconds));
+ close_button_->GetNativeWindow()->SetTransform(close_button_transform);
+ } else {
+ close_button_->GetNativeWindow()->SetTransform(close_button_transform);
+ }
+ }
+}
+
void WindowSelectorItem::UpdateWindowLabels(const gfx::Rect& window_bounds,
aura::Window* root_window,
bool animate) {
diff --git a/ash/wm/overview/window_selector_item.h b/ash/wm/overview/window_selector_item.h
index 4526325..ac57266 100644
--- a/ash/wm/overview/window_selector_item.h
+++ b/ash/wm/overview/window_selector_item.h
@@ -7,8 +7,8 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
-#include "base/strings/string16.h"
#include "ui/gfx/rect.h"
+#include "ui/views/controls/button/button.h"
namespace aura {
class Window;
@@ -24,7 +24,7 @@
// This class represents an item in overview mode. An item can have one or more
// windows, of which only one can be activated by keyboard (i.e. alt+tab) but
// any can be selected with a pointer (touch or mouse).
-class WindowSelectorItem {
+class WindowSelectorItem : public views::ButtonListener {
public:
WindowSelectorItem();
virtual ~WindowSelectorItem();
@@ -52,7 +52,7 @@
// Removes |window| from this item. Check empty() after calling this to see
// if the entire item is now empty.
- virtual void RemoveWindow(const aura::Window* window) = 0;
+ virtual void RemoveWindow(const aura::Window* window);
// Returns true if this item has no more selectable windows (i.e. after
// calling RemoveWindow for the last contained window).
@@ -76,8 +76,12 @@
// label is read.
void SendFocusAlert() const;
- const gfx::Rect& bounds() { return bounds_; }
- const gfx::Rect& target_bounds() { return target_bounds_; }
+ const gfx::Rect& bounds() const { return bounds_; }
+ const gfx::Rect& target_bounds() const { return target_bounds_; }
+
+ // views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender,
+ const ui::Event& event) OVERRIDE;
protected:
// Sets the bounds of this selector's items to |target_bounds| in
@@ -93,6 +97,10 @@
private:
friend class WindowSelectorTest;
+ // Creates |close_button_| if it does not exist and updates the bounds based
+ // on GetCloseButtonTargetBounds()
+ void UpdateCloseButtonBounds(aura::Window* root_window, bool animate);
+
// Creates a label to display under the window selector item.
void UpdateWindowLabels(const gfx::Rect& target_bounds,
aura::Window* root_window,
@@ -116,6 +124,9 @@
// Label under the window displaying its active tab name.
scoped_ptr<views::Widget> window_label_;
+ // An easy to access close button for the window in this item.
+ scoped_ptr<views::Widget> close_button_;
+
// Transparent window on top of the real windows in the overview that
// activates them on click or tap.
scoped_ptr<TransparentActivateWindowButton> activate_window_button_;
diff --git a/ash/wm/overview/window_selector_panels.cc b/ash/wm/overview/window_selector_panels.cc
index 588bf3b..e936f92 100644
--- a/ash/wm/overview/window_selector_panels.cc
+++ b/ash/wm/overview/window_selector_panels.cc
@@ -21,14 +21,12 @@
namespace {
-const int kPanelCalloutFadeInDurationMilliseconds = 50;
-
// This class extends ScopedTransformOverviewMode to hide and show the callout
// widget for a panel window when entering / leaving overview mode, as well as
// to add a transparent button for each panel window.
class ScopedTransformPanelWindow : public ScopedTransformOverviewWindow {
public:
- ScopedTransformPanelWindow(aura::Window* window);
+ explicit ScopedTransformPanelWindow(aura::Window* window);
virtual ~ScopedTransformPanelWindow();
// ScopedTransformOverviewWindow overrides:
@@ -40,20 +38,9 @@
bool animate) OVERRIDE;
private:
- // Returns the callout widget for the transformed panel.
- views::Widget* GetCalloutWidget();
-
- // Restores the callout visibility.
- void RestoreCallout();
-
- // Trigger relayout
- void Relayout();
-
// Returns the panel window bounds after the transformation.
gfx::Rect GetTransformedBounds();
- bool callout_visible_;
-
scoped_ptr<TransparentActivateWindowButton> window_button_;
DISALLOW_COPY_AND_ASSIGN(ScopedTransformPanelWindow);
@@ -64,14 +51,10 @@
}
ScopedTransformPanelWindow::~ScopedTransformPanelWindow() {
- // window() will be NULL if the window was destroyed.
- if (window())
- RestoreCallout();
}
void ScopedTransformPanelWindow::PrepareForOverview() {
ScopedTransformOverviewWindow::PrepareForOverview();
- GetCalloutWidget()->GetLayer()->SetOpacity(0.0f);
window_button_.reset(new TransparentActivateWindowButton(window()));
}
@@ -83,26 +66,6 @@
window_button_->SetBounds(GetTransformedBounds());
}
-views::Widget* ScopedTransformPanelWindow::GetCalloutWidget() {
- DCHECK(window()->parent()->id() == kShellWindowId_PanelContainer);
- PanelLayoutManager* panel_layout_manager =
- static_cast<PanelLayoutManager*>(window()->parent()->layout_manager());
- return panel_layout_manager->GetCalloutWidgetForPanel(window());
-}
-
-void ScopedTransformPanelWindow::RestoreCallout() {
- scoped_ptr<ui::LayerAnimationSequence> sequence(
- new ui::LayerAnimationSequence);
- sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
- ui::LayerAnimationElement::OPACITY, base::TimeDelta::FromMilliseconds(
- ScopedTransformOverviewWindow::kTransitionMilliseconds)));
- sequence->AddElement(ui::LayerAnimationElement::CreateOpacityElement(1,
- base::TimeDelta::FromMilliseconds(
- kPanelCalloutFadeInDurationMilliseconds)));
- GetCalloutWidget()->GetLayer()->GetAnimator()->StartAnimation(
- sequence.release());
-}
-
gfx::Rect ScopedTransformPanelWindow::GetTransformedBounds() {
gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
window()->GetRootWindow(), window()->layer()->bounds()));
@@ -118,13 +81,21 @@
} // namespace
-WindowSelectorPanels::WindowSelectorPanels() {
+WindowSelectorPanels::WindowSelectorPanels(aura::Window* panels_root_window)
+ : panels_root_window_(panels_root_window) {
+ static_cast<PanelLayoutManager*>(
+ Shell::GetContainer(panels_root_window_, kShellWindowId_PanelContainer)->
+ layout_manager())->SetShowCalloutWidgets(false);
}
WindowSelectorPanels::~WindowSelectorPanels() {
+ static_cast<PanelLayoutManager*>(
+ Shell::GetContainer(panels_root_window_, kShellWindowId_PanelContainer)->
+ layout_manager())->SetShowCalloutWidgets(true);
}
void WindowSelectorPanels::AddWindow(aura::Window* window) {
+ DCHECK(window->GetRootWindow() == panels_root_window_);
transform_windows_.push_back(new ScopedTransformPanelWindow(window));
}
@@ -173,6 +144,7 @@
break;
}
}
+ WindowSelectorItem::RemoveWindow(window);
}
bool WindowSelectorPanels::empty() const {
diff --git a/ash/wm/overview/window_selector_panels.h b/ash/wm/overview/window_selector_panels.h
index 7d2131c..b3ea49f 100644
--- a/ash/wm/overview/window_selector_panels.h
+++ b/ash/wm/overview/window_selector_panels.h
@@ -20,7 +20,7 @@
// overview mode and the callout arrows are hidden at this point.
class WindowSelectorPanels : public WindowSelectorItem {
public:
- WindowSelectorPanels();
+ explicit WindowSelectorPanels(aura::Window* panels_root_window);
virtual ~WindowSelectorPanels();
// Adds |window| to the selector item. This window should be an attached
@@ -44,6 +44,9 @@
typedef ScopedVector<ScopedTransformOverviewWindow> WindowList;
WindowList transform_windows_;
+ // The root window of the panels this item contains.
+ aura::Window* panels_root_window_;
+
DISALLOW_COPY_AND_ASSIGN(WindowSelectorPanels);
};
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index 01fad7d..d552d78 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+
#include "ash/accessibility_delegate.h"
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/root_window_controller.h"
@@ -20,6 +22,7 @@
#include "ash/wm/overview/window_selector.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/overview/window_selector_item.h"
+#include "ash/wm/panels/panel_layout_manager.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
@@ -41,6 +44,7 @@
#include "ui/gfx/transform.h"
#include "ui/views/controls/label.h"
#include "ui/views/widget/native_widget_aura.h"
+#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_delegate.h"
@@ -101,6 +105,18 @@
return window;
}
+ views::Widget* CreatePanelWindowWidget(const gfx::Rect& bounds) {
+ views::Widget* widget = new views::Widget;
+ views::Widget::InitParams params;
+ params.bounds = bounds;
+ params.type = views::Widget::InitParams::TYPE_PANEL;
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget->Init(params);
+ widget->Show();
+ ParentWindowInPrimaryRootWindow(widget->GetNativeWindow());
+ return widget;
+ }
+
bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) {
gfx::RectF window1_bounds = GetTransformedTargetBounds(window1);
gfx::RectF window2_bounds = GetTransformedTargetBounds(window2);
@@ -186,6 +202,10 @@
SelectedWindow()->SelectionWindow();
}
+ views::Widget* GetCloseButton(ash::WindowSelectorItem* window) {
+ return window->close_button_.get();
+ }
+
views::Widget* GetLabelWidget(ash::WindowSelectorItem* window) {
return window->window_label_.get();
}
@@ -861,4 +881,105 @@
EXPECT_EQ(GetSelectedWindow(), window4.get());
}
+// Tests selecting a window in overview mode with the return key.
+TEST_F(WindowSelectorTest, SelectWindowWithReturnKey) {
+ gfx::Rect bounds(0, 0, 100, 100);
+ scoped_ptr<aura::Window> window2(CreateWindow(bounds));
+ scoped_ptr<aura::Window> window1(CreateWindow(bounds));
+ ToggleOverview();
+
+ // Pressing the return key without a selection widget should not do anything.
+ SendKey(ui::VKEY_RETURN);
+ EXPECT_TRUE(IsSelecting());
+
+ // Select the first window.
+ SendKey(ui::VKEY_RIGHT);
+ SendKey(ui::VKEY_RETURN);
+ ASSERT_FALSE(IsSelecting());
+ EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
+
+ // Select the second window.
+ ToggleOverview();
+ SendKey(ui::VKEY_RIGHT);
+ SendKey(ui::VKEY_RIGHT);
+ SendKey(ui::VKEY_RETURN);
+ EXPECT_FALSE(IsSelecting());
+ EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
+}
+
+// Tests that overview mode hides the callout widget.
+TEST_F(WindowSelectorTest, WindowOverviewHidesCalloutWidgets) {
+ scoped_ptr<aura::Window> panel1(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
+ scoped_ptr<aura::Window> panel2(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
+ PanelLayoutManager* panel_manager =
+ static_cast<PanelLayoutManager*>(panel1->parent()->layout_manager());
+
+ // By default, panel callout widgets are visible.
+ EXPECT_TRUE(
+ panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
+ EXPECT_TRUE(
+ panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
+
+ // Toggling the overview should hide the callout widgets.
+ ToggleOverview();
+ EXPECT_FALSE(
+ panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
+ EXPECT_FALSE(
+ panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
+
+ // Ending the overview should show them again.
+ ToggleOverview();
+ EXPECT_TRUE(
+ panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
+ EXPECT_TRUE(
+ panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
+}
+
+// Tests that when panels are grouped that the close button only closes the
+// currently active panel. After the removal window selection should still be
+// active, and the label should have changed. Removing the last panel should
+// cause selection to end.
+TEST_F(WindowSelectorTest, CloseButtonOnPanels) {
+ scoped_ptr<views::Widget> widget1(CreatePanelWindowWidget(
+ gfx::Rect(0, 0, 300, 100)));
+ scoped_ptr<views::Widget> widget2(CreatePanelWindowWidget(
+ gfx::Rect(100, 0, 100, 100)));
+ aura::Window* window1 = widget1->GetNativeWindow();
+ aura::Window* window2 = widget2->GetNativeWindow();
+ base::string16 panel1_title = base::UTF8ToUTF16("Panel 1");
+ base::string16 panel2_title = base::UTF8ToUTF16("Panel 2");
+ window1->set_title(panel1_title);
+ window2->set_title(panel2_title);
+ wm::ActivateWindow(window1);
+ ToggleOverview();
+
+ gfx::RectF bounds1 = GetTransformedBoundsInRootWindow(window1);
+ gfx::Point point1(bounds1.top_right().x() - 1, bounds1.top_right().y() - 1);
+ aura::test::EventGenerator event_generator1(window1->GetRootWindow(), point1);
+
+ EXPECT_FALSE(widget1->IsClosed());
+ event_generator1.ClickLeftButton();
+ EXPECT_TRUE(widget1->IsClosed());
+ RunAllPendingInMessageLoop();
+ EXPECT_TRUE(IsSelecting());
+ WindowSelectorItem* window_item = GetWindowItemsForRoot(0).front();
+ EXPECT_FALSE(window_item->empty());
+ EXPECT_TRUE(window_item->Contains(window2));
+ EXPECT_TRUE(GetCloseButton(window_item)->IsVisible());
+
+ views::Widget* widget = GetLabelWidget(window_item);
+ views::Label* label = static_cast<views::Label*>(widget->GetContentsView());
+ EXPECT_EQ(label->text(), panel2_title);
+
+ gfx::RectF bounds2 = GetTransformedBoundsInRootWindow(window2);
+ gfx::Point point2(bounds2.top_right().x() - 1, bounds2.top_right().y() - 1);
+ aura::test::EventGenerator event_generator2(window2->GetRootWindow(), point2);
+
+ EXPECT_FALSE(widget2->IsClosed());
+ event_generator2.ClickLeftButton();
+ EXPECT_TRUE(widget2->IsClosed());
+ RunAllPendingInMessageLoop();
+ EXPECT_FALSE(IsSelecting());
+}
+
} // namespace ash
diff --git a/ash/wm/overview/window_selector_window.cc b/ash/wm/overview/window_selector_window.cc
index 6aad03f..ae276b6 100644
--- a/ash/wm/overview/window_selector_window.cc
+++ b/ash/wm/overview/window_selector_window.cc
@@ -19,35 +19,6 @@
namespace ash {
-namespace {
-
-views::Widget* CreateCloseWindowButton(aura::Window* root_window,
- views::ButtonListener* listener) {
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params;
- params.type = views::Widget::InitParams::TYPE_POPUP;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- params.parent =
- Shell::GetContainer(root_window, ash::kShellWindowId_OverlayContainer);
- widget->set_focus_on_creation(false);
- widget->Init(params);
- views::ImageButton* button = new views::ImageButton(listener);
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- button->SetImage(views::CustomButton::STATE_NORMAL,
- rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE));
- button->SetImage(views::CustomButton::STATE_HOVERED,
- rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_H));
- button->SetImage(views::CustomButton::STATE_PRESSED,
- rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE_P));
- widget->SetContentsView(button);
- widget->SetSize(rb.GetImageSkiaNamed(IDR_AURA_WINDOW_OVERVIEW_CLOSE)->size());
- widget->Show();
- return widget;
-}
-
-} // namespace
-
WindowSelectorWindow::WindowSelectorWindow(aura::Window* window)
: transform_window_(window) {
}
@@ -78,10 +49,7 @@
void WindowSelectorWindow::RemoveWindow(const aura::Window* window) {
DCHECK_EQ(transform_window_.window(), window);
transform_window_.OnWindowDestroyed();
- // Remove the close button now so that the exited mouse event which is
- // delivered to the destroyed button as it is destroyed does not happen while
- // this item is being removed from the list of windows in overview.
- close_button_.reset();
+ WindowSelectorItem::RemoveWindow(window);
}
bool WindowSelectorWindow::empty() const {
@@ -101,72 +69,6 @@
transform_window_.SetTransform(root_window,
ScopedTransformOverviewWindow::GetTransformForRect(src_rect, bounds()),
animate);
- // TODO move close button management to WindowSelectorItem, so that we can
- // also handle panels.
- // See http://crbug.com/352143
- UpdateCloseButtonBounds(root_window, animate);
-}
-
-void WindowSelectorWindow::ButtonPressed(views::Button* sender,
- const ui::Event& event) {
- views::Widget::GetTopLevelWidgetForNativeView(
- transform_window_.window())->Close();
-}
-
-void WindowSelectorWindow::UpdateCloseButtonBounds(aura::Window* root_window,
- bool animate) {
- gfx::Rect align_bounds(
- ScreenUtil::ConvertRectFromScreen(root_window, bounds()));
- gfx::Transform close_button_transform;
- close_button_transform.Translate(align_bounds.right(), align_bounds.y());
-
- // If the root window has changed, force the close button to be recreated
- // and faded in on the new root window.
- if (close_button_ &&
- close_button_->GetNativeWindow()->GetRootWindow() != root_window) {
- close_button_.reset();
- }
-
- if (!close_button_) {
- close_button_.reset(CreateCloseWindowButton(root_window, this));
- gfx::Rect close_button_rect(close_button_->GetNativeWindow()->bounds());
- // Align the center of the button with position (0, 0) so that the
- // translate transform does not need to take the button dimensions into
- // account.
- close_button_rect.set_x(-close_button_rect.width() / 2);
- close_button_rect.set_y(-close_button_rect.height() / 2);
- close_button_->GetNativeWindow()->SetBounds(close_button_rect);
- close_button_->GetNativeWindow()->SetTransform(close_button_transform);
- // The close button is initialized when entering overview, fade the button
- // in after the window should be in place.
- ui::Layer* layer = close_button_->GetNativeWindow()->layer();
- layer->SetOpacity(0);
- layer->GetAnimator()->StopAnimating();
- layer->GetAnimator()->SchedulePauseForProperties(
- base::TimeDelta::FromMilliseconds(
- ScopedTransformOverviewWindow::kTransitionMilliseconds),
- ui::LayerAnimationElement::OPACITY);
- {
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
- settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
- WindowSelectorItem::kFadeInMilliseconds));
- layer->SetOpacity(1);
- }
- } else {
- if (animate) {
- ui::ScopedLayerAnimationSettings settings(
- close_button_->GetNativeWindow()->layer()->GetAnimator());
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
- ScopedTransformOverviewWindow::kTransitionMilliseconds));
- close_button_->GetNativeWindow()->SetTransform(close_button_transform);
- } else {
- close_button_->GetNativeWindow()->SetTransform(close_button_transform);
- }
- }
}
} // namespace ash
diff --git a/ash/wm/overview/window_selector_window.h b/ash/wm/overview/window_selector_window.h
index 11b0ebd..e508438 100644
--- a/ash/wm/overview/window_selector_window.h
+++ b/ash/wm/overview/window_selector_window.h
@@ -9,7 +9,6 @@
#include "ash/wm/overview/window_selector_item.h"
#include "base/compiler_specific.h"
#include "ui/gfx/rect.h"
-#include "ui/views/controls/button/button.h"
namespace aura {
class Window;
@@ -23,10 +22,9 @@
// This implements a window overview item with a single window which can be
// selected.
-class WindowSelectorWindow : public WindowSelectorItem,
- public views::ButtonListener {
+class WindowSelectorWindow : public WindowSelectorItem {
public:
- WindowSelectorWindow(aura::Window* window);
+ explicit WindowSelectorWindow(aura::Window* window);
virtual ~WindowSelectorWindow();
// WindowSelectorItem:
@@ -42,20 +40,10 @@
const gfx::Rect& target_bounds,
bool animate) OVERRIDE;
- // views::ButtonListener:
- virtual void ButtonPressed(views::Button* sender,
- const ui::Event& event) OVERRIDE;
private:
- // Creates the close button window if it does not exist and updates the bounds
- // to match the window selector item.
- void UpdateCloseButtonBounds(aura::Window* root_window, bool animate);
-
// The window with a scoped transform represented by this selector item.
ScopedTransformOverviewWindow transform_window_;
- // An easy to access close button for the window in this item.
- scoped_ptr<views::Widget> close_button_;
-
DISALLOW_COPY_AND_ASSIGN(WindowSelectorWindow);
};
diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc
index 234adb9..a92ad02 100644
--- a/ash/wm/panels/panel_layout_manager.cc
+++ b/ash/wm/panels/panel_layout_manager.cc
@@ -258,6 +258,7 @@
: panel_container_(panel_container),
in_add_window_(false),
in_layout_(false),
+ show_callout_widgets_(true),
dragged_panel_(NULL),
shelf_(NULL),
shelf_layout_manager_(NULL),
@@ -325,6 +326,13 @@
window_state->Minimize();
}
+void PanelLayoutManager::SetShowCalloutWidgets(bool show) {
+ if (show_callout_widgets_ == show)
+ return;
+ show_callout_widgets_ = show;
+ UpdateCallouts();
+}
+
views::Widget* PanelLayoutManager::GetCalloutWidgetForPanel(
aura::Window* panel) {
DCHECK(panel->parent() == panel_container_);
@@ -814,7 +822,7 @@
panel->GetTargetBounds());
gfx::Rect icon_bounds = shelf_->GetScreenBoundsOfItemIconForWindow(panel);
if (icon_bounds.IsEmpty() || !panel->layer()->GetTargetVisibility() ||
- panel == dragged_panel_) {
+ panel == dragged_panel_ || !show_callout_widgets_) {
callout_widget->Hide();
callout_widget->GetNativeWindow()->layer()->SetOpacity(0);
continue;
diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h
index fc42af2..494d2c2 100644
--- a/ash/wm/panels/panel_layout_manager.h
+++ b/ash/wm/panels/panel_layout_manager.h
@@ -72,6 +72,9 @@
void ToggleMinimize(aura::Window* panel);
+ // Hide / Show the panel callout widgets.
+ void SetShowCalloutWidgets(bool show);
+
// Returns the callout widget (arrow) for |panel|.
views::Widget* GetCalloutWidgetForPanel(aura::Window* panel);
@@ -169,6 +172,8 @@
bool in_add_window_;
// Protect against recursive calls to Relayout().
bool in_layout_;
+ // Indicates if the panel callout widget should be created.
+ bool show_callout_widgets_;
// Ordered list of unowned pointers to panel windows.
PanelList panel_windows_;
// The panel being dragged.
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc
index 6bf85b4..4faeacb 100644
--- a/ash/wm/panels/panel_layout_manager_unittest.cc
+++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -117,9 +117,7 @@
EXPECT_FALSE(window1_bounds.Intersects(window2_bounds));
}
- // TODO(dcheng): This should be const, but GetScreenBoundsOfItemIconForWindow
- // takes a non-const Window. We can probably fix that.
- void IsPanelAboveLauncherIcon(aura::Window* panel) {
+ void IsPanelAboveLauncherIcon(const aura::Window* panel) {
// Waits until all shelf view animations are done.
shelf_view_test()->RunMessageLoopUntilAnimationsDone();
@@ -234,7 +232,7 @@
shell->SetShelfAlignment(alignment, root_window);
}
- ShelfAlignment GetAlignment(aura::Window* root_window) {
+ ShelfAlignment GetAlignment(const aura::Window* root_window) {
ash::Shell* shell = ash::Shell::GetInstance();
return shell->GetShelfAlignment(root_window);
}
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index e2af719..0e9c63f 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -383,8 +383,8 @@
toplevel->GetWindowBoundsInScreen().ToString());
}
-TEST_F(SystemGestureEventFilterTest, TwoFingerDragEdge) {
- gfx::Rect bounds(0, 0, 100, 100);
+TEST_F(SystemGestureEventFilterTest, DISABLED_TwoFingerDragEdge) {
+ gfx::Rect bounds(0, 0, 200, 100);
aura::Window* root_window = Shell::GetPrimaryRootWindow();
views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
new ResizableWidgetDelegate, root_window, bounds);
@@ -397,6 +397,8 @@
gfx::Point(0, 40), // Left edge
};
+ EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
+ GetNonClientComponent(points[0]));
EXPECT_EQ(HTLEFT, toplevel->GetNativeWindow()->delegate()->
GetNonClientComponent(points[1]));
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc
index 472a83d..54e702c 100644
--- a/ash/wm/window_cycle_controller.cc
+++ b/ash/wm/window_cycle_controller.cc
@@ -8,6 +8,7 @@
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/window_cycle_list.h"
+#include "base/metrics/histogram.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
@@ -79,6 +80,8 @@
window_cycle_list_.reset(new WindowCycleList(ash::Shell::GetInstance()->
mru_window_tracker()->BuildMruWindowList()));
event_handler_.reset(new WindowCycleEventFilter());
+ cycle_start_time_ = base::Time::Now();
+ Shell::GetInstance()->metrics()->RecordUserMetricsAction(UMA_WINDOW_CYCLE);
}
//////////////////////////////////////////////////////////////////////////////
@@ -93,6 +96,8 @@
window_cycle_list_.reset();
// Remove our key event filter.
event_handler_.reset();
+ UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowCycleController.CycleTime",
+ base::Time::Now() - cycle_start_time_);
}
} // namespace ash
diff --git a/ash/wm/window_cycle_controller.h b/ash/wm/window_cycle_controller.h
index d0da1f4..4120bc0 100644
--- a/ash/wm/window_cycle_controller.h
+++ b/ash/wm/window_cycle_controller.h
@@ -8,6 +8,7 @@
#include "ash/ash_export.h"
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
namespace ui {
class EventHandler;
@@ -65,6 +66,8 @@
// Event handler to watch for release of alt key.
scoped_ptr<ui::EventHandler> event_handler_;
+ base::Time cycle_start_time_;
+
DISALLOW_COPY_AND_ASSIGN(WindowCycleController);
};
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc
index 6e49351..ca1e4bc 100644
--- a/ash/wm/window_state.cc
+++ b/ash/wm/window_state.cc
@@ -81,24 +81,6 @@
} // namespace
-WindowState::WindowState(aura::Window* window)
- : window_(window),
- window_position_managed_(false),
- bounds_changed_by_user_(false),
- panel_attached_(true),
- ignored_by_shelf_(false),
- can_consume_system_keys_(false),
- top_row_keys_are_function_keys_(false),
- unminimize_to_restore_bounds_(false),
- in_immersive_fullscreen_(false),
- hide_shelf_when_fullscreen_(true),
- minimum_visibility_(false),
- can_be_dragged_(true),
- ignore_property_change_(false),
- current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {
- window_->AddObserver(this);
-}
-
WindowState::~WindowState() {
// WindowState is registered as an owned property of |window_|, and window
// unregisters all of its observers in its d'tor before destroying its
@@ -316,6 +298,28 @@
}
}
+WindowState::WindowState(aura::Window* window)
+ : window_(window),
+ window_position_managed_(false),
+ bounds_changed_by_user_(false),
+ panel_attached_(true),
+ ignored_by_shelf_(false),
+ can_consume_system_keys_(false),
+ top_row_keys_are_function_keys_(false),
+ unminimize_to_restore_bounds_(false),
+ in_immersive_fullscreen_(false),
+ hide_shelf_when_fullscreen_(true),
+ minimum_visibility_(false),
+ can_be_dragged_(true),
+ ignore_property_change_(false),
+ current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {
+ window_->AddObserver(this);
+}
+
+ui::WindowShowState WindowState::GetShowState() const {
+ return window_->GetProperty(aura::client::kShowStateKey);
+}
+
void WindowState::SetBoundsInScreen(
const gfx::Rect& bounds_in_screen) {
gfx::Rect bounds_in_parent =
@@ -324,10 +328,6 @@
window_->SetBounds(bounds_in_parent);
}
-ui::WindowShowState WindowState::GetShowState() const {
- return window_->GetProperty(aura::client::kShowStateKey);
-}
-
void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) {
if (is_dragged() || !IsSnapped())
return;
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h
index d26c031..8732d28 100644
--- a/ash/wm/window_state.h
+++ b/ash/wm/window_state.h
@@ -78,7 +78,7 @@
DISALLOW_COPY_AND_ASSIGN(State);
};
- explicit WindowState(aura::Window* window);
+ // Call GetWindowState() to instantiate this class.
virtual ~WindowState();
aura::Window* window() { return window_; }
@@ -306,8 +306,11 @@
friend class DefaultState;
friend class ash::LockWindowState;
friend class ash::MaximizeModeWindowState;
+ friend ASH_EXPORT WindowState* GetWindowState(aura::Window*);
FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest, CrossFadeToBounds);
+ explicit WindowState(aura::Window* window);
+
WindowStateDelegate* delegate() { return delegate_.get(); }
// Returns the window's current show state.
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 0326e6a..06b79bd 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -4,6 +4,8 @@
#include "ash/wm/workspace/workspace_layout_manager.h"
+#include <algorithm>
+
#include "ash/display/display_controller.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
@@ -135,7 +137,7 @@
ui::InputMethod* input_method =
root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
ui::TextInputClient* text_input_client = input_method->GetTextInputClient();
- if(!text_input_client)
+ if (!text_input_client)
return;
aura::Window *window = text_input_client->GetAttachedWindow();
if (!window || !window_->Contains(window))
@@ -163,6 +165,8 @@
const wm::WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
AdjustAllWindowsBoundsForWorkAreaChange(&event);
}
+ if (backdrop_delegate_)
+ backdrop_delegate_->OnDisplayWorkAreaInsetsChanged();
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/ash/wm/workspace/workspace_layout_manager_delegate.h b/ash/wm/workspace/workspace_layout_manager_delegate.h
index 4cd1710..cdc76c2 100644
--- a/ash/wm/workspace/workspace_layout_manager_delegate.h
+++ b/ash/wm/workspace/workspace_layout_manager_delegate.h
@@ -39,6 +39,9 @@
// A window state type has changed.
virtual void OnPostWindowStateTypeChange(wm::WindowState* window_state,
wm::WindowStateType old_type) = 0;
+
+ // The work area insets have changed, altering the total available space.
+ virtual void OnDisplayWorkAreaInsetsChanged() = 0;
};
} // namespace ash
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 651f1f8..3a9a58a 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -4,6 +4,8 @@
#include "ash/wm/workspace/workspace_layout_manager.h"
+#include <string>
+
#include "ash/display/display_layout.h"
#include "ash/display/display_manager.h"
#include "ash/root_window_controller.h"
@@ -27,6 +29,8 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/screen.h"
@@ -39,7 +43,7 @@
class MaximizeDelegateView : public views::WidgetDelegateView {
public:
- MaximizeDelegateView(const gfx::Rect& initial_bounds)
+ explicit MaximizeDelegateView(const gfx::Rect& initial_bounds)
: initial_bounds_(initial_bounds) {
}
virtual ~MaximizeDelegateView() {}
@@ -788,9 +792,6 @@
UpdateDisplay("800x600");
default_container_ = Shell::GetContainer(Shell::GetPrimaryRootWindow(),
kShellWindowId_DefaultContainer);
- // We set the size to something smaller then the display to avoid resizing
- // issues with the shelf.
- default_container_->SetBounds(gfx::Rect(0, 0, 800, 500));
}
aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
@@ -942,6 +943,33 @@
window3.get()));
}
+// Tests that when hidding the shelf, that the backdrop resizes to fill the
+// entire workspace area.
+TEST_F(WorkspaceLayoutManagerBackdropTest, ShelfVisibilityChangesBounds) {
+ ShelfLayoutManager* shelf_layout_manager =
+ Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
+ ShowTopWindowBackdrop(true);
+ RunAllPendingInMessageLoop();
+
+ ASSERT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
+ gfx::Rect initial_bounds = default_container()->children()[0]->bounds();
+ shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
+ shelf_layout_manager->UpdateVisibilityState();
+
+ // When the shelf is re-shown WorkspaceLayoutManager shrinks all children
+ // including the backdrop.
+ shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
+ shelf_layout_manager->UpdateVisibilityState();
+ gfx::Rect reduced_bounds = default_container()->children()[0]->bounds();
+ EXPECT_LT(reduced_bounds.height(), initial_bounds.height());
+
+ shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
+ shelf_layout_manager->UpdateVisibilityState();
+
+ EXPECT_GT(default_container()->children()[0]->bounds().height(),
+ reduced_bounds.height());
+}
+
class WorkspaceLayoutManagerKeyboardTest : public test::AshTestBase {
public:
WorkspaceLayoutManagerKeyboardTest() {}
@@ -983,14 +1011,14 @@
private:
gfx::Insets restore_work_area_insets_;
gfx::Rect keyboard_bounds_;
- WorkspaceLayoutManager *layout_manager_;
+ WorkspaceLayoutManager* layout_manager_;
DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerKeyboardTest);
};
class FakeTextInputClient : public ui::DummyTextInputClient {
public:
- FakeTextInputClient(gfx::NativeWindow window) : window_(window) {}
+ explicit FakeTextInputClient(gfx::NativeWindow window) : window_(window) {}
virtual ~FakeTextInputClient() {}
virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE {
@@ -1019,7 +1047,12 @@
FakeTextInputClient text_input_client(window.get());
ui::InputMethod* input_method =
root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
- input_method->SetFocusedTextInputClient(&text_input_client);
+ if (switches::IsTextInputFocusManagerEnabled()) {
+ ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
+ &text_input_client);
+ } else {
+ input_method->SetFocusedTextInputClient(&text_input_client);
+ }
int available_height =
Shell::GetScreen()->GetPrimaryDisplay().bounds().height() -
@@ -1039,7 +1072,12 @@
EXPECT_EQ(gfx::Rect(50, 0, 100, available_height).ToString(),
window->bounds().ToString());
HideKeyboard();
- input_method->SetFocusedTextInputClient(NULL);
+ if (switches::IsTextInputFocusManagerEnabled()) {
+ ui::TextInputFocusManager::GetInstance()->BlurTextInputClient(
+ &text_input_client);
+ } else {
+ input_method->SetFocusedTextInputClient(NULL);
+ }
}
} // namespace ash