Index: ash/wm/power_button_controller.cc |
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc |
index 58c8181069ffdf3834b3aa352c3ca6e45b8dfcbf..bd9bb911ac2c52702eb5dd1e700912104aebae51 100644 |
--- a/ash/wm/power_button_controller.cc |
+++ b/ash/wm/power_button_controller.cc |
@@ -8,23 +8,10 @@ |
#include "ash/shell.h" |
#include "ash/shell_delegate.h" |
#include "ash/shell_window_ids.h" |
-#include "ash/wm/cursor_manager.h" |
+#include "ash/wm/session_state_animator.h" |
#include "base/command_line.h" |
-#include "base/logging.h" |
-#include "base/time.h" |
-#include "third_party/skia/include/core/SkColor.h" |
-#include "ui/aura/env.h" |
#include "ui/aura/root_window.h" |
#include "ui/aura/shared/compound_event_filter.h" |
-#include "ui/aura/window.h" |
-#include "ui/compositor/layer.h" |
-#include "ui/compositor/layer_animation_element.h" |
-#include "ui/compositor/layer_animation_sequence.h" |
-#include "ui/compositor/layer_animator.h" |
-#include "ui/gfx/canvas.h" |
-#include "ui/gfx/rect.h" |
-#include "ui/gfx/size.h" |
-#include "ui/gfx/transform.h" |
namespace ash { |
@@ -59,256 +46,20 @@ const int kUndoSlowCloseAnimMs = 100; |
// system is shutting down. |
const int kFastCloseAnimMs = 150; |
-// Amount of time taken to make the lock window fade in when the screen is |
-// locked. |
-const int kLockFadeInAnimMs = 200; |
- |
// Additional time (beyond kFastCloseAnimMs) to wait after starting the |
// fast-close shutdown animation before actually requesting shutdown, to give |
// the animation time to finish. |
const int kShutdownRequestDelayMs = 50; |
-// Slightly-smaller size that we scale the screen down to for the pre-lock and |
-// pre-shutdown states. |
-const float kSlowCloseSizeRatio = 0.95f; |
- |
-// Returns the transform that should be applied to containers for the slow-close |
-// animation. |
-ui::Transform GetSlowCloseTransform() { |
- gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); |
- ui::Transform transform; |
- transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio); |
- transform.ConcatTranslate( |
- floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5), |
- floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5)); |
- return transform; |
-} |
- |
-// Returns the transform that should be applied to containers for the fast-close |
-// animation. |
-ui::Transform GetFastCloseTransform() { |
- gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); |
- ui::Transform transform; |
- transform.SetScale(0.0, 0.0); |
- transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5), |
- floor(0.5 * root_size.height() + 0.5)); |
- return transform; |
-} |
- |
-// Slowly shrinks |window| to a slightly-smaller size. |
-void StartSlowCloseAnimationForWindow(aura::Window* window) { |
- ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
- animator->set_preemption_strategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- animator->StartAnimation( |
- new ui::LayerAnimationSequence( |
- ui::LayerAnimationElement::CreateTransformElement( |
- GetSlowCloseTransform(), |
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs)))); |
-} |
- |
-// Quickly undoes the effects of the slow-close animation on |window|. |
-void StartUndoSlowCloseAnimationForWindow(aura::Window* window) { |
- ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
- animator->set_preemption_strategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- animator->StartAnimation( |
- new ui::LayerAnimationSequence( |
- ui::LayerAnimationElement::CreateTransformElement( |
- ui::Transform(), |
- base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs)))); |
-} |
- |
-// Quickly shrinks |window| down to a point in the center of the screen and |
-// fades it out to 0 opacity. |
-void StartFastCloseAnimationForWindow(aura::Window* window) { |
- ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
- animator->set_preemption_strategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- animator->StartAnimation( |
- new ui::LayerAnimationSequence( |
- ui::LayerAnimationElement::CreateTransformElement( |
- GetFastCloseTransform(), |
- base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); |
- animator->StartAnimation( |
- new ui::LayerAnimationSequence( |
- ui::LayerAnimationElement::CreateOpacityElement( |
- 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); |
-} |
- |
-// Fades |window| in to full opacity. |
-void FadeInWindow(aura::Window* window) { |
- ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
- animator->set_preemption_strategy( |
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
- animator->StartAnimation( |
- new ui::LayerAnimationSequence( |
- ui::LayerAnimationElement::CreateOpacityElement( |
- 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs)))); |
-} |
- |
-// Makes |window| fully transparent instantaneously. |
-void HideWindow(aura::Window* window) { |
- window->layer()->SetOpacity(0.0); |
-} |
- |
-// Restores |window| to its original position and scale and full opacity |
-// instantaneously. |
-void RestoreWindow(aura::Window* window) { |
- window->layer()->SetTransform(ui::Transform()); |
- window->layer()->SetOpacity(1.0); |
-} |
- |
-// Fills |containers| with the containers described by |container_mask|. |
-void GetContainers(int container_mask, aura::Window::Windows* containers) { |
- aura::RootWindow* root_window = Shell::GetPrimaryRootWindow(); |
- containers->clear(); |
- |
- if (container_mask & PowerButtonController::DESKTOP_BACKGROUND) { |
- containers->push_back(Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_DesktopBackgroundContainer)); |
- } |
- if (container_mask & PowerButtonController::LAUNCHER) { |
- containers->push_back(Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_LauncherContainer)); |
- } |
- if (container_mask & PowerButtonController::NON_LOCK_SCREEN_CONTAINERS) { |
- // TODO(antrim): Figure out a way to eliminate a need to exclude launcher |
- // in such way. |
- aura::Window* non_lock_screen_containers = Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_NonLockScreenContainersContainer); |
- aura::Window::Windows children = non_lock_screen_containers->children(); |
- |
- for (aura::Window::Windows::const_iterator it = children.begin(); |
- it != children.end(); ++it) { |
- aura::Window* window = *it; |
- if (window->id() == internal::kShellWindowId_LauncherContainer) |
- continue; |
- containers->push_back(window); |
- } |
- } |
- if (container_mask & PowerButtonController::LOCK_SCREEN_BACKGROUND) { |
- containers->push_back(Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_LockScreenBackgroundContainer)); |
- } |
- if (container_mask & PowerButtonController::LOCK_SCREEN_CONTAINERS) { |
- containers->push_back(Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_LockScreenContainersContainer)); |
- } |
- if (container_mask & PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS) { |
- containers->push_back(Shell::GetContainer( |
- root_window, |
- internal::kShellWindowId_LockScreenRelatedContainersContainer)); |
- } |
-} |
- |
-// Apply animation |type| to all containers described by |container_mask|. |
-void StartAnimation(int container_mask, |
- PowerButtonController::AnimationType type) { |
- aura::Window::Windows containers; |
- GetContainers(container_mask, &containers); |
- |
- for (aura::Window::Windows::const_iterator it = containers.begin(); |
- it != containers.end(); ++it) { |
- aura::Window* window = *it; |
- switch (type) { |
- case PowerButtonController::ANIMATION_SLOW_CLOSE: |
- StartSlowCloseAnimationForWindow(window); |
- break; |
- case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: |
- StartUndoSlowCloseAnimationForWindow(window); |
- break; |
- case PowerButtonController::ANIMATION_FAST_CLOSE: |
- StartFastCloseAnimationForWindow(window); |
- break; |
- case PowerButtonController::ANIMATION_FADE_IN: |
- FadeInWindow(window); |
- break; |
- case PowerButtonController::ANIMATION_HIDE: |
- HideWindow(window); |
- break; |
- case PowerButtonController::ANIMATION_RESTORE: |
- RestoreWindow(window); |
- break; |
- default: |
- NOTREACHED() << "Unhandled animation type " << type; |
- } |
- } |
-} |
- |
} // namespace |
-bool PowerButtonController::TestApi::ContainersAreAnimated( |
- int container_mask, AnimationType type) const { |
- aura::Window::Windows containers; |
- GetContainers(container_mask, &containers); |
- for (aura::Window::Windows::const_iterator it = containers.begin(); |
- it != containers.end(); ++it) { |
- aura::Window* window = *it; |
- ui::Layer* layer = window->layer(); |
- |
- switch (type) { |
- case PowerButtonController::ANIMATION_SLOW_CLOSE: |
- if (layer->GetTargetTransform() != GetSlowCloseTransform()) |
- return false; |
- break; |
- case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: |
- if (layer->GetTargetTransform() != ui::Transform()) |
- return false; |
- break; |
- case PowerButtonController::ANIMATION_FAST_CLOSE: |
- if (layer->GetTargetTransform() != GetFastCloseTransform() || |
- layer->GetTargetOpacity() > 0.0001) |
- return false; |
- break; |
- case PowerButtonController::ANIMATION_FADE_IN: |
- if (layer->GetTargetOpacity() < 0.9999) |
- return false; |
- break; |
- case PowerButtonController::ANIMATION_HIDE: |
- if (layer->GetTargetOpacity() > 0.0001) |
- return false; |
- break; |
- case PowerButtonController::ANIMATION_RESTORE: |
- if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform()) |
- return false; |
- break; |
- default: |
- NOTREACHED() << "Unhandled animation type " << type; |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-bool PowerButtonController::TestApi::BlackLayerIsVisible() const { |
- return controller_->black_layer_.get() && |
- controller_->black_layer_->visible(); |
-} |
- |
-gfx::Rect PowerButtonController::TestApi::GetBlackLayerBounds() const { |
- ui::Layer* layer = controller_->black_layer_.get(); |
- return layer ? layer->bounds() : gfx::Rect(); |
+PowerButtonController::TestApi::TestApi(PowerButtonController* controller) |
+ : controller_(controller), |
+ animator_api_(new internal::SessionStateAnimator::TestApi( |
+ controller->animator_.get())) { |
} |
-// static |
-int PowerButtonController::GetAllContainersMask() { |
- return PowerButtonController::DESKTOP_BACKGROUND | |
- PowerButtonController::LAUNCHER | |
- PowerButtonController::NON_LOCK_SCREEN_CONTAINERS | |
- GetAllLockScreenContainersMask(); |
-} |
- |
-// static |
-int PowerButtonController::GetAllLockScreenContainersMask() { |
- return PowerButtonController::LOCK_SCREEN_BACKGROUND | |
- PowerButtonController::LOCK_SCREEN_CONTAINERS | |
- PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS; |
+PowerButtonController::TestApi::~TestApi() { |
} |
PowerButtonController::PowerButtonController() |
@@ -320,7 +71,8 @@ PowerButtonController::PowerButtonController() |
shutting_down_(false), |
has_legacy_power_button_( |
CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kAuraLegacyPowerButton)) { |
+ switches::kAuraLegacyPowerButton)), |
+ animator_(new internal::SessionStateAnimator()) { |
Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); |
} |
@@ -341,8 +93,10 @@ void PowerButtonController::OnAppTerminating() { |
Shell* shell = ash::Shell::GetInstance(); |
shell->env_filter()->set_cursor_hidden_by_filter(false); |
shell->cursor_manager()->ShowCursor(false); |
- ShowBlackLayer(); |
- StartAnimation(GetAllContainersMask(), ANIMATION_HIDE); |
+ animator_->ShowBlackLayer(); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::kAllContainersMask, |
+ internal::SessionStateAnimator::ANIMATION_HIDE); |
} |
} |
@@ -359,7 +113,9 @@ void PowerButtonController::OnLockStateChanged(bool locked) { |
} |
if (locked) { |
- StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_FADE_IN); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_FADE_IN); |
lock_timer_.Stop(); |
lock_fail_timer_.Stop(); |
@@ -371,9 +127,12 @@ void PowerButtonController::OnLockStateChanged(bool locked) { |
this, &PowerButtonController::OnLockToShutdownTimeout); |
} |
} else { |
- StartAnimation(DESKTOP_BACKGROUND | LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, |
- ANIMATION_RESTORE); |
- HideBlackLayer(); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND | |
+ internal::SessionStateAnimator::LAUNCHER | |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_RESTORE); |
+ animator_->DropBlackLayer(); |
} |
} |
@@ -388,14 +147,20 @@ void PowerButtonController::OnStartingLock() { |
// Ensure that the black layer is visible -- if the screen was locked via |
// the wrench menu, we won't have already shown the black background |
// as part of the slow-close animation. |
- ShowBlackLayer(); |
+ animator_->ShowBlackLayer(); |
- StartAnimation(LAUNCHER, ANIMATION_HIDE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_HIDE); |
- StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_FAST_CLOSE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
// Hide the screen locker containers so we can make them fade in later. |
- StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_HIDE); |
} |
void PowerButtonController::OnPowerButtonEvent( |
@@ -415,9 +180,11 @@ void PowerButtonController::OnPowerButtonEvent( |
// running on official hardware, just lock the screen or shut down |
// immediately. |
if (down) { |
- ShowBlackLayer(); |
+ animator_->ShowBlackLayer(); |
if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) { |
- StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
OnLockTimeout(); |
} else { |
OnShutdownTimeout(); |
@@ -438,22 +205,21 @@ void PowerButtonController::OnPowerButtonEvent( |
if (login_status_ == user::LOGGED_IN_LOCKED) { |
// If we've already started shutdown transition at lock screen |
// desktop background needs to be restored immediately. |
- StartAnimation(DESKTOP_BACKGROUND, ANIMATION_RESTORE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
+ internal::SessionStateAnimator::ANIMATION_RESTORE); |
} |
- StartAnimation( |
+ animator_->StartAnimation( |
(login_status_ == user::LOGGED_IN_LOCKED) ? |
- GetAllLockScreenContainersMask() : GetAllContainersMask(), |
- ANIMATION_UNDO_SLOW_CLOSE); |
+ internal::SessionStateAnimator::kAllLockScreenContainersMask : |
+ internal::SessionStateAnimator::kAllContainersMask, |
+ internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
} |
// Drop the black layer after the undo animation finishes. |
if (lock_timer_.IsRunning() || |
(shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) { |
- hide_black_layer_timer_.Stop(); |
- hide_black_layer_timer_.Start( |
- FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), |
- this, &PowerButtonController::HideBlackLayer); |
+ animator_->ScheduleDropBlackLayer(); |
} |
lock_timer_.Stop(); |
@@ -482,12 +248,10 @@ void PowerButtonController::OnLockButtonEvent( |
StartLockTimer(); |
} else { |
if (lock_timer_.IsRunning()) { |
- StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_UNDO_SLOW_CLOSE); |
- hide_black_layer_timer_.Stop(); |
- hide_black_layer_timer_.Start( |
- FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), |
- this, &PowerButtonController::HideBlackLayer); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
+ animator_->ScheduleDropBlackLayer(); |
lock_timer_.Stop(); |
} |
} |
@@ -498,12 +262,6 @@ void PowerButtonController::RequestShutdown() { |
StartShutdownAnimationAndRequestShutdown(); |
} |
-void PowerButtonController::OnRootWindowResized(const aura::RootWindow* root, |
- const gfx::Size& new_size) { |
- if (black_layer_.get()) |
- black_layer_->SetBounds(gfx::Rect(root->bounds().size())); |
-} |
- |
void PowerButtonController::OnRootWindowHostCloseRequested( |
const aura::RootWindow*) { |
if(Shell::GetInstance() && Shell::GetInstance()->delegate()) |
@@ -530,8 +288,11 @@ void PowerButtonController::OnLockTimeout() { |
void PowerButtonController::OnLockFailTimeout() { |
DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); |
LOG(ERROR) << "Screen lock request timed out"; |
- StartAnimation(LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, ANIMATION_RESTORE); |
- HideBlackLayer(); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LAUNCHER | |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_RESTORE); |
+ animator_->DropBlackLayer(); |
} |
void PowerButtonController::OnLockToShutdownTimeout() { |
@@ -550,8 +311,10 @@ void PowerButtonController::OnRealShutdownTimeout() { |
} |
void PowerButtonController::StartLockTimer() { |
- ShowBlackLayer(); |
- StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); |
+ animator_->ShowBlackLayer(); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
lock_timer_.Stop(); |
lock_timer_.Start(FROM_HERE, |
base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs), |
@@ -559,8 +322,10 @@ void PowerButtonController::StartLockTimer() { |
} |
void PowerButtonController::StartShutdownTimer() { |
- ShowBlackLayer(); |
- StartAnimation(GetAllContainersMask(), ANIMATION_SLOW_CLOSE); |
+ animator_->ShowBlackLayer(); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::kAllContainersMask, |
+ internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
shutdown_timer_.Stop(); |
shutdown_timer_.Start( |
FROM_HERE, |
@@ -576,15 +341,22 @@ void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { |
shell->env_filter()->set_cursor_hidden_by_filter(false); |
shell->cursor_manager()->ShowCursor(false); |
- ShowBlackLayer(); |
+ animator_->ShowBlackLayer(); |
if (login_status_ != user::LOGGED_IN_NONE) { |
// Hide the other containers before starting the animation. |
// ANIMATION_FAST_CLOSE will make the screen locker windows partially |
// transparent, and we don't want the other windows to show through. |
- StartAnimation(LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); |
- StartAnimation(GetAllLockScreenContainersMask(), ANIMATION_FAST_CLOSE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_HIDE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::kAllLockScreenContainersMask, |
+ internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
} else { |
- StartAnimation(GetAllContainersMask(), ANIMATION_FAST_CLOSE); |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::kAllContainersMask, |
+ internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
} |
real_shutdown_timer_.Start( |
@@ -594,24 +366,4 @@ void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { |
this, &PowerButtonController::OnRealShutdownTimeout); |
} |
-void PowerButtonController::ShowBlackLayer() { |
- if (hide_black_layer_timer_.IsRunning()) |
- hide_black_layer_timer_.Stop(); |
- |
- if (!black_layer_.get()) { |
- black_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); |
- black_layer_->SetColor(SK_ColorBLACK); |
- |
- ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer(); |
- black_layer_->SetBounds(root_layer->bounds()); |
- root_layer->Add(black_layer_.get()); |
- root_layer->StackAtBottom(black_layer_.get()); |
- } |
- black_layer_->SetVisible(true); |
-} |
- |
-void PowerButtonController::HideBlackLayer() { |
- black_layer_.reset(); |
-} |
- |
} // namespace ash |