| // 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/wm/lock_action_handler_layout_manager.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "ash/lock_screen_action/lock_screen_action_background_controller.h" |
| #include "ash/public/cpp/shell_window_ids.h" |
| #include "ash/public/interfaces/tray_action.mojom.h" |
| #include "ash/shell.h" |
| #include "ash/tray_action/tray_action.h" |
| #include "ash/wm/lock_window_state.h" |
| #include "ash/wm/window_state.h" |
| #include "ash/wm/window_util.h" |
| #include "ash/wm/wm_event.h" |
| #include "base/bind.h" |
| #include "ui/wm/core/window_animations.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Whether child windows should be shown depending on lock screen note action |
| // state and lock screen action background state. |
| // This should not be used for lock screen background windows. |
| bool ShowChildWindows(mojom::TrayActionState action_state, |
| LockScreenActionBackgroundState background_state) { |
| return (action_state == mojom::TrayActionState::kActive || |
| action_state == mojom::TrayActionState::kLaunching) && |
| (background_state == LockScreenActionBackgroundState::kShown || |
| background_state == LockScreenActionBackgroundState::kHidden); |
| } |
| |
| } // namespace |
| |
| LockActionHandlerLayoutManager::LockActionHandlerLayoutManager( |
| aura::Window* window, |
| Shelf* shelf, |
| LockScreenActionBackgroundController* action_background_controller) |
| : LockLayoutManager(window, shelf), |
| action_background_controller_(action_background_controller), |
| tray_action_observer_(this), |
| action_background_observer_(this) { |
| TrayAction* tray_action = Shell::Get()->tray_action(); |
| tray_action_observer_.Add(tray_action); |
| action_background_observer_.Add(action_background_controller_); |
| } |
| |
| LockActionHandlerLayoutManager::~LockActionHandlerLayoutManager() = default; |
| |
| void LockActionHandlerLayoutManager::OnWindowAddedToLayout( |
| aura::Window* child) { |
| ::wm::SetWindowVisibilityAnimationTransition(child, ::wm::ANIMATE_NONE); |
| |
| // The lock action background should be shown behind the shelf (which is |
| // transparent on the lock screen), unlike lock action handler windows. |
| wm::WindowState* window_state = |
| action_background_controller_->IsBackgroundWindow(child) |
| ? LockWindowState::SetLockWindowState(child) |
| : LockWindowState::SetLockWindowStateWithShelfExcluded(child); |
| wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE); |
| window_state->OnWMEvent(&event); |
| } |
| |
| void LockActionHandlerLayoutManager::OnChildWindowVisibilityChanged( |
| aura::Window* child, |
| bool visible) { |
| if (action_background_controller_->IsBackgroundWindow(child)) { |
| window()->StackChildAtBottom(child); |
| return; |
| } |
| |
| // Windows should be shown only in active state. |
| if (visible && |
| !ShowChildWindows(Shell::Get()->tray_action()->GetLockScreenNoteState(), |
| action_background_controller_->state())) { |
| child->Hide(); |
| } |
| } |
| |
| void LockActionHandlerLayoutManager::OnLockScreenNoteStateChanged( |
| mojom::TrayActionState state) { |
| // Update the background controller state first. |
| bool background_changed = false; |
| switch (state) { |
| case mojom::TrayActionState::kNotAvailable: |
| background_changed = |
| action_background_controller_->HideBackgroundImmediately(); |
| break; |
| case mojom::TrayActionState::kAvailable: |
| background_changed = action_background_controller_->HideBackground(); |
| break; |
| case mojom::TrayActionState::kLaunching: |
| case mojom::TrayActionState::kActive: |
| background_changed = action_background_controller_->ShowBackground(); |
| break; |
| } |
| |
| // Given that background state changes invoke the background controller |
| // observers (one of which is |this|), and |UpdateChildren| is called as part |
| // of handling background state changes, the child windows state has alreday |
| // been updated if |background_changed| is true - no need to do it again. |
| if (background_changed) |
| return; |
| |
| UpdateChildren(state, action_background_controller_->state()); |
| } |
| |
| void LockActionHandlerLayoutManager::OnLockScreenActionBackgroundStateChanged( |
| LockScreenActionBackgroundState state) { |
| UpdateChildren(Shell::Get()->tray_action()->GetLockScreenNoteState(), state); |
| } |
| |
| void LockActionHandlerLayoutManager::UpdateChildren( |
| mojom::TrayActionState action_state, |
| LockScreenActionBackgroundState background_state) { |
| // Update children state: |
| // * a child can be visible only in active state |
| // * on transition to active state: |
| // * show hidden windows, so children that were added when action was not |
| // in active state are shown |
| // * activate a container child to ensure the container gets focus when |
| // moving from background state. |
| bool show_children = ShowChildWindows(action_state, background_state); |
| aura::Window* child_to_activate = nullptr; |
| for (aura::Window* child : window()->children()) { |
| if (action_background_controller_->IsBackgroundWindow(child)) |
| continue; |
| if (show_children) { |
| child->Show(); |
| child_to_activate = child; |
| } else { |
| child->Hide(); |
| } |
| } |
| |
| if (child_to_activate) |
| wm::ActivateWindow(child_to_activate); |
| } |
| |
| } // namespace ash |