// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/power/ml/user_activity_manager.h"

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/sequenced_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/clock.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/power/ml/fake_boot_clock.h"
#include "chrome/browser/chromeos/power/ml/idle_event_notifier.h"
#include "chrome/browser/chromeos/power/ml/smart_dim/model.h"
#include "chrome/browser/chromeos/power/ml/user_activity_event.pb.h"
#include "chrome/browser/chromeos/power/ml/user_activity_ukm_logger.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_activity_simulator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/test_browser_window_aura.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/idle.pb.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "chromeos/dbus/power_manager_client.h"
#include "components/session_manager/session_manager_types.h"
#include "components/ukm/content/source_url_recorder.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/user_activity/user_activity_detector.h"

namespace chromeos {
namespace power {
namespace ml {

using content::WebContentsTester;

void EqualEvent(const UserActivityEvent::Event& expected_event,
                const UserActivityEvent::Event& result_event) {
  EXPECT_EQ(expected_event.type(), result_event.type());
  EXPECT_EQ(expected_event.reason(), result_event.reason());
  EXPECT_EQ(expected_event.log_duration_sec(), result_event.log_duration_sec());
  EXPECT_EQ(expected_event.screen_dim_occurred(),
            result_event.screen_dim_occurred());
  EXPECT_EQ(expected_event.screen_off_occurred(),
            result_event.screen_off_occurred());
  EXPECT_EQ(expected_event.screen_lock_occurred(),
            result_event.screen_lock_occurred());
}

void EqualModelPrediction(
    const UserActivityEvent::ModelPrediction& expected_prediction,
    const UserActivityEvent::ModelPrediction& result_prediction) {
  EXPECT_EQ(expected_prediction.model_applied(),
            result_prediction.model_applied());
  EXPECT_EQ(expected_prediction.response(), result_prediction.response());
  if (expected_prediction.response() !=
      UserActivityEvent::ModelPrediction::MODEL_ERROR) {
    EXPECT_EQ(expected_prediction.decision_threshold(),
              result_prediction.decision_threshold());
    EXPECT_EQ(expected_prediction.inactivity_score(),
              result_prediction.inactivity_score());
  } else {
    EXPECT_FALSE(result_prediction.has_decision_threshold());
    EXPECT_FALSE(result_prediction.has_inactivity_score());
  }
}

// Testing UKM logger.
class TestingUserActivityUkmLogger : public UserActivityUkmLogger {
 public:
  TestingUserActivityUkmLogger() = default;
  ~TestingUserActivityUkmLogger() override = default;

  const std::vector<UserActivityEvent>& events() const { return events_; }

  // UserActivityUkmLogger overrides:
  void LogActivity(const UserActivityEvent& event) override {
    events_.push_back(event);
  }

 private:
  std::vector<UserActivityEvent> events_;

  DISALLOW_COPY_AND_ASSIGN(TestingUserActivityUkmLogger);
};

// Testing smart dim model.
class FakeSmartDimModel : public SmartDimModel {
 public:
  explicit FakeSmartDimModel(
      const scoped_refptr<base::SequencedTaskRunner> runner)
      : task_runner_(runner) {}
  ~FakeSmartDimModel() override = default;

  void set_inactivity_score(const int inactivity_score) {
    inactivity_score_ = inactivity_score;
  }

  void set_decision_threshold(const int decision_threshold) {
    decision_threshold_ = decision_threshold;
  }

  UserActivityEvent::ModelPrediction ShouldDim(
      const UserActivityEvent::Features& input_features) {
    UserActivityEvent::ModelPrediction model_prediction;
    // If either of these two values are set outside of the legal range [0,100],
    // return an error code.
    // The |model_applied| field is not filled by the model but by
    // UserActivityManager.
    if (inactivity_score_ < 0 || inactivity_score_ > 100 ||
        decision_threshold_ < 0 || decision_threshold_ > 100) {
      model_prediction.set_response(
          UserActivityEvent::ModelPrediction::MODEL_ERROR);
    } else {
      model_prediction.set_decision_threshold(decision_threshold_);
      model_prediction.set_inactivity_score(inactivity_score_);
      if (inactivity_score_ < decision_threshold_) {
        model_prediction.set_response(
            UserActivityEvent::ModelPrediction::NO_DIM);
      } else {
        model_prediction.set_response(UserActivityEvent::ModelPrediction::DIM);
      }
    }
    return model_prediction;
  }

  // SmartDimModel overrides:
  void RequestDimDecision(const UserActivityEvent::Features& features,
                          DimDecisionCallback dim_callback) override {
    // Cancel previously assigned callbacks and set it to the new callback.
    cancelable_callback_.Reset(std::move(dim_callback));
    base::PostTaskAndReplyWithResult(
        task_runner_.get(), FROM_HERE,
        base::BindOnce(&FakeSmartDimModel::ShouldDim, base::Unretained(this),
                       features),
        base::BindOnce(cancelable_callback_.callback()));
  }

