Home | History | Annotate | Download | only in task_manager
      1 // Copyright (c) 2012 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 #include "chrome/browser/task_manager/task_manager.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/strings/stringprintf.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "chrome/browser/chrome_notification_types.h"
     11 #include "chrome/browser/devtools/devtools_window.h"
     12 #include "chrome/browser/extensions/extension_browsertest.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/infobars/infobar_service.h"
     15 #include "chrome/browser/notifications/desktop_notification_service.h"
     16 #include "chrome/browser/notifications/notification.h"
     17 #include "chrome/browser/notifications/notification_test_util.h"
     18 #include "chrome/browser/notifications/notification_ui_manager.h"
     19 #include "chrome/browser/profiles/profile.h"
     20 #include "chrome/browser/task_manager/resource_provider.h"
     21 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
     22 #include "chrome/browser/ui/browser.h"
     23 #include "chrome/browser/ui/browser_commands.h"
     24 #include "chrome/browser/ui/browser_dialogs.h"
     25 #include "chrome/browser/ui/browser_navigator.h"
     26 #include "chrome/browser/ui/browser_window.h"
     27 #include "chrome/browser/ui/panels/panel.h"
     28 #include "chrome/browser/ui/panels/panel_manager.h"
     29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     30 #include "chrome/browser/web_applications/web_app.h"
     31 #include "chrome/common/chrome_switches.h"
     32 #include "chrome/test/base/in_process_browser_test.h"
     33 #include "chrome/test/base/ui_test_utils.h"
     34 #include "components/infobars/core/confirm_infobar_delegate.h"
     35 #include "components/infobars/core/infobar.h"
     36 #include "content/public/browser/notification_service.h"
     37 #include "content/public/common/content_switches.h"
     38 #include "content/public/common/page_transition_types.h"
     39 #include "content/public/test/browser_test_utils.h"
     40 #include "extensions/browser/extension_system.h"
     41 #include "extensions/common/extension.h"
     42 #include "grit/generated_resources.h"
     43 #include "net/dns/mock_host_resolver.h"
     44 #include "net/test/embedded_test_server/embedded_test_server.h"
     45 #include "testing/gtest/include/gtest/gtest.h"
     46 #include "ui/base/l10n/l10n_util.h"
     47 
     48 using content::WebContents;
     49 using task_manager::browsertest_util::MatchAboutBlankTab;
     50 using task_manager::browsertest_util::MatchAnyApp;
     51 using task_manager::browsertest_util::MatchAnyExtension;
     52 using task_manager::browsertest_util::MatchAnyTab;
     53 using task_manager::browsertest_util::MatchApp;
     54 using task_manager::browsertest_util::MatchExtension;
     55 using task_manager::browsertest_util::MatchTab;
     56 using task_manager::browsertest_util::WaitForTaskManagerRows;
     57 
     58 namespace {
     59 
     60 const base::FilePath::CharType* kTitle1File = FILE_PATH_LITERAL("title1.html");
     61 
     62 }  // namespace
     63 
     64 class TaskManagerBrowserTest : public ExtensionBrowserTest {
     65  public:
     66   TaskManagerBrowserTest() {}
     67   virtual ~TaskManagerBrowserTest() {}
     68 
     69   TaskManagerModel* model() const {
     70     return TaskManager::GetInstance()->model();
     71   }
     72 
     73   void ShowTaskManager() {
     74     EXPECT_EQ(0, model()->ResourceCount());
     75 
     76     // Show the task manager. This populates the model, and helps with debugging
     77     // (you see the task manager).
     78     chrome::ShowTaskManager(browser());
     79   }
     80 
     81   void Refresh() {
     82     model()->Refresh();
     83   }
     84 
     85   int GetUpdateTimeMs() {
     86     return TaskManagerModel::kUpdateTimeMs;
     87   }
     88 
     89   GURL GetTestURL() {
     90     return ui_test_utils::GetTestUrl(
     91         base::FilePath(base::FilePath::kCurrentDirectory),
     92         base::FilePath(kTitle1File));
     93   }
     94 
     95   int FindResourceIndex(const base::string16& title) {
     96     for (int i = 0; i < model()->ResourceCount(); ++i) {
     97       if (title == model()->GetResourceTitle(i))
     98         return i;
     99     }
    100     return -1;
    101   }
    102 
    103  protected:
    104   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    105     ExtensionBrowserTest::SetUpCommandLine(command_line);
    106 
    107     // Do not launch device discovery process.
    108     command_line->AppendSwitch(switches::kDisableDeviceDiscoveryNotifications);
    109   }
    110 
    111  private:
    112   DISALLOW_COPY_AND_ASSIGN(TaskManagerBrowserTest);
    113 };
    114 
    115 #if defined(OS_MACOSX) || defined(OS_LINUX)
    116 #define MAYBE_ShutdownWhileOpen DISABLED_ShutdownWhileOpen
    117 #else
    118 #define MAYBE_ShutdownWhileOpen ShutdownWhileOpen
    119 #endif
    120 
    121 // Regression test for http://crbug.com/13361
    122 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, MAYBE_ShutdownWhileOpen) {
    123   ShowTaskManager();
    124 }
    125 
    126 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeTabContentsChanges) {
    127   ShowTaskManager();
    128   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    129   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    130   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchTab("title1.html")));
    131 
    132   // Open a new tab and make sure the task manager notices it.
    133   AddTabAtIndex(0, GetTestURL(), content::PAGE_TRANSITION_TYPED);
    134 
    135   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("title1.html")));
    136   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    137 
    138   // Close the tab and verify that we notice.
    139   browser()->tab_strip_model()->CloseWebContentsAt(0,
    140                                                    TabStripModel::CLOSE_NONE);
    141   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchTab("title1.html")));
    142   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    143 }
    144 
    145 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, KillTab) {
    146   ShowTaskManager();
    147   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    148   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    149   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchTab("title1.html")));
    150 
    151   // Open a new tab and make sure the task manager notices it.
    152   AddTabAtIndex(0, GetTestURL(), content::PAGE_TRANSITION_TYPED);
    153 
    154   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("title1.html")));
    155   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    156 
    157   // Killing the tab via task manager should remove the row.
    158   int tab = FindResourceIndex(MatchTab("title1.html"));
    159   ASSERT_NE(-1, tab);
    160   ASSERT_TRUE(model()->GetResourceWebContents(tab) != NULL);
    161   ASSERT_TRUE(model()->CanActivate(tab));
    162   TaskManager::GetInstance()->KillProcess(tab);
    163   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchTab("title1.html")));
    164   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    165 
    166   // Tab should reappear in task manager upon reload.
    167   chrome::Reload(browser(), CURRENT_TAB);
    168   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("title1.html")));
    169   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    170 }
    171 
    172 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticePanel) {
    173   ASSERT_TRUE(LoadExtension(
    174       test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
    175                     .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    176                     .AppendASCII("1.0.0.0")));
    177 
    178   // Open a new panel to an extension url.
    179   GURL url(
    180     "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/french_sentence.html");
    181   Panel* panel = PanelManager::GetInstance()->CreatePanel(
    182       web_app::GenerateApplicationNameFromExtensionId(
    183           last_loaded_extension_id()),
    184       browser()->profile(),
    185       url,
    186       gfx::Rect(300, 400),
    187       PanelManager::CREATE_AS_DOCKED);
    188 
    189   // Make sure that a task manager model created after the panel shows the
    190   // existence of the panel and the extension.
    191   ShowTaskManager();
    192   ASSERT_NO_FATAL_FAILURE(
    193       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    194   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    195       1,
    196       MatchExtension(
    197           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    198           "french_sentence.html")));
    199   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    200   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    201   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    202 
    203   // Close the panel and verify that we notice.
    204   panel->Close();
    205   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyExtension()));
    206   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    207       0,
    208       MatchExtension(
    209           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    210           "french_sentence.html")));
    211   ASSERT_NO_FATAL_FAILURE(
    212       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    213 }
    214 
    215 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticePanelChanges) {
    216   ShowTaskManager();
    217   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    218   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    219 
    220   ASSERT_TRUE(LoadExtension(
    221       test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
    222                     .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    223                     .AppendASCII("1.0.0.0")));
    224 
    225   // Browser, the New Tab Page and Extension background page.
    226   ASSERT_NO_FATAL_FAILURE(
    227       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    228   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyExtension()));
    229   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    230 
    231   // Open a new panel to an extension url and make sure we notice that.
    232   GURL url(
    233     "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/french_sentence.html");
    234   Panel* panel = PanelManager::GetInstance()->CreatePanel(
    235       web_app::GenerateApplicationNameFromExtensionId(
    236           last_loaded_extension_id()),
    237       browser()->profile(),
    238       url,
    239       gfx::Rect(300, 400),
    240       PanelManager::CREATE_AS_DOCKED);
    241   ASSERT_NO_FATAL_FAILURE(
    242       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    243   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    244       1,
    245       MatchExtension(
    246           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    247           "french_sentence.html")));
    248   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    249   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    250   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    251 
    252   // Close the panel and verify that we notice.
    253   panel->Close();
    254   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyExtension()));
    255   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    256       0,
    257       MatchExtension(
    258           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    259           "french_sentence.html")));
    260   ASSERT_NO_FATAL_FAILURE(
    261       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    262 
    263   // Unload extension.
    264   UnloadExtension(last_loaded_extension_id());
    265   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    266   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    267 }
    268 
    269 // Kills a process that has more than one task manager entry.
    270 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, KillPanelViaExtensionResource) {
    271   ShowTaskManager();
    272   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("good")
    273                                 .AppendASCII("Extensions")
    274                                 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    275                                 .AppendASCII("1.0.0.0")));
    276 
    277   // Open a new panel to an extension url.
    278   GURL url(
    279       "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    280       "french_sentence.html");
    281   PanelManager::GetInstance()->CreatePanel(
    282       web_app::GenerateApplicationNameFromExtensionId(
    283           last_loaded_extension_id()),
    284       browser()->profile(),
    285       url,
    286       gfx::Rect(300, 400),
    287       PanelManager::CREATE_AS_DOCKED);
    288 
    289   ASSERT_NO_FATAL_FAILURE(
    290       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    291   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    292       1,
    293       MatchExtension(
    294           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    295           "french_sentence.html")));
    296   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    297   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    298   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    299 
    300   // Kill the process via the BACKGROUND PAGE (not the panel). Verify that both
    301   // the background page and the panel go away from the task manager.
    302   int background_page = FindResourceIndex(MatchExtension("My extension 1"));
    303   ASSERT_NE(-1, background_page);
    304   ASSERT_TRUE(model()->GetResourceWebContents(background_page) == NULL);
    305   ASSERT_FALSE(model()->CanActivate(background_page));
    306   TaskManager::GetInstance()->KillProcess(background_page);
    307   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    308   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    309 }
    310 
    311 // Kills a process that has more than one task manager entry. This test is the
    312 // same as KillPanelViaExtensionResource except it does the kill via the other
    313 // entry.
    314 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, KillPanelViaPanelResource) {
    315   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("good")
    316                                 .AppendASCII("Extensions")
    317                                 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    318                                 .AppendASCII("1.0.0.0")));
    319 
    320   // Open a new panel to an extension url.
    321   GURL url(
    322       "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    323       "french_sentence.html");
    324   PanelManager::GetInstance()->CreatePanel(
    325       web_app::GenerateApplicationNameFromExtensionId(
    326           last_loaded_extension_id()),
    327       browser()->profile(),
    328       url,
    329       gfx::Rect(300, 400),
    330       PanelManager::CREATE_AS_DOCKED);
    331 
    332   ShowTaskManager();
    333   ASSERT_NO_FATAL_FAILURE(
    334       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    335   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(
    336       1,
    337       MatchExtension(
    338           "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    339           "french_sentence.html")));
    340   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    341   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    342   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    343 
    344   int background_page = FindResourceIndex(MatchExtension("My extension 1"));
    345   ASSERT_NE(-1, background_page);
    346   ASSERT_TRUE(model()->GetResourceWebContents(background_page) == NULL);
    347   ASSERT_FALSE(model()->CanActivate(background_page));
    348 
    349   // Kill the process via the PANEL RESOURCE (not the background page). Verify
    350   // that both the background page and the panel go away from the task manager.
    351   int panel = FindResourceIndex(MatchExtension(
    352       "chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
    353       "french_sentence.html"));
    354   ASSERT_NE(-1, panel);
    355   ASSERT_TRUE(model()->GetResourceWebContents(panel) != NULL);
    356   ASSERT_TRUE(model()->CanActivate(panel));
    357   TaskManager::GetInstance()->KillProcess(panel);
    358   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    359   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    360 }
    361 
    362 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeExtensionTabChanges) {
    363   ShowTaskManager();
    364   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    365   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    366 
    367   ASSERT_TRUE(LoadExtension(
    368       test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
    369                     .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    370                     .AppendASCII("1.0.0.0")));
    371 
    372   // Browser, Extension background page, and the New Tab Page.
    373   ASSERT_NO_FATAL_FAILURE(
    374       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    375   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyExtension()));
    376   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    377 
    378   // Open a new tab to an extension URL. Afterwards, the third entry (background
    379   // page) should be an extension resource whose title starts with "Extension:".
    380   // The fourth entry (page.html) is also of type extension and has both a
    381   // WebContents and an extension. The title should start with "Extension:".
    382   GURL url("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html");
    383   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    384   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchExtension("Foobar")));
    385   ASSERT_NO_FATAL_FAILURE(
    386       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    387   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    388   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    389   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    390 
    391   int extension_tab = FindResourceIndex(MatchExtension("Foobar"));
    392   ASSERT_NE(-1, extension_tab);
    393   ASSERT_TRUE(model()->GetResourceWebContents(extension_tab) != NULL);
    394   ASSERT_TRUE(model()->CanActivate(extension_tab));
    395 
    396   int background_page = FindResourceIndex(MatchExtension("My extension 1"));
    397   ASSERT_NE(-1, background_page);
    398   ASSERT_TRUE(model()->GetResourceWebContents(background_page) == NULL);
    399   ASSERT_FALSE(model()->CanActivate(background_page));
    400 }
    401 
    402 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeExtensionTab) {
    403   // With the task manager closed, open a new tab to an extension URL.
    404   // Afterwards, when we open the task manager, the third entry (background
    405   // page) should be an extension resource whose title starts with "Extension:".
    406   // The fourth entry (page.html) is also of type extension and has both a
    407   // WebContents and an extension. The title should start with "Extension:".
    408   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("good")
    409                                 .AppendASCII("Extensions")
    410                                 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    411                                 .AppendASCII("1.0.0.0")));
    412   GURL url("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html");
    413   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    414 
    415   ShowTaskManager();
    416   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchExtension("Foobar")));
    417   ASSERT_NO_FATAL_FAILURE(
    418       WaitForTaskManagerRows(1, MatchExtension("My extension 1")));
    419   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyExtension()));
    420   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    421   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    422 
    423   int extension_tab = FindResourceIndex(MatchExtension("Foobar"));
    424   ASSERT_NE(-1, extension_tab);
    425   ASSERT_TRUE(model()->GetResourceWebContents(extension_tab) != NULL);
    426   ASSERT_TRUE(model()->CanActivate(extension_tab));
    427 
    428   int background_page = FindResourceIndex(MatchExtension("My extension 1"));
    429   ASSERT_NE(-1, background_page);
    430   ASSERT_TRUE(model()->GetResourceWebContents(background_page) == NULL);
    431   ASSERT_FALSE(model()->CanActivate(background_page));
    432 }
    433 
    434 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeAppTabChanges) {
    435   ShowTaskManager();
    436 
    437   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("packaged_app")));
    438   ExtensionService* service = extensions::ExtensionSystem::Get(
    439                                   browser()->profile())->extension_service();
    440   const extensions::Extension* extension =
    441       service->GetExtensionById(last_loaded_extension_id(), false);
    442 
    443   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    444   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    445   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    446   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyApp()));
    447 
    448   // Open a new tab to the app's launch URL and make sure we notice that.
    449   GURL url(extension->GetResourceURL("main.html"));
    450   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    451 
    452   // There should be 1 "App: " tab and the original new tab page.
    453   ASSERT_NO_FATAL_FAILURE(
    454       WaitForTaskManagerRows(1, MatchApp("Packaged App Test")));
    455   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
    456   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    457   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    458   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    459 
    460   // Check that the third entry (main.html) is of type extension and has both
    461   // a tab contents and an extension.
    462   int app_tab = FindResourceIndex(MatchApp("Packaged App Test"));
    463   ASSERT_NE(-1, app_tab);
    464   ASSERT_TRUE(model()->GetResourceWebContents(app_tab) != NULL);
    465   ASSERT_TRUE(model()->CanActivate(app_tab));
    466   ASSERT_EQ(task_manager::Resource::EXTENSION,
    467             model()->GetResourceType(app_tab));
    468   ASSERT_EQ(2, browser()->tab_strip_model()->count());
    469 
    470   // Unload extension to make sure the tab goes away.
    471   UnloadExtension(last_loaded_extension_id());
    472 
    473   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    474   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyApp()));
    475   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    476   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    477   ASSERT_EQ(1, browser()->tab_strip_model()->count());
    478 }
    479 
    480 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeAppTab) {
    481   ASSERT_TRUE(LoadExtension(
    482       test_data_dir_.AppendASCII("packaged_app")));
    483   ExtensionService* service = extensions::ExtensionSystem::Get(
    484       browser()->profile())->extension_service();
    485   const extensions::Extension* extension =
    486       service->GetExtensionById(last_loaded_extension_id(), false);
    487 
    488   // Open a new tab to the app's launch URL and make sure we notice that.
    489   GURL url(extension->GetResourceURL("main.html"));
    490   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    491 
    492   ShowTaskManager();
    493 
    494   ASSERT_NO_FATAL_FAILURE(
    495       WaitForTaskManagerRows(1, MatchApp("Packaged App Test")));
    496   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    497   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    498   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
    499 
    500   // Check that the third entry (main.html) is of type extension and has both
    501   // a tab contents and an extension.
    502   int app_tab = FindResourceIndex(MatchApp("Packaged App Test"));
    503   ASSERT_NE(-1, app_tab);
    504   ASSERT_TRUE(model()->GetResourceWebContents(app_tab) != NULL);
    505   ASSERT_TRUE(model()->CanActivate(app_tab));
    506   ASSERT_EQ(task_manager::Resource::EXTENSION,
    507             model()->GetResourceType(app_tab));
    508 }
    509 
    510 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeHostedAppTabChanges) {
    511   ShowTaskManager();
    512 
    513   // The app under test acts on URLs whose host is "localhost",
    514   // so the URLs we navigate to must have host "localhost".
    515   host_resolver()->AddRule("*", "127.0.0.1");
    516   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    517   GURL::Replacements replace_host;
    518   std::string host_str("localhost");  // must stay in scope with replace_host
    519   replace_host.SetHostStr(host_str);
    520   GURL base_url = embedded_test_server()->GetURL(
    521       "/extensions/api_test/app_process/");
    522   base_url = base_url.ReplaceComponents(replace_host);
    523 
    524   // Open a new tab to an app URL before the app is loaded.
    525   GURL url(base_url.Resolve("path1/empty.html"));
    526   content::WindowedNotificationObserver observer(
    527       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
    528       content::NotificationService::AllSources());
    529   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    530   observer.Wait();
    531 
    532   // Check that the new entry's title starts with "Tab:".
    533   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    534 
    535   // Load the hosted app and make sure it still starts with "Tab:",
    536   // since it hasn't changed to an app process yet.
    537   ASSERT_TRUE(LoadExtension(
    538       test_data_dir_.AppendASCII("api_test").AppendASCII("app_process")));
    539   // Force the TaskManager to query the title.
    540   Refresh();
    541   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    542   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    543   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("Unmodified")));
    544   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    545 
    546   // Now reload and check that the last entry's title now starts with "App:".
    547   ui_test_utils::NavigateToURL(browser(), url);
    548 
    549   // Force the TaskManager to query the title.
    550   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    551   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    552   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
    553   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchApp("Unmodified")));
    554   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    555 
    556   // Disable extension.
    557   DisableExtension(last_loaded_extension_id());
    558 
    559   // The hosted app should now show up as a normal "Tab: ".
    560   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    561   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    562   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("Unmodified")));
    563   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    564   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyApp()));
    565 
    566   // Reload the page.
    567   ui_test_utils::NavigateToURL(browser(), url);
    568 
    569   // No change expected.
    570   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    571   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
    572   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("Unmodified")));
    573   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    574   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyApp()));
    575 }
    576 
    577 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeHostedAppTabAfterReload) {
    578   // The app under test acts on URLs whose host is "localhost",
    579   // so the URLs we navigate to must have host "localhost".
    580   host_resolver()->AddRule("*", "127.0.0.1");
    581   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    582   GURL::Replacements replace_host;
    583   std::string host_str("localhost");  // must stay in scope with replace_host
    584   replace_host.SetHostStr(host_str);
    585   GURL base_url =
    586       embedded_test_server()->GetURL("/extensions/api_test/app_process/");
    587   base_url = base_url.ReplaceComponents(replace_host);
    588 
    589   // Open a new tab to an app URL before the app is loaded.
    590   GURL url(base_url.Resolve("path1/empty.html"));
    591   content::WindowedNotificationObserver observer(
    592       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
    593       content::NotificationService::AllSources());
    594   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    595   observer.Wait();
    596 
    597   // Load the hosted app and make sure it still starts with "Tab:",
    598   // since it hasn't changed to an app process yet.
    599   ASSERT_TRUE(LoadExtension(
    600       test_data_dir_.AppendASCII("api_test").AppendASCII("app_process")));
    601 
    602   // Now reload, which should transition this tab to being an App.
    603   ui_test_utils::NavigateToURL(browser(), url);
    604 
    605   ShowTaskManager();
    606 
    607   // The TaskManager should show this as an "App: "
    608   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    609   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
    610   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    611 }
    612 
    613 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeHostedAppTabBeforeReload) {
    614   // The app under test acts on URLs whose host is "localhost",
    615   // so the URLs we navigate to must have host "localhost".
    616   host_resolver()->AddRule("*", "127.0.0.1");
    617   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    618   GURL::Replacements replace_host;
    619   std::string host_str("localhost");  // must stay in scope with replace_host
    620   replace_host.SetHostStr(host_str);
    621   GURL base_url =
    622       embedded_test_server()->GetURL("/extensions/api_test/app_process/");
    623   base_url = base_url.ReplaceComponents(replace_host);
    624 
    625   // Open a new tab to an app URL before the app is loaded.
    626   GURL url(base_url.Resolve("path1/empty.html"));
    627   content::WindowedNotificationObserver observer(
    628       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
    629       content::NotificationService::AllSources());
    630   AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED);
    631   observer.Wait();
    632 
    633   // Load the hosted app and make sure it still starts with "Tab:",
    634   // since it hasn't changed to an app process yet.
    635   ASSERT_TRUE(LoadExtension(
    636       test_data_dir_.AppendASCII("api_test").AppendASCII("app_process")));
    637 
    638   ShowTaskManager();
    639 
    640   // The TaskManager should show this as a "Tab: " because the page hasn't been
    641   // reloaded since the hosted app was installed.
    642   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    643   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyApp()));
    644   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchAnyExtension()));
    645 }
    646 
    647 // Regression test for http://crbug.com/18693.
    648 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, ReloadExtension) {
    649   ShowTaskManager();
    650   ASSERT_TRUE(LoadExtension(
    651       test_data_dir_.AppendASCII("common").AppendASCII("background_page")));
    652 
    653   // Wait until we see the loaded extension in the task manager (the three
    654   // resources are: the browser process, New Tab Page, and the extension).
    655   ASSERT_NO_FATAL_FAILURE(
    656       WaitForTaskManagerRows(1, MatchExtension("background_page")));
    657 
    658   // Reload the extension a few times and make sure our resource count doesn't
    659   // increase.
    660   std::string extension_id = last_loaded_extension_id();
    661   for (int i = 1; i <= 5; i++) {
    662     SCOPED_TRACE(testing::Message() << "Reloading extension for the " << i
    663                                     << "th time.");
    664     ReloadExtension(extension_id);
    665     ASSERT_NO_FATAL_FAILURE(
    666         WaitForTaskManagerRows(1, MatchExtension("background_page")));
    667   }
    668 }
    669 
    670 // Crashy, http://crbug.com/42301.
    671 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest,
    672                        DISABLED_PopulateWebCacheFields) {
    673   ShowTaskManager();
    674   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    675 
    676   int resource_count = TaskManager::GetInstance()->model()->ResourceCount();
    677 
    678   // Open a new tab and make sure we notice that.
    679   AddTabAtIndex(0, GetTestURL(), content::PAGE_TRANSITION_TYPED);
    680   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    681 
    682   // Check that we get some value for the cache columns.
    683   DCHECK_NE(model()->GetResourceWebCoreImageCacheSize(resource_count),
    684             l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT));
    685   DCHECK_NE(model()->GetResourceWebCoreScriptsCacheSize(resource_count),
    686             l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT));
    687   DCHECK_NE(model()->GetResourceWebCoreCSSCacheSize(resource_count),
    688             l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT));
    689 }
    690 
    691 // Checks that task manager counts a worker thread JS heap size.
    692 // http://crbug.com/241066
    693 // Flaky, http://crbug.com/259368
    694 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DISABLED_WebWorkerJSHeapMemory) {
    695   ui_test_utils::NavigateToURL(browser(), GetTestURL());
    696   const int extra_timeout_ms = 500;
    697   size_t minimal_heap_size = 2 * 1024 * 1024 * sizeof(void*);
    698   std::string test_js = base::StringPrintf(
    699       "var blob = new Blob([\n"
    700       "    'mem = new Array(%lu);',\n"
    701       "    'for (var i = 0; i < mem.length; i += 16) mem[i] = i;',\n"
    702       "    'postMessage();']);\n"
    703       "blobURL = window.URL.createObjectURL(blob);\n"
    704       "worker = new Worker(blobURL);\n"
    705       "// Give the task manager few seconds to poll for JS heap sizes.\n"
    706       "worker.onmessage = setTimeout.bind(\n"
    707       "    this,\n"
    708       "    function () { window.domAutomationController.send(true); },\n"
    709       "    %d);\n"
    710       "worker.postMessage();\n",
    711       static_cast<unsigned long>(minimal_heap_size),
    712       GetUpdateTimeMs() + extra_timeout_ms);
    713   bool ok;
    714   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
    715       browser()->tab_strip_model()->GetActiveWebContents(), test_js, &ok));
    716   ASSERT_TRUE(ok);
    717 
    718   int resource_index = TaskManager::GetInstance()->model()->ResourceCount() - 1;
    719   size_t result;
    720 
    721   ASSERT_TRUE(model()->GetV8Memory(resource_index, &result));
    722   LOG(INFO) << "Got V8 Heap Size " << result << " bytes";
    723   EXPECT_GE(result, minimal_heap_size);
    724 
    725   ASSERT_TRUE(model()->GetV8MemoryUsed(resource_index, &result));
    726   LOG(INFO) << "Got V8 Used Heap Size " << result << " bytes";
    727   EXPECT_GE(result, minimal_heap_size);
    728 }
    729 
    730 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DevToolsNewDockedWindow) {
    731   ShowTaskManager();  // Task manager shown BEFORE dev tools window.
    732 
    733   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    734   DevToolsWindow::OpenDevToolsWindowForTest(
    735       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
    736       true);
    737   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    738   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    739 }
    740 
    741 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DevToolsNewUndockedWindow) {
    742   ShowTaskManager();  // Task manager shown BEFORE dev tools window.
    743   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
    744   DevToolsWindow::OpenDevToolsWindowForTest(
    745       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
    746       false);
    747   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    748   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    749 }
    750 
    751 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DevToolsOldDockedWindow) {
    752   DevToolsWindow::OpenDevToolsWindowForTest(
    753       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
    754       true);
    755 
    756   ShowTaskManager();  // Task manager shown AFTER dev tools window.
    757   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    758   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    759 }
    760 
    761 IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DevToolsOldUnockedWindow) {
    762   DevToolsWindow::OpenDevToolsWindowForTest(
    763       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
    764       false);
    765   ShowTaskManager();  // Task manager shown AFTER dev tools window.
    766   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    767   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(2, MatchAnyTab()));
    768 }
    769