chromium/chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector.cc

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

#include "chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector.h"

#include "base/command_line.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "chromeos/ash/components/dbus/dbus_thread_manager.h"
#include "chromeos/ash/components/network/network_handler.h"
#include "chromeos/ash/components/network/network_state.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_type_pattern.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/network_service_instance.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace em = enterprise_management;

namespace policy {

namespace {

std::unique_ptr<em::AppInstallReportLogEvent> CreateSessionChangeEvent(
    em::AppInstallReportLogEvent::SessionStateChangeType type) {
  std::unique_ptr<em::AppInstallReportLogEvent> event =
      std::make_unique<em::AppInstallReportLogEvent>();
  event->set_event_type(em::AppInstallReportLogEvent::SESSION_STATE_CHANGE);
  event->set_session_state_change_type(type);
  return event;
}

void SetTimestampFromTime(em::AppInstallReportLogEvent* event,
                          base::Time time) {
  event->set_timestamp((time - base::Time::UnixEpoch()).InMicroseconds());
}

}  // namespace

ArcAppInstallEventLogCollector::ArcAppInstallEventLogCollector(
    Delegate* delegate,
    Profile* profile,
    const std::set<std::string>& pending_packages)
    : InstallEventLogCollectorBase(profile),
      delegate_(delegate),
      pending_packages_(pending_packages) {
  // Might not be available in unit test.
  arc::ArcPolicyBridge* const policy_bridge =
      arc::ArcPolicyBridge::GetForBrowserContext(profile_);
  if (policy_bridge) {
    policy_bridge->AddObserver(this);
  }
  ArcAppListPrefs* const app_prefs = ArcAppListPrefs::Get(profile_);
  if (app_prefs) {
    app_prefs->AddObserver(this);
  }
}

ArcAppInstallEventLogCollector::~ArcAppInstallEventLogCollector() {
  ArcAppListPrefs* const app_prefs = ArcAppListPrefs::Get(profile_);
  if (app_prefs) {
    app_prefs->RemoveObserver(this);
  }
  arc::ArcPolicyBridge* const policy_bridge =
      arc::ArcPolicyBridge::GetForBrowserContext(profile_);
  if (policy_bridge) {
    policy_bridge->RemoveObserver(this);
  }
}

void ArcAppInstallEventLogCollector::OnPendingPackagesChanged(
    const std::set<std::string>& pending_packages) {
  pending_packages_ = pending_packages;
}

void ArcAppInstallEventLogCollector::OnLoginInternal() {
  std::unique_ptr<em::AppInstallReportLogEvent> event =
      CreateSessionChangeEvent(em::AppInstallReportLogEvent::LOGIN);
  event->set_online(online_);
  delegate_->AddForAllPackages(std::move(event));
}

void ArcAppInstallEventLogCollector::OnLogoutInternal() {
  delegate_->AddForAllPackages(
      CreateSessionChangeEvent(em::AppInstallReportLogEvent::LOGOUT));
}

void ArcAppInstallEventLogCollector::SuspendImminent(
    power_manager::SuspendImminent::Reason reason) {
  delegate_->AddForAllPackages(
      CreateSessionChangeEvent(em::AppInstallReportLogEvent::SUSPEND));
}

void ArcAppInstallEventLogCollector::SuspendDone(
    base::TimeDelta sleep_duration) {
  delegate_->AddForAllPackages(
      CreateSessionChangeEvent(em::AppInstallReportLogEvent::RESUME));
}

void ArcAppInstallEventLogCollector::OnConnectionStateChanged(
    network::mojom::ConnectionType type) {
  std::unique_ptr<em::AppInstallReportLogEvent> event =
      std::make_unique<em::AppInstallReportLogEvent>();
  event->set_event_type(em::AppInstallReportLogEvent::CONNECTIVITY_CHANGE);
  event->set_online(online_);
  delegate_->AddForAllPackages(std::move(event));
}

void ArcAppInstallEventLogCollector::OnInstallationStarted(
    const std::string& package_name) {
  if (!pending_packages_.count(package_name)) {
    return;
  }

  auto event = std::make_unique<em::AppInstallReportLogEvent>();
  event->set_event_type(em::AppInstallReportLogEvent::INSTALLATION_STARTED);
  delegate_->Add(package_name, true /* gather_disk_space_info */,
                 std::move(event));
}

void ArcAppInstallEventLogCollector::OnInstallationFinished(
    const std::string& package_name,
    bool success,
    bool is_launchable_app) {
  if (!pending_packages_.count(package_name)) {
    return;
  }

  auto event = std::make_unique<em::AppInstallReportLogEvent>();
  event->set_event_type(
      success ? em::AppInstallReportLogEvent::INSTALLATION_FINISHED
              : em::AppInstallReportLogEvent::INSTALLATION_FAILED);
  delegate_->UpdatePolicySuccessRate(package_name, success);
  delegate_->Add(package_name, true /* gather_disk_space_info */,
                 std::move(event));
}

void ArcAppInstallEventLogCollector::OnPlayStoreLocalPolicySet(
    base::Time time,
    const std::set<std::string>& package_names) {
  for (const std::string& package_name : package_names) {
    auto event = std::make_unique<em::AppInstallReportLogEvent>();
    event->set_event_type(
        em::AppInstallReportLogEvent::PLAYSTORE_LOCAL_POLICY_SET);
    SetTimestampFromTime(event.get(), time);
    delegate_->Add(package_name, true /* gather_disk_space_info */,
                   std::move(event));
  }
}

}  // namespace policy