| Index: chrome/browser/apps/ephemeral_app_browsertest.cc
 | 
| diff --git a/chrome/browser/apps/ephemeral_app_browsertest.cc b/chrome/browser/apps/ephemeral_app_browsertest.cc
 | 
| deleted file mode 100644
 | 
| index 2204ba60eb96099aa16e5293300518964a823e6e..0000000000000000000000000000000000000000
 | 
| --- a/chrome/browser/apps/ephemeral_app_browsertest.cc
 | 
| +++ /dev/null
 | 
| @@ -1,1051 +0,0 @@
 | 
| -// Copyright 2014 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include "chrome/browser/apps/ephemeral_app_browsertest.h"
 | 
| -
 | 
| -#include <vector>
 | 
| -
 | 
| -#include "apps/app_restore_service.h"
 | 
| -#include "apps/saved_files_service.h"
 | 
| -#include "base/files/scoped_temp_dir.h"
 | 
| -#include "base/scoped_observer.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_sync_data.h"
 | 
| -#include "chrome/browser/extensions/extension_sync_service.h"
 | 
| -#include "chrome/browser/extensions/extension_util.h"
 | 
| -#include "chrome/browser/notifications/notifier_state_tracker.h"
 | 
| -#include "chrome/browser/notifications/notifier_state_tracker_factory.h"
 | 
| -#include "content/public/browser/power_save_blocker.h"
 | 
| -#include "content/public/test/browser_test.h"
 | 
| -#include "content/public/test/test_utils.h"
 | 
| -#include "extensions/browser/api/power/power_api.h"
 | 
| -#include "extensions/browser/app_sorting.h"
 | 
| -#include "extensions/browser/event_router.h"
 | 
| -#include "extensions/browser/extension_prefs.h"
 | 
| -#include "extensions/browser/extension_registry.h"
 | 
| -#include "extensions/browser/extension_registry_observer.h"
 | 
| -#include "extensions/browser/extension_system.h"
 | 
| -#include "extensions/browser/extension_util.h"
 | 
| -#include "extensions/browser/process_manager.h"
 | 
| -#include "extensions/browser/test_extension_registry_observer.h"
 | 
| -#include "extensions/browser/uninstall_reason.h"
 | 
| -#include "extensions/common/api/alarms.h"
 | 
| -#include "extensions/common/extension.h"
 | 
| -#include "extensions/test/extension_test_message_listener.h"
 | 
| -#include "extensions/test/result_catcher.h"
 | 
| -#include "sync/api/fake_sync_change_processor.h"
 | 
| -#include "sync/api/sync_change_processor_wrapper_for_test.h"
 | 
| -#include "sync/api/sync_error_factory_mock.h"
 | 
| -#include "ui/app_list/app_list_switches.h"
 | 
| -#include "ui/message_center/message_center.h"
 | 
| -#include "ui/message_center/notifier_settings.h"
 | 
| -
 | 
| -using extensions::AppSorting;
 | 
| -using extensions::Event;
 | 
| -using extensions::EventRouter;
 | 
| -using extensions::Extension;
 | 
| -using extensions::ExtensionPrefs;
 | 
| -using extensions::ExtensionRegistry;
 | 
| -using extensions::ExtensionRegistryObserver;
 | 
| -using extensions::ExtensionSyncData;
 | 
| -using extensions::ExtensionSystem;
 | 
| -using extensions::Manifest;
 | 
| -using extensions::ResultCatcher;
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -namespace alarms = extensions::api::alarms;
 | 
| -
 | 
| -const char kPowerTestApp[] = "ephemeral_apps/power";
 | 
| -
 | 
| -// Enabling sync causes these tests to be flaky on Windows. Disable sync so that
 | 
| -// everything else can be tested. See crbug.com/401028
 | 
| -#if defined(OS_WIN)
 | 
| -const bool kEnableSync = false;
 | 
| -#else
 | 
| -const bool kEnableSync = true;
 | 
| -#endif
 | 
| -
 | 
| -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;
 | 
| -}
 | 
| -
 | 
| -// Saves some parameters from the extension installed notification in order
 | 
| -// to verify them in tests.
 | 
| -class InstallObserver : public ExtensionRegistryObserver {
 | 
| - public:
 | 
| -  struct InstallParameters {
 | 
| -    std::string id;
 | 
| -    bool is_update;
 | 
| -    bool from_ephemeral;
 | 
| -
 | 
| -    InstallParameters(
 | 
| -        const std::string& id,
 | 
| -        bool is_update,
 | 
| -        bool from_ephemeral)
 | 
| -          : id(id), is_update(is_update), from_ephemeral(from_ephemeral) {}
 | 
| -  };
 | 
| -
 | 
| -  explicit InstallObserver(Profile* profile) : registry_observer_(this) {
 | 
| -    registry_observer_.Add(ExtensionRegistry::Get(profile));
 | 
| -  }
 | 
| -
 | 
| -  ~InstallObserver() override {}
 | 
| -
 | 
| -  const InstallParameters& Last() {
 | 
| -    CHECK(!install_params_.empty());
 | 
| -    return install_params_.back();
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
 | 
| -                                  const Extension* extension,
 | 
| -                                  bool is_update,
 | 
| -                                  bool from_ephemeral,
 | 
| -                                  const std::string& old_name) override {
 | 
| -    install_params_.push_back(
 | 
| -        InstallParameters(extension->id(), is_update, from_ephemeral));
 | 
| -  }
 | 
| -
 | 
| -  std::vector<InstallParameters> install_params_;
 | 
| -  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
 | 
| -      registry_observer_;
 | 
| -};
 | 
| -
 | 
| -// Instead of actually changing the system power settings, tests will just
 | 
| -// issue requests to this mock.
 | 