  // TODO(crbug.com/893425): Add unit tests that test this API.
  void CancelPreviousRequest() override { cancelable_callback_.Cancel(); }

 private:
  int inactivity_score_ = -1;
  int decision_threshold_ = -1;
  const scoped_refptr<base::SequencedTaskRunner> task_runner_;
  base::CancelableOnceCallback<void(UserActivityEvent::ModelPrediction)>
      cancelable_callback_;

  DISALLOW_COPY_AND_ASSIGN(FakeSmartDimModel);
};

class UserActivityManagerTest : public ChromeRenderViewHostTestHarness {
 public:
  UserActivityManagerTest()
      : ChromeRenderViewHostTestHarness(
            base::test::ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME,
            base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED),
        model_(thread_bundle()->GetMainThreadTaskRunner()) {
    fake_power_manager_client_.Init(nullptr);
    viz::mojom::VideoDetectorObserverPtr observer;
    idle_event_notifier_ = std::make_unique<IdleEventNotifier>(
        &fake_power_manager_client_, &user_activity_detector_,
        mojo::MakeRequest(&observer));
    activity_logger_ = std::make_unique<UserActivityManager>(
        &delegate_, idle_event_notifier_.get(), &user_activity_detector_,
        &fake_power_manager_client_, &session_manager_,
        mojo::MakeRequest(&observer), &fake_user_manager_, &model_);
    activity_logger_->SetTaskRunnerForTesting(
        thread_bundle()->GetMainThreadTaskRunner(),
        std::make_unique<FakeBootClock>(thread_bundle(),
                                        base::TimeDelta::FromSeconds(10)));
  }

  ~UserActivityManagerTest() override = default;

 protected:
  void ReportUserActivity(const ui::Event* event) {
    activity_logger_->OnUserActivity(event);
  }

  void ReportIdleEvent(const IdleEventNotifier::ActivityData& data) {
    activity_logger_->OnIdleEventObserved(data);
  }

  void ReportLidEvent(chromeos::PowerManagerClient::LidState state) {
    fake_power_manager_client_.SetLidState(state, base::TimeTicks::UnixEpoch());
  }

  void ReportPowerChangeEvent(
      power_manager::PowerSupplyProperties::ExternalPower power,
      float battery_percent) {
    power_manager::PowerSupplyProperties proto;
    proto.set_external_power(power);
    proto.set_battery_percent(battery_percent);
    fake_power_manager_client_.UpdatePowerProperties(proto);
  }

  void ReportTabletModeEvent(chromeos::PowerManagerClient::TabletMode mode) {
    fake_power_manager_client_.SetTabletMode(mode,
                                             base::TimeTicks::UnixEpoch());
  }

  void ReportVideoStart() { activity_logger_->OnVideoActivityStarted(); }

  void ReportScreenIdleState(bool screen_dim, bool screen_off) {
    power_manager::ScreenIdleState proto;
    proto.set_dimmed(screen_dim);
    proto.set_off(screen_off);
    fake_power_manager_client_.SendScreenIdleStateChanged(proto);
  }

  void ReportScreenLocked() {
    session_manager_.SetSessionState(session_manager::SessionState::LOCKED);
  }

  void ReportSuspend(power_manager::SuspendImminent::Reason reason,
                     base::TimeDelta sleep_duration) {
    fake_power_manager_client_.SendSuspendImminent(reason);
    thread_bundle()->FastForwardBy(sleep_duration);
    fake_power_manager_client_.SendSuspendDone(sleep_duration);
  }

  void ReportInactivityDelays(base::TimeDelta screen_dim_delay,
                              base::TimeDelta screen_off_delay) {
    power_manager::PowerManagementPolicy::Delays proto;
    proto.set_screen_dim_ms(screen_dim_delay.InMilliseconds());
    proto.set_screen_off_ms(screen_off_delay.InMilliseconds());
    fake_power_manager_client_.SetInactivityDelays(proto);
  }

  int GetNumberOfDeferredDims() {
    return fake_power_manager_client_.num_defer_screen_dim_calls();
  }

  TabProperty UpdateOpenTabURL() {
    return activity_logger_->UpdateOpenTabURL();
  }

