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/chrome_notification_types.h" 9 #include "chrome/browser/extensions/api/file_system/file_system_api.h" 10 #include "chrome/browser/extensions/extension_prefs.h" 11 #include "chrome/browser/extensions/extension_test_message_listener.h" 12 #include "chrome/browser/extensions/platform_app_browsertest_util.h" 13 #include "chrome/common/extensions/extension.h" 14 #include "content/public/browser/notification_service.h" 15 #include "content/public/test/test_utils.h" 16 17 using extensions::Extension; 18 using extensions::ExtensionPrefs; 19 using extensions::ExtensionSystem; 20 using extensions::FileSystemChooseEntryFunction; 21 22 // TODO(benwells): Move PlatformAppBrowserTest to apps namespace in apps 23 // component. 24 using extensions::PlatformAppBrowserTest; 25 26 namespace apps { 27 28 // Tests that a running app is recorded in the preferences as such. 29 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, RunningAppsAreRecorded) { 30 content::WindowedNotificationObserver extension_suspended( 31 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 32 content::NotificationService::AllSources()); 33 34 const Extension* extension = LoadExtension( 35 test_data_dir_.AppendASCII("platform_apps/restart_test")); 36 ASSERT_TRUE(extension); 37 ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile()); 38 39 // App is running. 40 ASSERT_TRUE(extension_prefs->IsExtensionRunning(extension->id())); 41 42 // Wait for the extension to get suspended. 43 extension_suspended.Wait(); 44 45 // App isn't running because it got suspended. 46 ASSERT_FALSE(extension_prefs->IsExtensionRunning(extension->id())); 47 48 // Pretend that the app is supposed to be running. 49 extension_prefs->SetExtensionRunning(extension->id(), true); 50 51 ExtensionTestMessageListener restart_listener("onRestarted", false); 52 apps::AppRestoreServiceFactory::GetForProfile(browser()->profile())-> 53 HandleStartup(true); 54 restart_listener.WaitUntilSatisfied(); 55 } 56 57 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, FileAccessIsSavedToPrefs) { 58 content::WindowedNotificationObserver extension_suspended( 59 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 60 content::NotificationService::AllSources()); 61 62 base::ScopedTempDir temp_directory; 63 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); 64 base::FilePath temp_file; 65 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_directory.path(), 66 &temp_file)); 67 68 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( 69 &temp_file); 70 FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest( 71 "temp", temp_directory.path()); 72 73 ExtensionTestMessageListener file_written_listener("fileWritten", false); 74 ExtensionTestMessageListener access_ok_listener( 75 "restartedFileAccessOK", false); 76 77 const Extension* extension = 78 LoadAndLaunchPlatformApp("file_access_saved_to_prefs_test"); 79 ASSERT_TRUE(extension); 80 file_written_listener.WaitUntilSatisfied(); 81 82 SavedFilesService* saved_files_service = SavedFilesService::Get(profile()); 83 84 std::vector<SavedFileEntry> file_entries = 85 saved_files_service->GetAllFileEntries(extension->id()); 86 // One for the read-only file entry and one for the writable file entry. 87 ASSERT_EQ(2u, file_entries.size()); 88 89 extension_suspended.Wait(); 90 file_entries = saved_files_service->GetAllFileEntries(extension->id()); 91 // File entries should be cleared when the extension is suspended. 92 ASSERT_TRUE(file_entries.empty()); 93 } 94 95 // Flaky: crbug.com/269613 96 #if defined(OS_LINUX) 97 #define MAYBE_FileAccessIsRestored DISABLED_FileAccessIsRestored 98 #else 99 #define MAYBE_FileAccessIsRestored FileAccessIsRestored 100 #endif 101 102 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_FileAccessIsRestored) { 103 content::WindowedNotificationObserver extension_suspended( 104 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 105 content::NotificationService::AllSources()); 106 107 base::ScopedTempDir temp_directory; 108 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); 109 base::FilePath temp_file; 110 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_directory.path(), 111 &temp_file)); 112 113 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( 114 &temp_file); 115 FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest( 116 "temp", temp_directory.path()); 117 118 ExtensionTestMessageListener file_written_listener("fileWritten", false); 119 ExtensionTestMessageListener access_ok_listener( 120 "restartedFileAccessOK", false); 121 122 const Extension* extension = 123 LoadAndLaunchPlatformApp("file_access_restored_test"); 124 ASSERT_TRUE(extension); 125 file_written_listener.WaitUntilSatisfied(); 126 127 ExtensionPrefs* extension_prefs = 128 ExtensionPrefs::Get(browser()->profile()); 129 SavedFilesService* saved_files_service = SavedFilesService::Get(profile()); 130 std::vector<SavedFileEntry> file_entries = 131 saved_files_service->GetAllFileEntries(extension->id()); 132 extension_suspended.Wait(); 133 134 // Simulate a restart by populating the preferences as if the browser didn't 135 // get time to clean itself up. 136 extension_prefs->SetExtensionRunning(extension->id(), true); 137 for (std::vector<SavedFileEntry>::const_iterator it = file_entries.begin(); 138 it != file_entries.end(); ++it) { 139 saved_files_service->RegisterFileEntry( 140 extension->id(), it->id, it->path, it->writable); 141 } 142 143 apps::AppRestoreServiceFactory::GetForProfile(browser()->profile())-> 144 HandleStartup(true); 145 146 access_ok_listener.WaitUntilSatisfied(); 147 } 148 149 } // namespace apps 150