Commit 8c74a1c1 authored by yoshiki iguchi's avatar yoshiki iguchi Committed by Commit Bot

Defer user actions of notification if the ARC device shows the lock screen

This CL updates the logic of handling click events and passes all the
events to Chrome side at first. The chrome side may defer or cancel
the user action and pass back the action to Android side.

This CL also contains the mojo changes which is related with the lock
screen notification and not directy related with defering.

ARC-side: ag/4764629
Chromium-side: crrev.com/c/1174143

Bug: b/79951342
Test: Manual
Change-Id: I42f9953029867d8e46124ba087a4f84a49fae99d
Reviewed-on: https://chromium-review.googlesource.com/c/1174143
Commit-Queue: Yoshiki Iguchi <yoshiki@chromium.org>
Reviewed-by: default avatarHidehiko Abe <hidehiko@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarEliot Courtney <edcourtney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601526}
parent c879482a
......@@ -452,6 +452,11 @@ void ArcNotificationContentView::SetSurface(ArcNotificationSurface* surface) {
surface_->Detach();
}
AttachSurface();
if (activate_on_attach_) {
ActivateWidget(true);
activate_on_attach_ = false;
}
}
}
}
......@@ -752,7 +757,11 @@ void ArcNotificationContentView::ActivateWidget(bool activate) {
if (activate) {
GetWidget()->widget_delegate()->set_can_activate(true);
GetWidget()->Activate();
surface_->FocusSurfaceWindow();
if (surface_)
surface_->FocusSurfaceWindow();
else
activate_on_attach_ = true;
} else {
GetWidget()->widget_delegate()->set_can_activate(false);
}
......
......@@ -175,6 +175,9 @@ class ArcNotificationContentView
base::string16 accessible_name_;
// If it's true, the surface gets active when attached to this view.
bool activate_on_attach_ = false;
// Radiuses of rounded corners. These values are used in UpdateMask().
int top_radius_ = 0;
int bottom_radius_ = 0;
......
......@@ -14,6 +14,8 @@
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/arc/mojo_channel.h"
#include "ui/message_center/lock_screen/lock_screen_controller.h"
#include "ui/message_center/message_center_impl.h"
#include "ui/message_center/message_center_observer.h"
#include "ui/message_center/views/message_view_factory.h"
......@@ -233,6 +235,62 @@ void ArcNotificationManager::CloseMessageCenter() {
delegate_->HideMessageCenter();
}
void ArcNotificationManager::OnLockScreenSettingUpdated(
arc::mojom::ArcLockScreenNotificationSettingPtr setting) {
// TODO(yoshiki): sync the setting.
}
void ArcNotificationManager::ProcessUserAction(
arc::mojom::ArcNotificationUserActionDataPtr data) {
if (!data->defer_until_unlock) {
PerformUserAction(data->action_id);
return;
}
// TODO(yoshiki): remove the static cast after refactionring.
static_cast<message_center::MessageCenterImpl*>(message_center_)
->lock_screen_controller()
->DismissLockScreenThenExecute(
base::BindOnce(&ArcNotificationManager::PerformUserAction,
weak_ptr_factory_.GetWeakPtr(), data->action_id),
base::BindOnce(&ArcNotificationManager::CancelUserAction,
weak_ptr_factory_.GetWeakPtr(), data->action_id));
}
void ArcNotificationManager::PerformUserAction(uint32_t id) {
// TODO(yoshiki): Pass the event to the message center and handle the action
// in the NotificationDelegate::Click() for consistency with non-arc
// notifications.
auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD(
instance_owner_->holder(), PerformDeferredUserAction);
// On shutdown, the ARC channel may quit earlier than notifications.
if (!notifications_instance) {
VLOG(2) << "Trying to perform the defered operation, "
"but the ARC channel has already gone.";
return;
}
notifications_instance->PerformDeferredUserAction(id);
// TODO(yoshiki): open the message center and focus the target notification if
// the flag is set.
}
void ArcNotificationManager::CancelUserAction(uint32_t id) {
auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD(
instance_owner_->holder(), CancelDeferredUserAction);
// On shutdown, the ARC channel may quit earlier than notifications.
if (!notifications_instance) {
VLOG(2) << "Trying to cancel the defered operation, "
"but the ARC channel has already gone.";
return;
}
notifications_instance->CancelDeferredUserAction(id);
}
void ArcNotificationManager::OnNotificationRemoved(const std::string& key) {
auto it = items_.find(key);
if (it == items_.end()) {
......
......@@ -54,6 +54,10 @@ class ArcNotificationManager
void CloseMessageCenter() override;
void OnDoNotDisturbStatusUpdated(
arc::mojom::ArcDoNotDisturbStatusPtr status) override;
void OnLockScreenSettingUpdated(
arc::mojom::ArcLockScreenNotificationSettingPtr setting) override;
void ProcessUserAction(
arc::mojom::ArcNotificationUserActionDataPtr data) override;
// Methods called from ArcNotificationItem:
void SendNotificationRemovedFromChrome(const std::string& key);
......@@ -73,6 +77,9 @@ class ArcNotificationManager
bool ShouldIgnoreNotification(arc::mojom::ArcNotificationData* data);
void PerformUserAction(uint32_t id);
void CancelUserAction(uint32_t id);
// Invoked when |get_app_id_callback_| gets back the app id.
void OnGotAppId(arc::mojom::ArcNotificationDataPtr data,
const std::string& app_id);
......
......@@ -190,7 +190,7 @@ void ArcNotificationView::Layout() {
}
bool ArcNotificationView::HasFocus() const {
// In case that focus handling is defered to the content view, asking the
// In case that focus handling is deferred to the content view, asking the
// content view about focus.
return content_view_->IsFocusable() ? content_view_->HasFocus()
: message_center::MessageView::HasFocus();
......
......@@ -33,7 +33,7 @@ class ArcNotificationView : public message_center::MessageView,
const message_center::Notification& notification);
~ArcNotificationView() override;
// These method are called by the content view when focus handling is defered
// These method are called by the content view when focus handling is deferred
// to the content.
void OnContentFocused();
void OnContentBlurred();
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Next MinVersion: 21
// Next MinVersion: 22
module arc.mojom;
......@@ -154,6 +154,10 @@ struct ArcNotificationData {
string? package_name;
[MinVersion=17]
ArcNotificationFlags? flags;
[MinVersion=21]
bool hidden_on_lock_screen;
[MinVersion=21]
ArcBitmap? snapshot_image_public;
};
[Extensible, MinVersion=18]
......@@ -161,7 +165,29 @@ struct ArcDoNotDisturbStatus {
bool enabled;
};
// Next Method ID: 9
[MinVersion=21]
struct ArcNotificationUserActionData {
// Unique action id for this user action.
uint32 action_id;
// Notification key of top-level notification which contains the notification
// which is initiating this action.
string top_level_notification_key;
// True if the task should be executed on the unlocked state.
bool defer_until_unlock;
// True if the notification view should be focused after unlock. This is
// effective only when |defer_until_unlock| is true.
bool to_be_focused_after_unlock;
};
[Extensible, MinVersion=21]
struct ArcLockScreenNotificationSetting {
// Flag whether to show the notifications on the lock screen.
bool show_notification;
// Flag whether to show the private content on the lock screen.
bool show_private_notification;
};
// Next Method ID: 11
interface NotificationsHost {
// Set the Do-Not-Disturb status on Chrome side from Android side.
[MinVersion=18]
......@@ -188,9 +214,18 @@ interface NotificationsHost {
[MinVersion=20]
// Closes the Chrome OS message center.
CloseMessageCenter@8();
[MinVersion=21]
// Processes the user action initiated from Android side on Chrome side.
ProcessUserAction@9(ArcNotificationUserActionData data);
[MinVersion=21]
// Sets the lock screen setting on Chrome side from Android side. Usually
// invoked when the setting on Android side is chagned.
OnLockScreenSettingUpdated@10(ArcLockScreenNotificationSetting setting);
};
// Next Method ID: 9
// Next Method ID: 12
// TODO(lhchavez): Migrate all request/response messages to Mojo.
interface NotificationsInstance {
// DEPRECATED: Please use Init@5 instead.
......@@ -236,4 +271,16 @@ interface NotificationsInstance {
// event but as a scroll event, and the on-going touch should be cancelled.
[MinVersion=19]
CancelLongPress@8(string key);
// Performs the user action being deferred in Android.
[MinVersion=21]
PerformDeferredUserAction@9(uint32 action_id);
// Cancels the user action being deferred in Android.
[MinVersion=21]
CancelDeferredUserAction@10(uint32 action_id);
// Sets the lock screen notification setting on Android side from Chrome side.
[MinVersion=21]
SetLockScreenSettingOnAndroid@11(ArcLockScreenNotificationSetting setting);
};
......@@ -57,4 +57,9 @@ FakeNotificationsInstance::latest_do_not_disturb_status() const {
return latest_do_not_disturb_status_;
}
void FakeNotificationsInstance::PerformDeferredUserAction(uint32_t action_id) {}
void FakeNotificationsInstance::CancelDeferredUserAction(uint32_t action_id) {}
void FakeNotificationsInstance::SetLockScreenSettingOnAndroid(
mojom::ArcLockScreenNotificationSettingPtr setting) {}
} // namespace arc
......@@ -33,6 +33,10 @@ class FakeNotificationsInstance : public mojom::NotificationsInstance {
void SetDoNotDisturbStatusOnAndroid(
mojom::ArcDoNotDisturbStatusPtr status) override;
void CancelLongPress(const std::string& key) override;
void PerformDeferredUserAction(uint32_t action_id) override;
void CancelDeferredUserAction(uint32_t action_id) override;
void SetLockScreenSettingOnAndroid(
mojom::ArcLockScreenNotificationSettingPtr setting) override;
const std::vector<std::pair<std::string, mojom::ArcNotificationEvent>>&
events() const;
......
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