Skip to content

Commit

Permalink
- Moved screenshot shortcut handling from MaximizeModeController to P…
Browse files Browse the repository at this point in the history
…owerButtonController

- Added a command line switch to enable quick locking mode.
- Refactored SessionStateAnimator into an interface, implementation, and a test double so that all the LockStateControllerTests could be re-enabled.
- Re-enabled LockStateControllerTests.

BUG=371608, 167048, 162645

Review URL: https://codereview.chromium.org/326813004

Cr-Commit-Position: refs/heads/master@{#294696}
  • Loading branch information
bruthig-chromium authored and Commit bot committed Sep 12, 2014
1 parent 36f186d commit ca2e149
Show file tree
Hide file tree
Showing 18 changed files with 1,831 additions and 1,182 deletions.
4 changes: 4 additions & 0 deletions ash/ash.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@
'wm/screen_dimmer.h',
'wm/session_state_animator.cc',
'wm/session_state_animator.h',
'wm/session_state_animator_impl.cc',
'wm/session_state_animator_impl.h',
'wm/stacking_controller.cc',
'wm/stacking_controller.h',
'wm/status_area_layout_manager.cc',
Expand Down Expand Up @@ -698,6 +700,8 @@
'test/test_overlay_delegate.h',
'test/test_screenshot_delegate.cc',
'test/test_screenshot_delegate.h',
'test/test_session_state_animator.cc',
'test/test_session_state_animator.h',
'test/test_session_state_delegate.cc',
'test/test_session_state_delegate.h',
'test/test_shelf_delegate.cc',
Expand Down
4 changes: 4 additions & 0 deletions ash/ash_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const char kAshEnableMagnifierKeyScroller[] =
const char kAshDisableTextFilteringInOverviewMode[] =
"ash-disable-text-filtering-in-overview-mode";

// Enables quick, non-cancellable locking of the screen when in maximize mode.
const char kAshEnablePowerButtonQuickLock[] =
"ash-enable-power-button-quick-lock";

// Enables software based mirroring.
const char kAshEnableSoftwareMirroring[] = "ash-enable-software-mirroring";

Expand Down
1 change: 1 addition & 0 deletions ash/ash_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ASH_EXPORT extern const char kAshDisableTouchExplorationMode[];
ASH_EXPORT extern const char kAshEnableMagnifierKeyScroller[];
#endif
ASH_EXPORT extern const char kAshDisableTextFilteringInOverviewMode[];
ASH_EXPORT extern const char kAshEnablePowerButtonQuickLock[];
ASH_EXPORT extern const char kAshEnableSoftwareMirroring[];
ASH_EXPORT extern const char kAshEnableSystemSounds[];
ASH_EXPORT extern const char kAshEnableTouchViewTesting[];
Expand Down
304 changes: 304 additions & 0 deletions ash/test/test_session_state_animator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/test/test_session_state_animator.h"

#include <vector>

#include "base/bind.h"

namespace ash {
namespace test {

namespace {
// A no-op callback that can be used when managing an animation that didn't
// actually have a callback given.
void DummyCallback() {}
}

const SessionStateAnimator::Container
TestSessionStateAnimator::kAllContainers[] = {
SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::LOCK_SCREEN_BACKGROUND,
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS,
SessionStateAnimator::ROOT_CONTAINER
};

// A simple SessionStateAnimator::AnimationSequence that tracks the number of
// attached sequences. The callback will be invoked if all animations complete
// successfully.
class TestSessionStateAnimator::AnimationSequence
: public SessionStateAnimator::AnimationSequence {
public:
AnimationSequence(base::Closure callback, TestSessionStateAnimator* animator)
: SessionStateAnimator::AnimationSequence(callback),
sequence_count_(0),
sequence_aborted_(false),
animator_(animator) {
}

virtual ~AnimationSequence() {}

virtual void SequenceAttached() {
++sequence_count_;
}

// Notify the sequence that is has completed.
virtual void SequenceFinished(bool successfully) {
DCHECK_GT(sequence_count_, 0);
--sequence_count_;
sequence_aborted_ |= !successfully;
if (sequence_count_ == 0) {
if (sequence_aborted_)
OnAnimationAborted();
else
OnAnimationCompleted();
}
}

// ash::SessionStateAnimator::AnimationSequence:
virtual void StartAnimation(int container_mask,
AnimationType type,
AnimationSpeed speed) OVERRIDE {
animator_->StartAnimationInSequence(container_mask, type, speed, this);
}

private:
// Tracks the number of contained animations.
int sequence_count_;

// True if the sequence was aborted.
bool sequence_aborted_;

// The TestSessionAnimator that created this. Not owned.
TestSessionStateAnimator* animator_;

DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
};

TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
int animation_epoch,
base::TimeDelta duration,
SessionStateAnimator::Container container,
AnimationType type,
AnimationSpeed speed,
base::Closure success_callback,
base::Closure failed_callback)
: animation_epoch(animation_epoch),
remaining_duration(duration),
container(container),
type(type),
speed(speed),
success_callback(success_callback),
failed_callback(failed_callback) {
}

TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() {
}

TestSessionStateAnimator::TestSessionStateAnimator()
: last_animation_epoch_(0),
is_background_hidden_(false) {
}

TestSessionStateAnimator::~TestSessionStateAnimator() {
CompleteAllAnimations(false);
}

void TestSessionStateAnimator::ResetAnimationEpoch() {
CompleteAllAnimations(false);
last_animation_epoch_ = 0;
}

void TestSessionStateAnimator::Advance(const base::TimeDelta& duration) {
for (ActiveAnimationsMap::iterator container_iter =
active_animations_.begin();
container_iter != active_animations_.end();
++container_iter) {
AnimationList::iterator animation_iter = (*container_iter).second.begin();
while (animation_iter != (*container_iter).second.end()) {
ActiveAnimation& active_animation = *animation_iter;
active_animation.remaining_duration -= duration;
if (active_animation.remaining_duration <= base::TimeDelta()) {
active_animation.success_callback.Run();
animation_iter = (*container_iter).second.erase(animation_iter);
} else {
++animation_iter;
}
}
}
}

void TestSessionStateAnimator::CompleteAnimations(int animation_epoch,
bool completed_successfully) {
for (ActiveAnimationsMap::iterator container_iter =
active_animations_.begin();
container_iter != active_animations_.end();
++container_iter) {
AnimationList::iterator animation_iter = (*container_iter).second.begin();
while (animation_iter != (*container_iter).second.end()) {
ActiveAnimation active_animation = *animation_iter;
if (active_animation.animation_epoch <= animation_epoch) {
if (completed_successfully)
active_animation.success_callback.Run();
else
active_animation.failed_callback.Run();
animation_iter = (*container_iter).second.erase(animation_iter);
} else {
++animation_iter;
}
}
}
}

void TestSessionStateAnimator::CompleteAllAnimations(
bool completed_successfully) {
CompleteAnimations(last_animation_epoch_, completed_successfully);
}

bool TestSessionStateAnimator::IsContainerAnimated(
SessionStateAnimator::Container container,
SessionStateAnimator::AnimationType type) const {
ActiveAnimationsMap::const_iterator container_iter =
active_animations_.find(container);
if (container_iter != active_animations_.end()) {
for (AnimationList::const_iterator animation_iter =
(*container_iter).second.begin();
animation_iter != (*container_iter).second.end();
++animation_iter) {
const ActiveAnimation& active_animation = *animation_iter;
if (active_animation.type == type)
return true;
}
}
return false;
}

bool TestSessionStateAnimator::AreContainersAnimated(
int container_mask, SessionStateAnimator::AnimationType type) const {
for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
if (container_mask & kAllContainers[i] &&
!IsContainerAnimated(kAllContainers[i], type)) {
return false;
}
}
return true;
}

size_t TestSessionStateAnimator::GetAnimationCount() const {
size_t count = 0;
for (ActiveAnimationsMap::const_iterator container_iter =
active_animations_.begin();
container_iter != active_animations_.end();
++container_iter) {
count += (*container_iter).second.size();
}
return count;
}

void TestSessionStateAnimator::StartAnimation(int container_mask,
AnimationType type,
AnimationSpeed speed) {
++last_animation_epoch_;
for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
if (container_mask & kAllContainers[i]) {
// Use a dummy no-op callback because one isn't required by the client
// but one is required when completing or aborting animations.
base::Closure callback = base::Bind(&DummyCallback);
AddAnimation(kAllContainers[i], type, speed, callback, callback);
}
}
}

void TestSessionStateAnimator::StartAnimationWithCallback(
int container_mask,
AnimationType type,
AnimationSpeed speed,
base::Closure callback) {
++last_animation_epoch_;
for (size_t i = 0; i < arraysize(kAllContainers); ++i)
if (container_mask & kAllContainers[i]) {
// ash::SessionStateAnimatorImpl invokes the callback whether or not the
// animation was completed successfully or not.
AddAnimation(kAllContainers[i], type, speed, callback, callback);
}
}

ash::SessionStateAnimator::AnimationSequence*
TestSessionStateAnimator::BeginAnimationSequence(base::Closure callback) {
return new AnimationSequence(callback, this);
}

bool TestSessionStateAnimator::IsBackgroundHidden() const {
return is_background_hidden_;
}

void TestSessionStateAnimator::ShowBackground() {
is_background_hidden_ = false;
}

void TestSessionStateAnimator::HideBackground() {
is_background_hidden_ = true;
}

void TestSessionStateAnimator::StartAnimationInSequence(
int container_mask,
AnimationType type,
AnimationSpeed speed,
AnimationSequence* animation_sequence) {
++last_animation_epoch_;
for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
if (container_mask & kAllContainers[i]) {
base::Closure success_callback =
base::Bind(&AnimationSequence::SequenceFinished,
base::Unretained(animation_sequence), true);
base::Closure failed_callback =
base::Bind(&AnimationSequence::SequenceFinished,
base::Unretained(animation_sequence), false);
animation_sequence->SequenceAttached();
AddAnimation(kAllContainers[i], type, speed, success_callback,
failed_callback);
}
}
}

void TestSessionStateAnimator::AddAnimation(
SessionStateAnimator::Container container,
AnimationType type,
AnimationSpeed speed,
base::Closure success_callback,
base::Closure failed_callback) {
base::TimeDelta duration = GetDuration(speed);
ActiveAnimation active_animation(last_animation_epoch_,
duration,
container,
type,
speed,
success_callback,
failed_callback);
// This test double is limited to only have one animation active for a given
// container at a time.
AbortAnimation(container);
active_animations_[container].push_back(active_animation);
}

void TestSessionStateAnimator::AbortAnimation(
SessionStateAnimator::Container container) {
ActiveAnimationsMap::iterator container_iter =
active_animations_.find(container);
if (container_iter != active_animations_.end()) {
AnimationList::iterator animation_iter = (*container_iter).second.begin();
while (animation_iter != (*container_iter).second.end()) {
ActiveAnimation active_animation = *animation_iter;
active_animation.failed_callback.Run();
animation_iter = (*container_iter).second.erase(animation_iter);
}
}
}

} // namespace test
} // namespace ash
Loading

0 comments on commit ca2e149

Please sign in to comment.