  // Creates a test browser window and sets its visibility, activity and
  // incognito status.
  std::unique_ptr<Browser> CreateTestBrowser(bool is_visible,
                                             bool is_focused,
                                             bool is_incognito = false) {
    Profile* const original_profile = profile();
    Profile* const used_profile =
        is_incognito ? original_profile->GetOffTheRecordProfile()
                     : original_profile;
    Browser::CreateParams params(used_profile, true);

    auto dummy_window = std::make_unique<aura::Window>(nullptr);
    dummy_window->Init(ui::LAYER_SOLID_COLOR);
    root_window()->AddChild(dummy_window.get());
    dummy_window->SetBounds(gfx::Rect(root_window()->bounds().size()));
    if (is_visible) {
      dummy_window->Show();
    } else {
      dummy_window->Hide();
    }

    std::unique_ptr<Browser> browser =
        chrome::CreateBrowserWithAuraTestWindowForParams(
            std::move(dummy_window), &params);
    if (is_focused) {
      browser->window()->Activate();
    } else {
      browser->window()->Deactivate();
    }
    return browser;
  }

  // Adds a tab with specified url to the tab strip model. Also optionally sets
  // the tab to be the active one in the tab strip model.
  // If |mime_type| is an empty string, the content has a default text type.
  // TODO(jiameng): there doesn't seem to be a way to set form entry (via
  // page importance signal). Check if there's some other way to set it.
  ukm::SourceId CreateTestWebContents(TabStripModel* const tab_strip_model,
                                      const GURL& url,
                                      bool is_active,
                                      const std::string& mime_type = "") {
    DCHECK(tab_strip_model);
    DCHECK(!url.is_empty());
    content::WebContents* contents =
        tab_activity_simulator_.AddWebContentsAndNavigate(tab_strip_model, url);
    if (is_active) {
      tab_strip_model->ActivateTabAt(tab_strip_model->count() - 1);
    }
    if (!mime_type.empty())
      WebContentsTester::For(contents)->SetMainFrameMimeType(mime_type);

    WebContentsTester::For(contents)->TestSetIsLoading(false);
    return ukm::GetSourceIdForWebContentsDocument(contents);
  }

  TestingUserActivityUkmLogger delegate_;
  FakeSmartDimModel model_;
  chromeos::FakeChromeUserManager fake_user_manager_;
  // Only used to get SourceIds for URLs.
  ukm::TestAutoSetUkmRecorder ukm_recorder_;
  TabActivitySimulator tab_activity_simulator_;

  const GURL url1_ = GURL("https://example1.com/");
  const GURL url2_ = GURL("https://example2.com/");
  const GURL url3_ = GURL("https://example3.com/");
  const GURL url4_ = GURL("https://example4.com/");

 private:
  ui::UserActivityDetector user_activity_detector_;
  std::unique_ptr<IdleEventNotifier> idle_event_notifier_;
  chromeos::FakePowerManagerClient fake_power_manager_client_;
  session_manager::SessionManager session_manager_;
  std::unique_ptr<UserActivityManager> activity_logger_;

  DISALLOW_COPY_AND_ASSIGN(UserActivityManagerTest);
};

// After an idle event, we have a ui::Event, we should expect one
// UserActivityEvent.
TEST_F(UserActivityManagerTest, LogAfterIdleEvent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(2));
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(2);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
  EXPECT_FALSE(events[0].has_model_prediction());
  EXPECT_EQ(0, events[0].features().previous_positive_actions_count());
  EXPECT_EQ(0, events[0].features().previous_negative_actions_count());
}

// Get a user event before an idle event, we should not log it.
TEST_F(UserActivityManagerTest, LogBeforeIdleEvent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportUserActivity(nullptr);
  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  EXPECT_EQ(0U, delegate_.events().size());
}

// Get a user event, then an idle event, then another user event,
// we should log the last one.
TEST_F(UserActivityManagerTest, LogSecondEvent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportUserActivity(nullptr);
  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  // Another user event.
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
  EXPECT_FALSE(events[0].has_model_prediction());
  EXPECT_EQ(0, events[0].features().previous_positive_actions_count());
  EXPECT_EQ(0, events[0].features().previous_negative_actions_count());
}

// Log multiple events.
TEST_F(UserActivityManagerTest, LogMultipleEvents) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger the 1st idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  // First user event.
  ReportUserActivity(nullptr);

  // Trigger the 2nd idle event.
  ReportIdleEvent(data);
  // Second user event.
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(2));
  ReportUserActivity(nullptr);

