Commit d13d7807 authored by Jun Mukai's avatar Jun Mukai Committed by Chromium LUCI CQ

Fix autotestPrivate.WaitForLauncherState in tablet mode.

On the failed case of ui.HotseatAnimation tast test, app-list
is actually animating, and HomeLauncherStateWaiter is not used,
thus the callback is never invoked.

This CL cleans up the condition for HomeLauncherStateWaiter to
be used.

Note: this CL also adds a test case of autotestPrivate API.
However, this new test case does NOT reproduce the reported
problem -- it passes even without the change of
autotest_private_api_utils.cc. I couldn't find the way to
reproduce the reported problem within browser_tests. Still,
I think it's better to have a basic test case of
waitForLauncherState in tablet-mode, as its internal code
path is significantly different.

Bug: 1167225
Test: ui.HotseatAnimation.non_overflow_shelf tast test
Change-Id: I33352f216af795e20d651942ce219feb5c4f052a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2640928
Commit-Queue: Jun Mukai <mukai@chromium.org>
Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846277}
parent afc265a0
......@@ -12,6 +12,8 @@
#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
#include "base/callback_helpers.h"
#include "base/optional.h"
#include "base/scoped_observation.h"
#include "ui/compositor/layer_animation_observer.h"
namespace ash {
namespace {
......@@ -79,6 +81,33 @@ class LauncherStateWaiter {
DISALLOW_COPY_AND_ASSIGN(LauncherStateWaiter);
};
class LauncherAnimationWaiter : public ui::LayerAnimationObserver {
public:
LauncherAnimationWaiter(AppListView* view, base::OnceClosure closure)
: closure_(std::move(closure)) {
observation_.Observe(view->GetWidget()->GetLayer()->GetAnimator());
}
~LauncherAnimationWaiter() override = default;
LauncherAnimationWaiter(const LauncherAnimationWaiter&) = delete;
LauncherAnimationWaiter& operator=(const LauncherAnimationWaiter&) = delete;
private:
// ui::LayerAnimationObserver:
void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
std::move(closure_).Run();
delete this;
}
void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
OnLayerAnimationEnded(sequence);
}
void OnLayerAnimationScheduled(
ui::LayerAnimationSequence* sequence) override {}
base::OnceClosure closure_;
base::ScopedObservation<ui::LayerAnimator, ui::LayerAnimationObserver>
observation_{this};
};
bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
if (Shell::Get()->app_list_controller()->IsVisible(
/*display_id=*/base::nullopt) == target_visible) {
......@@ -90,6 +119,23 @@ bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
return false;
}
bool WaitForLauncherAnimation(base::OnceClosure closure) {
auto* app_list_view =
Shell::Get()->app_list_controller()->presenter()->GetView();
if (!app_list_view) {
std::move(closure).Run();
return true;
}
bool animating =
app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
if (!animating) {
std::move(closure).Run();
return true;
}
new LauncherAnimationWaiter(app_list_view, std::move(closure));
return false;
}
} // namespace
std::vector<aura::Window*> GetAppWindowList() {
......@@ -136,6 +182,7 @@ bool WaitForLauncherState(AppListViewState target_state,
(!app_list_view && effective_target_state == AppListViewState::kClosed) ||
(app_list_view &&
app_list_view->app_list_state() == effective_target_state);
if (at_target_state && !animating) {
// In tablet mode, ensure that the home launcher is in the expected state.
if (target_home_launcher_visibility.has_value()) {
......@@ -152,7 +199,12 @@ bool WaitForLauncherState(AppListViewState target_state,
? base::BindOnce(base::IgnoreResult(&WaitForHomeLauncherState),
*target_home_launcher_visibility, std::move(closure))
: std::move(closure);
new LauncherStateWaiter(target_state, std::move(callback));
if (at_target_state)
return WaitForLauncherAnimation(std::move(callback));
new LauncherStateWaiter(
target_state,
base::BindOnce(base::IgnoreResult(&WaitForLauncherAnimation),
std::move(callback)));
return false;
}
......
......@@ -39,6 +39,18 @@ function onRaf(rafWin) {
rafWin.close();
}
function promisify(f, ...args) {
return new Promise((resolve, reject) => {
f(...args, (result) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
} else {
resolve(result);
}
});
});
}
var defaultTests = [
// logout/restart/shutdown don't do anything as we don't want to kill the
// browser with these tests.
......@@ -464,6 +476,17 @@ var defaultTests = [
chrome.test.succeed();
});
},
function waitForLauncherStateInTabletMode() {
promisify(chrome.autotestPrivate.setTabletModeEnabled, true)
.then(promisify(chrome.autotestPrivate.waitForLauncherState,
'FullscreenAllApps'))
.then(promisify(chrome.autotestPrivate.setTabletModeEnabled, false))
.then(function() {
chrome.test.succeed();
}).catch(function(err) {
chrome.test.fail(err);
});
},
// Check if tablet mode is enabled.
function isTabletModeEnabled() {
chrome.autotestPrivate.isTabletModeEnabled(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment