Commit 1af739e0 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Add a helper for launching note action

This adds a helper class for launching lock screen note from ash that
provides a callback run when the launched note changes to active state
(i.e. when the associated app window becomes visible).

Note that current users of RequestNewLockScreenNote API, used to
launch lock screen note, do not require launch callback - this will
be needed for handling note launch due to stylus tool eject,
specifically if the stylus is ejected while the display is forced off.
Ejecting stylus should clear display "forced off" state, but this will
be delayed if a lock screen note is launched until the note launch
completes to avoid lock screen flashing before the note app UI is
shown (see the linked bug).

BUG=767711

Change-Id: I3f46202244c39f06ad26ce5240f28828e3e692b0
Reviewed-on: https://chromium-review.googlesource.com/758810
Commit-Queue: Toni Barzic <tbarzic@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#515813}
parent ffa79141
...@@ -228,6 +228,8 @@ component("ash") { ...@@ -228,6 +228,8 @@ component("ash") {
"lock_screen_action/lock_screen_action_background_state.h", "lock_screen_action/lock_screen_action_background_state.h",
"lock_screen_action/lock_screen_action_background_view.cc", "lock_screen_action/lock_screen_action_background_view.cc",
"lock_screen_action/lock_screen_action_background_view.h", "lock_screen_action/lock_screen_action_background_view.h",
"lock_screen_action/lock_screen_note_launcher.cc",
"lock_screen_action/lock_screen_note_launcher.h",
"login/lock_screen_apps_focus_observer.h", "login/lock_screen_apps_focus_observer.h",
"login/lock_screen_controller.cc", "login/lock_screen_controller.cc",
"login/lock_screen_controller.h", "login/lock_screen_controller.h",
...@@ -1284,6 +1286,7 @@ test("ash_unittests") { ...@@ -1284,6 +1286,7 @@ test("ash_unittests") {
"laser/laser_pointer_controller_unittest.cc", "laser/laser_pointer_controller_unittest.cc",
"laser/laser_segment_utils_unittest.cc", "laser/laser_segment_utils_unittest.cc",
"lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc", "lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc",
"lock_screen_action/lock_screen_note_launcher_unittest.cc",
"login/lock_screen_controller_unittest.cc", "login/lock_screen_controller_unittest.cc",
"login/mock_lock_screen_client.cc", "login/mock_lock_screen_client.cc",
"login/mock_lock_screen_client.h", "login/mock_lock_screen_client.h",
......
// Copyright 2017 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/lock_screen_action/lock_screen_note_launcher.h"
#include "ash/public/interfaces/tray_action.mojom.h"
#include "ash/shell.h"
#include "ash/tray_action/tray_action.h"
#include "base/bind.h"
namespace ash {
LockScreenNoteLauncher::LockScreenNoteLauncher()
: tray_action_observer_(this) {}
LockScreenNoteLauncher::~LockScreenNoteLauncher() = default;
// static
bool LockScreenNoteLauncher::CanAttemptLaunch() {
return Shell::Get()->tray_action()->GetLockScreenNoteState() ==
mojom::TrayActionState::kAvailable;
}
bool LockScreenNoteLauncher::Run(mojom::LockScreenNoteOrigin action_origin,
LaunchCallback callback) {
DCHECK(callback_.is_null());
if (!CanAttemptLaunch())
return false;
callback_ = std::move(callback);
tray_action_observer_.Add(Shell::Get()->tray_action());
Shell::Get()->tray_action()->RequestNewLockScreenNote(action_origin);
return true;
}
void LockScreenNoteLauncher::OnLockScreenNoteStateChanged(
mojom::TrayActionState state) {
if (state == mojom::TrayActionState::kLaunching)
return;
OnLaunchDone(state == mojom::TrayActionState::kActive);
}
void LockScreenNoteLauncher::OnLaunchDone(bool success) {
tray_action_observer_.RemoveAll();
if (!callback_.is_null())
std::move(callback_).Run(success);
}
} // namespace ash
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_LAUNCHER_H_
#define ASH_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_LAUNCHER_H_
#include "ash/ash_export.h"
#include "ash/tray_action/tray_action_observer.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
namespace ash {
class TrayAction;
// A helper class for requesting a lock screen app that provides a callback run
// when the action launch process finishes (both successfuly or with a failure).
class ASH_EXPORT LockScreenNoteLauncher : public TrayActionObserver {
public:
using LaunchCallback = base::OnceCallback<void(bool success)>;
LockScreenNoteLauncher();
~LockScreenNoteLauncher() override;
// Whether the lock screen note state indicates that a note action launch can
// be requested - note that |Run| will not succeed if this returns false.
static bool CanAttemptLaunch();
// Requests a lock screen note launch, and starts observing lock screen note
// state changes - when the state changes to a non-launching state (either
// kActive - indicating launch success, or kAvailable or kNotAvailable -
// indicating launch failure), it runs |callback|.
// This can handle only one launch requests at a time - i.e. it should not be
// called again before |callback| is run.
// Returns whether the note launch was successfully requested. |callback| will
// not be called if the return value is false.
bool Run(mojom::LockScreenNoteOrigin action_origin, LaunchCallback callback);
// TrayActionObserver:
void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override;
private:
// Called when the launch attempt completes - resets the object state and runs
// the launch callback provided to |Run|.
void OnLaunchDone(bool success);
// The callback provided to |Run|.
LaunchCallback callback_;
ScopedObserver<TrayAction, TrayActionObserver> tray_action_observer_;
DISALLOW_COPY_AND_ASSIGN(LockScreenNoteLauncher);
};
} // namespace ash
#endif // ASH_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_LAUNCHER_H_
// Copyright 2017 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/lock_screen_action/lock_screen_note_launcher.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/tray_action/test_tray_action_client.h"
#include "ash/tray_action/tray_action.h"
namespace ash {
namespace {
enum class LaunchStatus { kUnknown, kSuccess, kFailure };
void HandleLaunchCallback(LaunchStatus* result, bool success) {
*result = success ? LaunchStatus::kSuccess : LaunchStatus::kFailure;
}
} // namespace
using LockScreenNoteLauncherTest = AshTestBase;
TEST_F(LockScreenNoteLauncherTest, LaunchSuccess) {
TrayAction* tray_action = Shell::Get()->tray_action();
TestTrayActionClient action_client;
tray_action->SetClient(action_client.CreateInterfacePtrAndBind(),
mojom::TrayActionState::kAvailable);
EXPECT_TRUE(LockScreenNoteLauncher::CanAttemptLaunch());
LockScreenNoteLauncher launcher;
LaunchStatus launch_status = LaunchStatus::kUnknown;
ASSERT_TRUE(
launcher.Run(mojom::LockScreenNoteOrigin::kLockScreenButtonTap,
base::BindOnce(&HandleLaunchCallback, &launch_status)));
// Verify a lock screen action was requested.
tray_action->FlushMojoForTesting();
EXPECT_EQ(std::vector<mojom::LockScreenNoteOrigin>(
{mojom::LockScreenNoteOrigin::kLockScreenButtonTap}),
action_client.note_origins());
// Move note action to launching state, and verify the launch callback is not
// run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kLaunching);
EXPECT_EQ(LaunchStatus::kUnknown, launch_status);
// Move note action to active state and verify that the launch callback is
// run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kActive);
EXPECT_EQ(LaunchStatus::kSuccess, launch_status);
}
TEST_F(LockScreenNoteLauncherTest, LaunchFailure) {
TrayAction* tray_action = Shell::Get()->tray_action();
TestTrayActionClient action_client;
tray_action->SetClient(action_client.CreateInterfacePtrAndBind(),
mojom::TrayActionState::kAvailable);
EXPECT_TRUE(LockScreenNoteLauncher::CanAttemptLaunch());
LockScreenNoteLauncher launcher;
LaunchStatus launch_status = LaunchStatus::kUnknown;
ASSERT_TRUE(
launcher.Run(mojom::LockScreenNoteOrigin::kLockScreenButtonTap,
base::BindOnce(&HandleLaunchCallback, &launch_status)));
// Verify a lock screen action was requested.
tray_action->FlushMojoForTesting();
EXPECT_EQ(std::vector<mojom::LockScreenNoteOrigin>(
{mojom::LockScreenNoteOrigin::kLockScreenButtonTap}),
action_client.note_origins());
// Move note action to launching state, and verify the launch callback is not
// run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kLaunching);
EXPECT_EQ(LaunchStatus::kUnknown, launch_status);
// Move note action to active state and verify that the launch callback is
// run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kAvailable);
EXPECT_EQ(LaunchStatus::kFailure, launch_status);
}
TEST_F(LockScreenNoteLauncherTest, LaunchNotRequestedInUnavailableStates) {
TrayAction* tray_action = Shell::Get()->tray_action();
TestTrayActionClient action_client;
tray_action->SetClient(action_client.CreateInterfacePtrAndBind(),
mojom::TrayActionState::kLaunching);
EXPECT_FALSE(LockScreenNoteLauncher::CanAttemptLaunch());
LockScreenNoteLauncher launcher;
// Launch should not be requested if a lock screen note action is already
// being launched.
LaunchStatus launch_status = LaunchStatus::kUnknown;
ASSERT_FALSE(
launcher.Run(mojom::LockScreenNoteOrigin::kLockScreenButtonTap,
base::BindOnce(&HandleLaunchCallback, &launch_status)));
// Verify a lock screen action was not requested.
tray_action->FlushMojoForTesting();
EXPECT_TRUE(action_client.note_origins().empty());
// Move note action to active state and verify that the launch callback is
// not run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kActive);
EXPECT_EQ(LaunchStatus::kUnknown, launch_status);
// Launch request should fail if lock screen note is in active state.
EXPECT_FALSE(LockScreenNoteLauncher::CanAttemptLaunch());
ASSERT_FALSE(
launcher.Run(mojom::LockScreenNoteOrigin::kLockScreenButtonTap,
base::BindOnce(&HandleLaunchCallback, &launch_status)));
tray_action->FlushMojoForTesting();
EXPECT_TRUE(action_client.note_origins().empty());
// Move note action to not available state and verify that the launch callback
// is not run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kNotAvailable);
EXPECT_EQ(LaunchStatus::kUnknown, launch_status);
// Launch request should fail if lock screen note is in unavailable state.
EXPECT_FALSE(LockScreenNoteLauncher::CanAttemptLaunch());
ASSERT_FALSE(
launcher.Run(mojom::LockScreenNoteOrigin::kLockScreenButtonTap,
base::BindOnce(&HandleLaunchCallback, &launch_status)));
tray_action->FlushMojoForTesting();
EXPECT_TRUE(action_client.note_origins().empty());
// Move note action to available state and verify that the launch callback is
// not run.
tray_action->UpdateLockScreenNoteState(mojom::TrayActionState::kAvailable);
EXPECT_EQ(LaunchStatus::kUnknown, launch_status);
}
} // namespace ash
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