15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(rickcam): Bug 73183: Add unit tests for image loading
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstdlib>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/background/background_application_list_model.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_service_test_base.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/permissions_updater.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_prefs.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/uninstall_reason.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h"
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/permissions/permission_set.h"
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This value is used to seed the PRNG at the beginning of a sequence of
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operations to produce a repeatable sequence.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RANDOM_SEED (0x33F7A7A7)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::APIPermission;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For ExtensionService interface when it requires a path that is not used.
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::FilePath bogus_file_pathname(const std::string& name) {
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return base::FilePath(FILE_PATH_LITERAL("//foobar_nonexistent"))
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      .AppendASCII(name);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class BackgroundApplicationListModelTest
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : public extensions::ExtensionServiceTestBase {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackgroundApplicationListModelTest() {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BackgroundApplicationListModelTest() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeAndLoadEmptyExtensionService() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeEmptyExtensionService();
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    service_->Init(); /* Sends EXTENSIONS_READY */
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsBackgroundApp(const Extension& app) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return BackgroundApplicationListModel::IsBackgroundApp(app,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           profile_.get());
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)enum PushMessagingOption {
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NO_PUSH_MESSAGING,
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  PUSH_MESSAGING_PERMISSION,
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  PUSH_MESSAGING_BUT_NOT_BACKGROUND
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a barebones test Extension object with the specified |name|.  The
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returned extension will include background permission iff
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// |background_permission| is true and pushMessaging permission if requested
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// by |push_messaging| value. Also the extension may have a specific id set
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// to test the case when it has a pushMessaging permission but is not
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// considered a background app based on a whitelist.
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static scoped_refptr<Extension> CreateExtensionBase(
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::string& name,
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool background_permission,
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    PushMessagingOption push_messaging) {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue manifest;
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  manifest.SetString(extensions::manifest_keys::kVersion, "1.0.0.0");
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  manifest.SetString(extensions::manifest_keys::kName, name);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* permissions = new base::ListValue();
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  manifest.Set(extensions::manifest_keys::kPermissions, permissions);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (background_permission) {
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    permissions->Append(new base::StringValue("background"));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (push_messaging == PUSH_MESSAGING_PERMISSION ||
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      push_messaging == PUSH_MESSAGING_BUT_NOT_BACKGROUND) {
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    permissions->Append(new base::StringValue("pushMessaging"));
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> extension;
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // There is a whitelist for extensions that have pushMessaging permission but
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // are not considered a background app. Create a test extension with a known
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // test id if needed.
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (push_messaging == PUSH_MESSAGING_BUT_NOT_BACKGROUND) {
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension = Extension::Create(
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        bogus_file_pathname(name),
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        extensions::Manifest::INVALID_LOCATION,
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        manifest,
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Extension::NO_FLAGS,
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "aaaabbbbccccddddeeeeffffgggghhhh",
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &error);
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension = Extension::Create(
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        bogus_file_pathname(name),
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        extensions::Manifest::INVALID_LOCATION,
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        manifest,
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Extension::NO_FLAGS,
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &error);
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cannot ASSERT_* here because that attempts an illegitimate return.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cannot EXPECT_NE here because that assumes non-pointers unlike EXPECT_EQ
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(extension.get() != NULL) << error;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static scoped_refptr<Extension> CreateExtension(const std::string& name,
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                bool background_permission) {
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return CreateExtensionBase(name, background_permission, NO_PUSH_MESSAGING);
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateUniqueExtensionName() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int uniqueness = 0;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream output;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output << "Unique Named Extension " << uniqueness;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++uniqueness;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return output.str();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddBackgroundPermission(ExtensionService* service,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Extension* extension) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (BackgroundApplicationListModel::IsBackgroundApp(*extension,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      service->profile())) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> temporary =
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateExtension(GenerateUniqueExtensionName(), true);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const extensions::PermissionSet> permissions =
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      temporary->permissions_data()->active_permissions();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::PermissionsUpdater(service->profile()).AddPermissions(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension, permissions.get());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveBackgroundPermission(ExtensionService* service,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Extension* extension) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BackgroundApplicationListModel::IsBackgroundApp(*extension,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       service->profile())) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  extensions::PermissionsUpdater(service->profile()).RemovePermissions(
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extension, extension->permissions_data()->active_permissions().get());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AddEphemeralApp(const Extension* extension, ExtensionService* service) {
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  extensions::ExtensionPrefs* prefs =
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::ExtensionPrefs::Get(service->profile());
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(prefs);
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs->OnExtensionInstalled(extension,
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::Extension::ENABLED,
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              syncer::StringOrdinal(),
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::kInstallFlagIsEphemeral,
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              std::string());
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->AddExtension(extension);
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Crashes on Mac tryslaves.
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/165458
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX) || defined(OS_LINUX)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_ExplicitTest DISABLED_ExplicitTest
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_ExplicitTest ExplicitTest
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With minimal test logic, verifies behavior over an explicit set of
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extensions, of which some are Background Apps and others are not.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(BackgroundApplicationListModelTest, MAYBE_ExplicitTest) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeAndLoadEmptyExtensionService();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile_.get())->
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->is_ready());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions()->is_empty());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BackgroundApplicationListModel> model(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BackgroundApplicationListModel(profile_.get()));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> ext1 = CreateExtension("alpha", false);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> ext2 = CreateExtension("bravo", false);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> ext3 = CreateExtension("charlie", false);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> bgapp1 = CreateExtension("delta", true);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> bgapp2 = CreateExtension("echo", true);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions() != NULL);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, service->extensions()->size());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add alternating Extensions and Background Apps
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext1.get()));
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(ext1.get());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp1.get()));
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(bgapp1.get());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext2.get()));
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(ext2.get());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp2.get()));
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(bgapp2.get());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, service->extensions()->size());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext3.get()));
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(ext3.get());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(5U, service->extensions()->size());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove in FIFO order.
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext1.get()));
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(ext1->id(),
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, service->extensions()->size());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp1.get()));
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(bgapp1->id(),
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext2.get()));
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(ext2->id(),
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp2.get()));
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(bgapp2->id(),
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext3.get()));
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(ext3->id(),
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, service->extensions()->size());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Verifies that pushMessaging also triggers background detection, except
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// when extension is in a whitelist.
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(BackgroundApplicationListModelTest, PushMessagingTest) {
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  InitializeAndLoadEmptyExtensionService();
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile_.get())->
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_service();
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(service);
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(service->is_ready());
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(service->extensions());
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(service->extensions()->is_empty());
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<BackgroundApplicationListModel> model(
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new BackgroundApplicationListModel(profile_.get()));
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> ext1 = CreateExtension("alpha", false);
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> ext2 =
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CreateExtensionBase("charlie", false, PUSH_MESSAGING_BUT_NOT_BACKGROUND);
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> bgapp1 =
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CreateExtensionBase("bravo", false, PUSH_MESSAGING_PERMISSION);
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> bgapp2 =
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CreateExtensionBase("delta", true, PUSH_MESSAGING_PERMISSION);
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<Extension> bgapp3 =
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CreateExtensionBase("echo", true, PUSH_MESSAGING_BUT_NOT_BACKGROUND);
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(service->extensions() != NULL);
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, service->extensions()->size());
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Add alternating Extensions and Background Apps
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext1.get()));
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service->AddExtension(ext1.get());
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp1.get()));
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service->AddExtension(bgapp1.get());
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext2.get()));
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service->AddExtension(ext2.get());
3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp2.get()));
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service->AddExtension(bgapp2.get());
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(4U, service->extensions()->size());
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Need to remove ext2 because it uses same id as bgapp3.
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext2.get()));
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(ext2->id(),
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp3.get()));
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service->AddExtension(bgapp3.get());
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(4U, service->extensions()->size());
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(3U, model->size());
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Remove in FIFO order.
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext1.get()));
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(ext1->id(),
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(3U, model->size());
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp1.get()));
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(bgapp1->id(),
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp2.get()));
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(bgapp2->id(),
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp3.get()));
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->UninstallExtension(bgapp3->id(),
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              extensions::UNINSTALL_REASON_FOR_TESTING,
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Bind(&base::DoNothing),
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              NULL);
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, service->extensions()->size());
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Verifies that an ephemeral app cannot trigger background mode.
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(BackgroundApplicationListModelTest, EphemeralAppTest) {
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InitializeAndLoadEmptyExtensionService();
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile_.get())->
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extension_service();
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(service);
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(service->is_ready());
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(service->extensions());
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(service->extensions()->is_empty());
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<BackgroundApplicationListModel> model(
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new BackgroundApplicationListModel(profile_.get()));
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0U, model->size());
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<Extension> installed =
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CreateExtensionBase("installed", false, PUSH_MESSAGING_PERMISSION);
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<Extension> ephemeral =
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CreateExtensionBase("ephemeral", false, PUSH_MESSAGING_PERMISSION);
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<Extension> background = CreateExtension("background", true);
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Installed app with push messaging permissions can trigger background mode.
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*installed.get()));
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->AddExtension(installed.get());
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1U, model->size());
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // An ephemeral app with push messaging permissions should not trigger
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // background mode.
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddEphemeralApp(ephemeral.get(), service);
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ephemeral.get()));
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1U, model->size());
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // An ephemeral app with the background permission should not trigger
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // background mode.
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddEphemeralApp(background.get(), service);
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*background.get()));
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(1U, model->size());
3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the ephemeral app becomes promoted to an installed app, it can now
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // trigger background mode.
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  service->PromoteEphemeralApp(ephemeral.get(), false /*from sync*/);
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*ephemeral.get()));
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(3U, service->extensions()->size());
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(2U, model->size());
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With minimal test logic, verifies behavior with dynamic permissions.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackgroundApplicationListModelTest, AddRemovePermissionsTest) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeAndLoadEmptyExtensionService();
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile_.get())->
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->is_ready());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions()->is_empty());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BackgroundApplicationListModel> model(
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BackgroundApplicationListModel(profile_.get()));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> ext = CreateExtension("extension", false);
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ext->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> bgapp = CreateExtension("application", true);
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      bgapp->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions() != NULL);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, service->extensions()->size());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one (non-background) extension and one background application
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(IsBackgroundApp(*ext.get()));
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(ext.get());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, service->extensions()->size());
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(IsBackgroundApp(*bgapp.get()));
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(bgapp.get());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change permissions back and forth
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddBackgroundPermission(service, ext.get());
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ext->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, model->size());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveBackgroundPermission(service, bgapp.get());
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      bgapp->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveBackgroundPermission(service, ext.get());
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ext->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddBackgroundPermission(service, bgapp.get());
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      bgapp->permissions_data()->HasAPIPermission(APIPermission::kBackground));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, service->extensions()->size());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, model->size());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::set<scoped_refptr<Extension> > ExtensionCollection;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddExtension(ExtensionService* service,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ExtensionCollection* extensions,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  BackgroundApplicationListModel* model,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  size_t* expected,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  size_t* count) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool create_background = false;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rand() % 2) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_background = true;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++*expected;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension =
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateExtension(GenerateUniqueExtensionName(), create_background);
470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(BackgroundApplicationListModel::IsBackgroundApp(*extension.get(),
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            service->profile()),
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            create_background);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions->insert(extension);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++*count;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(*count, extensions->size());
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->AddExtension(extension.get());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(*count, service->extensions()->size());
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(*expected, model->size());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveExtension(ExtensionService* service,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ExtensionCollection* extensions,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     BackgroundApplicationListModel* model,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     size_t* expected,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     size_t* count) {  // Maybe remove an extension.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionCollection::iterator cursor = extensions->begin();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cursor == extensions->end()) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Nothing to remove.  Just verify accounting.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, *count);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, *expected);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, service->extensions()->size());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, model->size());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Randomly select which extension to remove
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extensions->size() > 1) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int offset = rand() % (extensions->size() - 1);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int index = 0; index < offset; ++index)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++cursor;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<Extension> extension = cursor->get();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string id = extension->id();
502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (BackgroundApplicationListModel::IsBackgroundApp(*extension.get(),
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        service->profile())) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --*expected;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extensions->erase(cursor);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --*count;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(*count, extensions->size());
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    service->UninstallExtension(extension->id(),
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                extensions::UNINSTALL_REASON_FOR_TESTING,
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                base::Bind(&base::DoNothing),
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                NULL);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(*count, service->extensions()->size());
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(*expected, model->size());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TogglePermission(ExtensionService* service,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      ExtensionCollection* extensions,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      BackgroundApplicationListModel* model,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      size_t* expected,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      size_t* count) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionCollection::iterator cursor = extensions->begin();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cursor == extensions->end()) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Nothing to toggle.  Just verify accounting.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, *count);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, *expected);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, service->extensions()->size());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0U, model->size());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Randomly select which extension to toggle.
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extensions->size() > 1) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int offset = rand() % (extensions->size() - 1);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int index = 0; index < offset; ++index)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++cursor;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<Extension> extension = cursor->get();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string id = extension->id();
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (BackgroundApplicationListModel::IsBackgroundApp(*extension.get(),
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        service->profile())) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --*expected;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*count, extensions->size());
543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RemoveBackgroundPermission(service, extension.get());
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*count, service->extensions()->size());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*expected, model->size());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++*expected;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*count, extensions->size());
549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AddBackgroundPermission(service, extension.get());
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*count, service->extensions()->size());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(*expected, model->size());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies behavior with a pseudo-randomly generated set of actions: Adding and
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// removing extensions, of which some are Background Apps and others are not.
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackgroundApplicationListModelTest, RandomTest) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeAndLoadEmptyExtensionService();
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile_.get())->
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->is_ready());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->extensions()->is_empty());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BackgroundApplicationListModel> model(
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BackgroundApplicationListModel(profile_.get()));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, model->size());
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static const int kIterations = 20;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionCollection extensions;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = 0;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t expected = 0;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  srand(RANDOM_SEED);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < kIterations; ++index) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (rand() % 3) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AddExtension(service, &extensions, model.get(), &expected, &count);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemoveExtension(service, &extensions, model.get(), &expected, &count);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 2:
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TogglePermission(service, &extensions, model.get(), &expected, &count);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
593