  // Trigger the 3rd idle event.
  ReportIdleEvent(data);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(3));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(10));

  // Trigger the 4th idle event.
  ReportIdleEvent(data);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(4));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(10));

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(4U, events.size());

  UserActivityEvent::Event expected_event1;
  expected_event1.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event1.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event1.set_log_duration_sec(0);
  expected_event1.set_screen_dim_occurred(false);
  expected_event1.set_screen_off_occurred(false);
  expected_event1.set_screen_lock_occurred(false);

  UserActivityEvent::Event expected_event2;
  expected_event2.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event2.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event2.set_log_duration_sec(2);
  expected_event2.set_screen_dim_occurred(false);
  expected_event2.set_screen_off_occurred(false);
  expected_event2.set_screen_lock_occurred(false);

  UserActivityEvent::Event expected_event3;
  expected_event3.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event3.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event3.set_log_duration_sec(3);
  expected_event3.set_screen_dim_occurred(false);
  expected_event3.set_screen_off_occurred(false);
  expected_event3.set_screen_lock_occurred(false);

  UserActivityEvent::Event expected_event4;
  expected_event4.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event4.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event4.set_log_duration_sec(4);
  expected_event4.set_screen_dim_occurred(false);
  expected_event4.set_screen_off_occurred(false);
  expected_event4.set_screen_lock_occurred(false);

  EqualEvent(expected_event1, events[0].event());
  EqualEvent(expected_event2, events[1].event());
  EqualEvent(expected_event3, events[2].event());
  EqualEvent(expected_event4, events[3].event());
  EXPECT_FALSE(events[0].has_model_prediction());
  EXPECT_FALSE(events[1].has_model_prediction());
  EXPECT_FALSE(events[2].has_model_prediction());
  EXPECT_FALSE(events[3].has_model_prediction());

  EXPECT_EQ(0, events[0].features().previous_positive_actions_count());
  EXPECT_EQ(0, events[0].features().previous_negative_actions_count());

  EXPECT_EQ(0, events[1].features().previous_positive_actions_count());
  EXPECT_EQ(1, events[1].features().previous_negative_actions_count());

  EXPECT_EQ(0, events[2].features().previous_positive_actions_count());
  EXPECT_EQ(2, events[2].features().previous_negative_actions_count());

  EXPECT_EQ(1, events[3].features().previous_positive_actions_count());
  EXPECT_EQ(2, events[3].features().previous_negative_actions_count());
}

TEST_F(UserActivityManagerTest, UserCloseLid) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportLidEvent(chromeos::PowerManagerClient::LidState::OPEN);
  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(2));
  ReportLidEvent(chromeos::PowerManagerClient::LidState::CLOSED);
  const std::vector<UserActivityEvent>& events = delegate_.events();
  EXPECT_TRUE(events.empty());
}

TEST_F(UserActivityManagerTest, PowerChangeActivity) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportPowerChangeEvent(power_manager::PowerSupplyProperties::AC, 23.0f);
  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  // We don't care about battery percentage change, but only power source.
  ReportPowerChangeEvent(power_manager::PowerSupplyProperties::AC, 25.0f);
  ReportPowerChangeEvent(power_manager::PowerSupplyProperties::DISCONNECTED,
                         28.0f);
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::POWER_CHANGED);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

TEST_F(UserActivityManagerTest, VideoActivity) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportVideoStart();
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::VIDEO_ACTIVITY);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

// System remains idle, screen is dimmed then turned off, and system is finally
// suspended.
TEST_F(UserActivityManagerTest, SystemIdleSuspend) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportScreenIdleState(true /* screen_dim */, false /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(30));
  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(10));

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event.set_log_duration_sec(50);
  expected_event.set_screen_dim_occurred(true);
  expected_event.set_screen_off_occurred(true);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

// System remains idle, screen is dimmed then turned off, but system is not
// suspended.
TEST_F(UserActivityManagerTest, SystemIdleNotSuspend) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportScreenIdleState(true /* screen_dim */, false /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(30));
  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);
  thread_bundle()->RunUntilIdle();

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(0U, events.size());
}

// Test system idle interrupt by user activity.
// We should only observe user activity.
TEST_F(UserActivityManagerTest, SystemIdleInterrupted) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportScreenIdleState(true /* screen_dim */, false /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(30));
  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(1));

  ReportUserActivity(nullptr);
  thread_bundle()->RunUntilIdle();

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(51);
  expected_event.set_screen_dim_occurred(true);
  expected_event.set_screen_off_occurred(true);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

TEST_F(UserActivityManagerTest, ScreenLockNoSuspend) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportScreenLocked();
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(0U, events.size());
}

TEST_F(UserActivityManagerTest, ScreenLockWithSuspend) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportScreenLocked();
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(1));

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(true);
  EqualEvent(expected_event, events[0].event());
}

// As we log when SuspendImminent is received, sleep duration from SuspendDone
// doesn't make any difference.
TEST_F(UserActivityManagerTest, SuspendIdleShortSleepDuration) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(1));
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event.set_log_duration_sec(20);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

TEST_F(UserActivityManagerTest, SuspendLidClosed) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportSuspend(power_manager::SuspendImminent_Reason_LID_CLOSED,
                base::TimeDelta::FromSeconds(10));
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::OFF);
  expected_event.set_reason(UserActivityEvent::Event::LID_CLOSED);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

