Commit 06919754 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Add a toast dialog shown on the first lock screen app launch

The dialog will be shown for each new note taking app when it's
launched from the lock screen. The dialog will not be shown for the
same app again if the user closes it.
This adds a user pref to track note taking apps for which toast
dialog has been shown (and dismissed).

The dialog is implemented as a sysmte modal bubble dialog in
ToastDialogView.
The cl introduces FirstAppRunToastManager, which is used by
lock_screen_apps::StateController to delegate showing of the toast
dialog - the FirstAppRunToastManager, if the toast hasn't been shown
before, observe a created app window's visibility, and show the toast
dialog when the app window is shown. Once the dialog is dismissed by
the user, the FirstAppRunToastManager will update the user preferences
accordingly, to prevent dialog shows on subsequent app launches.

BUG=767717

Change-Id: I87032afb099b7ef027d82bcaa06d16a5957c3527
Reviewed-on: https://chromium-review.googlesource.com/720099Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Commit-Queue: Toni Barzic <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509562}
parent 83b35b2b
......@@ -5337,4 +5337,12 @@ Battery full
<message name="IDS_HATS_NOTIFICATION_TAKE_SURVEY_BUTTON" desc="The title of the button in the notification for Happiness Tracking Survey to take the said survey.">
Take survey
</message>
<!-- Lock screen note app toast dialog -->
<message name="IDS_LOCK_SCREEN_NOTE_APP_TOAST_DIALOG_TITLE" desc="Title of the dialog shown to the user when they first launch note taking app from the lock screen - the title contains the launched app's name.">
Taking notes with <ph name="LOCK_SCREEN_APP_NAME">$1<ex>Lock Screen Enabled App</ex></ph>
</message>
<message name="IDS_LOCK_SCREEN_NOTE_APP_TOAST_DIALOG_MESSAGE" desc="Message shown in the body of the dialog shown to the user when they launch note taking app from the lock screen for the first time - the message has a placeholder for the launched app's name.">
Lock screen notes are accessible from the lock screen and automatically saved to <ph name="LOCK_SCREEN_APP_NAME">$1<ex>Lock Screen Enabled App</ex></ph>.
</message>
</grit-part>
......@@ -812,10 +812,14 @@ source_set("chromeos") {
"lock_screen_apps/app_manager_impl.h",
"lock_screen_apps/app_window_metrics_tracker.cc",
"lock_screen_apps/app_window_metrics_tracker.h",
"lock_screen_apps/first_app_run_toast_manager.cc",
"lock_screen_apps/first_app_run_toast_manager.h",
"lock_screen_apps/focus_cycler_delegate.h",
"lock_screen_apps/state_controller.cc",
"lock_screen_apps/state_controller.h",
"lock_screen_apps/state_observer.h",
"lock_screen_apps/toast_dialog_view.cc",
"lock_screen_apps/toast_dialog_view.h",
"logging.cc",
"logging.h",
"login/app_launch_controller.cc",
......
// 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 "chrome/browser/chromeos/lock_screen_apps/first_app_run_toast_manager.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/common/extension.h"
#include "ui/aura/window.h"
#include "ui/views/widget/widget.h"
namespace lock_screen_apps {
FirstAppRunToastManager::FirstAppRunToastManager(Profile* profile)
: profile_(profile),
toast_widget_observer_(this),
app_window_observer_(this),
weak_ptr_factory_(this) {}
FirstAppRunToastManager::~FirstAppRunToastManager() {
Reset();
}
void FirstAppRunToastManager::RunForAppWindow(
extensions::AppWindow* app_window) {
if (app_window_)
return;
DCHECK(app_window->GetNativeWindow());
const extensions::Extension* app = app_window->GetExtension();
const base::DictionaryValue* toast_shown =
profile_->GetPrefs()->GetDictionary(
prefs::kNoteTakingAppsLockScreenToastShown);
bool already_shown_for_app = false;
if (toast_shown->GetBoolean(app->id(), &already_shown_for_app) &&
already_shown_for_app) {
return;
}
app_window_ = app_window;
if (app_window_->GetNativeWindow()->IsVisible())
CreateAndShowToastDialog();
else
app_window_observer_.Add(app_window->GetNativeWindow());
}
void FirstAppRunToastManager::Reset() {
app_window_observer_.RemoveAll();
toast_widget_observer_.RemoveAll();
app_window_ = nullptr;
weak_ptr_factory_.InvalidateWeakPtrs();
if (toast_widget_ && !toast_widget_->IsClosed())
toast_widget_->Close();
toast_widget_ = nullptr;
}
void FirstAppRunToastManager::OnWidgetDestroyed(views::Widget* widget) {
Reset();
}
void FirstAppRunToastManager::OnWindowVisibilityChanged(aura::Window* window,
bool visible) {
// NOTE: Use |window->IsVisible()|, rather than |visible| because |IsVisible|
// takes into account whether the window is actually drawn (not just whether
// window show has been called).
if (!window->IsVisible())
return;
app_window_observer_.RemoveAll();
CreateAndShowToastDialog();
}
void FirstAppRunToastManager::CreateAndShowToastDialog() {
auto* toast_dialog = new ToastDialogView(
base::UTF8ToUTF16(app_window_->GetExtension()->name()),
base::Bind(&FirstAppRunToastManager::ToastDialogDismissed,
weak_ptr_factory_.GetWeakPtr()));
toast_dialog->Show();
toast_widget_ = toast_dialog->GetWidget();
toast_widget_observer_.Add(toast_widget_);
}
void FirstAppRunToastManager::ToastDialogDismissed() {
{
const extensions::Extension* app = app_window_->GetExtension();
DictionaryPrefUpdate dict_update(
profile_->GetPrefs(), prefs::kNoteTakingAppsLockScreenToastShown);
dict_update->SetBoolean(app->id(), true);
}
Reset();
}
} // namespace lock_screen_apps
// 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 CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_FIRST_APP_RUN_TOAST_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_FIRST_APP_RUN_TOAST_MANAGER_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "ui/aura/window_observer.h"
#include "ui/views/widget/widget_observer.h"
class Profile;
namespace views {
class Widget;
}
namespace extensions {
class AppWindow;
}
namespace lock_screen_apps {
// Manager that can be used on a lock screen note app to show a first run
// dialog informing the user about the app that's been launched from the lock
// screen.
class FirstAppRunToastManager : public aura::WindowObserver,
public views::WidgetObserver {
public:
explicit FirstAppRunToastManager(Profile* profile);
~FirstAppRunToastManager() override;
// Runs the manager for an app window launch. It determines whether the first
// lock screen run dialog for the app associated with the app window has been
// previously shown to the user (this information is kept in the user prefs).
// If the dialog has not yet been shown (and confirmed by the user), the
// manager will show the dialog once the app window becomes visible.
void RunForAppWindow(extensions::AppWindow* app_window);
// Resets current manager state - if a first run dialog is being shown, this
// method will close the dialog.
void Reset();
// views::WidgetObserver:
void OnWidgetDestroyed(views::Widget* widget) override;
// aura::WindowObserver:
void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
views::Widget* widget() { return toast_widget_; }
private:
// Creates and shows the first lock screen app dialog for the app associated
// with |app_window_|.
void CreateAndShowToastDialog();
// Called when the user closes the first app run dialog, and thus unblocks
// lock screen app UI.
// The manager will mark the first run dialog as handled for the app.
void ToastDialogDismissed();
Profile* const profile_;
// If set, the app window for which the manager is being run.
extensions::AppWindow* app_window_ = nullptr;
// The widget associated with the first run dialog, if the dialog is shown.
views::Widget* toast_widget_ = nullptr;
ScopedObserver<views::Widget, views::WidgetObserver> toast_widget_observer_;
ScopedObserver<aura::Window, aura::WindowObserver> app_window_observer_;
base::WeakPtrFactory<FirstAppRunToastManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FirstAppRunToastManager);
};
} // namespace lock_screen_apps
#endif // CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_FIRST_APP_RUN_TOAST_MANAGER_H_
......@@ -20,6 +20,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/lock_screen_apps/app_manager_impl.h"
#include "chrome/browser/chromeos/lock_screen_apps/app_window_metrics_tracker.h"
#include "chrome/browser/chromeos/lock_screen_apps/first_app_run_toast_manager.h"
#include "chrome/browser/chromeos/lock_screen_apps/focus_cycler_delegate.h"
#include "chrome/browser/chromeos/note_taking_helper.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
......@@ -167,6 +168,7 @@ void StateController::Shutdown() {
true /*close_window*/, CloseLockScreenNoteReason::kShutdown);
app_manager_.reset();
}
first_app_run_toast_manager_.reset();
focus_cycler_delegate_ = nullptr;
power_manager_client_observer_.RemoveAll();
input_devices_observer_.RemoveAll();
......@@ -250,6 +252,9 @@ void StateController::InitializeWithCryptoKey(Profile* profile,
app_manager_ = base::MakeUnique<AppManagerImpl>(tick_clock_.get());
app_manager_->Initialize(profile, lock_screen_profile_->GetOriginalProfile());
first_app_run_toast_manager_ =
std::make_unique<FirstAppRunToastManager>(profile);
input_devices_observer_.Add(ui::InputDeviceManager::GetInstance());
// Do not start state controller if stylus input is not present as lock
......@@ -355,6 +360,7 @@ void StateController::OnSessionStateChanged() {
void StateController::OnAppWindowAdded(extensions::AppWindow* app_window) {
if (note_app_window_ != app_window)
return;
first_app_run_toast_manager_->RunForAppWindow(note_app_window_);
note_app_window_metrics_->AppWindowCreated(app_window);
}
......@@ -464,6 +470,8 @@ void StateController::ResetNoteTakingWindowAndMoveToNextState(
bool close_window,
CloseLockScreenNoteReason reason) {
app_window_observer_.RemoveAll();
if (first_app_run_toast_manager_)
first_app_run_toast_manager_->Reset();
if (note_app_window_metrics_)
note_app_window_metrics_->Reset();
......
......@@ -56,6 +56,7 @@ namespace lock_screen_apps {
class AppWindowMetricsTracker;
class FocusCyclerDelegate;
class StateObserver;
class FirstAppRunToastManager;
// Manages state of lock screen action handler apps, and notifies
// interested parties as the state changes.
......@@ -159,6 +160,10 @@ class StateController : public ash::mojom::TrayActionClient,
// Returns whether the focus has been taken from the app window.
bool HandleTakeFocus(content::WebContents* web_contents, bool reverse);
FirstAppRunToastManager* first_app_run_toast_manager() {
return first_app_run_toast_manager_.get();
}
private:
// Called when profiles needed to run lock screen apps are ready - i.e. when
// primary user profile was set using |SetPrimaryProfile| and the profile in
......@@ -237,6 +242,13 @@ class StateController : public ash::mojom::TrayActionClient,
// launches per lock screen.
std::unique_ptr<AppWindowMetricsTracker> note_app_window_metrics_;
// Used to show first lock screen app run (toast) dialog when an app window
// is first launched for an app.
// NOTE: The manager can be used for every app launch - before showing the
// toast dialog, the manager will bail out if it determines that the toast
// for the associated app has been previosly seen (and closed) by the user.
std::unique_ptr<FirstAppRunToastManager> first_app_run_toast_manager_;
ScopedObserver<extensions::AppWindowRegistry,
extensions::AppWindowRegistry::Observer>
app_window_observer_;
......
......@@ -11,6 +11,8 @@
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/interfaces/tray_action.mojom.h"
#include "ash/session/test_session_controller_client.h"
#include "ash/test/ash_test_helper.h"
#include "base/base64.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
......@@ -18,6 +20,7 @@
#include "base/test/scoped_command_line.h"
#include "chrome/browser/chromeos/arc/arc_session_manager.h"
#include "chrome/browser/chromeos/lock_screen_apps/app_manager.h"
#include "chrome/browser/chromeos/lock_screen_apps/first_app_run_toast_manager.h"
#include "chrome/browser/chromeos/lock_screen_apps/focus_cycler_delegate.h"
#include "chrome/browser/chromeos/lock_screen_apps/state_observer.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
......@@ -28,6 +31,7 @@
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/ui/apps/chrome_app_delegate.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
......@@ -541,6 +545,15 @@ class LockScreenAppStateTest : public BrowserWithTestWindowTest {
ready_waiter_.Run();
}
void SetFirstRunCompletedIfNeeded(const std::string& app_id) {
if (is_first_app_run_test_)
return;
DictionaryPrefUpdate dict_update(
profile()->GetPrefs(), prefs::kNoteTakingAppsLockScreenToastShown);
dict_update->SetBoolean(app_id, true);
}
// Helper method to move state controller to the specified state.
// Should be called at the begining of tests, at most once.
bool InitializeNoteTakingApp(TrayActionState target_state,
......@@ -549,6 +562,7 @@ class LockScreenAppStateTest : public BrowserWithTestWindowTest {
extensions::ExtensionSystem::Get(lock_screen_profile())
->extension_service()
->AddExtension(app_.get());
SetFirstRunCompletedIfNeeded(app_->id());
app_manager_->SetInitialAppState(kTestAppId, enable_app_launch);
......@@ -558,6 +572,9 @@ class LockScreenAppStateTest : public BrowserWithTestWindowTest {
return true;
session_manager_->SetSessionState(session_manager::SessionState::LOCKED);
ash_test_helper()->test_session_controller_client()->SetSessionState(
session_manager::SessionState::LOCKED);
if (app_manager_->state() != TestAppManager::State::kStarted) {
ADD_FAILURE() << "Lock app manager Start not invoked.";
return false;
......@@ -603,6 +620,21 @@ class LockScreenAppStateTest : public BrowserWithTestWindowTest {
TrayActionState::kActive;
}
bool RelaunchLockScreenApp() {
state_controller_->CloseLockScreenNote(
CloseLockScreenNoteReason::kUnlockButtonPressed);
tray_action_.SendNewNoteRequest(LockScreenNoteOrigin::kLockScreenButtonTap);
state_controller_->FlushTrayActionForTesting();
app_window_ = CreateNoteTakingWindow(lock_screen_profile(), app());
app_window_->Initialize(true /* shown */);
ClearObservedStates();
return state_controller()->GetLockScreenNoteState() ==
TrayActionState::kActive;
}
chromeos::FakeChromeUserManager* fake_user_manager() {
return fake_user_manager_;
}
......@@ -634,6 +666,13 @@ class LockScreenAppStateTest : public BrowserWithTestWindowTest {
return focus_cycler_delegate_.get();
}
protected:
// Should be set by tests that excercise the logic for the first lock screen
// app run - i.e. logic for showing the first run toast dialog.
// If not set, app will be marked as previously run (and toast dialog accepted
// in |InitializeNoteTakingApp|)
bool is_first_app_run_test_ = false;
private:
std::unique_ptr<base::test::ScopedCommandLine> command_line_;
......@@ -1321,6 +1360,7 @@ TEST_F(LockScreenAppStateTest, AppWindowClosedOnNoteTakingAppChange) {
extensions::ExtensionSystem::Get(lock_screen_profile())
->extension_service()
->AddExtension(secondary_app.get());
SetFirstRunCompletedIfNeeded(secondary_app->id());
app_manager()->UpdateApp(secondary_app->id(), true);
......@@ -1467,3 +1507,29 @@ TEST_F(LockScreenAppStateTest, CloseNoteWhileLaunching) {
ExpectObservedStatesMatch({TrayActionState::kAvailable},
"Close lock screen note.");
}
TEST_F(LockScreenAppStateTest, ToastDialogShownOnFirstAppRun) {
is_first_app_run_test_ = true;
ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive,
true /* enable_app_launch */));
ASSERT_TRUE(state_controller()->first_app_run_toast_manager()->widget());
EXPECT_TRUE(
state_controller()->first_app_run_toast_manager()->widget()->IsVisible());
// The toast should be shown again after app re-launch, as the toast widget
// was not dismissed by the user.
ASSERT_TRUE(RelaunchLockScreenApp());
ASSERT_TRUE(state_controller()->first_app_run_toast_manager()->widget());
EXPECT_TRUE(
state_controller()->first_app_run_toast_manager()->widget()->IsVisible());
state_controller()->first_app_run_toast_manager()->widget()->Close();
base::RunLoop().RunUntilIdle();
// Relaunch the note taking app - this time the toast bubble should not have
// been shown.
ASSERT_TRUE(RelaunchLockScreenApp());
EXPECT_FALSE(state_controller()->first_app_run_toast_manager()->widget());
}
// 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 "chrome/browser/chromeos/lock_screen_apps/toast_dialog_view.h"
#include <memory>
#include <utility>
#include "chrome/browser/ui/ash/system_tray_client.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/grit/generated_resources.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
namespace lock_screen_apps {
namespace {
constexpr int kDialogWidthDp = 292;
constexpr int kDialogMarginBottomDp = 28;
constexpr int kDialogMessageMarginTopDp = 0;
constexpr int kDialogMessageMarginStartDp = 16;
constexpr int kDialogMessageMarginBottomDp = 18;
constexpr int kDialogMessageMarginEndDp = 12;
constexpr int kDialogMessageLineHeightDp = 20;
constexpr int kDialogTitleMarginTopDp = 14;
constexpr int kDialogTitleMarginStartDp = 16;
constexpr int kDialogTitleMarginBottomDp = 5;
constexpr int kDialogTitleMarginEndDp = 0;
// Adjust the dialog bounds inside the parent window, so the dialog overlaps
// the system shelf.
void AdjustDialogBounds(views::Widget* widget) {
gfx::Rect bounds = widget->GetNativeView()->GetBoundsInScreen();
gfx::Rect parent_bounds =
widget->GetNativeView()->parent()->GetBoundsInScreen();
widget->SetBounds(gfx::Rect(
parent_bounds.x() + (parent_bounds.width() - bounds.width()) / 2,
parent_bounds.bottom() - bounds.height() - kDialogMarginBottomDp,
bounds.width(), bounds.height()));
}
} // namespace
ToastDialogView::ToastDialogView(const base::string16& app_name,
base::OnceClosure dismissed_callback)
: app_name_(app_name), dismissed_callback_(std::move(dismissed_callback)) {
chrome::RecordDialogCreation(
chrome::DialogIdentifier::LOCK_SCREEN_NOTE_APP_TOAST);
set_arrow(views::BubbleBorder::NONE);
set_margins(
gfx::Insets(kDialogMessageMarginTopDp, kDialogMessageMarginStartDp,
kDialogMessageMarginBottomDp, kDialogMessageMarginEndDp));
set_title_margins(
gfx::Insets(kDialogTitleMarginTopDp, kDialogTitleMarginStartDp,
kDialogTitleMarginBottomDp, kDialogTitleMarginEndDp));
set_shadow(views::BubbleBorder::SMALL_SHADOW);
SetLayoutManager(new views::FillLayout());
auto* label = new views::Label(l10n_util::GetStringFUTF16(
IDS_LOCK_SCREEN_NOTE_APP_TOAST_DIALOG_MESSAGE, app_name_));
label->SetMultiLine(true);
label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
label->SetEnabledColor(SkColorSetARGB(138, 0, 0, 0));
label->SetLineHeight(kDialogMessageLineHeightDp);
label->SetFontList(views::Label::GetDefaultFontList().Derive(
1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL));
label->SetPreferredSize(
gfx::Size(kDialogWidthDp, label->GetHeightForWidth(kDialogWidthDp)));
label->SizeToPreferredSize();
AddChildView(label);
}
ToastDialogView::~ToastDialogView() = default;
void ToastDialogView::Show() {
views::Widget* widget = SystemTrayClient::CreateUnownedDialogWidget(this);
AdjustDialogBounds(widget);
widget->Show();
}
ui::ModalType ToastDialogView::GetModalType() const {
return ui::MODAL_TYPE_SYSTEM;
}
base::string16 ToastDialogView::GetWindowTitle() const {
return l10n_util::GetStringFUTF16(IDS_LOCK_SCREEN_NOTE_APP_TOAST_DIALOG_TITLE,
app_name_);
}
bool ToastDialogView::Close() {
if (!dismissed_callback_.is_null())
std::move(dismissed_callback_).Run();
return true;
}
void ToastDialogView::AddedToWidget() {
std::unique_ptr<views::Label> title =
views::BubbleFrameView::CreateDefaultTitleLabel(GetWindowTitle());
title->SetFontList(views::Label::GetDefaultFontList().Derive(
3, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM));
GetBubbleFrameView()->SetTitleView(std::move(title));
}
int ToastDialogView::GetDialogButtons() const {
return ui::DIALOG_BUTTON_NONE;
}
bool ToastDialogView::ShouldShowCloseButton() const {
return true;
}
} // namespace lock_screen_apps
// 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 CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_TOAST_DIALOG_VIEW_H_
#define CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_TOAST_DIALOG_VIEW_H_
#include "base/callback.h"
#include "base/macros.h"
#include "base/strings/string16.h"
#include "ui/views/bubble/bubble_dialog_delegate.h"
namespace lock_screen_apps {
// The system modal bubble dialog shown to the user when a lock screen app is
// first launched from the lock screen. The dialog will block the app UI until
// the uesr closes it.
class ToastDialogView : public views::BubbleDialogDelegateView {
public:
ToastDialogView(const base::string16& app_name,
base::OnceClosure dismissed_callback);
~ToastDialogView() override;
// Shows the toast dialog.
void Show();
// views::WidgetDelegate:
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
// views::BubbleDialogDelegate:
bool Close() override;
void AddedToWidget() override;
int GetDialogButtons() const override;
bool ShouldShowCloseButton() const override;
private:
// The name of the app for which the dialog is shown.
const base::string16 app_name_;
// Callback to be called when the user closes the dialog.
base::OnceClosure dismissed_callback_;
DISALLOW_COPY_AND_ASSIGN(ToastDialogView);
};
} // namespace lock_screen_apps
#endif // CHROME_BROWSER_CHROMEOS_LOCK_SCREEN_APPS_TOAST_DIALOG_VIEW_H_
......@@ -321,6 +321,7 @@ void Preferences::RegisterProfilePrefs(
registry->RegisterBooleanPref(prefs::kNoteTakingAppEnabledOnLockScreen, true);
registry->RegisterListPref(prefs::kNoteTakingAppsLockScreenWhitelist);
registry->RegisterBooleanPref(prefs::kRestoreLastLockScreenNote, true);
registry->RegisterDictionaryPref(prefs::kNoteTakingAppsLockScreenToastShown);
// We don't sync wake-on-wifi related prefs because they are device specific.
registry->RegisterBooleanPref(prefs::kWakeOnWifiDarkConnect, true);
......
......@@ -256,6 +256,7 @@ enum class DialogIdentifier {
VALIDATION_MESSAGE = 77,
WEB_SHARE_TARGET_PICKER = 78,
ZOOM = 79,
LOCK_SCREEN_NOTE_APP_TOAST = 80,
MAX_VALUE
};
......
......@@ -609,6 +609,12 @@ const char kNoteTakingAppEnabledOnLockScreen[] =
const char kNoteTakingAppsLockScreenWhitelist[] =
"settings.note_taking_apps_lock_screen_whitelist";
// Dictionary pref that maps lock screen app ID to a boolean indicating whether
// the toast dialog has been show and dismissed as the app was being launched
// on the lock screen.
const char kNoteTakingAppsLockScreenToastShown[] =
"settings.note_taking_apps_lock_screen_toast_shown";
// Whether the preferred note taking app should be requested to restore the last
// note created on lock screen when launched on lock screen.
const char kRestoreLastLockScreenNote[] =
......
......@@ -223,6 +223,7 @@ extern const char kDisplayRotationLock[];
extern const char kNoteTakingAppId[];
extern const char kNoteTakingAppEnabledOnLockScreen[];
extern const char kNoteTakingAppsLockScreenWhitelist[];
extern const char kNoteTakingAppsLockScreenToastShown[];
extern const char kRestoreLastLockScreenNote[];
extern const char kSessionUserActivitySeen[];
extern const char kSessionStartTime[];
......
......@@ -8391,6 +8391,7 @@ uploading your change for review. These are checked by presubmit scripts.
<int value="77" label="Validation Message"/>
<int value="78" label="Web Share Target Picker"/>
<int value="79" label="Zoom"/>
<int value="80" label="Lock Screen Note App Toast"/>
</enum>
<enum name="DidNavigateToAd">
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