15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/apps/ephemeral_app_browsertest.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/apps/ephemeral_app_service.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_utils.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/manifest.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::Extension; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionPrefs; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionSystem; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kNumTestApps = 2; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char* kTestApps[] = { 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "app_window/generic", 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "minimal" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class EphemeralAppServiceBrowserTest : public EphemeralAppTestBase { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void LoadApps() { 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < kNumTestApps; ++i) { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Extension* extension = InstallEphemeralApp(kTestApps[i]); 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(extension); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_ids_.push_back(extension->id()); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(kNumTestApps, (int) app_ids_.size()); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void GarbageCollectEphemeralApps() { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService* ephemeral_service = EphemeralAppService::Get( 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser()->profile()); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(ephemeral_service); 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ephemeral_service->GarbageCollectApps(); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void InitEphemeralAppCount(EphemeralAppService* ephemeral_service) { 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ephemeral_service->InitEphemeralAppCount(); 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> app_ids_; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies that inactive ephemeral apps are uninstalled and active apps are 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// not removed. Extensive testing of the ephemeral app cache's replacement 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// policies is done in the unit tests for EphemeralAppService. This is more 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// like an integration test. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(EphemeralAppServiceBrowserTest, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GarbageCollectInactiveApps) { 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EphemeralAppService* ephemeral_service = 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EphemeralAppService::Get(browser()->profile()); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(ephemeral_service); 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InitEphemeralAppCount(ephemeral_service); 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LoadApps(); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Time time_now = base::Time::Now(); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile()); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(prefs); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set launch time for an inactive app. 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string inactive_app_id = app_ids_[0]; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time inactive_launch = time_now - 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromDays(EphemeralAppService::kAppInactiveThreshold + 1); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs->SetLastLaunchTime(inactive_app_id, inactive_launch); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set launch time for an active app. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string active_app_id = app_ids_[1]; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time active_launch = time_now - 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromDays(EphemeralAppService::kAppKeepThreshold); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs->SetLastLaunchTime(active_app_id, active_launch); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Perform garbage collection. 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::WindowedNotificationObserver uninstall_signal( 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::Source<Profile>(browser()->profile())); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GarbageCollectEphemeralApps(); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uninstall_signal.Wait(); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionService* service = ExtensionSystem::Get(browser()->profile()) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->extension_service(); 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(service); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(service->GetInstalledExtension(inactive_app_id)); 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(service->GetInstalledExtension(active_app_id)); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1, ephemeral_service->ephemeral_app_count()); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Verify that the count of ephemeral apps is maintained correctly. 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(EphemeralAppServiceBrowserTest, 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EphemeralAppCount) { 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EphemeralAppService* ephemeral_service = 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EphemeralAppService::Get(browser()->profile()); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(ephemeral_service); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InitEphemeralAppCount(ephemeral_service); 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The count should not increase for regular installed apps. 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(InstallPlatformApp("minimal")); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0, ephemeral_service->ephemeral_app_count()); 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The count should increase when an ephemeral app is added. 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Extension* app = InstallEphemeralApp(kMessagingReceiverApp); 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(app); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1, ephemeral_service->ephemeral_app_count()); 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The count should remain constant if the ephemeral app is updated. 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string app_id = app->id(); 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) app = UpdateEphemeralApp( 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) app_id, GetTestPath(kMessagingReceiverAppV2), 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetTestPath(kMessagingReceiverApp).ReplaceExtension( 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FILE_PATH_LITERAL(".pem"))); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(app); 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1, ephemeral_service->ephemeral_app_count()); 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The count should decrease when an ephemeral app is promoted to a regular 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // installed app. 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PromoteEphemeralApp(app); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0, ephemeral_service->ephemeral_app_count()); 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 132