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