Commit a999290e authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Remove demo mode resources after sufficient amount of user activity

Have DemoModeResourcesRemover keep track of amount of time the user is
interacting with the device (using UserActivityDetector), and once the
total amount of active usage is over 8 hours, attempt demo mode
resources removal - substantial amount of active usage should be a good
signal that the device has been owned by a real user.

BUG=827368
TEST=unittests

Change-Id: Ib7b90da7da41bdcebbead0f0239579e727f07ae8
Reviewed-on: https://chromium-review.googlesource.com/1180603Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584360}
parent 6f360d69
......@@ -14,9 +14,13 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chromeos/idle_detector.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
......@@ -27,6 +31,7 @@
#include "components/user_manager/user.h"
#include "components/user_manager/user_type.h"
#include "third_party/re2/src/re2/re2.h"
#include "ui/base/user_activity/user_activity_detector.h"
namespace chromeos {
......@@ -38,6 +43,11 @@ DemoModeResourcesRemover* g_instance = nullptr;
// have been removed from the device.
constexpr char kDemoModeResourcesRemoved[] = "demo_mode_resources_removed";
// Key for the pref in local state that tracks accumulated device usage time in
// seconds.
constexpr char kAccumulatedUsagePref[] =
"demo_mode_resources_remover.accumulated_device_usage_s";
// Regex matching legacy demo retail mode domains.
constexpr char kLegacyDemoRetailModeDomainRegex[] =
"[[:alpha:]]{2}-retailmode.com";
......@@ -76,10 +86,24 @@ bool IsLegacyDemoRetailModeSession(const user_manager::User* user) {
} // namespace
DemoModeResourcesRemover::UsageAccumulationConfig::UsageAccumulationConfig()
: resources_removal_threshold(base::TimeDelta::FromHours(48)),
update_interval(base::TimeDelta::FromMinutes(5)),
idle_threshold(base::TimeDelta::FromSeconds(30)) {}
DemoModeResourcesRemover::UsageAccumulationConfig::UsageAccumulationConfig(
const base::TimeDelta& resources_removal_threshold,
const base::TimeDelta& update_interval,
const base::TimeDelta& idle_threshold)
: resources_removal_threshold(resources_removal_threshold),
update_interval(update_interval),
idle_threshold(idle_threshold) {}
// static
void DemoModeResourcesRemover::RegisterLocalStatePrefs(
PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(kDemoModeResourcesRemoved, false);
registry->RegisterIntegerPref(kAccumulatedUsagePref, 0);
}
// static
......@@ -109,6 +133,9 @@ DemoModeResourcesRemover::~DemoModeResourcesRemover() {
CHECK_EQ(g_instance, this);
g_instance = nullptr;
if (usage_start_.has_value() && usage_end_.has_value())
UpdateDeviceUsage(*usage_end_ - *usage_start_);
ChromeUserManager::Get()->RemoveSessionStateObserver(this);
}
......@@ -132,12 +159,53 @@ void DemoModeResourcesRemover::ActiveUserChanged(
// mode domain.
if (g_browser_process->platform_part()
->browser_policy_connector_chromeos()
->IsEnterpriseManaged() &&
!IsLegacyDemoRetailModeSession(user)) {
AttemptRemoval(RemovalReason::kEnterpriseEnrolled, RemovalCallback());
->IsEnterpriseManaged()) {
if (!IsLegacyDemoRetailModeSession(user))
AttemptRemoval(RemovalReason::kEnterpriseEnrolled, RemovalCallback());
return;
}
// Start tracking user activity, if it's already not in progress.
if (!user_activity_observer_.IsObserving(ui::UserActivityDetector::Get())) {
if (!AttemptRemovalIfUsageOverThreshold()) {
user_activity_observer_.Add(ui::UserActivityDetector::Get());
OnUserActivity(nullptr);
}
}
}
void DemoModeResourcesRemover::OnUserActivity(const ui::Event* event) {
base::TimeTicks now = tick_clock_->NowTicks();
if (!usage_start_.has_value()) {
usage_start_ = now;
usage_end_ = now;
return;
}
bool was_idle =
usage_end_.has_value() &&
(now - *usage_end_) > usage_accumulation_config_.idle_threshold;
base::TimeTicks interval_end = was_idle ? *usage_end_ : now;
base::TimeDelta duration = interval_end - *usage_start_;
// If enough time has passed, or the current usage interval was interrupted by
// idle period, record the usage.
if (was_idle || duration >= usage_accumulation_config_.update_interval) {
UpdateDeviceUsage(duration);
// Attempt to remove resources will stop observing user activity, so no need
// to start the next usage interval.
if (AttemptRemovalIfUsageOverThreshold())
return;
// Start tracking the next active usage interval.
usage_start_ = now;
}
usage_end_ = now;
}
void DemoModeResourcesRemover::AttemptRemoval(RemovalReason reason,
RemovalCallback callback) {
if (local_state_->GetBoolean(kDemoModeResourcesRemoved)) {
......@@ -172,9 +240,22 @@ void DemoModeResourcesRemover::AttemptRemoval(RemovalReason reason,
weak_ptr_factory_.GetWeakPtr()));
}
void DemoModeResourcesRemover::OverrideTimeForTesting(
base::TickClock* tick_clock,
const UsageAccumulationConfig& config) {
tick_clock_ = tick_clock;
usage_start_ = base::nullopt;
usage_end_ = base::nullopt;
usage_accumulation_config_ = config;
}
DemoModeResourcesRemover::DemoModeResourcesRemover(PrefService* local_state)
: local_state_(local_state),
tick_clock_(base::DefaultTickClock::GetInstance()),
cryptohome_observer_(this),
user_activity_observer_(this),
weak_ptr_factory_(this) {
CHECK(!g_instance);
g_instance = this;
......@@ -183,14 +264,48 @@ DemoModeResourcesRemover::DemoModeResourcesRemover(PrefService* local_state)
ChromeUserManager::Get()->AddSessionStateObserver(this);
}
void DemoModeResourcesRemover::UpdateDeviceUsage(
const base::TimeDelta& duration) {
int accumulated_activity = local_state_->GetInteger(kAccumulatedUsagePref);
int64_t removal_threshold_s =
usage_accumulation_config_.resources_removal_threshold.InSeconds();
if (accumulated_activity < removal_threshold_s)
accumulated_activity += std::min(duration.InSeconds(), removal_threshold_s);
local_state_->SetInteger(kAccumulatedUsagePref, accumulated_activity);
usage_start_ = base::nullopt;
usage_end_ = base::nullopt;
}
bool DemoModeResourcesRemover::AttemptRemovalIfUsageOverThreshold() {
int accumulated_activity = local_state_->GetInteger(kAccumulatedUsagePref);
int64_t removal_threshold_s =
usage_accumulation_config_.resources_removal_threshold.InSeconds();
if (accumulated_activity < removal_threshold_s)
return false;
// Stop observing usage.
user_activity_observer_.RemoveAll();
AttemptRemoval(RemovalReason::kRegularUsage, RemovalCallback());
return true;
}
void DemoModeResourcesRemover::OnRemovalDone(RemovalResult result) {
DCHECK(removal_in_progress_);
removal_in_progress_ = false;
if (result == RemovalResult::kNotFound || result == RemovalResult::kSuccess) {
local_state_->SetBoolean(kDemoModeResourcesRemoved, true);
local_state_->ClearPref(kAccumulatedUsagePref);
cryptohome_observer_.RemoveAll();
ChromeUserManager::Get()->RemoveSessionStateObserver(this);
user_activity_observer_.RemoveAll();
usage_start_ = base::nullopt;
usage_end_ = base::nullopt;
}
UMA_HISTOGRAM_ENUMERATION("DemoMode.ResourcesRemoval.Result", result);
......
......@@ -12,13 +12,26 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "components/user_manager/user_manager.h"
#include "ui/base/user_activity/user_activity_observer.h"
class PrefRegistrySimple;
class PrefService;
namespace base {
class TickClock;
class TimeDelta;
class TimeTicks;
} // namespace base
namespace ui {
class Event;
class UserActivityDetector;
} // namespace ui
namespace chromeos {
// Handles removal of pre-installed demo mode resources.
......@@ -31,11 +44,11 @@ namespace chromeos {
// of the following conditions are satisfied:
// * device is running low on disk space
// * device is enrolled in a non-demo-mode domain
// * TODO(crbug.com/827368): enough non-demo-mode user activity has been
// detected on the device
// * enough user activity has been detected on the device
class DemoModeResourcesRemover
: public CryptohomeClient::Observer,
public user_manager::UserManager::UserSessionStateObserver {
public user_manager::UserManager::UserSessionStateObserver,
public ui::UserActivityObserver {
public:
// The reason a removal was requested.
// DO NOT REORDER - used to report metrics.
......@@ -73,6 +86,30 @@ class DemoModeResourcesRemover
// partition.
using RemovalCallback = base::OnceCallback<void(RemovalResult result)>;
// Configures how DemoModeResourcesRemover tracks the amount of active
// device usage in order to determine when demo mode resources are not needed
// anymore.
struct UsageAccumulationConfig {
// Creates the config with default params used in production.
UsageAccumulationConfig();
UsageAccumulationConfig(const base::TimeDelta& resources_removal_threshold,
const base::TimeDelta& update_interval,
const base::TimeDelta& idle_threshold);
// Amount of accumulated device usage time that warrants demo mode resources
// removal. When this threshold is reached, demo mode resources removal will
// be attempted.
base::TimeDelta resources_removal_threshold;
// The interval in which accumulated usage time is updated in prefs (during
// active device usage).
base::TimeDelta update_interval;
// The amount of time without user activity after which the device is
// considered idle.
base::TimeDelta idle_threshold;
};
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
// Gets the demo mode resources remover instance for this process - at most
......@@ -104,15 +141,37 @@ class DemoModeResourcesRemover
// user_manager::UserManager::UserSessionStateObserver:
void ActiveUserChanged(const user_manager::User* user) override;
// ui::UserActivityObserver:
void OnUserActivity(const ui::Event* event) override;
// Requests demo mode resources removal from the disk. If a removal operation
// is already in progress, this method will schedule the callback to be run
// with the result of the operation in progress.
void AttemptRemoval(RemovalReason reason, RemovalCallback callback);
// Allows tests to override the tick clock and configuration for accumulating
// the amount of active device usage.
void OverrideTimeForTesting(base::TickClock* tick_clock,
const UsageAccumulationConfig& config);
private:
// Defined here so it can be overridden in tests.
UsageAccumulationConfig usage_accumulation_config_;
// Use CreateIfNeeded() to create an instance.
explicit DemoModeResourcesRemover(PrefService* local_state);
// Updates the accumulated information about the amount of active device
// usage, which is used to detect when the device owned by a real user, and
// thus does not require demo mode resources.
void UpdateDeviceUsage(const base::TimeDelta& duration);
// If the amount of detected device usage is above the threshold for removing
// demo mode resources, attempts the resources removal. If resoruces removal
// is requested, stops observing device usage.
// Returns whether the resources removal was requested.
bool AttemptRemovalIfUsageOverThreshold();
// Passes as the callback to directory removal file operations.
void OnRemovalDone(RemovalResult result);
......@@ -124,8 +183,16 @@ class DemoModeResourcesRemover
// Callbacks for the resources removal operation, if one is in progress.
std::vector<RemovalCallback> removal_callbacks_;
const base::TickClock* tick_clock_;
// Used to track the duration of last unrecorded interval of user activity.
base::Optional<base::TimeTicks> usage_start_;
base::Optional<base::TimeTicks> usage_end_;
ScopedObserver<CryptohomeClient, DemoModeResourcesRemover>
cryptohome_observer_;
ScopedObserver<ui::UserActivityDetector, DemoModeResourcesRemover>
user_activity_observer_;
base::WeakPtrFactory<DemoModeResourcesRemover> weak_ptr_factory_;
......
......@@ -13,22 +13,34 @@
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/values.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/stub_install_attributes.h"
#include "chrome/browser/extensions/external_policy_loader.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_cryptohome_client.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_names.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/user_activity/user_activity_detector.h"
namespace chromeos {
namespace {
// Key for the pref in local state that tracks accumulated device usage time in
// seconds.
constexpr char kAccumulatedUsagePref[] =
"demo_mode_resources_remover.accumulated_device_usage_s";
// Used as a callback to DemoModeResourcesRemover::AttemptRemoval - it records
// the result of the attempt to |result_out|.
void RecordRemovalResult(
......@@ -113,6 +125,7 @@ class DemoModeResourcesRemoverTest : public testing::Test {
enum class TestUserType {
kRegular,
kRegularSecond,
kGuest,
kPublicAccount,
kKiosk,
......@@ -128,6 +141,10 @@ class DemoModeResourcesRemoverTest : public testing::Test {
user =
user_manager->AddUser(AccountId::FromUserEmail("fake_user@test"));
break;
case TestUserType::kRegularSecond:
user =
user_manager->AddUser(AccountId::FromUserEmail("fake_user_1@test"));
break;
case TestUserType::kGuest:
user = user_manager->AddGuestUser();
break;
......@@ -151,11 +168,24 @@ class DemoModeResourcesRemoverTest : public testing::Test {
remover->ActiveUserChanged(user);
}
void AdvanceTestTime(const base::TimeDelta& time) {
test_clock_.Advance(time);
// TODO(tbarzic): Add support for injecting a test tick clock to
// ui::ActivityDetector so activity_detector_ time gets updated by
// test_clock_, too.
activity_detector_.set_now_for_test(test_clock_.NowTicks());
}
FakeCryptohomeClient* cryptohome_client_ = nullptr;
TestingPrefServiceSimple local_state_;
content::TestBrowserThreadBundle thread_bundle_;
ui::UserActivityDetector activity_detector_;
// Tick clock that can be used for tests - not used by default, but tests can
// inject it into DemoModeResourcesRemover using OverrideTimeForTesting().
base::SimpleTestTickClock test_clock_;
private:
std::unique_ptr<ScopedStubInstallAttributes> install_attributes_;
......@@ -388,6 +418,385 @@ TEST_F(DemoModeResourcesRemoverTest, NoRemovalOnLogin) {
EXPECT_TRUE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, RemoveAfterActiveUse) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance time so it's longer than removal threshold, but under the idle
// threshold (so it's not disregarded as idle time).
AdvanceTestTime(base::TimeDelta::FromSeconds(4));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, IgnoreUsageBeforeLogin) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
activity_detector_.HandleExternalUserActivity();
// Advance time so it's longer than removal threshold, but under the idle
// threshold (so it's not disregarded as idle time).
AdvanceTestTime(base::TimeDelta::FromSeconds(4));
activity_detector_.HandleExternalUserActivity();
AddAndLogInUser(TestUserType::kRegular, remover.get());
// The total usage was over the removal threshold, but it happened before
// login - the resources should still be around.
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, RemoveAfterActiveUse_AccumulateActivity) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Over update interval, but under removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(2));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// This should get accumulated time over removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(2));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, DoNotAccumulateIdleTimeUsage) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(8) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(3) /*update_interval*/,
base::TimeDelta::FromSeconds(4) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance to the time just under removal threshold in small increments
// (within the idle threshold)
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Simulate longer idle period.
AdvanceTestTime(base::TimeDelta::FromSeconds(10));
activity_detector_.HandleExternalUserActivity();
// The resources should be still be here, as usage amount should not have been
// incremented.
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance time little bit more, so it's over the removal threshold (and over
// the update interval).
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, ReportUsageBeforeIdlePeriod) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(12) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(7) /*update_interval*/,
base::TimeDelta::FromSeconds(5) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance to the time just under removal threshold in small increments
// (within the idle threshold), that are under the update interval combined.
// This will leave unrecorded usage before the idle period.
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Simulate longer idle period.
AdvanceTestTime(base::TimeDelta::FromSeconds(10));
activity_detector_.HandleExternalUserActivity();
// The resources should be still be here, as usage amount should not have been
// incremented.
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance time cummulatively over the update period.
AdvanceTestTime(base::TimeDelta::FromSeconds(4));
activity_detector_.HandleExternalUserActivity();
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
// When combined the accumulated active usage was above the removal threshold.
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, RemovalThresholdReachedBeforeIdlePeriod) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(9) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(5) /*update_interval*/,
base::TimeDelta::FromSeconds(7) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance to the time just under removal threshold in small increments, but
// with total over the update interval.
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Advance time so total is over the remova threshold, but in increment under
// the update interval.
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Simulate longer idle period.
AdvanceTestTime(base::TimeDelta::FromSeconds(10));
activity_detector_.HandleExternalUserActivity();
// Activity after the idle period ended should have flushed previous pending
// usage, and the resources should have been removed.
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest, UpdateInterval) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
// Test that local state is not updated on each detected user activity.
AdvanceTestTime(base::TimeDelta::FromMilliseconds(300));
activity_detector_.HandleExternalUserActivity();
EXPECT_EQ(0, local_state_.GetInteger(kAccumulatedUsagePref));
AdvanceTestTime(base::TimeDelta::FromMilliseconds(300));
activity_detector_.HandleExternalUserActivity();
EXPECT_EQ(0, local_state_.GetInteger(kAccumulatedUsagePref));
AdvanceTestTime(base::TimeDelta::FromMilliseconds(300));
activity_detector_.HandleExternalUserActivity();
EXPECT_EQ(0, local_state_.GetInteger(kAccumulatedUsagePref));
AdvanceTestTime(base::TimeDelta::FromMilliseconds(300));
activity_detector_.HandleExternalUserActivity();
EXPECT_EQ(1, local_state_.GetInteger(kAccumulatedUsagePref));
}
TEST_F(DemoModeResourcesRemoverTest,
RemoveAfterActiveUse_AccumulateActivityOverRestarts) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Over update interval, but under removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(2));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
remover.reset();
remover = DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(3) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(1) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegularSecond, remover.get());
// This should get accumulated time over removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(2));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverTest,
RemoveAfterActiveUse_RecordLeftoverUsageOnShutdown) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(4) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(2) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// Over update interval, but under removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(3));
activity_detector_.HandleExternalUserActivity();
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
// This is under update interval, but should get accumulated time over
// removal threshold.
AdvanceTestTime(base::TimeDelta::FromSeconds(1));
activity_detector_.HandleExternalUserActivity();
remover.reset();
// Session restart on with usage already over threshold - expect resources
// removal.
remover = DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(4) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(2) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kRegular, remover.get());
thread_bundle_.RunUntilIdle();
EXPECT_FALSE(DemoModeResourcesExist());
}
// Tests the kiosk app incarnation of demo mode.
TEST_F(DemoModeResourcesRemoverTest, NoRemovalInKioskDemoMode) {
ASSERT_TRUE(CreateDemoModeResources());
......@@ -401,6 +810,30 @@ TEST_F(DemoModeResourcesRemoverTest, NoRemovalInKioskDemoMode) {
EXPECT_TRUE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverInLegacyDemoRetailModeTest,
NoRemovalInKioskDemoModeWithUserActivity) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(4) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(2) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kDerelictDemoKiosk, remover.get());
AdvanceTestTime(base::TimeDelta::FromSeconds(5));
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
}
TEST_F(ManagedDemoModeResourcesRemoverTest, RemoveOnRegularLogin) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
......@@ -490,4 +923,28 @@ TEST_F(DemoModeResourcesRemoverInLegacyDemoRetailModeTest,
EXPECT_FALSE(DemoModeResourcesExist());
}
TEST_F(DemoModeResourcesRemoverInLegacyDemoRetailModeTest,
ActiveUsageShouldNotTriggerRemoval) {
ASSERT_TRUE(CreateDemoModeResources());
std::unique_ptr<DemoModeResourcesRemover> remover =
DemoModeResourcesRemover::CreateIfNeeded(&local_state_);
ASSERT_TRUE(remover.get());
AdvanceTestTime(base::TimeDelta::FromMinutes(1));
remover->OverrideTimeForTesting(
&test_clock_,
DemoModeResourcesRemover::UsageAccumulationConfig(
base::TimeDelta::FromSeconds(4) /*resources_removal_threshold*/,
base::TimeDelta::FromSeconds(2) /*update_interval*/,
base::TimeDelta::FromSeconds(9) /*idle_threshold*/));
AddAndLogInUser(TestUserType::kPublicAccount, remover.get());
AdvanceTestTime(base::TimeDelta::FromSeconds(5));
thread_bundle_.RunUntilIdle();
EXPECT_TRUE(DemoModeResourcesExist());
}
} // namespace chromeos
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment