Home | History | Annotate | Download | only in apps
      1 // Copyright (c) 2013 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 "apps/app_restore_service.h"
      6 #include "apps/app_restore_service_factory.h"
      7 #include "apps/saved_files_service.h"
      8 #include "chrome/browser/apps/app_browsertest_util.h"
      9 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "content/public/browser/notification_service.h"
     12 #include "content/public/test/test_utils.h"
     13 #include "extensions/browser/extension_prefs.h"
     14 #include "extensions/browser/notification_types.h"
     15 #include "extensions/common/extension.h"
     16 #include "extensions/test/extension_test_message_listener.h"
     17 
     18 using extensions::Extension;
     19 using extensions::ExtensionPrefs;
     20 using extensions::ExtensionSystem;
     21 using extensions::FileSystemChooseEntryFunction;
     22 
     23 // TODO(benwells): Move PlatformAppBrowserTest to apps namespace in apps
     24 // component.
     25 using extensions::PlatformAppBrowserTest;
     26 
     27 namespace apps {
     28 
     29 // Tests that a running app is recorded in the preferences as such.
     30 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, RunningAppsAreRecorded) {
     31   content::WindowedNotificationObserver extension_suspended(
     32       extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
     33       content::NotificationService::AllSources());
     34 
     35   const Extension* extension = LoadExtension(
     36       test_data_dir_.AppendASCII("platform_apps/restart_test"));
     37   ASSERT_TRUE(extension);
     38   ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
     39 
     40   // App is running.
     41   ASSERT_TRUE(extension_prefs->IsExtensionRunning(extension->id()));
     42 
     43   // Wait for the extension to get suspended.
     44   extension_suspended.Wait();
     45 
     46   // App isn't running because it got suspended.
     47   ASSERT_FALSE(extension_prefs->IsExtensionRunning(extension->id()));
     48 
     49   // Pretend that the app is supposed to be running.
     50   extension_prefs->SetExtensionRunning(extension->id(), true);
     51 
     52   ExtensionTestMessageListener restart_listener("onRestarted", false);
     53   apps::AppRestoreServiceFactory::GetForProfile(browser()->profile())->
     54       HandleStartup(true);
     55   restart_listener.WaitUntilSatisfied();
     56 }
     57 
     58 // Tests that apps are recorded in the preferences as active when and only when
     59 // they have visible windows.
     60 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ActiveAppsAreRecorded) {
     61   ExtensionTestMessageListener ready_listener("ready", true);
     62   const Extension* extension =
     63       LoadExtension(test_data_dir_.AppendASCII("platform_apps/active_test"));
     64   ASSERT_TRUE(extension);
     65   ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
     66   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     67 
     68   // Open a visible window and check the app is marked active.
     69   ready_listener.Reply("create");
     70   ready_listener.Reset();
     71   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     72   ASSERT_TRUE(extension_prefs->IsActive(extension->id()));
     73 
     74   // Close the window, then open a minimized window and check the app is active.
     75   ready_listener.Reply("closeLastWindow");
     76   ready_listener.Reset();
     77   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     78   ready_listener.Reply("createMinimized");
     79   ready_listener.Reset();
     80   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     81   ASSERT_TRUE(extension_prefs->IsActive(extension->id()));
     82 
     83   // Close the window, then open a hidden window and check the app is not
     84   // marked active.
     85   ready_listener.Reply("closeLastWindow");
     86   ready_listener.Reset();
     87   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     88   ready_listener.Reply("createHidden");
     89   ready_listener.Reset();
     90   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     91   ASSERT_FALSE(extension_prefs->IsActive(extension->id()));
     92 
     93   // Open another window and check the app is marked active.
     94   ready_listener.Reply("create");
     95   ready_listener.Reset();
     96   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
     97   ASSERT_TRUE(extension_prefs->IsActive(extension->id()));
     98 
     99   // Close the visible window and check the app has been marked inactive.
    100   ready_listener.Reply("closeLastWindow");
    101   ready_listener.Reset();
    102   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
    103   ASSERT_FALSE(extension_prefs->IsActive(extension->id()));
    104 
    105   // Close the last window and exit.
    106   ready_listener.Reply("closeLastWindow");
    107   ready_listener.Reset();
    108   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
    109   ready_listener.Reply("exit");
    110 }
    111 
    112 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, FileAccessIsSavedToPrefs) {
    113   content::WindowedNotificationObserver extension_suspended(
    114       extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
    115       content::NotificationService::AllSources());
    116 
    117   base::ScopedTempDir temp_directory;
    118   ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
    119   base::FilePath temp_file;
    120   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.path(),
    121                                              &temp_file));
    122 
    123   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
    124       &temp_file);
    125   FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest(
    126       "temp", temp_directory.path());
    127 
    128   const Extension* extension = LoadAndLaunchPlatformApp(
    129       "file_access_saved_to_prefs_test", "fileWritten");
    130   ASSERT_TRUE(extension);
    131 
    132   SavedFilesService* saved_files_service = SavedFilesService::Get(profile());
    133 
    134   std::vector<SavedFileEntry> file_entries =
    135       saved_files_service->GetAllFileEntries(extension->id());
    136   // One for the read-only file entry and one for the writable file entry.
    137   ASSERT_EQ(2u, file_entries.size());
    138 
    139   extension_suspended.Wait();
    140   file_entries = saved_files_service->GetAllFileEntries(extension->id());
    141   // File entries should be cleared when the extension is suspended.
    142   ASSERT_TRUE(file_entries.empty());
    143 }
    144 
    145 // Flaky: crbug.com/269613
    146 #if defined(OS_LINUX) || defined(OS_WIN)
    147 #define MAYBE_FileAccessIsRestored DISABLED_FileAccessIsRestored
    148 #else
    149 #define MAYBE_FileAccessIsRestored FileAccessIsRestored
    150 #endif
    151 
    152 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_FileAccessIsRestored) {
    153   content::WindowedNotificationObserver extension_suspended(
    154       extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
    155       content::NotificationService::AllSources());
    156 
    157   base::ScopedTempDir temp_directory;
    158   ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
    159   base::FilePath temp_file;
    160   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.path(),
    161                                              &temp_file));
    162 
    163   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
    164       &temp_file);
    165   FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest(
    166       "temp", temp_directory.path());
    167 
    168   ExtensionTestMessageListener access_ok_listener(
    169       "restartedFileAccessOK", false);
    170 
    171   const Extension* extension =
    172       LoadAndLaunchPlatformApp("file_access_restored_test", "fileWritten");
    173   ASSERT_TRUE(extension);
    174 
    175   ExtensionPrefs* extension_prefs =
    176       ExtensionPrefs::Get(browser()->profile());
    177   SavedFilesService* saved_files_service = SavedFilesService::Get(profile());
    178   std::vector<SavedFileEntry> file_entries =
    179       saved_files_service->GetAllFileEntries(extension->id());
    180   extension_suspended.Wait();
    181 
    182   // Simulate a restart by populating the preferences as if the browser didn't
    183   // get time to clean itself up.
    184   extension_prefs->SetExtensionRunning(extension->id(), true);
    185   for (std::vector<SavedFileEntry>::const_iterator it = file_entries.begin();
    186        it != file_entries.end(); ++it) {
    187     saved_files_service->RegisterFileEntry(
    188         extension->id(), it->id, it->path, it->is_directory);
    189   }
    190 
    191   apps::AppRestoreServiceFactory::GetForProfile(browser()->profile())->
    192       HandleStartup(true);
    193 
    194   access_ok_listener.WaitUntilSatisfied();
    195 }
    196 
    197 }  // namespace apps
    198