| -class PowerSettingsMock {
 | 
| - public:
 | 
| -  PowerSettingsMock() : keep_awake_count_(0) {}
 | 
| -
 | 
| -  void request_keep_awake() { ++keep_awake_count_; }
 | 
| -
 | 
| -  void release_keep_awake() {
 | 
| -    --keep_awake_count_;
 | 
| -    ASSERT_GE(keep_awake_count_, 0);
 | 
| -  }
 | 
| -
 | 
| -  int keep_awake_count() const { return keep_awake_count_; }
 | 
| -
 | 
| - private:
 | 
| -  int keep_awake_count_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(PowerSettingsMock);
 | 
| -};
 | 
| -
 | 
| -// Stub implementation of content::PowerSaveBlocker that updates the
 | 
| -// PowerSettingsMock.
 | 
| -class PowerSaveBlockerStub : public content::PowerSaveBlocker {
 | 
| - public:
 | 
| -  explicit PowerSaveBlockerStub(PowerSettingsMock* power_settings)
 | 
| -      : power_settings_(power_settings) {
 | 
| -    power_settings_->request_keep_awake();
 | 
| -  }
 | 
| -
 | 
| -  ~PowerSaveBlockerStub() override { power_settings_->release_keep_awake(); }
 | 
| -
 | 
| -  static scoped_ptr<PowerSaveBlocker> Create(PowerSettingsMock* power_settings,
 | 
| -                                             PowerSaveBlockerType type,
 | 
| -                                             Reason reason,
 | 
| -                                             const std::string& description) {
 | 
| -    return scoped_ptr<PowerSaveBlocker>(
 | 
| -        new PowerSaveBlockerStub(power_settings));
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  PowerSettingsMock* power_settings_;  // Not owned.
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStub);
 | 
| -};
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -
 | 
| -// EphemeralAppTestBase:
 | 
| -
 | 
| -const char EphemeralAppTestBase::kMessagingReceiverApp[] =
 | 
| -    "ephemeral_apps/messaging_receiver";
 | 
| -const char EphemeralAppTestBase::kMessagingReceiverAppV2[] =
 | 
| -    "ephemeral_apps/messaging_receiver2";
 | 
| -const char EphemeralAppTestBase::kDispatchEventTestApp[] =
 | 
| -    "ephemeral_apps/dispatch_event";
 | 
| -const char EphemeralAppTestBase::kNotificationsTestApp[] =
 | 
| -    "ephemeral_apps/notification_settings";
 | 
| -const char EphemeralAppTestBase::kFileSystemTestApp[] =
 | 
| -    "ephemeral_apps/filesystem_retain_entries";
 | 
| -
 | 
| -EphemeralAppTestBase::EphemeralAppTestBase() {}
 | 
| -
 | 
| -EphemeralAppTestBase::~EphemeralAppTestBase() {}
 | 
| -
 | 
| -void EphemeralAppTestBase::SetUpCommandLine(base::CommandLine* command_line) {
 | 
| -  // Skip PlatformAppBrowserTest, which sets different values for the switches
 | 
| -  // below.
 | 
| -  ExtensionBrowserTest::SetUpCommandLine(command_line);
 | 
| -
 | 
| -  // Make event pages get suspended immediately.
 | 
| -  extensions::ProcessManager::SetEventPageIdleTimeForTesting(1);
 | 
| -  extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(1);
 | 
| -
 | 
| -  // Enable ephemeral apps, which are gated by the experimental app launcher
 | 
| -  // flag.
 | 
| -  command_line->AppendSwitch(app_list::switches::kEnableExperimentalAppList);
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::SetUpOnMainThread() {
 | 
| -  PlatformAppBrowserTest::SetUpOnMainThread();
 | 
| -
 | 
| -  // Disable ephemeral apps immediately after they stop running in tests.
 | 
| -  EphemeralAppService::Get(profile())->set_disable_delay_for_test(0);
 | 
| -}
 | 
| -
 | 
| -base::FilePath EphemeralAppTestBase::GetTestPath(const char* test_path) {
 | 
| -  return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path);
 | 
| -}
 | 
| -
 | 
| -const Extension* EphemeralAppTestBase::InstallEphemeralApp(
 | 
| -    const char* test_path, Manifest::Location manifest_location) {
 | 
| -  const Extension* extension = InstallEphemeralAppWithSourceAndFlags(
 | 
| -      GetTestPath(test_path), 1, manifest_location, Extension::NO_FLAGS);
 | 
| -  EXPECT_TRUE(extension);
 | 
| -  if (extension)
 | 
| -    EXPECT_TRUE(extensions::util::IsEphemeralApp(extension->id(), profile()));
 | 
| -  return extension;
 | 
| -}
 | 
| -
 | 
| -const Extension* EphemeralAppTestBase::InstallEphemeralApp(
 | 
| -    const char* test_path) {
 | 
| -  return InstallEphemeralApp(test_path, Manifest::INTERNAL);
 | 
| -}
 | 
| -
 | 
| -const Extension* EphemeralAppTestBase::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;
 | 
| -}
 | 
| -
 | 
| -const Extension* EphemeralAppTestBase::UpdateEphemeralApp(
 | 
| -    const std::string& app_id,
 | 
| -    const base::FilePath& test_dir,
 | 
| -    const base::FilePath& pem_path) {
 | 
| -  // Pack a new version of the app.
 | 
| -  base::ScopedTempDir temp_dir;
 | 
| -  EXPECT_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 existing crx: " << crx_path.value();
 | 
| -    return NULL;
 | 
| -  }
 | 
| -
 | 
| -  base::FilePath app_v2_path = PackExtensionWithOptions(
 | 
| -      test_dir, crx_path, pem_path, base::FilePath());
 | 
| -  EXPECT_FALSE(app_v2_path.empty());
 | 
| -
 | 
| -  // Update the ephemeral app and wait for the update to finish.
 | 
| -  extensions::CrxInstaller* crx_installer = NULL;
 | 
| -  content::WindowedNotificationObserver windowed_observer(
 | 
| -      extensions::NOTIFICATION_CRX_INSTALLER_DONE,
 | 
| -      content::Source<extensions::CrxInstaller>(crx_installer));
 | 
| -  ExtensionService* service =
 | 
