focus_controller_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/focus_controller.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/activation_change_observer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/activation_client.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/default_capture_client.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_change_observer.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/aura_test_base.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/event_generator.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_windows.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_tracker.h"
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_handler.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/base_focus_rules.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/wm_state.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace wm {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusNotificationObserver : public aura::client::ActivationChangeObserver,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  public aura::client::FocusChangeObserver {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusNotificationObserver()
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : activation_changed_count_(0),
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        focus_changed_count_(0),
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_count_(0),
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_requested_window_(NULL),
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_actual_window_(NULL) {}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FocusNotificationObserver() {}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectCounts(int activation_changed_count, int focus_changed_count) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(activation_changed_count, activation_changed_count_);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(focus_changed_count, focus_changed_count_);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int reactivation_count() const {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_count_;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_requested_window() const {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_requested_window_;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_actual_window() const {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_actual_window_;
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++activation_changed_count_;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnAttemptToReactivateWindow(
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::Window* request_active,
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::Window* actual_active) OVERRIDE {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++reactivation_count_;
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    reactivation_requested_window_ = request_active;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    reactivation_actual_window_ = actual_active;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++focus_changed_count_;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int activation_changed_count_;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int focus_changed_count_;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int reactivation_count_;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_requested_window_;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_actual_window_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class WindowDeleter {
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() = 0;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~WindowDeleter() {}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ActivationChangeObserver and FocusChangeObserver that keeps track of whether
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// it was notified about activation changes or focus changes with a deleted
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// window.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class RecordingActivationAndFocusChangeObserver
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public aura::client::ActivationChangeObserver,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      public aura::client::FocusChangeObserver {
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RecordingActivationAndFocusChangeObserver(aura::Window* root,
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            WindowDeleter* deleter)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(root),
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        deleter_(deleter),
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        was_notified_with_deleted_window_(false) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->AddObserver(this);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->AddObserver(this);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~RecordingActivationAndFocusChangeObserver() {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->RemoveObserver(this);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->RemoveObserver(this);
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool was_notified_with_deleted_window() const {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return was_notified_with_deleted_window_;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (lost_active && lost_active == deleter_->GetDeletedWindow())
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      was_notified_with_deleted_window_ = true;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      was_notified_with_deleted_window_ = true;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not owned.
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WindowDeleter* deleter_;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Whether the observer was notified about the loss of activation or the
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // loss of focus with a window already deleted by |deleter_| as the
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |lost_active| or |lost_focus| parameter.
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool was_notified_with_deleted_window_;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RecordingActivationAndFocusChangeObserver);
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ActivationChangeObserver that deletes the window losing activation.
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DeleteOnLoseActivationChangeObserver :
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public aura::client::ActivationChangeObserver,
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public WindowDeleter {
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit DeleteOnLoseActivationChangeObserver(aura::Window* window)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(window->GetRootWindow()),
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        window_(window),
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        did_delete_(false) {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->AddObserver(this);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DeleteOnLoseActivationChangeObserver() {
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->RemoveObserver(this);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_ && lost_active == window_) {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delete lost_active;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_delete_ = true;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from WindowDeleter:
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() OVERRIDE {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return did_delete_ ? window_ : NULL;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window_;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_delete_;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// FocusChangeObserver that deletes the window losing focus.
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DeleteOnLoseFocusChangeObserver
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public aura::client::FocusChangeObserver,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      public WindowDeleter {
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(window->GetRootWindow()),
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        window_(window),
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        did_delete_(false) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->AddObserver(this);
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DeleteOnLoseFocusChangeObserver() {
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->RemoveObserver(this);
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_ && lost_focus == window_) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delete lost_focus;
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_delete_ = true;
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from WindowDeleter:
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() OVERRIDE {
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return did_delete_ ? window_ : NULL;
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window_;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_delete_;
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseFocusChangeObserver);
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedFocusNotificationObserver : public FocusNotificationObserver {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScopedFocusNotificationObserver(aura::Window* root_window)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : root_window_(root_window) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window_)->AddObserver(this);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window_)->AddObserver(this);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScopedFocusNotificationObserver() {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window_;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : target_(root_window->GetChildById(id)) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetActivationChangeObserver(target_, this);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetFocusChangeObserver(target_, this);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.Add(target_);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScopedTargetFocusNotificationObserver() {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (tracker_.Contains(target_)) {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::SetActivationChangeObserver(target_, NULL);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::SetFocusChangeObserver(target_, NULL);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* target_;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::WindowTracker tracker_;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusShiftingActivationObserver
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public aura::client::ActivationChangeObserver {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit FocusShiftingActivationObserver(aura::Window* activated_window)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : activated_window_(activated_window),
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shift_focus_to_(NULL) {}
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FocusShiftingActivationObserver() {}
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_shift_focus_to(aura::Window* shift_focus_to) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shift_focus_to_ = shift_focus_to;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Shift focus to a child. This should prevent the default focusing from
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // occurring in FocusController::FocusWindow().
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gained_active == activated_window_) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::FocusClient* client =
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          aura::client::GetFocusClient(gained_active);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client->FocusWindow(shift_focus_to_);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* activated_window_;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* shift_focus_to_;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BaseFocusRules subclass that allows basic overrides of focus/activation to
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be tested. This is intended more as a test that the override system works at
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// all, rather than as an exhaustive set of use cases, those should be covered
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in tests for those FocusRules implementations.
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestFocusRules : public BaseFocusRules {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules() : focus_restriction_(NULL) {}
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Restricts focus and activation to this window and its child hierarchy.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_focus_restriction(aura::Window* focus_restriction) {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_restriction_ = focus_restriction;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from BaseFocusRules:
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In FocusControllerTests, only the RootWindow has activatable children.
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return window->GetRootWindow() == window;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Restricting focus to a non-activatable child window means the activatable
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // parent outside the focus restriction is activatable.
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool can_activate =
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) || window->Contains(focus_restriction_);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanFocusWindow(aura::Window* window) const OVERRIDE {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CanFocusOrActivate(window) ?
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BaseFocusRules::CanFocusWindow(window) : false;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetActivatableWindow(
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* window) const OVERRIDE {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return BaseFocusRules::GetActivatableWindow(
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) ? window : focus_restriction_);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetFocusableWindow(
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* window) const OVERRIDE {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return BaseFocusRules::GetFocusableWindow(
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) ? window : focus_restriction_);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetNextActivatableWindow(
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* ignore) const OVERRIDE {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BaseFocusRules::GetNextActivatableWindow(ignore);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CanFocusOrActivate(next_activatable) ?
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        next_activatable : GetActivatableWindow(focus_restriction_);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CanFocusOrActivate(aura::Window* window) const {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !focus_restriction_ || focus_restriction_->Contains(window);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* focus_restriction_;
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Common infrastructure shared by all FocusController test types.
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerTestBase : public aura::test::AuraTestBase {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerTestBase() {}
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::test::AuraTestBase:
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wm_state_.reset(new wm::WMState);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FocusController registers itself as an Env observer so it can catch all
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // window initializations, including the root_window()'s, so we create it
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // before allowing the base setup.
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules_ = new TestFocusRules;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_controller_.reset(new FocusController(test_focus_rules_));
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::AuraTestBase::SetUp();
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->AddPreTargetHandler(focus_controller_.get());
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetFocusClient(root_window(), focus_controller_.get());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetActivationClient(root_window(), focus_controller_.get());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Hierarchy used by all tests:
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // root_window
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w1
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w11
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w12
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w2
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w21
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |         +-- w211
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w3
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(0, 0, 50, 50), root_window());
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11,
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(5, 5, 10, 10), w1);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12,
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(15, 15, 10, 10), w1);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = aura::test::CreateTestWindowWithDelegate(
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2,
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(75, 75, 50, 50), root_window());
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w21 = aura::test::CreateTestWindowWithDelegate(
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21,
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(5, 5, 10, 10), w2);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211,
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(1, 1, 5, 5), w21);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(125, 125, 50, 50), root_window());
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->RemovePreTargetHandler(focus_controller_.get());
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::AuraTestBase::TearDown();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules_ = NULL;  // Owned by FocusController.
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_controller_.reset();
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    wm_state_.reset();
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FocusWindow(aura::Window* window) {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window())->FocusWindow(window);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetFocusedWindow() {
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return aura::client::GetFocusClient(root_window())->GetFocusedWindow();
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetFocusedWindowId() {
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::Window* focused_window = GetFocusedWindow();
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return focused_window ? focused_window->id() : -1;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ActivateWindow(aura::Window* window) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window())->ActivateWindow(window);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DeactivateWindow(aura::Window* window) {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window())->DeactivateWindow(window);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetActiveWindow() {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return aura::client::GetActivationClient(root_window())->GetActiveWindow();
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetActiveWindowId() {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* active_window = GetActiveWindow();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return active_window ? active_window->id() : -1;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules* test_focus_rules() { return test_focus_rules_; }
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test functions.
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() = 0;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() = 0;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() = 0;
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateFocusEvents() {}
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() = 0;
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ReactivationEvents() {}
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateActivationEvents() {}
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusWithinActiveWindow() {}
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToChildOfInactiveWindow() {}
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToParentOfFocusedWindow() {}
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() = 0;
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() = 0;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusOnActivation() {}
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ShiftFocusOnActivationDueToHide() {}
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoShiftActiveOnActivation() {}
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoFocusChangeOnClickOnCaptureWindow() {}
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DontPassDeletedWindow() {}
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FocusController> focus_controller_;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules* test_focus_rules_;
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<wm::WMState> wm_state_;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test base for tests where focus is directly set to a target window.
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerDirectTestBase : public FocusControllerTestBase {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDirectTestBase() {}
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Different test types shift focus in different ways.
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) = 0;
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) = 0;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) = 0;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Input events do not change focus if the window can not be focused.
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() = 0;
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FocusWindowById(int id) {
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* window = root_window()->GetChildById(id);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(window);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowDirect(window);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ActivateWindowById(int id) {
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* window = root_window()->GetChildById(id);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(window);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowDirect(window);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() OVERRIDE {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(2);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() OVERRIDE {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that attempting to deactivate NULL does not crash and does not
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // change activation.
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(NULL);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(GetActiveWindow());
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() OVERRIDE {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(2);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(2, 2);
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(2, 2);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateFocusEvents() OVERRIDE {
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Focusing an existing focused window should not resend focus events.
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() OVERRIDE {
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ReactivationEvents() OVERRIDE {
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(1);
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0, root_observer.reactivation_count());
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(2)->Hide();
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // When we attempt to activate "2", which cannot be activated because it
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is not visible, "1" will be reactivated.
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(2);
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, root_observer.reactivation_count());
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(root_window()->GetChildById(2),
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              root_observer.reactivation_requested_window());
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(root_window()->GetChildById(1),
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              root_observer.reactivation_actual_window());
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateActivationEvents() OVERRIDE {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Activating an existing active window should not resend activation events.
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusWithinActiveWindow() OVERRIDE {
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12, GetFocusedWindowId());
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToChildOfInactiveWindow() OVERRIDE {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToParentOfFocusedWindow() OVERRIDE {
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Focus should _not_ shift to the parent of the already-focused window.
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() OVERRIDE {
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Input events leave focus unchanged; direct API calls will change focus
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // to the restricted window.
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int focused_window = IsInputEvent() ? 11 : 211;
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(focused_window, GetFocusedWindowId());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12, GetFocusedWindowId());
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() OVERRIDE {
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w3 = root_window()->GetChildById(3);
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(w3);
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Input events leave activation unchanged; direct API calls will activate
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the restricted window.
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int active_window = IsInputEvent() ? 1 : 3;
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(active_window, GetActiveWindowId());
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(active_window, GetFocusedWindowId());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusOnActivation() OVERRIDE {
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When a window is activated, by default that window is also focused.
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // An ActivationChangeObserver may shift focus to another window within the
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // same activatable window.
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* target = root_window()->GetChildById(1);
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::ActivationClient* client =
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::client::GetActivationClient(root_window());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FocusShiftingActivationObserver> observer(
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FocusShiftingActivationObserver(target));
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer->set_shift_focus_to(target->GetChildById(11));
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client->AddObserver(observer.get());
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // w1's ActivationChangeObserver shifted focus to this child, pre-empting
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FocusController's default setting.
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Simulate a focus reset by the ActivationChangeObserver. This should
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // trigger the default setting in FocusController.
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer->set_shift_focus_to(NULL);
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client->RemoveObserver(observer.get());
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ShiftFocusOnActivationDueToHide() OVERRIDE {
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Similar to ShiftFocusOnActivation except the activation change is
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // triggered by hiding the active window.
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(1);
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Removes window 3 as candidate for next activatable window.
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(3)->Hide();
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura::Window* target = root_window()->GetChildById(2);
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura::client::ActivationClient* client =
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        aura::client::GetActivationClient(root_window());
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<FocusShiftingActivationObserver> observer(
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new FocusShiftingActivationObserver(target));
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer->set_shift_focus_to(target->GetChildById(21));
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client->AddObserver(observer.get());
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Hide the active window.
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(1)->Hide();
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(21, GetFocusedWindowId());
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client->RemoveObserver(observer.get());
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoShiftActiveOnActivation() OVERRIDE {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When a window is activated, we need to prevent any change to activation
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // from being made in response to an activation change notification.
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoFocusChangeOnClickOnCaptureWindow() OVERRIDE {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new aura::client::DefaultCaptureClient(root_window()));
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clicking on a window which has capture should not cause a focus change
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to the window. This test verifies whether that is indeed the case.
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->SetCapture(w2);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), w2);
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w2);
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Verifies focus change is honored while capture held.
74258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void ChangeFocusWhenNothingFocusedAndCaptured() OVERRIDE {
74358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
74458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new aura::client::DefaultCaptureClient(root_window()));
74558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::Window* w1 = root_window()->GetChildById(1);
74658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->SetCapture(w1);
74758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
74858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(-1, GetActiveWindowId());
74958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(-1, GetFocusedWindowId());
75058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
75158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FocusWindowById(1);
75258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
75358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
75458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
75558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
75658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
75758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
75858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verifies if a window that loses activation or focus is deleted during
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // observer notification we don't pass the deleted window to other observers.
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DontPassDeletedWindow() OVERRIDE {
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FocusWindowById(1);
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* to_delete = root_window()->GetChildById(1);
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DeleteOnLoseActivationChangeObserver observer1(to_delete);
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RecordingActivationAndFocusChangeObserver observer2(root_window(),
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                          &observer1);
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FocusWindowById(2);
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(2, GetActiveWindowId());
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(2, GetFocusedWindowId());
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* to_delete = root_window()->GetChildById(2);
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DeleteOnLoseFocusChangeObserver observer1(to_delete);
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RecordingActivationAndFocusChangeObserver observer2(root_window(),
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                          &observer1);
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FocusWindowById(3);
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(3, GetActiveWindowId());
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(3, GetFocusedWindowId());
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes via aura::client::ActivationClient API.
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerApiTest : public FocusControllerDirectTestBase {
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerApiTest() {}
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(window);
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(window);
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(window);
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return false; }
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest);
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes via input events.
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerMouseEventTest() {}
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), window);
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), window);
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_focus_rules()->GetNextActivatableWindow(window);
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), next_activatable);
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return true; }
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest);
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerGestureEventTest() {}
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), window);
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), window);
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_focus_rules()->GetNextActivatableWindow(window);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator generator(root_window(), next_activatable);
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return true; }
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest);
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test base for tests where focus is implicitly set to a window as the result
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of a disposition change to the focused window or the hierarchy that contains
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it.
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerImplicitTestBase : public FocusControllerTestBase {
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetDispositionWindow(aura::Window* window) {
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return parent_ ? window->parent() : window;
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the disposition of |window| in such a way as it will lose focus.
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) = 0;
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allow each disposition change test to add additional post-disposition
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // change expectations.
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PostDispostionChangeExpectations() {}
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() OVERRIDE {
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(211, GetFocusedWindowId());
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // BasicFocusRules passes focus to the parent.
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() OVERRIDE {
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w2);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w2);
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetActiveWindowId());
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PostDispostionChangeExpectations();
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() OVERRIDE {
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer211(root_window(), 211);
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer211.ExpectCounts(0, 0);
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 1);
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer211.ExpectCounts(0, 1);
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() OVERRIDE {
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w2);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer3(root_window(), 3);
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer3.ExpectCounts(0, 0);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w2);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer3.ExpectCounts(1, 1);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() OVERRIDE {
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(211, GetFocusedWindowId());
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11));
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normally, focus would shift to the parent (w21) but the override shifts
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // it to 11.
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() OVERRIDE {
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w1 = root_window()->GetChildById(1);
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w1);
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w3 = root_window()->GetChildById(3);
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(w3);
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normally, activation/focus would move to w2, but since we have a focus
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // restriction, it should move to w3 instead.
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w1);
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetActiveWindowId());
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetFocusedWindowId());
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(root_window()->GetChildById(2));
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When true, the disposition change occurs to the parent of the window
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // instead of to the window. This verifies that changes occurring in the
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hierarchy that contains the window affect the window's focus.
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool parent_;
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase);
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window visibility changes.
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerHideTest : public FocusControllerImplicitTestBase {
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerHideTest(bool parent)
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetDispositionWindow(window)->Hide();
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PostDispostionChangeExpectations() OVERRIDE {
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // BasicActivation() starts with the stacking order: 1, 2, 3 (3 topmost)
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // and then activates 2. After 2 is hidden in ChangeWindowDisposition
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // above, 3 is activated, but code in
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FocusController::OnWindowVisibilityChanging keeps 2's layer above 3's
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // until a hide animation completes (e.g. a fade-out transition).
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w3 = root_window()->GetChildById(3);
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // W2 was hidden, but its layer should still be stacked above W3's.
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    typedef std::vector<ui::Layer*> Layers;
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Layers& children = w3->parent()->layer()->children();
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layers::const_iterator w3_iter =
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::find(children.begin(), children.end(), w3->layer());
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layers::const_iterator w2_iter =
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::find(children.begin(), children.end(), w2->layer());
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(w2_iter > w3_iter);
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest);
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent visibility
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// changes.
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentHideTest : public FocusControllerHideTest {
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentHideTest() : FocusControllerHideTest(true) {}
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest);
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window destruction.
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDestructionTest(bool parent)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete GetDispositionWindow(window);
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest);
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent destruction.
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentDestructionTest
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public FocusControllerDestructionTest {
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentDestructionTest()
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerDestructionTest(true) {}
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentDestructionTest);
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window removal.
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerRemovalTest(bool parent)
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* disposition_window = GetDispositionWindow(window);
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    disposition_window->parent()->RemoveChild(disposition_window);
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_owner_.reset(disposition_window);
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_owner_.reset();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusControllerImplicitTestBase::TearDown();
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window_owner_;
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest);
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent removal.
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest);
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs direct focus change tests (input events and API calls).
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs implicit focus change tests for disposition changes to target.
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs implicit focus change tests for disposition changes to target's parent
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hierarchy.
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* TODO(beng): parent destruction tests are not supported at
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       present due to workspace manager issues. \
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs all implicit focus change tests (changes to the target and target's
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parent hierarchy)
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs all possible focus change tests.
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ALL_FOCUS_TESTS(TESTNAME) \
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs focus change tests that apply only to the target. For example,
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// implicit activation changes caused by window disposition changes do not
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// occur when changes to the containing hierarchy happen.
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TARGET_FOCUS_TESTS(TESTNAME) \
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses a window, verifies that focus changed.
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(BasicFocus);
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Activates a window, verifies that activation changed.
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(BasicActivation);
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses a window, verifies that focus events were dispatched.
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(FocusEvents);
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses or activates a window multiple times, verifies that events are only
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   dispatched when focus/activation actually changes.
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents);
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Activates a window, verifies that activation events were dispatched.
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(ActivationEvents);
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - Attempts to active a hidden window, verifies that current window is
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   attempted to be reactivated and the appropriate event dispatched.
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents);
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls shift focus between focusable windows within the
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   active window.
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow);
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls to a child window of an inactive window shifts
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   activation to the activatable parent and focuses the child.
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow);
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls to focus the parent of the focused window do not
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   shift focus away from the child.
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow);
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that FocusRules determine what can be focused.
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(FocusRulesOverride);
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that FocusRules determine what can be activated.
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(ActivationRulesOverride);
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that attempts to change focus or activation from a focus or
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   activation change observer are ignored.
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation);
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide);
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation);
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Clicking on a window which has capture should not result in a focus change.
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(NoFocusChangeOnClickOnCaptureWindow);
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
119658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
119758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      ChangeFocusWhenNothingFocusedAndCaptured);
119858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// See description above DontPassDeletedWindow() for details.
12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow);
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace wm
1203