diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 14:58:18 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 14:58:18 +0000 |
commit | afac6fe84c150e64339e3c71b460f05d9415ae5b (patch) | |
tree | eecd23fb1badb76714ac3d1b094db1bc6303bcc2 /chrome/browser | |
parent | 08513e45ac4e0e351cfb426aa78cb66de8a8819e (diff) | |
download | chromium_src-afac6fe84c150e64339e3c71b460f05d9415ae5b.zip chromium_src-afac6fe84c150e64339e3c71b460f05d9415ae5b.tar.gz chromium_src-afac6fe84c150e64339e3c71b460f05d9415ae5b.tar.bz2 |
make extension apis tolerate browser absence during start-up & shutdown
Note: I was never able to directly reproduce the 13082 bug, the error mode is clear (there was no selected tab during a call to tabs.getSelected()). This fix will address that issue and we should stop seeing this crash reports.
R=erikkay
BUG=13082
Review URL: http://codereview.chromium.org/119117
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17631 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
5 files changed, 63 insertions, 30 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index dc5c8f1..93a34db 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -68,7 +68,7 @@ void FactoryRegistry::ResetFunctions() { namespace bookmarks = extension_bookmarks_module_constants; // Windows - factories_[tabs::kGetWindowFunction] = + factories_[tabs::kGetWindowFunction] = &NewExtensionFunction<GetWindowFunction>; factories_[tabs::kGetCurrentWindowFunction] = &NewExtensionFunction<GetCurrentWindowFunction>; @@ -76,27 +76,27 @@ void FactoryRegistry::ResetFunctions() { &NewExtensionFunction<GetLastFocusedWindowFunction>; factories_[tabs::kGetAllWindowsFunction] = &NewExtensionFunction<GetAllWindowsFunction>; - factories_[tabs::kCreateWindowFunction] = + factories_[tabs::kCreateWindowFunction] = &NewExtensionFunction<CreateWindowFunction>; - factories_[tabs::kUpdateWindowFunction] = + factories_[tabs::kUpdateWindowFunction] = &NewExtensionFunction<UpdateWindowFunction>; - factories_[tabs::kRemoveWindowFunction] = + factories_[tabs::kRemoveWindowFunction] = &NewExtensionFunction<RemoveWindowFunction>; // Tabs - factories_[tabs::kGetTabFunction] = + factories_[tabs::kGetTabFunction] = &NewExtensionFunction<GetTabFunction>; factories_[tabs::kGetSelectedTabFunction] = &NewExtensionFunction<GetSelectedTabFunction>; factories_[tabs::kGetAllTabsInWindowFunction] = &NewExtensionFunction<GetAllTabsInWindowFunction>; - factories_[tabs::kCreateTabFunction] = + factories_[tabs::kCreateTabFunction] = &NewExtensionFunction<CreateTabFunction>; - factories_[tabs::kUpdateTabFunction] = + factories_[tabs::kUpdateTabFunction] = &NewExtensionFunction<UpdateTabFunction>; - factories_[tabs::kMoveTabFunction] = + factories_[tabs::kMoveTabFunction] = &NewExtensionFunction<MoveTabFunction>; - factories_[tabs::kRemoveTabFunction] = + factories_[tabs::kRemoveTabFunction] = &NewExtensionFunction<RemoveTabFunction>; // Page Actions. @@ -185,7 +185,6 @@ Browser* ExtensionFunctionDispatcher::GetBrowser() { DCHECK(delegate_); Browser* retval = delegate_->GetBrowser(); - DCHECK(retval); return retval; } diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 741c9fc..9509577 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -132,9 +132,13 @@ void ExtensionHost::ShowCreatedWindow(int route_id, const GURL& creator_url) { TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id); if (contents) { + Browser* browser = GetBrowser(); + DCHECK(browser); + if (!browser) + return; // TODO(erikkay) is it safe to pass in NULL as source? - GetBrowser()->AddTabContents(contents, disposition, initial_pos, - user_gesture); + browser->AddTabContents(contents, disposition, initial_pos, + user_gesture); } } @@ -142,7 +146,11 @@ void ExtensionHost::ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos) { RenderWidgetHostView* widget_host_view = delegate_view_helper_.GetCreatedWidget(route_id); - GetBrowser()->BrowserRenderWidgetShowing(); + Browser *browser = GetBrowser(); + DCHECK(browser); + if (!browser) + return; + browser->BrowserRenderWidgetShowing(); // TODO(erikkay): These two lines could be refactored with TabContentsView. widget_host_view->InitAsPopup(render_view_host()->view(), initial_pos); widget_host_view->GetRenderWidgetHost()->Init(); @@ -186,8 +194,11 @@ Browser* ExtensionHost::GetBrowser() { #endif Browser* browser = BrowserList::GetLastActiveWithProfile( render_view_host()->process()->profile()); - // TODO(mpcomplete): what this verifies doesn't actually happen yet. - CHECK(browser) << "ExtensionHost running in Profile with no Browser active." - " It should have been deleted."; + // NOTE(rafaelw): This can return NULL in some circumstances. In particular, + // a toolstrip or background_page onload chrome.tabs api call can make it + // into here before the browser is sufficiently initialized to return here. + // A similar situation may arise during shutdown. + // TODO(rafaelw): Delay creation of background_page until the browser + // is available. http://code.google.com/p/chromium/issues/detail?id=13284 return browser; } diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index a3868fa..ea1d3be 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -164,12 +164,20 @@ bool GetWindowFunction::RunImpl() { bool GetCurrentWindowFunction::RunImpl() { Browser* browser = dispatcher_->GetBrowser(); + if (!browser) { + error_ = keys::kNoCurrentWindowError; + return false; + } result_.reset(CreateWindowValue(browser, false)); return true; } bool GetLastFocusedWindowFunction::RunImpl() { Browser* browser = BrowserList::GetLastActiveWithProfile(profile()); + if (!browser) { + error_ = keys::kNoLastFocusedWindowError; + return false; + } result_.reset(CreateWindowValue(browser, false)); return true; } @@ -218,7 +226,10 @@ bool CreateWindowFunction::RunImpl() { gfx::Rect bounds; bool maximized; // The call offsets the bounds by kWindowTilePixels (defined in WindowSizer to - // be 10). + // be 10) + // + // NOTE(rafaelw): It's ok if dispatcher_->GetBrowser() returns NULL here. + // GetBrowserWindowBounds will default to saved "default" values for the app. WindowSizer::GetBrowserWindowBounds(std::wstring(), empty_bounds, dispatcher_->GetBrowser(), &bounds, &maximized); @@ -309,9 +320,6 @@ bool UpdateWindowFunction::RunImpl() { bounds.set_height(bounds_val); } - // TODO(rafaelw): This call to SetBounds() ends up resulting in the target - // window being activated (pushed to the front). On win32, this appears to be - // the result of HWND event handling. browser->window()->SetBounds(bounds); // TODO(rafaelw): Support |focused|. result_.reset(CreateWindowValue(browser, false)); @@ -342,16 +350,21 @@ bool GetSelectedTabFunction::RunImpl() { if (!args_->IsType(Value::TYPE_NULL)) { EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); browser = GetBrowserInProfileWithId(profile(), window_id, &error_); - if (!browser) - return false; } else { browser = dispatcher_->GetBrowser(); + if (!browser) + error_ = keys::kNoCurrentWindowError; } + if (!browser) + return false; TabStripModel* tab_strip = browser->tabstrip_model(); - result_.reset(ExtensionTabUtil::CreateTabValue( - tab_strip->GetSelectedTabContents(), - tab_strip, + TabContents* contents = tab_strip->GetSelectedTabContents(); + if (!contents) { + error_ = keys::kNoSelectedTabError; + return false; + } + result_.reset(ExtensionTabUtil::CreateTabValue(contents, tab_strip, tab_strip->selected_index())); return true; } @@ -363,11 +376,13 @@ bool GetAllTabsInWindowFunction::RunImpl() { if (!args_->IsType(Value::TYPE_NULL)) { EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); browser = GetBrowserInProfileWithId(profile(), window_id, &error_); - if (!browser) - return false; } else { browser = dispatcher_->GetBrowser(); + if (!browser) + error_ = keys::kNoCurrentWindowError; } + if (!browser) + return false; result_.reset(CreateTabList(browser)); @@ -385,11 +400,13 @@ bool CreateTabFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(args->GetInteger( keys::kWindowIdKey, &window_id)); browser = GetBrowserInProfileWithId(profile(), window_id, &error_); - if (!browser) - return false; } else { - browser = dispatcher_->GetBrowser(); + browser = dispatcher_->GetBrowser(); + if (!browser) + error_ = keys::kNoCurrentWindowError; } + if (!browser) + return false; TabStripModel* tab_strip = browser->tabstrip_model(); diff --git a/chrome/browser/extensions/extension_tabs_module_constants.cc b/chrome/browser/extensions/extension_tabs_module_constants.cc index bf5e728..049f36a 100755 --- a/chrome/browser/extensions/extension_tabs_module_constants.cc +++ b/chrome/browser/extensions/extension_tabs_module_constants.cc @@ -34,8 +34,11 @@ const wchar_t kWindowIdKey[] = L"windowId"; const char kStatusValueComplete[] = "complete"; const char kStatusValueLoading[] = "loading"; +const char kNoCurrentWindowError[] = "No current window"; +const char kNoLastFocusedWindowError[] = "No last-focused window"; const char kWindowNotFoundError[] = "No window with id: *."; const char kTabNotFoundError[] = "No tab with id: *."; +const char kNoSelectedTabError[] = "No selected tab"; const char kInvalidUrlError[] = "Invalid url: \"*\"."; const char kGetWindowFunction[] = "GetWindow"; diff --git a/chrome/browser/extensions/extension_tabs_module_constants.h b/chrome/browser/extensions/extension_tabs_module_constants.h index a990c5c..10abcf7 100755 --- a/chrome/browser/extensions/extension_tabs_module_constants.h +++ b/chrome/browser/extensions/extension_tabs_module_constants.h @@ -40,8 +40,11 @@ extern const char kStatusValueComplete[]; extern const char kStatusValueLoading[]; // Error messages. +extern const char kNoCurrentWindowError[]; +extern const char kNoLastFocusedWindowError[]; extern const char kWindowNotFoundError[]; extern const char kTabNotFoundError[]; +extern const char kNoSelectedTabError[]; extern const char kInvalidUrlError[]; // Function names, Windows API. |