| -      ExtensionSystem::Get(profile())->extension_service();
 | 
| -  EXPECT_TRUE(service->UpdateExtension(
 | 
| -      extensions::CRXFileInfo(app_id, app_v2_path), true, &crx_installer));
 | 
| -  windowed_observer.Wait();
 | 
| -
 | 
| -  return ExtensionRegistry::Get(profile())
 | 
| -      ->GetExtensionById(app_id, ExtensionRegistry::EVERYTHING);
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::PromoteEphemeralApp(
 | 
| -    const extensions::Extension* app) {
 | 
| -  ExtensionService* extension_service =
 | 
| -      ExtensionSystem::Get(profile())->extension_service();
 | 
| -  ASSERT_TRUE(extension_service);
 | 
| -  extension_service->PromoteEphemeralApp(app, false);
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::DisableEphemeralApp(
 | 
| -    const Extension* app,
 | 
| -    Extension::DisableReason disable_reason) {
 | 
| -  ExtensionSystem::Get(profile())->extension_service()->DisableExtension(
 | 
| -      app->id(), disable_reason);
 | 
| -
 | 
| -  ASSERT_TRUE(ExtensionRegistry::Get(profile())->disabled_extensions().Contains(
 | 
| -      app->id()));
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::CloseApp(const std::string& app_id) {
 | 
| -  EXPECT_EQ(1U, GetAppWindowCountForApp(app_id));
 | 
| -  extensions::AppWindow* app_window = GetFirstAppWindowForApp(app_id);
 | 
| -  ASSERT_TRUE(app_window);
 | 
| -  CloseAppWindow(app_window);
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::CloseAppWaitForUnload(const std::string& app_id) {
 | 
| -  // Ephemeral apps are unloaded from extension system after they stop running.
 | 
| -  extensions::TestExtensionRegistryObserver observer(
 | 
| -      ExtensionRegistry::Get(profile()), app_id);
 | 
| -  CloseApp(app_id);
 | 
| -  observer.WaitForExtensionUnloaded();
 | 
| -}
 | 
| -
 | 
| -void EphemeralAppTestBase::EvictApp(const std::string& app_id) {
 | 
| -  // Uninstall the app, which is what happens when ephemeral apps get evicted
 | 
| -  // from the cache.
 | 
| -  extensions::TestExtensionRegistryObserver observer(
 | 
| -      ExtensionRegistry::Get(profile()), app_id);
 | 
| -
 | 
| -  ExtensionService* service =
 | 
| -      ExtensionSystem::Get(profile())->extension_service();
 | 
| -  ASSERT_TRUE(service);
 | 
| -  service->UninstallExtension(
 | 
| -      app_id,
 | 
| -      extensions::UNINSTALL_REASON_ORPHANED_EPHEMERAL_EXTENSION,
 | 
| -      base::Bind(&base::DoNothing),
 | 
| -      NULL);
 | 
| -
 | 
| -  observer.WaitForExtensionUninstalled();
 | 
| -}
 | 
| -
 | 
| -// EphemeralAppBrowserTest:
 | 
| -
 | 
| -class EphemeralAppBrowserTest : public EphemeralAppTestBase {
 | 
| - protected:
 | 
| -  bool LaunchAppAndRunTest(const Extension* app, const char* test_name) {
 | 
| -    // Ephemeral apps are unloaded after they are closed. Ensure they are
 | 
| -    // enabled before launch.
 | 
| -    ExtensionService* service =
 | 
| -        ExtensionSystem::Get(profile())->extension_service();
 | 
| -    service->EnableExtension(app->id());
 | 
| -
 | 
| -    ExtensionTestMessageListener launched_listener("launched", true);
 | 
| -    LaunchPlatformApp(app);
 | 
| -    if (!launched_listener.WaitUntilSatisfied()) {
 | 
| -      message_ = "Failed to receive launched message from test";
 | 
| -      return false;
 | 
| -    }
 | 
| -
 | 
| -    ResultCatcher catcher;
 | 
| -    launched_listener.Reply(test_name);
 | 
| -
 | 
| -    bool result = catcher.GetNextResult();
 | 
| -    message_ = catcher.message();
 | 
| -
 | 
| -    CloseAppWaitForUnload(app->id());
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  // Verify that the event page of the app has not been loaded.
 | 
| -  void VerifyAppNotLoaded(const std::string& app_id) {
 | 
| -    EXPECT_FALSE(extensions::ProcessManager::Get(profile())
 | 
| -                     ->GetBackgroundHostForExtension(app_id));
 | 
| -  }
 | 
| -
 | 
| -  // Verify properties of ephemeral apps.
 | 
| -  void VerifyEphemeralApp(const std::string& app_id) {
 | 
| -    EXPECT_TRUE(extensions::util::IsEphemeralApp(app_id, profile()));
 | 
| -
 | 
| -    // Ephemeral apps should not be synced.
 | 
| -    scoped_ptr<ExtensionSyncData> sync_change = GetLastSyncChangeForApp(app_id);
 | 
| -    EXPECT_FALSE(sync_change.get());
 | 
| -
 | 
| -    // Ephemeral apps should not be assigned ordinals.
 | 
| -    AppSorting* app_sorting = ExtensionSystem::Get(profile())->app_sorting();
 | 
| -    EXPECT_FALSE(app_sorting->GetAppLaunchOrdinal(app_id).IsValid());
 | 
| -    EXPECT_FALSE(app_sorting->GetPageOrdinal(app_id).IsValid());
 | 
| -  }
 | 
| -
 | 
| -  // Verify that after ephemeral apps stop running, they reside in extension
 | 
| -  // system in a disabled and unloaded state.
 | 
| -  void VerifyInactiveEphemeralApp(const std::string& app_id) {
 | 
| -    EXPECT_TRUE(
 | 
| -        ExtensionRegistry::Get(profile())->disabled_extensions().Contains(
 | 
| -            app_id));
 | 
| -
 | 
| -    ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
 | 
| -    EXPECT_TRUE(prefs->IsExtensionDisabled(app_id));
 | 
| -    EXPECT_NE(0,
 | 
| -              prefs->GetDisableReasons(app_id) &
 | 
| -                  Extension::DISABLE_INACTIVE_EPHEMERAL_APP);
 | 
| -  }
 | 
| -
 | 
| -  // Verify the state of an app that has been promoted from an ephemeral to a
 | 
| -  // fully installed app.
 | 
| -  void VerifyPromotedApp(const std::string& app_id,
 | 
| -                         ExtensionRegistry::IncludeFlag expected_set) {
 | 
| -    const Extension* app = ExtensionRegistry::Get(profile())
 | 
| -                               ->GetExtensionById(app_id, expected_set);
 | 
| -    ASSERT_TRUE(app) << "App not found in expected set: " << expected_set;
 | 
| -
 | 
| -    // The app should not be ephemeral.
 | 
| -    ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
 | 
| -    ASSERT_TRUE(prefs);
 | 
| -    EXPECT_FALSE(prefs->IsEphemeralApp(app_id));
 | 
| -    EXPECT_EQ(0,
 | 
| -              prefs->GetDisableReasons(app_id) &
 | 
| -                  Extension::DISABLE_INACTIVE_EPHEMERAL_APP);
 | 
| -
 | 
| -    // Check sort ordinals.
 | 
| -    AppSorting* app_sorting = ExtensionSystem::Get(profile())->app_sorting();
 | 
| -    EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).IsValid());
 | 
| -    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).IsValid());
 | 
| -  }
 | 
| -
 | 
| -  // Dispatch a fake alarm event to the app.
 | 
| -  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(extensions::events::ALARMS_ON_ALARM,
 | 
| -                                      alarms::OnAlarm::kEventName,
 | 
| -                                      args.Pass()));
 | 
