1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_TAB_HELPER_H_ 6 #define CHROME_BROWSER_AUTOMATION_AUTOMATION_TAB_HELPER_H_ 7 #pragma once 8 9 #include <set> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/observer_list.h" 14 #include "base/memory/weak_ptr.h" 15 #include "content/browser/tab_contents/tab_contents_observer.h" 16 17 class TabContents; 18 class AutomationTabHelper; 19 20 namespace IPC { 21 class Message; 22 } 23 24 // An observer API implemented by classes which are interested in various 25 // tab events from AutomationTabHelper(s). 26 class TabEventObserver { 27 public: 28 // |LOAD_START| and |LOAD_STOP| notifications may occur several times for a 29 // sequence of loads that may appear as one complete navigation to a user. 30 // For instance, navigating to a non-existent page will cause a load start 31 // and stop for the non-existent page; following that, Chrome will schedule 32 // a navigation to an error page which causes another load start and stop. 33 // 34 // A pending load is a load that is currently in progress or one that is 35 // scheduled to occur immediately. The only scheduled loads that are 36 // tracked are client redirects, such as javascript redirects. 37 // TODO(kkania): Handle redirects that are scheduled to occur later, and 38 // change this definition of a pending load. 39 // TODO(kkania): Track other types of scheduled navigations. 40 41 // Called when the tab that had no pending loads now has a new pending 42 // load. |tab_contents| will always be valid. OnFirstPendingLoad(TabContents * tab_contents)43 virtual void OnFirstPendingLoad(TabContents* tab_contents) { } 44 45 // Called when the tab that had one or more pending loads now has no 46 // pending loads. |tab_contents| will always be valid. 47 // 48 // This method will always be called if |OnFirstPendingLoad| was called. OnNoMorePendingLoads(TabContents * tab_contents)49 virtual void OnNoMorePendingLoads(TabContents* tab_contents) { } 50 51 protected: 52 TabEventObserver(); 53 virtual ~TabEventObserver(); 54 55 // On construction, this class does not observe any events. This method 56 // sets us up to observe events from the given |AutomationTabHelper|. 57 void StartObserving(AutomationTabHelper* tab_helper); 58 59 // Stop observing events from the given |AutomationTabHelper|. This does not 60 // need to be called before the helper dies, and it is ok if this object is 61 // destructed while it is still observing an |AutomationTabHelper|. 62 void StopObserving(AutomationTabHelper* tab_helper); 63 64 private: 65 friend class AutomationTabHelperTest; 66 typedef std::vector<base::WeakPtr<AutomationTabHelper> > EventSourceVector; 67 68 // Vector of all the event sources we are observing. Tracked so that this 69 // class can remove itself from each source at its destruction. 70 EventSourceVector event_sources_; 71 72 DISALLOW_COPY_AND_ASSIGN(TabEventObserver); 73 }; 74 75 // Per-tab automation support class. Receives automation/testing messages 76 // from the renderer. Broadcasts tab events to |TabEventObserver|s. 77 class AutomationTabHelper 78 : public TabContentsObserver, 79 public base::SupportsWeakPtr<AutomationTabHelper> { 80 public: 81 explicit AutomationTabHelper(TabContents* tab_contents); 82 virtual ~AutomationTabHelper(); 83 84 void AddObserver(TabEventObserver* observer); 85 void RemoveObserver(TabEventObserver* observer); 86 87 // Returns true if the tab is loading or the tab is scheduled to load 88 // immediately. Note that scheduled loads may be canceled. 89 bool has_pending_loads() const; 90 91 private: 92 friend class AutomationTabHelperTest; 93 94 // TabContentsObserver implementation. 95 virtual void DidStartLoading(); 96 virtual void DidStopLoading(); 97 virtual void RenderViewGone(); 98 virtual void TabContentsDestroyed(TabContents* tab_contents); 99 virtual bool OnMessageReceived(const IPC::Message& message); 100 101 void OnWillPerformClientRedirect(int64 frame_id, double delay_seconds); 102 void OnDidCompleteOrCancelClientRedirect(int64 frame_id); 103 void OnTabOrRenderViewDestroyed(TabContents* tab_contents); 104 105 // True if the tab is currently loading. If a navigation is scheduled but not 106 // yet loading, this will be false. 107 bool is_loading_; 108 109 // Set of all the frames (by frame ID) that are scheduled to perform a client 110 // redirect. 111 std::set<int64> pending_client_redirects_; 112 113 // List of all the |TabEventObserver|s, which we broadcast events to. 114 ObserverList<TabEventObserver> observers_; 115 116 DISALLOW_COPY_AND_ASSIGN(AutomationTabHelper); 117 }; 118 119 #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_TAB_HELPER_H_ 120