TEST_F(UserActivityManagerTest, SuspendOther) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Trigger an idle event.
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportSuspend(power_manager::SuspendImminent_Reason_OTHER,
                base::TimeDelta::FromSeconds(10));
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::OFF);
  expected_event.set_reason(UserActivityEvent::Event::MANUAL_SLEEP);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

// Test feature extraction.
TEST_F(UserActivityManagerTest, FeatureExtraction) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportLidEvent(chromeos::PowerManagerClient::LidState::OPEN);
  ReportTabletModeEvent(chromeos::PowerManagerClient::TabletMode::UNSUPPORTED);
  ReportPowerChangeEvent(power_manager::PowerSupplyProperties::AC, 23.0f);

  IdleEventNotifier::ActivityData data;
  data.last_activity_day = UserActivityEvent_Features_DayOfWeek_MON;
  data.last_activity_time_of_day = base::TimeDelta::FromSeconds(100);
  data.recent_time_active = base::TimeDelta::FromSeconds(10);
  data.time_since_last_mouse = base::TimeDelta::FromSeconds(20);
  data.time_since_last_touch = base::TimeDelta::FromSeconds(30);
  data.video_playing_time = base::TimeDelta::FromSeconds(90);
  data.time_since_video_ended = base::TimeDelta::FromSeconds(2);
  data.key_events_in_last_hour = 0;
  data.mouse_events_in_last_hour = 10;
  data.touch_events_in_last_hour = 20;

  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(UserActivityEvent::Features::CLAMSHELL, features.device_mode());
  EXPECT_EQ(23.0f, features.battery_percent());
  EXPECT_FALSE(features.on_battery());
  EXPECT_EQ(UserActivityEvent::Features::UNMANAGED,
            features.device_management());
  EXPECT_EQ(UserActivityEvent_Features_DayOfWeek_MON,
            features.last_activity_day());
  EXPECT_EQ(100, features.last_activity_time_sec());
  EXPECT_EQ(10, features.recent_time_active_sec());
  EXPECT_EQ(20, features.time_since_last_mouse_sec());
  EXPECT_EQ(30, features.time_since_last_touch_sec());
  EXPECT_EQ(90, features.video_playing_time_sec());
  EXPECT_EQ(2, features.time_since_video_ended_sec());
  EXPECT_EQ(0, features.key_events_in_last_hour());
  EXPECT_EQ(10, features.mouse_events_in_last_hour());
  EXPECT_EQ(20, features.touch_events_in_last_hour());
  EXPECT_FALSE(features.has_last_user_activity_time_sec());
  EXPECT_FALSE(features.has_time_since_last_key_sec());
  EXPECT_FALSE(features.screen_dimmed_initially());
  EXPECT_FALSE(features.screen_off_initially());
  EXPECT_FALSE(features.screen_locked_initially());
}

TEST_F(UserActivityManagerTest, ManagedDevice) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  fake_user_manager_.set_is_enterprise_managed(true);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(UserActivityEvent::Features::MANAGED, features.device_management());
}

TEST_F(UserActivityManagerTest, DimAndOffDelays) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportInactivityDelays(
      base::TimeDelta::FromMilliseconds(2000) /* screen_dim_delay */,
      base::TimeDelta::FromMilliseconds(3000) /* screen_off_delay */);
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(2, features.on_to_dim_sec());
  EXPECT_EQ(1, features.dim_to_screen_off_sec());
}

TEST_F(UserActivityManagerTest, DimDelays) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportInactivityDelays(
      base::TimeDelta::FromMilliseconds(2000) /* screen_dim_delay */,
      base::TimeDelta() /* screen_off_delay */);
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(2, features.on_to_dim_sec());
  EXPECT_TRUE(!features.has_dim_to_screen_off_sec());
}

TEST_F(UserActivityManagerTest, OffDelays) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportInactivityDelays(
      base::TimeDelta() /* screen_dim_delay */,
      base::TimeDelta::FromMilliseconds(4000) /* screen_off_delay */);
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(4, features.dim_to_screen_off_sec());
  EXPECT_TRUE(!features.has_on_to_dim_sec());
}

// Screen is off when idle event is reported. No subsequent change in screen
// state.
TEST_F(UserActivityManagerTest, InitialScreenOff) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportScreenIdleState(false /* screen_dim */, true /* screen_off */);

  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(7));
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_TRUE(features.screen_dimmed_initially());
  EXPECT_TRUE(features.screen_off_initially());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(7);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

