diff options
Diffstat (limited to 'chrome/browser')
20 files changed, 123 insertions, 116 deletions
diff --git a/chrome/browser/background_application_list_model.cc b/chrome/browser/background_application_list_model.cc index f94b07e..63f2b94 100644 --- a/chrome/browser/background_application_list_model.cc +++ b/chrome/browser/background_application_list_model.cc @@ -239,7 +239,9 @@ void BackgroundApplicationListModel::Observe( Update(); return; } - + ExtensionsService* service = profile_->GetExtensionsService(); + if (!service || !service->is_ready()) + return; switch (type.value) { case NotificationType::EXTENSION_LOADED: OnExtensionLoaded(Details<Extension>(details).ptr()); @@ -284,6 +286,7 @@ void BackgroundApplicationListModel::RemoveObserver(Observer* observer) { // each observer. void BackgroundApplicationListModel::Update() { ExtensionsService* service = profile_->GetExtensionsService(); + DCHECK(service->is_ready()); // Discover current background applications, compare with previous list, which // is consistently sorted, and notify observers if they differ. diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index b306ec1..2cfc68e 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -573,42 +573,6 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, CloseWithAppMenuOpen) { new RunCloseWithAppMenuTask(browser())); } -#if !defined(OS_MACOSX) -IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) { - ASSERT_TRUE(test_server()->Start()); - - // Load an app - host_resolver()->AddRule("www.example.com", "127.0.0.1"); - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); - const Extension* extension_app = GetExtension(); - - // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would. - TabContents* app_window = Browser::OpenApplication( - browser()->profile(), extension_app, extension_misc::LAUNCH_WINDOW, NULL); - ASSERT_TRUE(app_window); - - // Apps launched in a window from the NTP do not have extension_app set in - // tab contents. - EXPECT_FALSE(app_window->extension_app()); - EXPECT_EQ(extension_app->GetFullLaunchURL(), app_window->GetURL()); - - // The launch should have created a new browser. - ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); - - // Find the new browser. - Browser* new_browser = NULL; - for (BrowserList::const_iterator i = BrowserList::begin(); - i != BrowserList::end() && !new_browser; ++i) { - if (*i != browser()) - new_browser = *i; - } - ASSERT_TRUE(new_browser); - ASSERT_TRUE(new_browser != browser()); - - EXPECT_EQ(Browser::TYPE_APP, new_browser->type()); -} -#endif // !defined(OS_MACOSX) - // TODO(ben): this test was never enabled. It has bit-rotted since being added. // It originally lived in browser_unittest.cc, but has been moved here to make // room for real browser unit tests. diff --git a/chrome/browser/dom_ui/app_launcher_handler.cc b/chrome/browser/dom_ui/app_launcher_handler.cc index e57dfdc..77e3ee0 100644 --- a/chrome/browser/dom_ui/app_launcher_handler.cc +++ b/chrome/browser/dom_ui/app_launcher_handler.cc @@ -190,14 +190,6 @@ void AppLauncherHandler::FillAppDictionary(DictionaryValue* dictionary) { bool showLauncher = CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppLauncher); dictionary->SetBoolean("showLauncher", showLauncher); - -#if defined(OS_MACOSX) - // App windows are not yet implemented on mac. - bool disable_app_window_launch = true; -#else - bool disable_app_window_launch = false; -#endif - dictionary->SetBoolean("disableAppWindowLaunch", disable_app_window_launch); } void AppLauncherHandler::HandleGetApps(const ListValue* args) { @@ -256,18 +248,8 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { old_contents = browser->GetSelectedTabContents(); AnimateAppIcon(extension, rect); - - extension_misc::LaunchContainer launch_container = - extension->launch_container(); - ExtensionPrefs::LaunchType prefs_launch_type = - extensions_service_->extension_prefs()->GetLaunchType(extension_id); - - // If the user chose to open in a window, change the container type. - if (prefs_launch_type == ExtensionPrefs::LAUNCH_WINDOW) - launch_container = extension_misc::LAUNCH_WINDOW; - TabContents* new_contents = Browser::OpenApplication( - profile, extension, launch_container, old_contents); + profile, extension, extension->launch_container(), old_contents); if (new_contents != old_contents && browser->tab_count() > 1) browser->CloseTabContents(old_contents); @@ -328,7 +310,7 @@ void AppLauncherHandler::HandleHideAppsPromo(const ListValue* args) { extensions_service_->default_apps()->SetPromoHidden(); } -// static +//static void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { if (!promo_active) return; @@ -337,7 +319,7 @@ void AppLauncherHandler::RecordWebStoreLaunch(bool promo_active) { extension_misc::PROMO_BUCKET_BOUNDARY); } -// static +//static void AppLauncherHandler::RecordAppLaunch(bool promo_active) { // TODO(jstritar): record app launches that occur when the promo is not // active using a different histogram. diff --git a/chrome/browser/dom_ui/ntp_resource_cache.cc b/chrome/browser/dom_ui/ntp_resource_cache.cc index 859c666..7d0a5d4 100644 --- a/chrome/browser/dom_ui/ntp_resource_cache.cc +++ b/chrome/browser/dom_ui/ntp_resource_cache.cc @@ -310,8 +310,6 @@ void NTPResourceCache::CreateNewTabHTML() { l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED)); localized_strings.SetString("applaunchtyperegular", l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR)); - localized_strings.SetString("applaunchtypewindow", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW)); localized_strings.SetString("applaunchtypefullscreen", l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN)); localized_strings.SetString("web_store_title", diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc index faaa74b..c0522f0 100644 --- a/chrome/browser/extensions/extension_dom_ui.cc +++ b/chrome/browser/extensions/extension_dom_ui.cc @@ -243,6 +243,13 @@ bool ExtensionDOMUI::HandleChromeURLOverride(GURL* url, Profile* profile) { return false; ExtensionsService* service = profile->GetExtensionsService(); + if (!service->is_ready()) { + // TODO(erikkay) So far, it looks like extensions load before the new tab + // page. I don't know if we have anything that enforces this, so add this + // check for safety. + NOTREACHED() << "Chrome URL override requested before extensions loaded"; + return false; + } size_t i = 0; while (i < url_list->GetSize()) { diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index 26e601f0..3c789b0 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -452,22 +452,12 @@ void ExtensionPrefs::SetAllowFileAccess(const std::string& extension_id, ExtensionPrefs::LaunchType ExtensionPrefs::GetLaunchType( const std::string& extension_id) { int value; - if (ReadExtensionPrefInteger(extension_id, kPrefLaunchType, &value) && - (value == LAUNCH_PINNED || + if (ReadExtensionPrefInteger(extension_id, kPrefLaunchType, &value) && ( + value == LAUNCH_PINNED || value == LAUNCH_REGULAR || - value == LAUNCH_FULLSCREEN || - value == LAUNCH_WINDOW)) { - -#if defined(OS_MACOSX) - // App windows are not yet supported on mac. Pref sync could make - // the launch type LAUNCH_WINDOW, even if there is no UI to set it - // on mac. - if (value == LAUNCH_WINDOW) - return LAUNCH_REGULAR; -#endif + value == LAUNCH_FULLSCREEN)) { return static_cast<LaunchType>(value); } - return LAUNCH_REGULAR; } diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index ad8e9c8..298d03c 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -35,8 +35,7 @@ class ExtensionPrefs { enum LaunchType { LAUNCH_PINNED, LAUNCH_REGULAR, - LAUNCH_FULLSCREEN, - LAUNCH_WINDOW + LAUNCH_FULLSCREEN }; explicit ExtensionPrefs(PrefService* prefs, const FilePath& root_dir_); diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index 3aec736..8fd5538 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -279,15 +279,18 @@ void ExtensionProcessManager::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { switch (type.value) { - case NotificationType::EXTENSIONS_READY: { + case NotificationType::EXTENSIONS_READY: CreateBackgroundHosts(this, Source<Profile>(source).ptr()->GetExtensionsService()->extensions()); break; - } case NotificationType::EXTENSION_LOADED: { - const Extension* extension = Details<const Extension>(details).ptr(); - ::CreateBackgroundHost(this, extension); + ExtensionsService* service = + Source<Profile>(source).ptr()->GetExtensionsService(); + if (service->is_ready()) { + const Extension* extension = Details<const Extension>(details).ptr(); + ::CreateBackgroundHost(this, extension); + } break; } @@ -451,7 +454,8 @@ void IncognitoExtensionProcessManager::Observe( if (browser->profile() == browsing_instance_->profile()) { ExtensionsService* service = browsing_instance_->profile()->GetExtensionsService(); - CreateBackgroundHosts(this, service->extensions()); + if (service && service->is_ready()) + CreateBackgroundHosts(this, service->extensions()); } break; } diff --git a/chrome/browser/extensions/extension_startup_browsertest.cc b/chrome/browser/extensions/extension_startup_browsertest.cc index a5561ef..1b15ce0 100644 --- a/chrome/browser/extensions/extension_startup_browsertest.cc +++ b/chrome/browser/extensions/extension_startup_browsertest.cc @@ -84,6 +84,9 @@ class ExtensionStartupTestBase : public InProcessBrowserTest { void WaitForServicesToStart(int num_expected_extensions, bool expect_extensions_enabled) { ExtensionsService* service = browser()->profile()->GetExtensionsService(); + if (!service->is_ready()) + ui_test_utils::WaitForNotification(NotificationType::EXTENSIONS_READY); + ASSERT_TRUE(service->is_ready()); // Count the number of non-component extensions. int found_extensions = 0; diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc index 7d31043..9b36825 100644 --- a/chrome/browser/extensions/extension_toolbar_model.cc +++ b/chrome/browser/extensions/extension_toolbar_model.cc @@ -90,6 +90,9 @@ void ExtensionToolbarModel::Observe(NotificationType type, return; } + if (!service_->is_ready()) + return; + const Extension* extension = Details<const Extension>(details).ptr(); if (type == NotificationType::EXTENSION_LOADED) { AddExtension(extension); @@ -148,6 +151,8 @@ void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { // 2. Create a vector of extensions that did not have a pref value. // 3. Remove holes from the sorted vector and append the unsorted vector. void ExtensionToolbarModel::InitializeExtensionList() { + DCHECK(service_->is_ready()); + std::vector<std::string> pref_order = service_->extension_prefs()-> GetToolbarOrder(); // Items that have a pref for their position. diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 13fee46..e8f39aa 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -538,7 +538,7 @@ ExtensionsService::ExtensionsService(Profile* profile, install_directory_(install_directory), extensions_enabled_(true), show_extensions_prompts_(true), - init_done_(false), + ready_(false), ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)), default_apps_(profile->GetPrefs()), event_routers_initialized_(false) { @@ -608,7 +608,7 @@ void ExtensionsService::InitEventRouters() { void ExtensionsService::Init() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!init_done_); // Can't redo init. + DCHECK(!ready_); DCHECK_EQ(extensions_.size(), 0u); // Hack: we need to ensure the ResourceDispatcherHost is ready before we load @@ -623,8 +623,6 @@ void ExtensionsService::Init() { // TODO(erikkay) this should probably be deferred as well. GarbageCollectExtensions(); - - init_done_ = true; } void ExtensionsService::InstallExtension(const FilePath& extension_path) { @@ -1475,6 +1473,7 @@ void ExtensionsService::GarbageCollectExtensions() { } void ExtensionsService::OnLoadedInstalledExtensions() { + ready_ = true; if (updater_.get()) { updater_->Start(); } diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 11e4b1c8..d3fd80b 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -381,6 +381,9 @@ class ExtensionsService ExtensionPrefs* extension_prefs() { return extension_prefs_.get(); } + // Whether the extension service is ready. + bool is_ready() { return ready_; } + // Note that this may return NULL if autoupdate is not turned on. ExtensionUpdater* updater() { return updater_.get(); } @@ -505,8 +508,8 @@ class ExtensionsService // Used by dispatchers to limit API quota for individual extensions. ExtensionsQuotaService quota_service_; - // Record that Init() has been called. - bool init_done_; + // Is the service ready to go? + bool ready_; // Our extension updater, if updates are turned on. scoped_refptr<ExtensionUpdater> updater_; diff --git a/chrome/browser/resources/new_new_tab.html b/chrome/browser/resources/new_new_tab.html index 23ea917..001c378 100644 --- a/chrome/browser/resources/new_new_tab.html +++ b/chrome/browser/resources/new_new_tab.html @@ -236,8 +236,6 @@ if ('mode' in hashParams) { launch-type="0"> <command id="apps-launch-type-regular" i18n-values=".label:applaunchtyperegular" launch-type="1"> -<command id="apps-launch-type-window" - i18n-values=".label:applaunchtypewindow" launch-type="3"> <command id="apps-launch-type-fullscreen" i18n-values=".label:applaunchtypefullscreen" launch-type="2"> @@ -246,8 +244,6 @@ if ('mode' in hashParams) { <hr> <button command="#apps-launch-type-regular" launch-type="1"></button> <button command="#apps-launch-type-pinned" launch-type="0"></button> - <button id="apps-launch-type-window-menu-item" - command="#apps-launch-type-window" launch-type="3"></button> <button command="#apps-launch-type-fullscreen" launch-type="2"></button> <hr> <button command="#apps-options-command"></button> diff --git a/chrome/browser/resources/ntp/apps.js b/chrome/browser/resources/ntp/apps.js index 2e4a92c..7069231 100644 --- a/chrome/browser/resources/ntp/apps.js +++ b/chrome/browser/resources/ntp/apps.js @@ -21,10 +21,6 @@ function getAppsCallback(data) { var appsPromoPing = PING_WEBSTORE_LAUNCH_PREFIX + '+' + data.showPromo; var webStoreEntry; - // Hide the app window menu option on platforms that do not support it. - $('apps-launch-type-window-menu-item').style.display = - (data.disableAppWindowLaunch ? 'none' : 'inline'); - appsMiniview.textContent = ''; appsSectionContent.textContent = ''; @@ -154,11 +150,10 @@ var apps = (function() { var LaunchType = { LAUNCH_PINNED: 0, LAUNCH_REGULAR: 1, - LAUNCH_FULLSCREEN: 2, - LAUNCH_WINDOW: 3 + LAUNCH_FULLSCREEN: 2 }; - // Keep in sync with LaunchContainer in extension_constants.h + // Keep in sync with LaunchContainer in extension.h var LaunchContainer = { LAUNCH_WINDOW: 0, LAUNCH_PANEL: 1, @@ -189,8 +184,7 @@ var apps = (function() { // Update the commands related to the launch type. var launchTypeIds = ['apps-launch-type-pinned', 'apps-launch-type-regular', - 'apps-launch-type-fullscreen', - 'apps-launch-type-window']; + 'apps-launch-type-fullscreen']; launchTypeIds.forEach(function(id) { var command = $(id); command.disabled = isPanel; @@ -221,7 +215,6 @@ var apps = (function() { case 'apps-launch-type-pinned': case 'apps-launch-type-regular': case 'apps-launch-type-fullscreen': - case 'apps-launch-type-window': chrome.send('setLaunchType', [currentApp['id'], e.command.getAttribute('launch-type')]); break; diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index 3417215..6f38e51 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc @@ -272,7 +272,8 @@ class SessionRestoreImpl : public NotificationObserver { synchronous_(synchronous), clobber_existing_window_(clobber_existing_window), always_create_tabbed_browser_(always_create_tabbed_browser), - urls_to_open_(urls_to_open) { + urls_to_open_(urls_to_open), + waiting_for_extension_service_(false) { } void Restore() { @@ -338,6 +339,19 @@ class SessionRestoreImpl : public NotificationObserver { delete this; return; + case NotificationType::EXTENSIONS_READY: { + if (!waiting_for_extension_service_) + return; + + waiting_for_extension_service_ = false; + if (synchronous_) { + MessageLoop::current()->Quit(); + return; + } + ProcessSessionWindows(&windows_); + return; + } + default: NOTREACHED(); break; @@ -382,6 +396,18 @@ class SessionRestoreImpl : public NotificationObserver { void OnGotSession(SessionService::Handle handle, std::vector<SessionWindow*>* windows) { + if (HasExtensionApps(*windows) && profile_->GetExtensionsService() && + !profile_->GetExtensionsService()->is_ready()) { + // At least one tab is an app tab and the extension service hasn't + // finished loading. Wait to continue processing until the extensions + // service finishes loading. + registrar_.Add(this, NotificationType::EXTENSIONS_READY, + Source<Profile>(profile_)); + windows_.swap(*windows); + waiting_for_extension_service_ = true; + return; + } + if (synchronous_) { // See comment above windows_ as to why we don't process immediately. windows_.swap(*windows); @@ -392,6 +418,28 @@ class SessionRestoreImpl : public NotificationObserver { ProcessSessionWindows(windows); } + // Returns true if any tab in |windows| has an application extension id. + bool HasExtensionApps(const std::vector<SessionWindow*>& windows) { + for (std::vector<SessionWindow*>::const_iterator i = windows.begin(); + i != windows.end(); ++i) { + if (HasExtensionApps((*i)->tabs)) + return true; + } + + return false; + } + + // Returns true if any tab in |tabs| has an application extension id. + bool HasExtensionApps(const std::vector<SessionTab*>& tabs) { + for (std::vector<SessionTab*>::const_iterator i = tabs.begin(); + i != tabs.end(); ++i) { + if (!(*i)->extension_app_id.empty()) + return true; + } + + return false; + } + void ProcessSessionWindows(std::vector<SessionWindow*>* windows) { if (windows->empty()) { // Restore was unsuccessful. @@ -553,6 +601,10 @@ class SessionRestoreImpl : public NotificationObserver { // windows when the nested message loop exits. std::vector<SessionWindow*> windows_; + // If true, indicates at least one tab has an application extension id and + // we're waiting for the extension service to finish loading. + bool waiting_for_extension_service_; + NotificationRegistrar registrar_; }; diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc index 75b6ddc..8c8754d 100644 --- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc +++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc @@ -39,7 +39,10 @@ RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents( const string16& frame_name) { ExtensionsService* extensions_service = profile->GetExtensionsService(); - if (!opener_url.is_valid() || frame_name.empty()) + if (!opener_url.is_valid() || + frame_name.empty() || + !extensions_service || + !extensions_service->is_ready()) return NULL; const Extension* extension = diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 979b40b..5f091ee 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -598,10 +598,12 @@ void TabContents::SetExtensionAppById(const std::string& extension_app_id) { return; ExtensionsService* extension_service = profile()->GetExtensionsService(); - const Extension* extension = - extension_service->GetExtensionById(extension_app_id, false); - if (extension) - SetExtensionApp(extension); + if (extension_service && extension_service->is_ready()) { + const Extension* extension = + extension_service->GetExtensionById(extension_app_id, false); + if (extension) + SetExtensionApp(extension); + } } SkBitmap* TabContents::GetExtensionAppIcon() { diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 29d7dd0..2f02b64 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -498,6 +498,8 @@ TabContents* Browser::OpenApplication(Profile* profile, const std::string& app_id, TabContents* existing_tab) { ExtensionsService* extensions_service = profile->GetExtensionsService(); + if (!extensions_service->is_ready()) + return NULL; // If the extension with |app_id| could't be found, most likely because it // was uninstalled. @@ -520,11 +522,9 @@ TabContents* Browser::OpenApplication( UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100); + // The app is not yet open. Load it. switch (container) { case extension_misc::LAUNCH_WINDOW: - tab = Browser::OpenApplicationWindow(profile, - extension->GetFullLaunchURL()); - break; case extension_misc::LAUNCH_PANEL: tab = Browser::OpenApplicationWindow(profile, extension, container, GURL()); @@ -588,7 +588,7 @@ TabContents* Browser::OpenApplicationWindow( } // static -TabContents* Browser::OpenApplicationWindow(Profile* profile, const GURL& url) { +TabContents* Browser::OpenApplicationWindow(Profile* profile, GURL& url) { return OpenApplicationWindow(profile, NULL, extension_misc::LAUNCH_WINDOW, url); } diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 901137f..b70049b 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -250,9 +250,8 @@ class Browser : public TabHandlerDelegate, extension_misc::LaunchContainer container, const GURL& url); - // Open an application in a new application window. Used to implement - // app shortcuts. - static TabContents* OpenApplicationWindow(Profile* profile, const GURL& url); + // Open an application for |extension| in a new application window or panel. + static TabContents* OpenApplicationWindow(Profile* profile, GURL& url); // Open an application for |extension| in a new application tab, or // |existing_tab| if not NULL. Returns NULL if there are no appropriate diff --git a/chrome/browser/ui/browser_init.cc b/chrome/browser/ui/browser_init.cc index 439f31f..9085033 100644 --- a/chrome/browser/ui/browser_init.cc +++ b/chrome/browser/ui/browser_init.cc @@ -605,9 +605,14 @@ bool BrowserInit::LaunchWithProfile::OpenApplicationWindow(Profile* profile) { if (!IsAppLaunch(&url_string, &app_id)) return false; - // This can fail if the app_id is invalid. It can also fail if the - // extension is external, and has not yet been installed. - // TODO(skerner): Do something reasonable here. Pop up a warning panel? + // http://crbug.com/37548 + // TODO(rafaelw): There are two legitimate cases where the extensions + // service could not be ready at this point which need to be handled: + // 1) The locale has changed and the manifests stored in the preferences + // need to be relocalized. + // 2) An externally installed extension will be found and installed. + // Note that this can also fail if the app_id is simply invalid. + // TODO(rafaelw): Do something reasonable here. Pop up a warning panel? // Open an URL to the gallery page of the extension id? if (!app_id.empty()) return Browser::OpenApplication(profile, app_id, NULL) != NULL; |