| -
 | 
| -    event_router->DispatchEventToExtension(app_id, event.Pass());
 | 
| -  }
 | 
| -
 | 
| -  // Simulates the scenario where an app is installed, via the normal
 | 
| -  // installation route, on top of an ephemeral app. This can occur due to race
 | 
| -  // conditions.
 | 
| -  const Extension* ReplaceEphemeralApp(const std::string& app_id,
 | 
| -                                       const char* test_path,
 | 
| -                                       int expected_enabled_change) {
 | 
| -    return UpdateExtensionWaitForIdle(
 | 
| -        app_id, GetTestPath(test_path), expected_enabled_change);
 | 
| -  }
 | 
| -
 | 
| -  void PromoteEphemeralAppAndVerify(
 | 
| -      const Extension* app,
 | 
| -      ExtensionRegistry::IncludeFlag expected_set,
 | 
| -      bool expect_sync_enabled) {
 | 
| -    ASSERT_TRUE(app);
 | 
| -
 | 
| -    // Ephemeral apps should not be synced.
 | 
| -    scoped_ptr<ExtensionSyncData> sync_change =
 | 
| -        GetLastSyncChangeForApp(app->id());
 | 
| -    EXPECT_FALSE(sync_change.get());
 | 
| -
 | 
| -    // Promote the app to a regular installed app.
 | 
| -    InstallObserver installed_observer(profile());
 | 
| -    PromoteEphemeralApp(app);
 | 
| -    VerifyPromotedApp(app->id(), expected_set);
 | 
| -
 | 
| -    // Check the notification parameters.
 | 
| -    const InstallObserver::InstallParameters& params =
 | 
| -        installed_observer.Last();
 | 
| -    EXPECT_EQ(app->id(), params.id);
 | 
| -    EXPECT_TRUE(params.is_update);
 | 
| -    EXPECT_TRUE(params.from_ephemeral);
 | 
| -
 | 
| -    // The installation should now be synced.
 | 
| -    sync_change = GetLastSyncChangeForApp(app->id());
 | 
| -    VerifySyncChange(sync_change.get(), expect_sync_enabled);
 | 
| -  }
 | 
| -
 | 
| -  void PromoteEphemeralAppAndVerify(
 | 
| -      const Extension* app,
 | 
| -      ExtensionRegistry::IncludeFlag expected_set) {
 | 
| -    PromoteEphemeralAppAndVerify(app, expected_set,
 | 
| -                                 expected_set == ExtensionRegistry::ENABLED);
 | 
| -  }
 | 
| -
 | 
| -  void PromoteEphemeralAppFromSyncAndVerify(
 | 
| -      const Extension* app,
 | 
| -      bool enable_from_sync,
 | 
| -      ExtensionRegistry::IncludeFlag expected_set) {
 | 
| -    ASSERT_TRUE(app);
 | 
| -
 | 
| -    // Simulate an install from sync.
 | 
| -    int disable_reasons = enable_from_sync ? 0 : Extension::DISABLE_USER_ACTION;
 | 
| -    const syncer::StringOrdinal kAppLaunchOrdinal("x");
 | 
| -    const syncer::StringOrdinal kPageOrdinal("y");
 | 
| -    ExtensionSyncData app_sync_data(
 | 
| -        *app,
 | 
| -        enable_from_sync,
 | 
| -        disable_reasons,
 | 
| -        false /* incognito enabled */,
 | 
| -        false /* remote install */,
 | 
| -        extensions::ExtensionSyncData::BOOLEAN_UNSET,
 | 
| -        kAppLaunchOrdinal,
 | 
| -        kPageOrdinal,
 | 
| -        extensions::LAUNCH_TYPE_REGULAR);
 | 
| -
 | 
| -    std::string app_id = app->id();
 | 
| -    app = NULL;
 | 
| -
 | 
| -    ExtensionSyncService::Get(profile())->ProcessSyncChanges(
 | 
| -        FROM_HERE,
 | 
| -        syncer::SyncChangeList(
 | 
| -            1, app_sync_data.GetSyncChange(syncer::SyncChange::ACTION_ADD)));
 | 
| -
 | 
| -    // Verify the installation.
 | 
| -    VerifyPromotedApp(app_id, expected_set);
 | 
| -
 | 
| -    // The sort ordinals from sync should not be overridden.
 | 
| -    AppSorting* app_sorting = ExtensionSystem::Get(profile())->app_sorting();
 | 
| -    EXPECT_TRUE(
 | 
| -        app_sorting->GetAppLaunchOrdinal(app_id).Equals(kAppLaunchOrdinal));
 | 
| -    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).Equals(kPageOrdinal));
 | 
| -  }
 | 
| -
 | 
| -  void InitSyncService() {
 | 
| -    if (!kEnableSync)
 | 
| -      return;
 | 
| -
 | 
| -    ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile());
 | 
| -    sync_service->MergeDataAndStartSyncing(
 | 
| -        syncer::APPS,
 | 
| -        syncer::SyncDataList(),
 | 
| -        scoped_ptr<syncer::SyncChangeProcessor>(
 | 
| -            new syncer::SyncChangeProcessorWrapperForTest(
 | 
| -                &mock_sync_processor_)),
 | 
| -        scoped_ptr<syncer::SyncErrorFactory>(
 | 
| -            new syncer::SyncErrorFactoryMock()));
 | 
| -  }
 | 
| -
 | 
| -  scoped_ptr<ExtensionSyncData> GetLastSyncChangeForApp(const std::string& id) {
 | 
| -    scoped_ptr<ExtensionSyncData> sync_data;
 | 
| -    for (syncer::SyncChangeList::iterator it =
 | 
| -             mock_sync_processor_.changes().begin();
 | 
| -         it != mock_sync_processor_.changes().end(); ++it) {
 | 
| -      scoped_ptr<ExtensionSyncData> data(
 | 
| -          ExtensionSyncData::CreateFromSyncChange(*it));
 | 
| -      if (data.get() && data->id() == id)
 | 
| -        sync_data.reset(data.release());
 | 
| -    }
 | 
| -
 | 
| -    return sync_data.Pass();
 | 
| -  }
 | 
| -
 | 
| -  void VerifySyncChange(const ExtensionSyncData* sync_change,
 | 
| -                        bool expect_enabled) {
 | 
| -    if (!kEnableSync)
 | 
| -      return;
 | 
| -
 | 
| -    ASSERT_TRUE(sync_change);
 | 
| -    EXPECT_TRUE(sync_change->page_ordinal().IsValid());
 | 
| -    EXPECT_TRUE(sync_change->app_launch_ordinal().IsValid());
 | 
| -    EXPECT_FALSE(sync_change->uninstalled());
 | 
| -    EXPECT_EQ(expect_enabled, sync_change->enabled());
 | 
| -  }
 | 
| -
 | 
| -  void TestInstallEvent(bool close_app) {
 | 
| -    ExtensionTestMessageListener first_msg_listener(false);
 | 
| -    const Extension* app = InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
 | 
| -    ASSERT_TRUE(app);
 | 
| -
 | 
| -    // When an ephemeral app is first added, it should not receive the
 | 
| -    // onInstalled event, hence the first message received from the test should
 | 
| -    // be "launched" and not "installed".
 | 
| -    ASSERT_TRUE(first_msg_listener.WaitUntilSatisfied());
 | 
| -    EXPECT_EQ(std::string("launched"), first_msg_listener.message());
 | 
| -
 | 
| -    if (close_app)
 | 
| -      CloseAppWaitForUnload(app->id());
 | 
| -
 | 
| -    // When installed permanently, the app should receive the onInstalled event.
 | 
| -    ExtensionTestMessageListener install_listener("installed", false);
 | 
| -    PromoteEphemeralApp(app);
 | 
| -    ASSERT_TRUE(install_listener.WaitUntilSatisfied());
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  syncer::FakeSyncChangeProcessor mock_sync_processor_;
 | 
| -};
 | 
| -
 | 
| -// Verify that ephemeral apps can be launched and receive system events when
 | 
| -// they are running. Once they are inactive they should not receive system
 | 
| -// events.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) {
 | 
| -  const Extension* extension =
 | 
| -      InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
 | 
| -  ASSERT_TRUE(extension);
 | 
| -
 | 
| -  // Send a fake alarm event to the app and verify that a response is
 | 
| -  // received.
 | 
| -  EventRouter* event_router = EventRouter::Get(profile());
 | 
| -  ASSERT_TRUE(event_router);
 | 
| -
 | 
| -  ExtensionTestMessageListener alarm_received_listener("alarm_received", false);
 | 
| -  DispatchAlarmEvent(event_router, extension->id());
 | 
| -  ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied());
 | 
| -
 | 
| -  CloseAppWaitForUnload(extension->id());
 | 
| -
 | 
| -  // Dispatch the alarm event again and verify that the event page did not get
 | 
| -  // loaded for the app.
 | 
| -  DispatchAlarmEvent(event_router, extension->id());
 | 
| -  VerifyAppNotLoaded(extension->id());
 | 
| -}
 | 
| -
 | 
| -// Verify that ephemeral apps will receive messages while they are running.
 | 
| -// Flaky test: crbug.com/394426
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       DISABLED_ReceiveMessagesWhenLaunched) {
 | 
| -  const Extension* receiver =
 | 
| -      InstallAndLaunchEphemeralApp(kMessagingReceiverApp);
 | 
| -  ASSERT_TRUE(receiver);
 | 
| -
 | 
| -  // Verify that messages are received while the app is running.
 | 
| -  ResultCatcher result_catcher;
 | 
| -  LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_success",
 | 
| -                           "Launched");
 | 
| -  EXPECT_TRUE(result_catcher.GetNextResult());
 | 
| -
 | 
| -  CloseAppWaitForUnload(receiver->id());
 | 
| -
 | 
| -  // Verify that messages are not received while the app is inactive.
 | 
| -  LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_fail", "Launched");
 | 
| -  EXPECT_TRUE(result_catcher.GetNextResult());
 | 
| -}
 | 
| -
 | 
| -// Verifies that the chrome.runtime.onInstalled() event is received by a running
 | 
