focus_controller_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/default_capture_client.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_change_observer.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/aura_test_base.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_windows.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_tracker.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/ime/dummy_text_input_client.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/ime/text_input_focus_manager.h"
200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "ui/events/event.h"
210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "ui/events/event_constants.h"
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_handler.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/base_focus_rules.h"
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/wm_state.h"
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_change_observer.h"
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace wm {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusNotificationObserver : public aura::client::ActivationChangeObserver,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  public aura::client::FocusChangeObserver {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusNotificationObserver()
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : activation_changed_count_(0),
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        focus_changed_count_(0),
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_count_(0),
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_requested_window_(NULL),
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reactivation_actual_window_(NULL) {}
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FocusNotificationObserver() {}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectCounts(int activation_changed_count, int focus_changed_count) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(activation_changed_count, activation_changed_count_);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(focus_changed_count, focus_changed_count_);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int reactivation_count() const {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_count_;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_requested_window() const {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_requested_window_;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_actual_window() const {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reactivation_actual_window_;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++activation_changed_count_;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnAttemptToReactivateWindow(
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::Window* request_active,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::Window* actual_active) OVERRIDE {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++reactivation_count_;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    reactivation_requested_window_ = request_active;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    reactivation_actual_window_ = actual_active;
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++focus_changed_count_;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int activation_changed_count_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int focus_changed_count_;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int reactivation_count_;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_requested_window_;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* reactivation_actual_window_;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class WindowDeleter {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() = 0;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~WindowDeleter() {}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ActivationChangeObserver and FocusChangeObserver that keeps track of whether
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// it was notified about activation changes or focus changes with a deleted
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// window.
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class RecordingActivationAndFocusChangeObserver
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public aura::client::ActivationChangeObserver,
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      public aura::client::FocusChangeObserver {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RecordingActivationAndFocusChangeObserver(aura::Window* root,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            WindowDeleter* deleter)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(root),
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        deleter_(deleter),
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        was_notified_with_deleted_window_(false) {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->AddObserver(this);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->AddObserver(this);
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~RecordingActivationAndFocusChangeObserver() {
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->RemoveObserver(this);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->RemoveObserver(this);
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool was_notified_with_deleted_window() const {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return was_notified_with_deleted_window_;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (lost_active && lost_active == deleter_->GetDeletedWindow())
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      was_notified_with_deleted_window_ = true;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      was_notified_with_deleted_window_ = true;
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not owned.
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WindowDeleter* deleter_;
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Whether the observer was notified about the loss of activation or the
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // loss of focus with a window already deleted by |deleter_| as the
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |lost_active| or |lost_focus| parameter.
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool was_notified_with_deleted_window_;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RecordingActivationAndFocusChangeObserver);
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ActivationChangeObserver that deletes the window losing activation.
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DeleteOnLoseActivationChangeObserver :
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public aura::client::ActivationChangeObserver,
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public WindowDeleter {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit DeleteOnLoseActivationChangeObserver(aura::Window* window)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(window->GetRootWindow()),
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        window_(window),
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        did_delete_(false) {
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->AddObserver(this);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DeleteOnLoseActivationChangeObserver() {
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetActivationClient(root_)->RemoveObserver(this);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_ && lost_active == window_) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delete lost_active;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_delete_ = true;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from WindowDeleter:
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() OVERRIDE {
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return did_delete_ ? window_ : NULL;
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window_;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_delete_;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver);
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// FocusChangeObserver that deletes the window losing focus.
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DeleteOnLoseFocusChangeObserver
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public aura::client::FocusChangeObserver,
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      public WindowDeleter {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : root_(window->GetRootWindow()),
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        window_(window),
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        did_delete_(false) {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->AddObserver(this);
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DeleteOnLoseFocusChangeObserver() {
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::client::GetFocusClient(root_)->RemoveObserver(this);
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_ && lost_focus == window_) {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delete lost_focus;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_delete_ = true;
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from WindowDeleter:
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual aura::Window* GetDeletedWindow() OVERRIDE {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return did_delete_ ? window_ : NULL;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* root_;
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window_;
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_delete_;
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseFocusChangeObserver);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedFocusNotificationObserver : public FocusNotificationObserver {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScopedFocusNotificationObserver(aura::Window* root_window)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : root_window_(root_window) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window_)->AddObserver(this);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window_)->AddObserver(this);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScopedFocusNotificationObserver() {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window_;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : target_(root_window->GetChildById(id)) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetActivationChangeObserver(target_, this);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetFocusChangeObserver(target_, this);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.Add(target_);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScopedTargetFocusNotificationObserver() {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (tracker_.Contains(target_)) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::SetActivationChangeObserver(target_, NULL);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::SetFocusChangeObserver(target_, NULL);
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* target_;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::WindowTracker tracker_;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ScopedFocusedTextInputClientChanger
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : public ScopedFocusNotificationObserver {
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ScopedFocusedTextInputClientChanger(aura::Window* root_window,
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                      ui::TextInputClient* text_input_client)
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      : ScopedFocusNotificationObserver(root_window),
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        text_input_client_(text_input_client) {}
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Overridden from aura::client::FocusChangeObserver:
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void OnWindowFocused(aura::Window* gained_focus,
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               aura::Window* lost_focus) OVERRIDE {
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        text_input_client_);
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui::TextInputClient* text_input_client_;
276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Used to fake the handling of events in the pre-target phase.
2790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class SimpleEventHandler : public ui::EventHandler {
2800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public:
2810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  SimpleEventHandler() {}
2820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual ~SimpleEventHandler() {}
2830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
2840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Overridden from ui::EventHandler:
2850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
2860de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    event->SetHandled();
2870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
2880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    event->SetHandled();
2900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
2910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
2920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private:
2930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SimpleEventHandler);
2940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)};
2950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusShiftingActivationObserver
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public aura::client::ActivationChangeObserver {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit FocusShiftingActivationObserver(aura::Window* activated_window)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : activated_window_(activated_window),
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shift_focus_to_(NULL) {}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FocusShiftingActivationObserver() {}
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_shift_focus_to(aura::Window* shift_focus_to) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shift_focus_to_ = shift_focus_to;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::client::ActivationChangeObserver:
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowActivated(aura::Window* gained_active,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 aura::Window* lost_active) OVERRIDE {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Shift focus to a child. This should prevent the default focusing from
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // occurring in FocusController::FocusWindow().
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gained_active == activated_window_) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::client::FocusClient* client =
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          aura::client::GetFocusClient(gained_active);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client->FocusWindow(shift_focus_to_);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* activated_window_;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* shift_focus_to_;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BaseFocusRules subclass that allows basic overrides of focus/activation to
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be tested. This is intended more as a test that the override system works at
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// all, rather than as an exhaustive set of use cases, those should be covered
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in tests for those FocusRules implementations.
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestFocusRules : public BaseFocusRules {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules() : focus_restriction_(NULL) {}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Restricts focus and activation to this window and its child hierarchy.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_focus_restriction(aura::Window* focus_restriction) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_restriction_ = focus_restriction;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from BaseFocusRules:
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In FocusControllerTests, only the RootWindow has activatable children.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return window->GetRootWindow() == window;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Restricting focus to a non-activatable child window means the activatable
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // parent outside the focus restriction is activatable.
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool can_activate =
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) || window->Contains(focus_restriction_);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanFocusWindow(aura::Window* window) const OVERRIDE {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CanFocusOrActivate(window) ?
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BaseFocusRules::CanFocusWindow(window) : false;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetActivatableWindow(
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* window) const OVERRIDE {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return BaseFocusRules::GetActivatableWindow(
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) ? window : focus_restriction_);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetFocusableWindow(
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* window) const OVERRIDE {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return BaseFocusRules::GetFocusableWindow(
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CanFocusOrActivate(window) ? window : focus_restriction_);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual aura::Window* GetNextActivatableWindow(
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      aura::Window* ignore) const OVERRIDE {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BaseFocusRules::GetNextActivatableWindow(ignore);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CanFocusOrActivate(next_activatable) ?
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        next_activatable : GetActivatableWindow(focus_restriction_);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CanFocusOrActivate(aura::Window* window) const {
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !focus_restriction_ || focus_restriction_->Contains(window);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* focus_restriction_;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Common infrastructure shared by all FocusController test types.
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerTestBase : public aura::test::AuraTestBase {
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerTestBase() {}
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from aura::test::AuraTestBase:
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wm_state_.reset(new wm::WMState);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FocusController registers itself as an Env observer so it can catch all
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // window initializations, including the root_window()'s, so we create it
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // before allowing the base setup.
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules_ = new TestFocusRules;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_controller_.reset(new FocusController(test_focus_rules_));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::AuraTestBase::SetUp();
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->AddPreTargetHandler(focus_controller_.get());
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetFocusClient(root_window(), focus_controller_.get());
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::SetActivationClient(root_window(), focus_controller_.get());
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Hierarchy used by all tests:
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // root_window
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w1
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w11
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w12
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w2
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |    +-- w21
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       |         +-- w211
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //       +-- w3
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(0, 0, 50, 50), root_window());
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11,
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(5, 5, 10, 10), w1);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12,
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(15, 15, 10, 10), w1);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = aura::test::CreateTestWindowWithDelegate(
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2,
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(75, 75, 50, 50), root_window());
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w21 = aura::test::CreateTestWindowWithDelegate(
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21,
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(5, 5, 10, 10), w2);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211,
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(1, 1, 5, 5), w21);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::CreateTestWindowWithDelegate(
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3,
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(125, 125, 50, 50), root_window());
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->RemovePreTargetHandler(focus_controller_.get());
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::AuraTestBase::TearDown();
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules_ = NULL;  // Owned by FocusController.
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    focus_controller_.reset();
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    wm_state_.reset();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FocusWindow(aura::Window* window) {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetFocusClient(root_window())->FocusWindow(window);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetFocusedWindow() {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return aura::client::GetFocusClient(root_window())->GetFocusedWindow();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetFocusedWindowId() {
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::Window* focused_window = GetFocusedWindow();
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return focused_window ? focused_window->id() : -1;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ActivateWindow(aura::Window* window) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window())->ActivateWindow(window);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DeactivateWindow(aura::Window* window) {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetActivationClient(root_window())->DeactivateWindow(window);
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetActiveWindow() {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return aura::client::GetActivationClient(root_window())->GetActiveWindow();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetActiveWindowId() {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* active_window = GetActiveWindow();
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return active_window ? active_window->id() : -1;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules* test_focus_rules() { return test_focus_rules_; }
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test functions.
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() = 0;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() = 0;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() = 0;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateFocusEvents() {}
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() = 0;
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ReactivationEvents() {}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateActivationEvents() {}
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusWithinActiveWindow() {}
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToChildOfInactiveWindow() {}
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToParentOfFocusedWindow() {}
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() = 0;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() = 0;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusOnActivation() {}
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ShiftFocusOnActivationDueToHide() {}
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoShiftActiveOnActivation() {}
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoFocusChangeOnClickOnCaptureWindow() {}
48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DontPassDeletedWindow() {}
486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void FocusedTextInputClient() {}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FocusController> focus_controller_;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFocusRules* test_focus_rules_;
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<wm::WMState> wm_state_;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase);
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test base for tests where focus is directly set to a target window.
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerDirectTestBase : public FocusControllerTestBase {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDirectTestBase() {}
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Different test types shift focus in different ways.
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) = 0;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) = 0;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) = 0;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Input events do not change focus if the window can not be focused.
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() = 0;
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FocusWindowById(int id) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* window = root_window()->GetChildById(id);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(window);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowDirect(window);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ActivateWindowById(int id) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* window = root_window()->GetChildById(id);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(window);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowDirect(window);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() OVERRIDE {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(2);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() OVERRIDE {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that attempting to deactivate NULL does not crash and does not
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // change activation.
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(NULL);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(GetActiveWindow());
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() OVERRIDE {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(2);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(2, 2);
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(2, 2);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateFocusEvents() OVERRIDE {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Focusing an existing focused window should not resend focus events.
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() OVERRIDE {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ReactivationEvents() OVERRIDE {
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(1);
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0, root_observer.reactivation_count());
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(2)->Hide();
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // When we attempt to activate "2", which cannot be activated because it
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is not visible, "1" will be reactivated.
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(2);
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, root_observer.reactivation_count());
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(root_window()->GetChildById(2),
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              root_observer.reactivation_requested_window());
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(root_window()->GetChildById(1),
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              root_observer.reactivation_actual_window());
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DuplicateActivationEvents() OVERRIDE {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Activating an existing active window should not resend activation events.
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(0, 0);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer1.ExpectCounts(1, 1);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusWithinActiveWindow() OVERRIDE {
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12, GetFocusedWindowId());
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToChildOfInactiveWindow() OVERRIDE {
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusToParentOfFocusedWindow() OVERRIDE {
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(1);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Focus should _not_ shift to the parent of the already-focused window.
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() OVERRIDE {
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(11);
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Input events leave focus unchanged; direct API calls will change focus
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // to the restricted window.
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int focused_window = IsInputEvent() ? 11 : 211;
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(focused_window, GetFocusedWindowId());
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindowById(12);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12, GetFocusedWindowId());
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() OVERRIDE {
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w3 = root_window()->GetChildById(3);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(w3);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Input events leave activation unchanged; direct API calls will activate
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the restricted window.
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int active_window = IsInputEvent() ? 1 : 3;
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(active_window, GetActiveWindowId());
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(active_window, GetFocusedWindowId());
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShiftFocusOnActivation() OVERRIDE {
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When a window is activated, by default that window is also focused.
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // An ActivationChangeObserver may shift focus to another window within the
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // same activatable window.
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* target = root_window()->GetChildById(1);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::ActivationClient* client =
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        aura::client::GetActivationClient(root_window());
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FocusShiftingActivationObserver> observer(
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FocusShiftingActivationObserver(target));
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer->set_shift_focus_to(target->GetChildById(11));
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client->AddObserver(observer.get());
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // w1's ActivationChangeObserver shifted focus to this child, pre-empting
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FocusController's default setting.
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Simulate a focus reset by the ActivationChangeObserver. This should
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // trigger the default setting in FocusController.
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer->set_shift_focus_to(NULL);
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client->RemoveObserver(observer.get());
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(2);
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ShiftFocusOnActivationDueToHide() OVERRIDE {
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Similar to ShiftFocusOnActivation except the activation change is
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // triggered by hiding the active window.
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ActivateWindowById(1);
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Removes window 3 as candidate for next activatable window.
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(3)->Hide();
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura::Window* target = root_window()->GetChildById(2);
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura::client::ActivationClient* client =
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        aura::client::GetActivationClient(root_window());
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<FocusShiftingActivationObserver> observer(
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new FocusShiftingActivationObserver(target));
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer->set_shift_focus_to(target->GetChildById(21));
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client->AddObserver(observer.get());
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Hide the active window.
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_window()->GetChildById(1)->Hide();
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(21, GetFocusedWindowId());
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client->RemoveObserver(observer.get());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoShiftActiveOnActivation() OVERRIDE {
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When a window is activated, we need to prevent any change to activation
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // from being made in response to an activation change notification.
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NoFocusChangeOnClickOnCaptureWindow() OVERRIDE {
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new aura::client::DefaultCaptureClient(root_window()));
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clicking on a window which has capture should not cause a focus change
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to the window. This test verifies whether that is indeed the case.
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindowById(1);
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->SetCapture(w2);
7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), w2);
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w2);
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Verifies focus change is honored while capture held.
78458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void ChangeFocusWhenNothingFocusedAndCaptured() OVERRIDE {
78558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
78658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new aura::client::DefaultCaptureClient(root_window()));
78758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::Window* w1 = root_window()->GetChildById(1);
78858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->SetCapture(w1);
78958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
79058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(-1, GetActiveWindowId());
79158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(-1, GetFocusedWindowId());
79258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
79358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FocusWindowById(1);
79458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
79558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
79658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
79758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
79858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
79958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verifies if a window that loses activation or focus is deleted during
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // observer notification we don't pass the deleted window to other observers.
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DontPassDeletedWindow() OVERRIDE {
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FocusWindowById(1);
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* to_delete = root_window()->GetChildById(1);
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DeleteOnLoseActivationChangeObserver observer1(to_delete);
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RecordingActivationAndFocusChangeObserver observer2(root_window(),
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                          &observer1);
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FocusWindowById(2);
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(2, GetActiveWindowId());
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(2, GetFocusedWindowId());
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* to_delete = root_window()->GetChildById(2);
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DeleteOnLoseFocusChangeObserver observer1(to_delete);
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RecordingActivationAndFocusChangeObserver observer2(root_window(),
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                          &observer1);
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FocusWindowById(3);
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(3, GetActiveWindowId());
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(3, GetFocusedWindowId());
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
840010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verifies if the focused text input client is cleared when a window gains
841010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // or loses the focus.
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void FocusedTextInputClient() OVERRIDE {
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ui::TextInputFocusManager* text_input_focus_manager =
844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        ui::TextInputFocusManager::GetInstance();
845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ui::DummyTextInputClient text_input_client;
846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ui::TextInputClient* null_text_input_client = NULL;
847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(null_text_input_client,
849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    text_input_focus_manager->FocusTextInputClient(&text_input_client);
852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(&text_input_client,
853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FocusWindowById(1);
855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The focused text input client gets cleared when a window gets focused
856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // unless any of observers sets the focused text input client.
857010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(null_text_input_client,
858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ScopedFocusedTextInputClientChanger text_input_focus_changer(
861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        root_window(), &text_input_client);
862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(null_text_input_client,
863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FocusWindowById(2);
865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // |text_input_focus_changer| sets the focused text input client.
866010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(&text_input_client,
867010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
868010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
869010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FocusWindow(NULL);
870010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The focused text input client gets cleared when a window loses the focus.
871010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(null_text_input_client,
872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              text_input_focus_manager->GetFocusedTextInputClient());
873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes via aura::client::ActivationClient API.
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerApiTest : public FocusControllerDirectTestBase {
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerApiTest() {}
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(window);
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(window);
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeactivateWindow(window);
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return false; }
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest);
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes via input events.
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerMouseEventTest() {}
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9050de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Tests that a handled mouse or gesture event does not trigger a window
9060de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // activation.
9070de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  void IgnoreHandledEvent() {
9080de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
9090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    aura::Window* w1 = root_window()->GetChildById(1);
9100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    SimpleEventHandler handler;
9110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    root_window()->PrependPreTargetHandler(&handler);
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), w1);
9130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    generator.ClickLeftButton();
9140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
9150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    generator.GestureTapAt(w1->bounds().CenterPoint());
9160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
9170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    root_window()->RemovePreTargetHandler(&handler);
9180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    generator.ClickLeftButton();
9190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
9200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
9210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), window);
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
9295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), window);
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_focus_rules()->GetNextActivatableWindow(window);
9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), next_activatable);
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.ClickLeftButton();
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return true; }
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest);
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerGestureEventTest() {}
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), window);
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), window);
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* next_activatable =
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_focus_rules()->GetNextActivatableWindow(window);
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::test::EventGenerator generator(root_window(), next_activatable);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureTapAt(window->bounds().CenterPoint());
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsInputEvent() OVERRIDE { return true; }
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest);
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test base for tests where focus is implicitly set to a window as the result
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of a disposition change to the focused window or the hierarchy that contains
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it.
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerImplicitTestBase : public FocusControllerTestBase {
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* GetDispositionWindow(aura::Window* window) {
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return parent_ ? window->parent() : window;
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the disposition of |window| in such a way as it will lose focus.
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) = 0;
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allow each disposition change test to add additional post-disposition
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // change expectations.
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PostDispostionChangeExpectations() {}
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerTestBase:
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicFocus() OVERRIDE {
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(211, GetFocusedWindowId());
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // BasicFocusRules passes focus to the parent.
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BasicActivation() OVERRIDE {
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetActiveWindow());
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w2);
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w2);
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetActiveWindowId());
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PostDispostionChangeExpectations();
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusEvents() OVERRIDE {
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer211(root_window(), 211);
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer211.ExpectCounts(0, 0);
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 1);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer211.ExpectCounts(0, 1);
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationEvents() OVERRIDE {
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w2 = root_window()->GetChildById(2);
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w2);
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedFocusNotificationObserver root_observer(root_window());
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedTargetFocusNotificationObserver observer3(root_window(), 3);
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(0, 0);
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(0, 0);
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer3.ExpectCounts(0, 0);
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w2);
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_observer.ExpectCounts(1, 1);
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer2.ExpectCounts(1, 1);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer3.ExpectCounts(1, 1);
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FocusRulesOverride() OVERRIDE {
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(NULL, GetFocusedWindow());
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w211 = root_window()->GetChildById(211);
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusWindow(w211);
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(211, GetFocusedWindowId());
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11));
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w211);
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normally, focus would shift to the parent (w21) but the override shifts
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // it to 11.
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(11, GetFocusedWindowId());
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivationRulesOverride() OVERRIDE {
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!parent_) << "Activation tests don't support parent changes.";
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w1 = root_window()->GetChildById(1);
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(w1);
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetActiveWindowId());
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, GetFocusedWindowId());
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* w3 = root_window()->GetChildById(3);
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(w3);
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normally, activation/focus would move to w2, but since we have a focus
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // restriction, it should move to w3 instead.
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChangeWindowDisposition(w1);
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetActiveWindowId());
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, GetFocusedWindowId());
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_focus_rules()->set_focus_restriction(NULL);
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ActivateWindow(root_window()->GetChildById(2));
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetActiveWindowId());
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(2, GetFocusedWindowId());
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When true, the disposition change occurs to the parent of the window
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // instead of to the window. This verifies that changes occurring in the
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hierarchy that contains the window affect the window's focus.
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool parent_;
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase);
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window visibility changes.
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerHideTest : public FocusControllerImplicitTestBase {
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerHideTest(bool parent)
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetDispositionWindow(window)->Hide();
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest);
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent visibility
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// changes.
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentHideTest : public FocusControllerHideTest {
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentHideTest() : FocusControllerHideTest(true) {}
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest);
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window destruction.
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerDestructionTest(bool parent)
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete GetDispositionWindow(window);
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest);
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent destruction.
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentDestructionTest
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public FocusControllerDestructionTest {
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentDestructionTest()
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerDestructionTest(true) {}
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentDestructionTest);
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window removal.
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerRemovalTest(bool parent)
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FocusControllerImplicitTestBase(parent) {}
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from FocusControllerImplicitTestBase:
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* disposition_window = GetDispositionWindow(window);
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    disposition_window->parent()->RemoveChild(disposition_window);
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_owner_.reset(disposition_window);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_owner_.reset();
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FocusControllerImplicitTestBase::TearDown();
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window_owner_;
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest);
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Focus and Activation changes in response to window parent removal.
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest);
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs direct focus change tests (input events and API calls).
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs implicit focus change tests for disposition changes to target.
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs implicit focus change tests for disposition changes to target's parent
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hierarchy.
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* TODO(beng): parent destruction tests are not supported at
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       present due to workspace manager issues. \
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs all implicit focus change tests (changes to the target and target's
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parent hierarchy)
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs all possible focus change tests.
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ALL_FOCUS_TESTS(TESTNAME) \
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs focus change tests that apply only to the target. For example,
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// implicit activation changes caused by window disposition changes do not
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// occur when changes to the containing hierarchy happen.
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TARGET_FOCUS_TESTS(TESTNAME) \
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses a window, verifies that focus changed.
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(BasicFocus);
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Activates a window, verifies that activation changed.
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(BasicActivation);
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses a window, verifies that focus events were dispatched.
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(FocusEvents);
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Focuses or activates a window multiple times, verifies that events are only
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   dispatched when focus/activation actually changes.
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents);
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents);
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Activates a window, verifies that activation events were dispatched.
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(ActivationEvents);
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - Attempts to active a hidden window, verifies that current window is
1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   attempted to be reactivated and the appropriate event dispatched.
1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents);
1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls shift focus between focusable windows within the
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   active window.
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow);
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls to a child window of an inactive window shifts
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   activation to the activatable parent and focuses the child.
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow);
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Input events/API calls to focus the parent of the focused window do not
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   shift focus away from the child.
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow);
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that FocusRules determine what can be focused.
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ALL_FOCUS_TESTS(FocusRulesOverride);
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that FocusRules determine what can be activated.
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TARGET_FOCUS_TESTS(ActivationRulesOverride);
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Verifies that attempts to change focus or activation from a focus or
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   activation change observer are ignored.
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation);
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide);
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation);
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Clicking on a window which has capture should not result in a focus change.
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DIRECT_FOCUS_CHANGE_TESTS(NoFocusChangeOnClickOnCaptureWindow);
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
127258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
127358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      ChangeFocusWhenNothingFocusedAndCaptured);
127458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// See description above DontPassDeletedWindow() for details.
12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow);
12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// - Verifies that the focused text input client is cleard when the window focus
1279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//   changes.
1280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ALL_FOCUS_TESTS(FocusedTextInputClient);
1281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
12820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// If a mouse event was handled, it should not activate a window.
12830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent);
12840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace wm
1286