// Screen is off when idle event is reported. No subsequent change in screen
// state.
TEST_F(UserActivityManagerTest, InitialScreenStateFlipped) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  ReportScreenIdleState(true /* screen_dim */, false /* screen_off */);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportScreenIdleState(false /* screen_dim */, false /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(7));
  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);

  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_TRUE(features.screen_dimmed_initially());
  EXPECT_FALSE(features.screen_off_initially());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(7);
  expected_event.set_screen_dim_occurred(true);
  expected_event.set_screen_off_occurred(true);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

// Screen is off when idle event is reported. No subsequent change in screen
// state.
TEST_F(UserActivityManagerTest, ScreenOffStateChanged) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);

  ReportScreenIdleState(true /* screen_dim */, false /* screen_off */);
  ReportScreenIdleState(true /* screen_dim */, true /* screen_off */);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(7));
  ReportScreenIdleState(false /* screen_dim */, false /* screen_off */);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_FALSE(features.screen_dimmed_initially());
  EXPECT_FALSE(features.screen_off_initially());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(7);
  expected_event.set_screen_dim_occurred(true);
  expected_event.set_screen_off_occurred(true);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());
}

TEST_F(UserActivityManagerTest, ScreenDimDeferredWithFinalEvent) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", "0.651"}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  model_.set_inactivity_score(60);
  model_.set_decision_threshold(65);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  ReportUserActivity(nullptr);
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 1);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());

  UserActivityEvent::ModelPrediction expected_prediction;
  expected_prediction.set_decision_threshold(65);
  expected_prediction.set_inactivity_score(60);
  expected_prediction.set_model_applied(true);
  expected_prediction.set_response(UserActivityEvent::ModelPrediction::NO_DIM);
  EqualModelPrediction(expected_prediction, events[0].model_prediction());
}

TEST_F(UserActivityManagerTest, ScreenDimDeferredWithoutFinalEvent) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", "0.651"}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  model_.set_inactivity_score(60);
  model_.set_decision_threshold(65);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 1);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  EXPECT_TRUE(events.empty());
}

// Tests the cancellation of a Smart Dim decision request, immediately after it
// has been requested.
TEST_F(UserActivityManagerTest, ScreenDimRequestCanceled) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", "0.651"}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  model_.set_inactivity_score(60);
  model_.set_decision_threshold(65);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  // Report user activity immediately after the idle event, so that
  // the SmartDimModel doesn't get a chance to run.
  ReportUserActivity(nullptr);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(0, GetNumberOfDeferredDims());

  std::string hist_complete("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(hist_complete, 0);
  std::string hist_cancel("PowerML.SmartDimModel.RequestCanceledDuration");
  histogram_tester.ExpectTotalCount(hist_cancel, 1);

  // Since the pending SmartDim decision request was canceled, we shouldn't
  // have any UserActivityEvent generated.
  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(0U, events.size());
}

// Tests the cancellation of a Smart Dim decision request, when two idle events
// occur in quick succession. This verifies that only one request is serviced.
TEST_F(UserActivityManagerTest, ScreenDimConsecutiveRequests) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", "0.651"}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  model_.set_inactivity_score(60);
  model_.set_decision_threshold(65);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  ReportUserActivity(nullptr);
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  std::string hist_complete("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(hist_complete, 1);
  std::string hist_cancel("PowerML.SmartDimModel.RequestCanceledDuration");
  histogram_tester.ExpectTotalCount(hist_cancel, 1);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());

  UserActivityEvent::ModelPrediction expected_prediction;
  expected_prediction.set_decision_threshold(65);
  expected_prediction.set_inactivity_score(60);
  expected_prediction.set_model_applied(true);
  expected_prediction.set_response(UserActivityEvent::ModelPrediction::NO_DIM);
  EqualModelPrediction(expected_prediction, events[0].model_prediction());
}

TEST_F(UserActivityManagerTest, ScreenDimNotDeferred) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", base::NumberToString(0.5)}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  model_.set_inactivity_score(60);
  model_.set_decision_threshold(50);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  ReportUserActivity(nullptr);
  EXPECT_EQ(0, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 1);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::ModelPrediction expected_prediction;
  expected_prediction.set_decision_threshold(50);
  expected_prediction.set_inactivity_score(60);
  expected_prediction.set_model_applied(true);
  expected_prediction.set_response(UserActivityEvent::ModelPrediction::DIM);

  EqualModelPrediction(expected_prediction, events[0].model_prediction());
}