| -// ephemeral app only when it is promoted.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       InstallEventReceivedWhileRunning) {
 | 
| -  TestInstallEvent(false /* close app */);
 | 
| -}
 | 
| -
 | 
| -// Verifies that when an idle ephemeral app is promoted, it will be loaded to
 | 
| -// receive the chrome.runtime.onInstalled() event.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, InstallEventReceivedWhileIdle) {
 | 
| -  TestInstallEvent(true /* close app */);
 | 
| -}
 | 
| -
 | 
| -// Verifies that the chrome.runtime.onRestarted() event is received by an
 | 
| -// ephemeral app.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RestartEventReceived) {
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -
 | 
| -  // Fake ephemeral app running before restart.
 | 
| -  ExtensionSystem::Get(profile())->extension_service()->EnableExtension(
 | 
| -      app->id());
 | 
| -  ASSERT_TRUE(ExtensionRegistry::Get(profile())->enabled_extensions().Contains(
 | 
| -      app->id()));
 | 
| -  ExtensionPrefs::Get(profile())->SetExtensionRunning(app->id(), true);
 | 
| -
 | 
| -  ExtensionTestMessageListener restart_listener("restarted", false);
 | 
| -  apps::AppRestoreService::Get(profile())->HandleStartup(true);
 | 
| -  EXPECT_TRUE(restart_listener.WaitUntilSatisfied());
 | 
| -}
 | 
| -
 | 
| -// Verify that an updated ephemeral app will still have its ephemeral flag
 | 
| -// enabled.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app_v1 = InstallAndLaunchEphemeralApp(kMessagingReceiverApp);
 | 
| -  ASSERT_TRUE(app_v1);
 | 
| -  VerifyEphemeralApp(app_v1->id());
 | 
| -  CloseAppWaitForUnload(app_v1->id());
 | 
| -  VerifyInactiveEphemeralApp(app_v1->id());
 | 
| -
 | 
| -  std::string app_id = app_v1->id();
 | 
| -  base::Version app_original_version = *app_v1->version();
 | 
| -
 | 
| -  // Update to version 2 of the app.
 | 
| -  app_v1 = NULL;  // The extension object will be destroyed during update.
 | 
| -  InstallObserver installed_observer(profile());
 | 
| -  const Extension* app_v2 =
 | 
| -      UpdateEphemeralApp(app_id,
 | 
| -                         GetTestPath(kMessagingReceiverAppV2),
 | 
| -                         GetTestPath(kMessagingReceiverApp)
 | 
| -                             .ReplaceExtension(FILE_PATH_LITERAL(".pem")));
 | 
| -
 | 
| -  // Check the notification parameters.
 | 
| -  const InstallObserver::InstallParameters& params = installed_observer.Last();
 | 
| -  EXPECT_EQ(app_id, params.id);
 | 
| -  EXPECT_TRUE(params.is_update);
 | 
| -  EXPECT_FALSE(params.from_ephemeral);
 | 
| -
 | 
| -  // The ephemeral flag should still be set.
 | 
| -  ASSERT_TRUE(app_v2);
 | 
| -  EXPECT_GT(app_v2->version()->CompareTo(app_original_version), 0);
 | 
| -  VerifyEphemeralApp(app_id);
 | 
| -
 | 
| -  // The app should still be disabled in extension system.
 | 
| -  VerifyInactiveEphemeralApp(app_id);
 | 
| -}
 | 
| -
 | 
| -// Verify that if notifications have been disabled for an ephemeral app, it will
 | 
| -// remain disabled even after being evicted from the cache.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) {
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -
 | 
| -  // Disable notifications for this app.
 | 
| -  NotifierStateTracker* notifier_state_tracker =
 | 
| -      NotifierStateTrackerFactory::GetForProfile(profile());
 | 
| -  ASSERT_TRUE(notifier_state_tracker);
 | 
| -
 | 
| -  message_center::NotifierId notifier_id(
 | 
| -      message_center::NotifierId::APPLICATION, app->id());
 | 
| -  EXPECT_TRUE(notifier_state_tracker->IsNotifierEnabled(notifier_id));
 | 
| -  notifier_state_tracker->SetNotifierEnabled(notifier_id, false);
 | 
| -  EXPECT_FALSE(notifier_state_tracker->IsNotifierEnabled(notifier_id));
 | 
| -
 | 
| -  // Remove the app.
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  EvictApp(app->id());
 | 
| -
 | 
| -  // Reinstall the ephemeral app and verify that notifications remain disabled.
 | 
| -  app = InstallEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  message_center::NotifierId reinstalled_notifier_id(
 | 
| -      message_center::NotifierId::APPLICATION, app->id());
 | 
| -  EXPECT_FALSE(notifier_state_tracker->IsNotifierEnabled(
 | 
| -      reinstalled_notifier_id));
 | 
| -}
 | 
| -
 | 
| -// Verify that only running ephemeral apps will appear in the Notification
 | 
| -// Settings UI. Inactive, cached ephemeral apps should not appear.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       IncludeRunningEphemeralAppsInNotifiers) {
 | 
| -  message_center::NotifierSettingsProvider* settings_provider =
 | 
| -      message_center::MessageCenter::Get()->GetNotifierSettingsProvider();
 | 
| -  DCHECK(settings_provider);
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  message_center::NotifierId notifier_id(
 | 
| -      message_center::NotifierId::APPLICATION, app->id());
 | 
| -
 | 
| -  // Since the ephemeral app is running, it should be included in the list
 | 
| -  // of notifiers to show in the UI.
 | 
| -  NotifierList notifiers;
 | 
| -  STLElementDeleter<NotifierList> notifier_deleter(¬ifiers);
 | 
| -
 | 
| -  settings_provider->GetNotifierList(¬ifiers);
 | 
| -  EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers));
 | 
| -  STLDeleteElements(¬ifiers);
 | 
| -
 | 
| -  // Close the ephemeral app.
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -
 | 
| -  // Inactive ephemeral apps should not be included in the list of notifiers to
 | 
