Commit d572bfd0 authored by sreeram@chromium.org's avatar sreeram@chromium.org

Use scoped_ptr to document ownership in InstantUnloadHandler.

And some cosmetic changes in other Instant files.

BUG=none
R=jered@chromium.org,sky@chromium.org
TEST=none; no change in functionality.


Review URL: https://chromiumcodereview.appspot.com/12256029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182397 0039d316-1c4b-4281-b951-d872f2087c98
parent 4858648a
...@@ -5,20 +5,20 @@ ...@@ -5,20 +5,20 @@
#ifndef CHROME_BROWSER_INSTANT_INSTANT_COMMIT_TYPE_H_ #ifndef CHROME_BROWSER_INSTANT_INSTANT_COMMIT_TYPE_H_
#define CHROME_BROWSER_INSTANT_INSTANT_COMMIT_TYPE_H_ #define CHROME_BROWSER_INSTANT_INSTANT_COMMIT_TYPE_H_
// Reason why the Instant preview is committed (merged into a tab). // Reason why the Instant overlay is committed (merged into a tab).
enum InstantCommitType { enum InstantCommitType {
// The commit is due to the user pressing Enter from the omnibox. // The commit is due to the user pressing Enter from the omnibox.
INSTANT_COMMIT_PRESSED_ENTER, INSTANT_COMMIT_PRESSED_ENTER,
// The commit is due to the user pressing Alt-Enter from the omnibox (which // The commit is due to the user pressing Alt-Enter from the omnibox (which
// causes the preview to be committed on to a new tab). // causes the overlay to be committed onto a new tab).
INSTANT_COMMIT_PRESSED_ALT_ENTER, INSTANT_COMMIT_PRESSED_ALT_ENTER,
// The commit is due to the omnibox losing focus, usually due to the user // The commit is due to the omnibox losing focus, usually due to the user
// clicking on the preview. // clicking on the overlay.
INSTANT_COMMIT_FOCUS_LOST, INSTANT_COMMIT_FOCUS_LOST,
// The commit is due to the instant page navigating. // The commit is due to the Instant overlay navigating to a non-Instant URL.
INSTANT_COMMIT_NAVIGATED, INSTANT_COMMIT_NAVIGATED,
// The commit is due to the user clicking on a query suggestion. // The commit is due to the user clicking on a query suggestion.
......
...@@ -22,11 +22,7 @@ void InstantService::AddInstantProcess(int process_id) { ...@@ -22,11 +22,7 @@ void InstantService::AddInstantProcess(int process_id) {
} }
bool InstantService::IsInstantProcess(int process_id) const { bool InstantService::IsInstantProcess(int process_id) const {
return process_ids_.count(process_id) != 0; return process_ids_.find(process_id) != process_ids_.end();
}
int InstantService::GetInstantProcessCount() const {
return process_ids_.size();
} }
void InstantService::Shutdown() { void InstantService::Shutdown() {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
// Tracks render process host ids that are associated with Instant. // Tracks render process host IDs that are associated with Instant.
class InstantService : public ProfileKeyedService, class InstantService : public ProfileKeyedService,
public content::NotificationObserver { public content::NotificationObserver {
public: public:
...@@ -25,13 +25,17 @@ class InstantService : public ProfileKeyedService, ...@@ -25,13 +25,17 @@ class InstantService : public ProfileKeyedService,
void AddInstantProcess(int process_id); void AddInstantProcess(int process_id);
bool IsInstantProcess(int process_id) const; bool IsInstantProcess(int process_id) const;
// For testing. #if defined(UNIT_TEST)
int GetInstantProcessCount() const; int GetInstantProcessCount() const {
return process_ids_.size();
}
#endif
private: private:
// ProfileKeyedService: // Overridden from ProfileKeyedService:
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
// Overridden from content::NotificationObserver:
virtual void Observe(int type, virtual void Observe(int type,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE; const content::NotificationDetails& details) OVERRIDE;
......
...@@ -18,11 +18,6 @@ InstantServiceFactory* InstantServiceFactory::GetInstance() { ...@@ -18,11 +18,6 @@ InstantServiceFactory* InstantServiceFactory::GetInstance() {
return Singleton<InstantServiceFactory>::get(); return Singleton<InstantServiceFactory>::get();
} }
// static
ProfileKeyedService* InstantServiceFactory::BuildInstanceFor(Profile* profile) {
return new InstantService;
}
InstantServiceFactory::InstantServiceFactory() InstantServiceFactory::InstantServiceFactory()
: ProfileKeyedServiceFactory("InstantService", : ProfileKeyedServiceFactory("InstantService",
ProfileDependencyManager::GetInstance()) { ProfileDependencyManager::GetInstance()) {
...@@ -38,5 +33,5 @@ bool InstantServiceFactory::ServiceRedirectedInIncognito() const { ...@@ -38,5 +33,5 @@ bool InstantServiceFactory::ServiceRedirectedInIncognito() const {
ProfileKeyedService* InstantServiceFactory::BuildServiceInstanceFor( ProfileKeyedService* InstantServiceFactory::BuildServiceInstanceFor(
Profile* profile) const { Profile* profile) const {
return BuildInstanceFor(profile); return new InstantService;
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_INSTANT_INSTANT_SERVICE_FACTORY_H_ #define CHROME_BROWSER_INSTANT_INSTANT_SERVICE_FACTORY_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h"
...@@ -13,8 +14,7 @@ class InstantService; ...@@ -13,8 +14,7 @@ class InstantService;
class Profile; class Profile;
class ProfileKeyedService; class ProfileKeyedService;
// Singleton that owns all InstantServices and associates them with // Singleton that owns all InstantServices and associates them with Profiles.
// Profiles.
class InstantServiceFactory : public ProfileKeyedServiceFactory { class InstantServiceFactory : public ProfileKeyedServiceFactory {
public: public:
// Returns the InstantService for |profile|. // Returns the InstantService for |profile|.
...@@ -22,15 +22,13 @@ class InstantServiceFactory : public ProfileKeyedServiceFactory { ...@@ -22,15 +22,13 @@ class InstantServiceFactory : public ProfileKeyedServiceFactory {
static InstantServiceFactory* GetInstance(); static InstantServiceFactory* GetInstance();
static ProfileKeyedService* BuildInstanceFor(Profile* profile);
private: private:
friend struct DefaultSingletonTraits<InstantServiceFactory>; friend struct DefaultSingletonTraits<InstantServiceFactory>;
InstantServiceFactory(); InstantServiceFactory();
virtual ~InstantServiceFactory(); virtual ~InstantServiceFactory();
// ProfileKeyedServiceFactory: // Overridden from ProfileKeyedServiceFactory:
virtual bool ServiceRedirectedInIncognito() const OVERRIDE; virtual bool ServiceRedirectedInIncognito() const OVERRIDE;
virtual ProfileKeyedService* BuildServiceInstanceFor( virtual ProfileKeyedService* BuildServiceInstanceFor(
Profile* profile) const OVERRIDE; Profile* profile) const OVERRIDE;
......
...@@ -12,42 +12,43 @@ ...@@ -12,42 +12,43 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
// WebContentsDelegate implementation. This owns the WebContents supplied to the
// constructor.
class InstantUnloadHandler::WebContentsDelegateImpl class InstantUnloadHandler::WebContentsDelegateImpl
: public content::WebContentsDelegate { : public content::WebContentsDelegate {
public: public:
WebContentsDelegateImpl(InstantUnloadHandler* handler, WebContentsDelegateImpl(InstantUnloadHandler* handler,
content::WebContents* contents, scoped_ptr<content::WebContents> contents,
int index) int index)
: handler_(handler), : handler_(handler),
contents_(contents), contents_(contents.Pass()),
index_(index) { index_(index) {
contents->SetDelegate(this); contents_->SetDelegate(this);
contents_->GetRenderViewHost()->FirePageBeforeUnload(false);
} }
// content::WebContentsDelegate overrides: // Overridden from content::WebContentsDelegate:
virtual void WillRunBeforeUnloadConfirm() OVERRIDE { virtual void CloseContents(content::WebContents* source) OVERRIDE {
content::WebContents* contents = contents_.release(); DCHECK_EQ(contents_, source);
contents->SetDelegate(NULL); // Remove ourselves as the delegate, so that CloseContents() won't be
handler_->Activate(this, contents, index_); // called twice, leading to double deletion (http://crbug.com/155848).
contents_->SetDelegate(NULL);
handler_->Destroy(this);
} }
virtual bool ShouldSuppressDialogs() OVERRIDE { virtual void WillRunBeforeUnloadConfirm() OVERRIDE {
return true; // Return true so dialogs are suppressed. contents_->SetDelegate(NULL);
handler_->Activate(this, contents_.Pass(), index_);
} }
virtual void CloseContents(content::WebContents* source) OVERRIDE { virtual bool ShouldSuppressDialogs() OVERRIDE {
contents_->SetDelegate(NULL); return true;
handler_->Destroy(this);
} }
private: private:
InstantUnloadHandler* const handler_; InstantUnloadHandler* const handler_;
scoped_ptr<content::WebContents> contents_; scoped_ptr<content::WebContents> contents_;
// The index |contents_| was originally at. If we add the tab back we add it // The tab strip index |contents_| was originally at. If we add the tab back
// at this index. // to the tabstrip, we add it at this index.
const int index_; const int index_;
DISALLOW_COPY_AND_ASSIGN(WebContentsDelegateImpl); DISALLOW_COPY_AND_ASSIGN(WebContentsDelegateImpl);
...@@ -61,7 +62,7 @@ InstantUnloadHandler::~InstantUnloadHandler() { ...@@ -61,7 +62,7 @@ InstantUnloadHandler::~InstantUnloadHandler() {
} }
void InstantUnloadHandler::RunUnloadListenersOrDestroy( void InstantUnloadHandler::RunUnloadListenersOrDestroy(
content::WebContents* contents, scoped_ptr<content::WebContents> contents,
int index) { int index) {
DCHECK(!contents->GetDelegate()); DCHECK(!contents->GetDelegate());
...@@ -71,27 +72,25 @@ void InstantUnloadHandler::RunUnloadListenersOrDestroy( ...@@ -71,27 +72,25 @@ void InstantUnloadHandler::RunUnloadListenersOrDestroy(
// get here from BrowserInstantController::TabDeactivated, other tab // get here from BrowserInstantController::TabDeactivated, other tab
// observers may still expect to interact with the tab before the event has // observers may still expect to interact with the tab before the event has
// finished propagating. // finished propagating.
MessageLoop::current()->DeleteSoon(FROM_HERE, contents); MessageLoop::current()->DeleteSoon(FROM_HERE, contents.release());
return; return;
} }
// Tab has before unload listener. Install a delegate and fire the before // Tab has beforeunload listeners. Install a delegate to run them.
// unload listener. delegates_.push_back(
delegates_.push_back(new WebContentsDelegateImpl(this, contents, index)); new WebContentsDelegateImpl(this, contents.Pass(), index));
contents->GetRenderViewHost()->FirePageBeforeUnload(false);
} }
void InstantUnloadHandler::Activate(WebContentsDelegateImpl* delegate, void InstantUnloadHandler::Activate(WebContentsDelegateImpl* delegate,
content::WebContents* contents, scoped_ptr<content::WebContents> contents,
int index) { int index) {
chrome::NavigateParams params(browser_, contents);
params.disposition = NEW_FOREGROUND_TAB;
params.tabstrip_index = index;
// Remove (and delete) the delegate. // Remove (and delete) the delegate.
Destroy(delegate); Destroy(delegate);
// Add the tab back in. // Add the tab back in.
chrome::NavigateParams params(browser_, contents.release());
params.disposition = NEW_FOREGROUND_TAB;
params.tabstrip_index = index;
chrome::Navigate(&params); chrome::Navigate(&params);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_INSTANT_INSTANT_UNLOAD_HANDLER_H_ #define CHROME_BROWSER_INSTANT_INSTANT_UNLOAD_HANDLER_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
class Browser; class Browser;
...@@ -14,29 +15,39 @@ namespace content { ...@@ -14,29 +15,39 @@ namespace content {
class WebContents; class WebContents;
} }
// InstantUnloadHandler ensures that the beforeunload and unload handlers are // InstantUnloadHandler ensures that it runs the BeforeUnload/Unload Handlers
// run when using Instant. When the user commits the Instant preview the // (BUH) of a page if the page is replaced by an Instant overlay.
// existing WebContents is passed to RunUnloadListenersOrDestroy(). If the tab //
// has no beforeunload or unload listeners, the tab is deleted; otherwise the // Why is this needed? Say the user is looking at a page P. They then try to
// beforeunload and unload listeners are executed. If the beforeunload listener // navigate to another page Q. Consider what happens with and without Instant:
// shows a dialog the tab is added back to the tabstrip at its original location //
// next to the Instant page. // Without Instant: Before the navigation is committed, P's BUH are run. If P's
// BUH return a string (instead of the default null), the user is prompted to
// "Stay or Leave?". If the user clicks "Stay", the navigation is cancelled,
// and the user remains on P.
//
// With Instant: The navigation to Q has already happened, since Q is being
// shown as a preview (overlay). When the user "commits" the overlay, it's too
// late to cancel Q based on P's BUH. So, Instant just replaces P with Q and
// passes P to InstantUnloadHandler::RunUnloadListenersOrDestroy(). This class
// runs P's BUH in the background. If the "Stay or Leave?" dialog needs to be
// shown, it adds P back onto the tabstrip, next to Q. Otherwise, P is deleted.
class InstantUnloadHandler { class InstantUnloadHandler {
public: public:
explicit InstantUnloadHandler(Browser* browser); explicit InstantUnloadHandler(Browser* browser);
~InstantUnloadHandler(); ~InstantUnloadHandler();
// See class description for details on what this does. // See class description for details on what this does.
void RunUnloadListenersOrDestroy(content::WebContents* contents, int index); void RunUnloadListenersOrDestroy(scoped_ptr<content::WebContents> contents,
int index);
private: private:
class WebContentsDelegateImpl; class WebContentsDelegateImpl;
// Invoked if the tab is to be shown, at |index| on the tab strip. This // Invoked if the tab is to be shown, at |index| on the tab strip. This
// happens if the before unload listener returns a string. Takes ownership of // happens if the beforeunload listener returns a string.
// |delegate| and |contents|.
void Activate(WebContentsDelegateImpl* delegate, void Activate(WebContentsDelegateImpl* delegate,
content::WebContents* contents, scoped_ptr<content::WebContents> contents,
int index); int index);
// Destroys the old tab. This is invoked if script tries to close the page. // Destroys the old tab. This is invoked if script tries to close the page.
......
...@@ -169,15 +169,10 @@ void BrowserInstantController::ReplaceWebContentsAt( ...@@ -169,15 +169,10 @@ void BrowserInstantController::ReplaceWebContentsAt(
int index, int index,
scoped_ptr<content::WebContents> new_contents) { scoped_ptr<content::WebContents> new_contents) {
DCHECK_NE(TabStripModel::kNoTab, index); DCHECK_NE(TabStripModel::kNoTab, index);
content::WebContents* old_contents = scoped_ptr<content::WebContents> old_contents(browser_->tab_strip_model()->
browser_->tab_strip_model()->GetWebContentsAt(index); ReplaceWebContentsAt(index, new_contents.release()));
// TabStripModel takes ownership of |new_contents|. instant_unload_handler_.RunUnloadListenersOrDestroy(old_contents.Pass(),
browser_->tab_strip_model()->ReplaceWebContentsAt( index);
index, new_contents.release());
// TODO(samarth): use scoped_ptr instead of comments to document ownership
// transfer.
// InstantUnloadHandler takes ownership of |old_contents|.
instant_unload_handler_.RunUnloadListenersOrDestroy(old_contents, index);
} }
void BrowserInstantController::SetInstantSuggestion( void BrowserInstantController::SetInstantSuggestion(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment