This source file includes following definitions.
- IsNotifierInList
- IsAppInExtensionsInfo
- SetUpCommandLine
- GetTestPath
- InstallEphemeralApp
- InstallEphemeralApp
- InstallAndLaunchEphemeralApp
- LaunchAppAndRunTest
- CloseApp
- EvictApp
- VerifyAppNotLoaded
- DispatchAlarmEvent
- GarbageCollectData
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include "apps/saved_files_service.h"
#include "base/files/scoped_temp_dir.h"
#include "base/stl_util.h"
#include "chrome/browser/apps/app_browsertest_util.h"
#include "chrome/browser/apps/ephemeral_app_service.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
#include "chrome/common/extensions/api/alarms.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/switches.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notifier_settings.h"
using extensions::Event;
using extensions::EventRouter;
using extensions::Extension;
using extensions::ExtensionInfo;
using extensions::ExtensionPrefs;
using extensions::ExtensionSystem;
using extensions::Manifest;
using extensions::PlatformAppBrowserTest;
namespace {
namespace alarms = extensions::api::alarms;
const char kDispatchEventTestApp[] = "ephemeral_apps/dispatch_event";
const char kMessagingReceiverApp[] = "ephemeral_apps/messaging_receiver";
const char kMessagingReceiverAppV2[] = "ephemeral_apps/messaging_receiver2";
const char kNotificationsTestApp[] = "ephemeral_apps/notification_settings";
const char kFileSystemTestApp[] = "ephemeral_apps/filesystem_retain_entries";
const char kRetainDataApp[] = "ephemeral_apps/retain_data";
typedef std::vector<message_center::Notifier*> NotifierList;
bool IsNotifierInList(const message_center::NotifierId& notifier_id,
const NotifierList& notifiers) {
for (NotifierList::const_iterator it = notifiers.begin();
it != notifiers.end(); ++it) {
const message_center::Notifier* notifier = *it;
if (notifier->notifier_id == notifier_id)
return true;
}
return false;
}
bool IsAppInExtensionsInfo(const ExtensionPrefs::ExtensionsInfo& ext_info,
const std::string& extension_id) {
for (size_t i = 0; i < ext_info.size(); ++i) {
ExtensionInfo* info = ext_info.at(i).get();
if (info->extension_id == extension_id)
return true;
}
return false;
}
}
class EphemeralAppBrowserTest : public PlatformAppBrowserTest {
protected:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(
extensions::switches::kEventPageIdleTime, "10");
command_line->AppendSwitchASCII(
extensions::switches::kEventPageSuspendingTime, "10");
}
base::FilePath GetTestPath(const char* test_path) {
return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path);
}
const Extension* InstallEphemeralApp(const char* test_path,
Manifest::Location manifest_location) {
const Extension* extension =
InstallExtensionWithSourceAndFlags(
GetTestPath(test_path),
1,
manifest_location,
Extension::IS_EPHEMERAL);
return extension;
}
const Extension* InstallEphemeralApp(const char* test_path) {
return InstallEphemeralApp(test_path, Manifest::INTERNAL);
}
const Extension* InstallAndLaunchEphemeralApp(const char* test_path) {
ExtensionTestMessageListener launched_listener("launched", false);
const Extension* extension = InstallEphemeralApp(test_path);
EXPECT_TRUE(extension);
if (!extension)
return NULL;
LaunchPlatformApp(extension);
bool wait_result = launched_listener.WaitUntilSatisfied();
EXPECT_TRUE(wait_result);
if (!wait_result)
return NULL;
return extension;
}
bool LaunchAppAndRunTest(const Extension* app, const char* test_name) {
ExtensionTestMessageListener launched_listener("launched", true);
LaunchPlatformApp(app);
if (!launched_listener.WaitUntilSatisfied()) {
message_ = "Failed to receive launched message from test";
return false;
}
launched_listener.Reply(test_name);
ResultCatcher catcher;
if (!catcher.GetNextResult()) {
message_ = catcher.message();
return false;
}
CloseApp(app->id());
return true;
}
void CloseApp(const std::string& app_id) {
content::WindowedNotificationObserver event_page_destroyed_signal(
chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
content::Source<Profile>(browser()->profile()));
EXPECT_EQ(1U, GetAppWindowCountForApp(app_id));
apps::AppWindow* app_window = GetFirstAppWindowForApp(app_id);
ASSERT_TRUE(app_window);
CloseAppWindow(app_window);
event_page_destroyed_signal.Wait();
}
void EvictApp(const std::string& app_id) {
content::WindowedNotificationObserver uninstalled_signal(
chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(browser()->profile()));
ExtensionService* service =
ExtensionSystem::Get(browser()->profile())->extension_service();
ASSERT_TRUE(service);
service->UninstallExtension(app_id, false, NULL);
uninstalled_signal.Wait();
}
void VerifyAppNotLoaded(const std::string& app_id) {
EXPECT_FALSE(ExtensionSystem::Get(browser()->profile())->
process_manager()->GetBackgroundHostForExtension(app_id));
}
void DispatchAlarmEvent(EventRouter* event_router,
const std::string& app_id) {
alarms::Alarm dummy_alarm;
dummy_alarm.name = "test_alarm";
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Append(dummy_alarm.ToValue().release());
scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName,
args.Pass()));
event_router->DispatchEventToExtension(app_id, event.Pass());
}
void GarbageCollectData() {
EphemeralAppService* service =
EphemeralAppService::Get(browser()->profile());
ASSERT_TRUE(service);
service->GarbageCollectData();
}
};
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) {
const Extension* extension =
InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
ASSERT_TRUE(extension);
EventRouter* event_router =
ExtensionSystem::Get(browser()->profile())->event_router();
ASSERT_TRUE(event_router);
ExtensionTestMessageListener alarm_received_listener("alarm_received", false);
DispatchAlarmEvent(event_router, extension->id());
ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied());
CloseApp(extension->id());
ASSERT_TRUE(event_router->ExtensionHasEventListener(
extension->id(), alarms::OnAlarm::kEventName));
DispatchAlarmEvent(event_router, extension->id());
VerifyAppNotLoaded(extension->id());
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReceiveMessagesWhenLaunched) {
const Extension* receiver =
InstallAndLaunchEphemeralApp(kMessagingReceiverApp);
ASSERT_TRUE(receiver);
ExtensionApiTest::ResultCatcher result_catcher;
LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_success");
EXPECT_TRUE(result_catcher.GetNextResult());
CloseApp(receiver->id());
LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_fail");
EXPECT_TRUE(result_catcher.GetNextResult());
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) {
const Extension* app_v1 = InstallEphemeralApp(kMessagingReceiverApp);
ASSERT_TRUE(app_v1);
ASSERT_TRUE(app_v1->is_ephemeral());
std::string app_id = app_v1->id();
base::Version app_original_version = *app_v1->version();
app_v1 = NULL;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
if (!base::DeleteFile(crx_path, false)) {
ADD_FAILURE() << "Failed to delete crx: " << crx_path.value();
return;
}
base::FilePath app_v2_path = PackExtensionWithOptions(
GetTestPath(kMessagingReceiverAppV2),
crx_path,
GetTestPath(kMessagingReceiverApp).ReplaceExtension(
FILE_PATH_LITERAL(".pem")),
base::FilePath());
ASSERT_FALSE(app_v2_path.empty());
extensions::CrxInstaller* crx_installer = NULL;
content::WindowedNotificationObserver windowed_observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::Source<extensions::CrxInstaller>(crx_installer));
ExtensionService* service =
ExtensionSystem::Get(browser()->profile())->extension_service();
EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true, GURL(),
&crx_installer));
windowed_observer.Wait();
const Extension* app_v2 = service->GetExtensionById(app_id, false);
ASSERT_TRUE(app_v2);
EXPECT_TRUE(app_v2->version()->CompareTo(app_original_version) > 0);
EXPECT_TRUE(app_v2->is_ephemeral());
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) {
const Extension* app = InstallEphemeralApp(kNotificationsTestApp);
ASSERT_TRUE(app);
DesktopNotificationService* notification_service =
DesktopNotificationServiceFactory::GetForProfile(browser()->profile());
ASSERT_TRUE(notification_service);
message_center::NotifierId notifier_id(
message_center::NotifierId::APPLICATION, app->id());
EXPECT_TRUE(notification_service->IsNotifierEnabled(notifier_id));
notification_service->SetNotifierEnabled(notifier_id, false);
EXPECT_FALSE(notification_service->IsNotifierEnabled(notifier_id));
EvictApp(app->id());
app = InstallEphemeralApp(kNotificationsTestApp);
ASSERT_TRUE(app);
message_center::NotifierId reinstalled_notifier_id(
message_center::NotifierId::APPLICATION, app->id());
EXPECT_FALSE(notification_service->IsNotifierEnabled(
reinstalled_notifier_id));
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
IncludeRunningEphemeralAppsInNotifiers) {
message_center::NotifierSettingsProvider* settings_provider =
message_center::MessageCenter::Get()->GetNotifierSettingsProvider();
if (!settings_provider)
return;
const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
ASSERT_TRUE(app);
message_center::NotifierId notifier_id(
message_center::NotifierId::APPLICATION, app->id());
NotifierList notifiers;
STLElementDeleter<NotifierList> notifier_deleter(¬ifiers);
settings_provider->GetNotifierList(¬ifiers);
EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers));
STLDeleteElements(¬ifiers);
CloseApp(app->id());
settings_provider->GetNotifierList(¬ifiers);
EXPECT_FALSE(IsNotifierInList(notifier_id, notifiers));
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
DisableRetainFileSystemEntries) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath temp_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
using extensions::FileSystemChooseEntryFunction;
FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
&temp_file);
FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest(
"temp", temp_dir.path());
const Extension* app = InstallEphemeralApp(kFileSystemTestApp,
Manifest::UNPACKED);
ASSERT_TRUE(LaunchAppAndRunTest(app, "OpenAndRetainFile")) << message_;
std::vector<apps::SavedFileEntry> file_entries =
apps::SavedFilesService::Get(browser()->profile())
->GetAllFileEntries(app->id());
EXPECT_TRUE(file_entries.empty());
ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_;
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RetainData) {
const Extension* app = InstallEphemeralApp(kRetainDataApp);
ASSERT_TRUE(app);
ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_;
ASSERT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_;
const std::string app_id = app->id();
EvictApp(app->id());
app = NULL;
ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile());
ASSERT_TRUE(prefs);
scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
prefs->GetEvictedEphemeralAppsInfo());
EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id));
extensions_info = prefs->GetInstalledExtensionsInfo();
EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
GURL site_url = extensions::util::GetSiteForExtensionId(
app_id, browser()->profile());
EXPECT_TRUE(extensions::util::SiteHasIsolatedStorage(
site_url, browser()->profile()));
app = InstallEphemeralApp(kRetainDataApp);
ASSERT_TRUE(app);
EXPECT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_;
extensions_info = prefs->GetInstalledExtensionsInfo();
EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id));
extensions_info = prefs->GetEvictedEphemeralAppsInfo();
EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RemoveInstalledData) {
const Extension* app = InstallPlatformApp(kRetainDataApp);
ASSERT_TRUE(app);
ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_;
const std::string app_id = app->id();
EvictApp(app->id());
app = NULL;
ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile());
ASSERT_TRUE(prefs);
scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
prefs->GetEvictedEphemeralAppsInfo());
EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
extensions_info = prefs->GetInstalledExtensionsInfo();
EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
app = InstallPlatformApp(kRetainDataApp);
ASSERT_TRUE(LaunchAppAndRunTest(app, "DataReset")) << message_;
}
IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, GarbageCollectData) {
const Extension* evict_app = InstallEphemeralApp(kRetainDataApp);
ASSERT_TRUE(evict_app);
ASSERT_TRUE(LaunchAppAndRunTest(evict_app, "WriteData")) << message_;
std::string evict_app_id = evict_app->id();
EvictApp(evict_app_id);
evict_app = NULL;
const Extension* retain_app = InstallEphemeralApp(kDispatchEventTestApp);
ASSERT_TRUE(retain_app);
std::string retain_app_id = retain_app->id();
EvictApp(retain_app_id);
retain_app = NULL;
ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile());
ASSERT_TRUE(prefs);
scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
prefs->GetEvictedEphemeralAppsInfo());
EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id));
EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, evict_app_id));
base::Time launch_time =
base::Time::Now() - base::TimeDelta::FromDays(
EphemeralAppService::kDataInactiveThreshold + 1);
prefs->SetLastLaunchTime(evict_app_id, launch_time);
prefs->SetLastLaunchTime(retain_app_id, base::Time::Now());
GarbageCollectData();
extensions_info = prefs->GetEvictedEphemeralAppsInfo();
EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id));
ASSERT_FALSE(IsAppInExtensionsInfo(*extensions_info, evict_app_id));
evict_app = InstallEphemeralApp(kRetainDataApp);
ASSERT_TRUE(LaunchAppAndRunTest(evict_app, "DataReset")) << message_;
}