| -  // show in the UI.
 | 
| -  settings_provider->GetNotifierList(¬ifiers);
 | 
| -  EXPECT_FALSE(IsNotifierInList(notifier_id, notifiers));
 | 
| -}
 | 
| -
 | 
| -// Verify that ephemeral apps will have no ability to retain file entries after
 | 
| -// close. Normal retainEntry behavior for installed apps is tested in
 | 
| -// FileSystemApiTest.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       DisableRetainFileSystemEntries) {
 | 
| -  // Create a dummy file that we can just return to the test.
 | 
| -  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);
 | 
| -  // The temporary file needs to be registered for the tests to pass on
 | 
| -  // ChromeOS.
 | 
| -  FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest(
 | 
| -      "temp", temp_dir.path());
 | 
| -
 | 
| -  // The first test opens the file and writes the file handle to local storage.
 | 
| -  const Extension* app = InstallEphemeralApp(kFileSystemTestApp,
 | 
| -                                             Manifest::UNPACKED);
 | 
| -  ASSERT_TRUE(LaunchAppAndRunTest(app, "OpenAndRetainFile")) << message_;
 | 
| -
 | 
| -  // Verify that after the app has been closed, all retained entries are
 | 
| -  // flushed.
 | 
| -  std::vector<apps::SavedFileEntry> file_entries =
 | 
| -      apps::SavedFilesService::Get(profile())
 | 
| -          ->GetAllFileEntries(app->id());
 | 
| -  EXPECT_TRUE(file_entries.empty());
 | 
| -
 | 
| -  // The second test verifies that the file cannot be reopened.
 | 
| -  ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_;
 | 
| -}
 | 
| -
 | 
| -// Checks the process of launching an ephemeral app and then promoting the app
 | 
| -// while it is running.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppWhileRunning) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -
 | 
| -  PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED);
 | 
| -
 | 
| -  // Ensure that the app is not unloaded and disabled after it is closed.
 | 
| -  CloseApp(app->id());
 | 
| -  VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED);
 | 
| -}
 | 
| -
 | 
| -// Checks the process of launching an ephemeral app and then promoting the app
 | 
| -// while it is idle.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppWhileIdle) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  VerifyInactiveEphemeralApp(app->id());
 | 
| -
 | 
| -  PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED);
 | 
| -}
 | 
| -
 | 
| -// Verifies that promoting an ephemeral app that was disabled due to a
 | 
| -// permissions increase will enable it.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppAndGrantPermissions) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  DisableEphemeralApp(app, Extension::DISABLE_PERMISSIONS_INCREASE);
 | 
| -
 | 
| -  PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED);
 | 
| -  EXPECT_FALSE(ExtensionPrefs::Get(profile())
 | 
| -                   ->DidExtensionEscalatePermissions(app->id()));
 | 
| -}
 | 
| -
 | 
| -// Verifies that promoting an ephemeral app that has unsupported requirements
 | 
| -// will not enable it.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       PromoteUnsupportedEphemeralApp) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  DisableEphemeralApp(app, Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
 | 
| -
 | 
| -  // When promoted to a regular installed app, it should remain disabled.
 | 
| -  // However, DISABLE_UNSUPPORTED_REQUIREMENT is not a syncable disable reason,
 | 
| -  // so sync should still say "enabled".
 | 
| -  bool expect_sync_enabled = true;
 | 
| -  PromoteEphemeralAppAndVerify(app, ExtensionRegistry::DISABLED,
 | 
| -                               expect_sync_enabled);
 | 
| -}
 | 
| -
 | 
| -// Verifies that promoting an ephemeral app that is blacklisted will not enable
 | 
| -// it.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       PromoteBlacklistedEphemeralApp) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -
 | 
| -  ExtensionService* service =
 | 
| -      ExtensionSystem::Get(profile())->extension_service();
 | 
| -  service->BlacklistExtensionForTest(app->id());
 | 
| -  ASSERT_TRUE(
 | 
| -      ExtensionRegistry::Get(profile())->blacklisted_extensions().Contains(
 | 
| -          app->id()));
 | 
| -
 | 
| -  // When promoted to a regular installed app, it should remain blacklisted.
 | 
| -  PromoteEphemeralAppAndVerify(app, ExtensionRegistry::BLACKLISTED);
 | 
| -
 | 
| -  // The app should be synced, but disabled.
 | 
| -  scoped_ptr<ExtensionSyncData> sync_change =
 | 
| -      GetLastSyncChangeForApp(app->id());
 | 
| -  VerifySyncChange(sync_change.get(), false);
 | 
| -}
 | 
| -
 | 
| -// Checks the process of promoting an ephemeral app from sync while the app is
 | 
| -// running.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       PromoteAppFromSyncWhileRunning) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -
 | 
| -  PromoteEphemeralAppFromSyncAndVerify(app, true, ExtensionRegistry::ENABLED);
 | 
| -
 | 
| -  // Ensure that the app is not unloaded and disabled after it is closed.
 | 
| -  CloseApp(app->id());
 | 
| -  VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED);
 | 
| -}
 | 
| -
 | 
| -// Checks the process of promoting an ephemeral app from sync while the app is
 | 
| -// idle.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppFromSyncWhileIdle) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  VerifyInactiveEphemeralApp(app->id());
 | 
| -
 | 
| -  PromoteEphemeralAppFromSyncAndVerify(app, true, ExtensionRegistry::ENABLED);
 | 
| -}
 | 
| -
 | 
| -// Checks the process of promoting an ephemeral app from sync, where the app
 | 
| -// from sync is disabled, and the ephemeral app is running.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       PromoteDisabledAppFromSyncWhileRunning) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -
 | 
| -  PromoteEphemeralAppFromSyncAndVerify(app, false, ExtensionRegistry::DISABLED);
 | 
| -}
 | 
| -
 | 
| -// Checks the process of promoting an ephemeral app from sync, where the app
 | 