TEST_F(UserActivityManagerTest, TwoScreenDimImminentWithEventInBetween) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", base::NumberToString(0.5)}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);
  model_.set_decision_threshold(50);

  // 1st ScreenDimImminent gets deferred
  model_.set_inactivity_score(40);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(6));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(3));

  // 2nd ScreenDimImminent is not deferred despite model score says so.
  model_.set_inactivity_score(20);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(10));
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 2);

  // Log when a SuspendImminent is received
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(3));

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(2U, events.size());

  // The first screen dim imminent event.
  UserActivityEvent::Event expected_event1;
  expected_event1.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event1.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event1.set_log_duration_sec(6);
  expected_event1.set_screen_dim_occurred(false);
  expected_event1.set_screen_off_occurred(false);
  expected_event1.set_screen_lock_occurred(false);
  EqualEvent(expected_event1, events[0].event());

  UserActivityEvent::ModelPrediction expected_prediction1;
  expected_prediction1.set_decision_threshold(50);
  expected_prediction1.set_inactivity_score(40);
  expected_prediction1.set_model_applied(true);
  expected_prediction1.set_response(UserActivityEvent::ModelPrediction::NO_DIM);

  EqualModelPrediction(expected_prediction1, events[0].model_prediction());

  // The second screen dim imminent event.
  UserActivityEvent::Event expected_event2;
  expected_event2.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event2.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event2.set_log_duration_sec(20);
  expected_event2.set_screen_dim_occurred(false);
  expected_event2.set_screen_off_occurred(false);
  expected_event2.set_screen_lock_occurred(false);
  EqualEvent(expected_event2, events[1].event());

  UserActivityEvent::ModelPrediction expected_prediction2;
  expected_prediction2.set_decision_threshold(50);
  expected_prediction2.set_inactivity_score(20);
  expected_prediction2.set_model_applied(false);
  expected_prediction2.set_response(UserActivityEvent::ModelPrediction::NO_DIM);
  EqualModelPrediction(expected_prediction2, events[1].model_prediction());
}

TEST_F(UserActivityManagerTest, TwoScreenDimImminentWithoutEventInBetween) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", base::NumberToString(0.5)}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);
  model_.set_decision_threshold(50);

  // 1st ScreenDimImminent gets deferred
  model_.set_inactivity_score(40);
  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  // 2nd ScreenDimImminent is not deferred despite model score says so.
  model_.set_inactivity_score(20);
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(10));
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  EXPECT_EQ(1, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 2);

  // Log when a SuspendImminent is received
  thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(20));
  ReportSuspend(power_manager::SuspendImminent_Reason_IDLE,
                base::TimeDelta::FromSeconds(3));

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(2U, events.size());

  // The current event logged is after the earlier idle event.
  UserActivityEvent::Event expected_event1;
  expected_event1.set_type(UserActivityEvent::Event::TIMEOUT);
  expected_event1.set_reason(UserActivityEvent::Event::IDLE_SLEEP);
  expected_event1.set_log_duration_sec(20);
  expected_event1.set_screen_dim_occurred(false);
  expected_event1.set_screen_off_occurred(false);
  expected_event1.set_screen_lock_occurred(false);
  EqualEvent(expected_event1, events[1].event());

  UserActivityEvent::ModelPrediction expected_prediction1;
  expected_prediction1.set_decision_threshold(50);
  expected_prediction1.set_inactivity_score(20);
  expected_prediction1.set_model_applied(false);
  expected_prediction1.set_response(UserActivityEvent::ModelPrediction::NO_DIM);

  EqualModelPrediction(expected_prediction1, events[1].model_prediction());

  UserActivityEvent::Event expected_event2 = expected_event1;
  expected_event2.set_log_duration_sec(30);
  EqualEvent(expected_event2, events[0].event());

  UserActivityEvent::ModelPrediction expected_prediction2;
  expected_prediction2.set_decision_threshold(50);
  expected_prediction2.set_inactivity_score(40);
  expected_prediction2.set_model_applied(true);
  expected_prediction2.set_response(UserActivityEvent::ModelPrediction::NO_DIM);

  EqualModelPrediction(expected_prediction2, events[0].model_prediction());
}

TEST_F(UserActivityManagerTest, ModelError) {
  base::HistogramTester histogram_tester;
  const std::map<std::string, std::string> params = {
      {"dim_threshold", "0.651"}};
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      features::kUserActivityPrediction, params);

  // This value will trigger a model error.
  model_.set_inactivity_score(160);
  model_.set_decision_threshold(65);

  const IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  thread_bundle()->RunUntilIdle();
  ReportUserActivity(nullptr);
  EXPECT_EQ(0, GetNumberOfDeferredDims());

  std::string histogram("PowerML.SmartDimModel.RequestCompleteDuration");
  histogram_tester.ExpectTotalCount(histogram, 1);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  UserActivityEvent::Event expected_event;
  expected_event.set_type(UserActivityEvent::Event::REACTIVATE);
  expected_event.set_reason(UserActivityEvent::Event::USER_ACTIVITY);
  expected_event.set_log_duration_sec(0);
  expected_event.set_screen_dim_occurred(false);
  expected_event.set_screen_off_occurred(false);
  expected_event.set_screen_lock_occurred(false);
  EqualEvent(expected_event, events[0].event());

  UserActivityEvent::ModelPrediction expected_prediction;
  expected_prediction.set_model_applied(false);
  expected_prediction.set_response(
      UserActivityEvent::ModelPrediction::MODEL_ERROR);
  EqualModelPrediction(expected_prediction, events[0].model_prediction());
}

