summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation
diff options
context:
space:
mode:
authordarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-15 04:32:57 +0000
committerdarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-15 04:32:57 +0000
commit295039bdf97f08bf5c1c1c136dd977b7e97ddd31 (patch)
treeae3b47308e7d2f2db903f6a61c193e7a8c9ec882 /chrome/browser/automation
parent1c33790ef99bf8301260b9144110e71e7723d0f4 (diff)
downloadchromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.zip
chromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.tar.gz
chromium_src-295039bdf97f08bf5c1c1c136dd977b7e97ddd31.tar.bz2
Introduce MessagePump to represent the native message pump used to drive a
MessageLoop. A MessageLoop now has a MessagePump. This will make it possible to port the MessagePump interface to other platforms as well as to use an IO completion port for our worker threads on Windows. Currently, there is only MessagePumpWin, which attempts to preserve the pre-existing behavior of the MessageLoop. API changes to MessageLoop: 1. MessageLoop::Quit means return from Run when the MessageLoop would otherwise wait for more work. 2. MessageLoop::Quit can no longer be called outside the context of an active Run call. So, things like this: MessageLoop::current()->Quit(); MessageLoop::current()->Run(); are now: MessageLoop::current()->RunAllPending(); 3. MessageLoop::Quit can no longer be called from other threads. This means that PostTask(..., new MessageLoop::QuitTask()) must be used explicitly to Quit across thread boundaries. 4. No protection is made to deal with nested MessageLoops involving watched objects or APCs. In fact, an assertion is added to flag such cases. This is a temporary measure until object watching and APC facilities are removed in favor of a MessagePump designed around an IO completion port. As part of this CL, I also changed the automation system to use an IPC::ChannelProxy instead of an IPC::Channel. This moves the automation IPC onto Chrome's IO thread where it belongs. I also fixed some abuses of RefCounted in the AutomationProvider class. It was deleting itself in some cases! This led to having to fix the ownership model for AutomationProvider, which explains the changes to AutomationProviderList and so on. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@928 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
-rw-r--r--chrome/browser/automation/automation_provider.cc39
-rw-r--r--chrome/browser/automation/automation_provider.h7
-rw-r--r--chrome/browser/automation/automation_provider_list.cc8
3 files changed, 21 insertions, 33 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index f23e7d1..d6e6b08 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -582,13 +582,8 @@ class DocumentPrintedNotificationObserver : public NotificationObserver {
};
AutomationProvider::AutomationProvider(Profile* profile)
- : connected_(false),
- redirect_query_(0),
+ : redirect_query_(0),
profile_(profile) {
- AutomationProviderList* list =
- g_browser_process->InitAutomationProviderList();
- DCHECK(NULL != list);
- list->AddProvider(this);
browser_tracker_.reset(new AutomationBrowserTracker(this));
window_tracker_.reset(new AutomationWindowTracker(this));
tab_tracker_.reset(new AutomationTabTracker(this));
@@ -601,21 +596,13 @@ AutomationProvider::AutomationProvider(Profile* profile)
}
AutomationProvider::~AutomationProvider() {
- // TODO(vibhor) : Delete the pending observer objects.
- AutomationProviderList* list =
- g_browser_process->InitAutomationProviderList();
- DCHECK(NULL != list);
- list->RemoveProvider(this);
}
void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) {
- scoped_ptr<IPC::Channel> channel(
- new IPC::Channel(channel_id, IPC::Channel::MODE_CLIENT, this));
- connected_ = channel->Connect();
- if (connected_) {
- channel_.swap(channel);
- channel_->Send(new AutomationMsg_Hello(0));
- }
+ channel_.reset(
+ new IPC::ChannelProxy(channel_id, IPC::Channel::MODE_CLIENT, this, NULL,
+ g_browser_process->io_thread()->message_loop()));
+ channel_->Send(new AutomationMsg_Hello(0));
}
void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
@@ -1450,7 +1437,7 @@ void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
void AutomationProvider::OnChannelError() {
LOG(ERROR) << "AutomationProxy went away, shutting down app.";
- delete this;
+ AutomationProviderList::GetInstance()->RemoveProvider(this);
}
// TODO(brettw) change this to accept GURLs when history supports it
@@ -1478,11 +1465,8 @@ void AutomationProvider::OnRedirectQueryComplete(
}
bool AutomationProvider::Send(IPC::Message* msg) {
- if (connected_) {
- DCHECK(channel_.get());
- return channel_->Send(msg);
- }
- return false;
+ DCHECK(channel_.get());
+ return channel_->Send(msg);
}
Browser* AutomationProvider::FindAndActivateTab(
@@ -2235,7 +2219,8 @@ void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
// last browser goes away.
if (BrowserList::size() == 1) {
// If you change this, update Observer for NOTIFY_SESSION_END below.
- MessageLoop::current()->ReleaseSoon(FROM_HERE, this);
+ MessageLoop::current()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
}
}
@@ -2248,3 +2233,7 @@ void TestingAutomationProvider::Observe(NotificationType type,
// Release balance out the Release scheduled by OnBrowserRemoving.
Release();
}
+
+void TestingAutomationProvider::OnRemoveProvider() {
+ AutomationProviderList::GetInstance()->RemoveProvider(this);
+}
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 20f34a1..1bde370 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -47,7 +47,7 @@
#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/history/history.h"
-#include "chrome/common/ipc_channel.h"
+#include "chrome/common/ipc_channel_proxy.h"
#include "chrome/common/ipc_message.h"
#include "chrome/common/notification_service.h"
@@ -321,8 +321,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
typedef ObserverList<NotificationObserver> NotificationObserverList;
typedef std::map<NavigationController*, LoginHandler*> LoginHandlerMap;
- bool connected_;
- scoped_ptr<IPC::Channel> channel_;
+ scoped_ptr<IPC::ChannelProxy> channel_;
scoped_ptr<NotificationObserver> initial_load_observer_;
scoped_ptr<NotificationObserver> new_tab_ui_load_observer_;
scoped_ptr<NotificationObserver> find_in_page_observer_;
@@ -383,5 +382,7 @@ class TestingAutomationProvider : public AutomationProvider,
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
+
+ void OnRemoveProvider(); // Called via PostTask
};
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_
diff --git a/chrome/browser/automation/automation_provider_list.cc b/chrome/browser/automation/automation_provider_list.cc
index 4d9bb93..8d683d8 100644
--- a/chrome/browser/automation/automation_provider_list.cc
+++ b/chrome/browser/automation/automation_provider_list.cc
@@ -41,18 +41,15 @@ AutomationProviderList::AutomationProviderList() {
AutomationProviderList::~AutomationProviderList() {
iterator iter = automation_providers_.begin();
while (iter != automation_providers_.end()) {
- AutomationProvider* provider = (*iter);
- // Delete the entry first and update the iterator first because the d'tor
- // of AutomationProvider will call RemoveProvider, making this iterator
- // invalid
+ (*iter)->Release();
iter = automation_providers_.erase(iter);
g_browser_process->ReleaseModule();
- delete provider;
}
instance_ = NULL;
}
bool AutomationProviderList::AddProvider(AutomationProvider* provider) {
+ provider->AddRef();
automation_providers_.push_back(provider);
g_browser_process->AddRefModule();
return true;
@@ -62,6 +59,7 @@ bool AutomationProviderList::RemoveProvider(AutomationProvider* provider) {
const iterator remove_provider =
find(automation_providers_.begin(), automation_providers_.end(), provider);
if (remove_provider != automation_providers_.end()) {
+ (*remove_provider)->Release();
automation_providers_.erase(remove_provider);
g_browser_process->ReleaseModule();
return true;