| -// from sync is disabled, and the ephemeral app is idle.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       PromoteDisabledAppFromSyncWhileIdle) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  VerifyInactiveEphemeralApp(app->id());
 | 
| -
 | 
| -  PromoteEphemeralAppFromSyncAndVerify(app, false, ExtensionRegistry::DISABLED);
 | 
| -}
 | 
| -
 | 
| -// In most cases, ExtensionService::PromoteEphemeralApp() will be called to
 | 
| -// permanently install an ephemeral app. However, there may be cases where an
 | 
| -// install occurs through the usual route of installing from the Web Store (due
 | 
| -// to race conditions). Ensure that the app is still installed correctly.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       ReplaceEphemeralAppWithInstalledApp) {
 | 
| -  InitSyncService();
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -  std::string app_id = app->id();
 | 
| -  app = NULL;
 | 
| -
 | 
| -  InstallObserver installed_observer(profile());
 | 
| -  ReplaceEphemeralApp(app_id, kNotificationsTestApp, 1);
 | 
| -  VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED);
 | 
| -
 | 
| -  // Check the notification parameters.
 | 
| -  const InstallObserver::InstallParameters& params = installed_observer.Last();
 | 
| -  EXPECT_EQ(app_id, params.id);
 | 
| -  EXPECT_TRUE(params.is_update);
 | 
| -  EXPECT_TRUE(params.from_ephemeral);
 | 
| -}
 | 
| -
 | 
| -// This is similar to ReplaceEphemeralAppWithInstalledApp, but installs will
 | 
| -// be delayed until the app is idle.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       ReplaceEphemeralAppWithDelayedInstalledApp) {
 | 
| -  InitSyncService();
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  std::string app_id = app->id();
 | 
| -  app = NULL;
 | 
| -
 | 
| -  // Initiate install.
 | 
| -  ReplaceEphemeralApp(app_id, kNotificationsTestApp, 0);
 | 
| -
 | 
| -  // The delayed installation will occur when the ephemeral app is closed.
 | 
| -  extensions::TestExtensionRegistryObserver observer(
 | 
| -      ExtensionRegistry::Get(profile()), app_id);
 | 
| -  InstallObserver installed_observer(profile());
 | 
| -  CloseAppWaitForUnload(app_id);
 | 
| -  observer.WaitForExtensionWillBeInstalled();
 | 
| -  VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED);
 | 
| -
 | 
| -  // Check the notification parameters.
 | 
| -  const InstallObserver::InstallParameters& params = installed_observer.Last();
 | 
| -  EXPECT_EQ(app_id, params.id);
 | 
| -  EXPECT_TRUE(params.is_update);
 | 
| -  EXPECT_TRUE(params.from_ephemeral);
 | 
| -}
 | 
| -
 | 
| -// Verifies that an installed app cannot turn into an ephemeral app as result of
 | 
| -// race conditions, i.e. an ephemeral app can be promoted to an installed app,
 | 
| -// but not vice versa.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       ReplaceInstalledAppWithEphemeralApp) {
 | 
| -  const Extension* app = InstallPlatformApp(kNotificationsTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  std::string app_id = app->id();
 | 
| -  app = NULL;
 | 
| -
 | 
| -  EXPECT_FALSE(extensions::util::IsEphemeralApp(app_id, profile()));
 | 
| -  app =
 | 
| -      InstallEphemeralAppWithSourceAndFlags(GetTestPath(kNotificationsTestApp),
 | 
| -                                            0,
 | 
| -                                            Manifest::INTERNAL,
 | 
| -                                            Extension::NO_FLAGS);
 | 
| -  EXPECT_FALSE(extensions::util::IsEphemeralApp(app_id, profile()));
 | 
| -}
 | 
| -
 | 
| -// Ephemerality was previously encoded by the Extension::IS_EPHEMERAL creation
 | 
| -// flag. This was changed to an "ephemeral_app" property. Check that the prefs
 | 
| -// are handled correctly.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
 | 
| -                       ExtensionPrefBackcompatibility) {
 | 
| -  // Ensure that apps with the old prefs are recognized as ephemeral.
 | 
| -  const Extension* app =
 | 
| -      InstallExtensionWithSourceAndFlags(GetTestPath(kNotificationsTestApp),
 | 
| -                                         1,
 | 
| -                                         Manifest::INTERNAL,
 | 
| -                                         Extension::IS_EPHEMERAL);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  EXPECT_TRUE(extensions::util::IsEphemeralApp(app->id(), profile()));
 | 
| -
 | 
| -  // Ensure that when the app is promoted to an installed app, the bit in the
 | 
| -  // creation flags is cleared.
 | 
| -  PromoteEphemeralApp(app);
 | 
| -  EXPECT_FALSE(extensions::util::IsEphemeralApp(app->id(), profile()));
 | 
| -
 | 
| -  int creation_flags =
 | 
| -      ExtensionPrefs::Get(profile())->GetCreationFlags(app->id());
 | 
| -  EXPECT_EQ(0, creation_flags & Extension::IS_EPHEMERAL);
 | 
| -}
 | 
| -
 | 
| -// Verifies that the power keep awake will be automatically released for
 | 
| -// ephemeral apps that stop running. Well behaved apps should actually call
 | 
| -// chrome.power.releaseKeepAwake() themselves.
 | 
| -IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReleasePowerKeepAwake) {
 | 
| -  PowerSettingsMock power_settings;
 | 
| -  extensions::PowerAPI::Get(profile())->SetCreateBlockerFunctionForTesting(
 | 
| -      base::Bind(&PowerSaveBlockerStub::Create, &power_settings));
 | 
| -
 | 
| -  const Extension* app = InstallAndLaunchEphemeralApp(kPowerTestApp);
 | 
| -  ASSERT_TRUE(app);
 | 
| -  EXPECT_EQ(1, power_settings.keep_awake_count());
 | 
| -
 | 
| -  CloseAppWaitForUnload(app->id());
 | 
| -
 | 
| -  EXPECT_EQ(0, power_settings.keep_awake_count());
 | 
| -}
 | 
| 
 |