TEST_F(UserActivityManagerTest, BasicTabs) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  std::unique_ptr<Browser> browser =
      CreateTestBrowser(true /* is_visible */, true /* is_focused */);
  BrowserList::GetInstance()->SetLastActive(browser.get());
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  const ukm::SourceId source_id1 = CreateTestWebContents(
      tab_strip_model, url1_, true /* is_active */, "application/pdf");
  SiteEngagementService::Get(profile())->ResetBaseScoreForURL(url1_, 95);

  CreateTestWebContents(tab_strip_model, url2_, false /* is_active */);

  IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(features.source_id(), source_id1);
  EXPECT_EQ(features.tab_domain(), url1_.host());
  EXPECT_FALSE(features.tab_domain().empty());
  EXPECT_EQ(features.engagement_score(), 90);
  EXPECT_FALSE(features.has_form_entry());

  tab_strip_model->CloseAllTabs();
}

TEST_F(UserActivityManagerTest, MultiBrowsersAndTabs) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  // Simulates three browsers:
  //  - browser1 is the last active but minimized and so not visible.
  //  - browser2 and browser3 are both visible but browser2 is the topmost.
  std::unique_ptr<Browser> browser1 =
      CreateTestBrowser(false /* is_visible */, false /* is_focused */);
  std::unique_ptr<Browser> browser2 =
      CreateTestBrowser(true /* is_visible */, true /* is_focused */);
  std::unique_ptr<Browser> browser3 =
      CreateTestBrowser(true /* is_visible */, false /* is_focused */);

  BrowserList::GetInstance()->SetLastActive(browser3.get());
  BrowserList::GetInstance()->SetLastActive(browser2.get());
  BrowserList::GetInstance()->SetLastActive(browser1.get());

  TabStripModel* tab_strip_model1 = browser1->tab_strip_model();
  CreateTestWebContents(tab_strip_model1, url1_, false /* is_active */);
  CreateTestWebContents(tab_strip_model1, url2_, true /* is_active */);

  TabStripModel* tab_strip_model2 = browser2->tab_strip_model();
  const ukm::SourceId source_id3 =
      CreateTestWebContents(tab_strip_model2, url3_, true /* is_active */);

  TabStripModel* tab_strip_model3 = browser3->tab_strip_model();
  CreateTestWebContents(tab_strip_model3, url4_, true /* is_active */);

  IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_EQ(features.source_id(), source_id3);
  EXPECT_EQ(features.tab_domain(), url3_.host());
  EXPECT_EQ(features.engagement_score(), 0);
  EXPECT_FALSE(features.has_form_entry());

  tab_strip_model1->CloseAllTabs();
  tab_strip_model2->CloseAllTabs();
  tab_strip_model3->CloseAllTabs();
}

TEST_F(UserActivityManagerTest, Incognito) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  std::unique_ptr<Browser> browser = CreateTestBrowser(
      true /* is_visible */, true /* is_focused */, true /* is_incognito */);
  BrowserList::GetInstance()->SetLastActive(browser.get());

  TabStripModel* tab_strip_model = browser->tab_strip_model();
  CreateTestWebContents(tab_strip_model, url1_, true /* is_active */);
  CreateTestWebContents(tab_strip_model, url2_, false /* is_active */);

  IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_FALSE(features.has_source_id());
  EXPECT_FALSE(features.has_tab_domain());
  EXPECT_FALSE(features.has_engagement_score());
  EXPECT_FALSE(features.has_has_form_entry());

  tab_strip_model->CloseAllTabs();
}

TEST_F(UserActivityManagerTest, NoOpenTabs) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(features::kUserActivityPrediction);

  std::unique_ptr<Browser> browser =
      CreateTestBrowser(true /* is_visible */, true /* is_focused */);

  IdleEventNotifier::ActivityData data;
  ReportIdleEvent(data);
  ReportUserActivity(nullptr);

  const std::vector<UserActivityEvent>& events = delegate_.events();
  ASSERT_EQ(1U, events.size());

  const UserActivityEvent::Features& features = events[0].features();
  EXPECT_FALSE(features.has_source_id());
  EXPECT_FALSE(features.has_tab_domain());
  EXPECT_FALSE(features.has_engagement_score());
  EXPECT_FALSE(features.has_has_form_entry());
}

}  // namespace ml
}  // namespace power
}  // namespace chromeos
