Commit 9c18d34f authored by khmel@google.com's avatar khmel@google.com Committed by Commit Bot

Add installation packages event into app install logger.

This adds information about package installation started, finished and
failed into app install logger.

Bug: b/73277923
Test: unit_tests, manually
Change-Id: I0903e72eef8090328d9d9e3a14d12473d1610fab
Reviewed-on: https://chromium-review.googlesource.com/996302
Commit-Queue: Yury Khmel <khmel@google.com>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Reviewed-by: default avatarBartosz Fabianowski <bartfab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550083}
parent 72d9e8f4
...@@ -59,7 +59,10 @@ AppInstallEventLogCollector::AppInstallEventLogCollector( ...@@ -59,7 +59,10 @@ AppInstallEventLogCollector::AppInstallEventLogCollector(
Delegate* delegate, Delegate* delegate,
Profile* profile, Profile* profile,
const std::set<std::string>& pending_packages) const std::set<std::string>& pending_packages)
: delegate_(delegate), profile_(profile), online_(GetOnlineState()) { : delegate_(delegate),
profile_(profile),
online_(GetOnlineState()),
pending_packages_(pending_packages) {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
this); this);
net::NetworkChangeNotifier::AddNetworkChangeObserver(this); net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
...@@ -69,9 +72,17 @@ AppInstallEventLogCollector::AppInstallEventLogCollector( ...@@ -69,9 +72,17 @@ AppInstallEventLogCollector::AppInstallEventLogCollector(
if (policy_bridge) { if (policy_bridge) {
policy_bridge->AddObserver(this); policy_bridge->AddObserver(this);
} }
ArcAppListPrefs* const app_prefs = ArcAppListPrefs::Get(profile_);
if (app_prefs) {
app_prefs->AddObserver(this);
}
} }
AppInstallEventLogCollector::~AppInstallEventLogCollector() { AppInstallEventLogCollector::~AppInstallEventLogCollector() {
ArcAppListPrefs* const app_prefs = ArcAppListPrefs::Get(profile_);
if (app_prefs) {
app_prefs->RemoveObserver(this);
}
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
this); this);
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
...@@ -83,8 +94,9 @@ AppInstallEventLogCollector::~AppInstallEventLogCollector() { ...@@ -83,8 +94,9 @@ AppInstallEventLogCollector::~AppInstallEventLogCollector() {
} }
void AppInstallEventLogCollector::OnPendingPackagesChanged( void AppInstallEventLogCollector::OnPendingPackagesChanged(
const std::set<std::string>& added, const std::set<std::string>& pending_packages) {
const std::set<std::string>& removed) {} pending_packages_ = pending_packages;
}
void AppInstallEventLogCollector::AddLoginEvent() { void AppInstallEventLogCollector::AddLoginEvent() {
// Don't log in case session is restared or recovered from crash. // Don't log in case session is restared or recovered from crash.
...@@ -173,4 +185,31 @@ void AppInstallEventLogCollector::OnCloudDpsFailed( ...@@ -173,4 +185,31 @@ void AppInstallEventLogCollector::OnCloudDpsFailed(
std::move(event)); std::move(event));
} }
void AppInstallEventLogCollector::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 AppInstallEventLogCollector::OnInstallationFinished(
const std::string& package_name,
bool success) {
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_->Add(package_name, true /* gather_disk_space_info */,
std::move(event));
}
} // namespace policy } // namespace policy
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/power_manager_client.h"
#include "components/arc/common/policy.mojom.h" #include "components/arc/common/policy.mojom.h"
#include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier.h"
...@@ -30,7 +31,8 @@ namespace policy { ...@@ -30,7 +31,8 @@ namespace policy {
class AppInstallEventLogCollector class AppInstallEventLogCollector
: public chromeos::PowerManagerClient::Observer, : public chromeos::PowerManagerClient::Observer,
public arc::ArcPolicyBridge::Observer, public arc::ArcPolicyBridge::Observer,
public net::NetworkChangeNotifier::NetworkChangeObserver { public net::NetworkChangeNotifier::NetworkChangeObserver,
public ArcAppListPrefs::Observer {
public: public:
// The delegate that events are forwarded to for inclusion in the log. // The delegate that events are forwarded to for inclusion in the log.
class Delegate { class Delegate {
...@@ -62,8 +64,7 @@ class AppInstallEventLogCollector ...@@ -62,8 +64,7 @@ class AppInstallEventLogCollector
~AppInstallEventLogCollector() override; ~AppInstallEventLogCollector() override;
// Called whenever the list of pending app-install requests changes. // Called whenever the list of pending app-install requests changes.
void OnPendingPackagesChanged(const std::set<std::string>& added, void OnPendingPackagesChanged(const std::set<std::string>& pending_packages);
const std::set<std::string>& removed);
// Called in case of login and pending apps. // Called in case of login and pending apps.
void AddLoginEvent(); void AddLoginEvent();
...@@ -88,6 +89,11 @@ class AppInstallEventLogCollector ...@@ -88,6 +89,11 @@ class AppInstallEventLogCollector
const std::string& package_name, const std::string& package_name,
arc::mojom::InstallErrorReason reason) override; arc::mojom::InstallErrorReason reason) override;
// ArcAppListPrefs::Observer:
void OnInstallationStarted(const std::string& package_name) override;
void OnInstallationFinished(const std::string& package_name,
bool success) override;
private: private:
Delegate* const delegate_; Delegate* const delegate_;
Profile* const profile_; Profile* const profile_;
...@@ -95,6 +101,9 @@ class AppInstallEventLogCollector ...@@ -95,6 +101,9 @@ class AppInstallEventLogCollector
// Whether the device is currently online. // Whether the device is currently online.
bool online_ = false; bool online_ = false;
// Set of apps whose push-install is currently pending.
std::set<std::string> pending_packages_;
DISALLOW_COPY_AND_ASSIGN(AppInstallEventLogCollector); DISALLOW_COPY_AND_ASSIGN(AppInstallEventLogCollector);
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/shill_service_client.h" #include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_handler.h" #include "chromeos/network/network_handler.h"
#include "components/arc/common/app.mojom.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h" #include "components/prefs/testing_pref_service.h"
...@@ -131,9 +133,13 @@ class AppInstallEventLogCollectorTest : public testing::Test { ...@@ -131,9 +133,13 @@ class AppInstallEventLogCollectorTest : public testing::Test {
shill::kTypeEthernet, shill::kStateOffline, shill::kTypeEthernet, shill::kStateOffline,
true /* visible */); true /* visible */);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
arc_app_test_.SetUp(profile_.get());
} }
void TearDown() override { void TearDown() override {
arc_app_test_.TearDown();
profile_.reset(); profile_.reset();
chromeos::NetworkHandler::Shutdown(); chromeos::NetworkHandler::Shutdown();
chromeos::DBusThreadManager::Shutdown(); chromeos::DBusThreadManager::Shutdown();
...@@ -169,6 +175,7 @@ class AppInstallEventLogCollectorTest : public testing::Test { ...@@ -169,6 +175,7 @@ class AppInstallEventLogCollectorTest : public testing::Test {
chromeos::FakePowerManagerClient* power_manager_client() { chromeos::FakePowerManagerClient* power_manager_client() {
return power_manager_client_; return power_manager_client_;
} }
ArcAppListPrefs* app_prefs() { return arc_app_test_.arc_app_list_prefs(); }
const std::set<std::string> packages_ = {kPackageName}; const std::set<std::string> packages_ = {kPackageName};
...@@ -181,6 +188,7 @@ class AppInstallEventLogCollectorTest : public testing::Test { ...@@ -181,6 +188,7 @@ class AppInstallEventLogCollectorTest : public testing::Test {
FakeAppInstallEventLogCollectorDelegate delegate_; FakeAppInstallEventLogCollectorDelegate delegate_;
TestingPrefServiceSimple pref_service_; TestingPrefServiceSimple pref_service_;
chromeos::FakePowerManagerClient* power_manager_client_ = nullptr; chromeos::FakePowerManagerClient* power_manager_client_ = nullptr;
ArcAppTest arc_app_test_;
DISALLOW_COPY_AND_ASSIGN(AppInstallEventLogCollectorTest); DISALLOW_COPY_AND_ASSIGN(AppInstallEventLogCollectorTest);
}; };
...@@ -385,4 +393,56 @@ TEST_F(AppInstallEventLogCollectorTest, CloudDPSEvent) { ...@@ -385,4 +393,56 @@ TEST_F(AppInstallEventLogCollectorTest, CloudDPSEvent) {
delegate()->last_request().event.clouddps_response()); delegate()->last_request().event.clouddps_response());
} }
TEST_F(AppInstallEventLogCollectorTest, InstallPackages) {
arc::mojom::AppHost* const app_host = app_prefs();
std::unique_ptr<AppInstallEventLogCollector> collector =
std::make_unique<AppInstallEventLogCollector>(delegate(), profile(),
packages_);
app_host->OnInstallationStarted(kPackageName);
ASSERT_EQ(1, delegate()->add_count());
EXPECT_EQ(em::AppInstallReportLogEvent::INSTALLATION_STARTED,
delegate()->last_event().event_type());
EXPECT_EQ(kPackageName, delegate()->last_request().package_name);
EXPECT_TRUE(delegate()->last_request().add_disk_space_info);
// kPackageName2 is not in the pending set.
app_host->OnInstallationStarted(kPackageName2);
EXPECT_EQ(1, delegate()->add_count());
arc::mojom::InstallationResult result;
result.package_name = kPackageName;
result.success = true;
app_host->OnInstallationFinished(
arc::mojom::InstallationResultPtr(result.Clone()));
EXPECT_EQ(2, delegate()->add_count());
EXPECT_EQ(em::AppInstallReportLogEvent::INSTALLATION_FINISHED,
delegate()->last_event().event_type());
EXPECT_EQ(kPackageName, delegate()->last_request().package_name);
EXPECT_TRUE(delegate()->last_request().add_disk_space_info);
collector->OnPendingPackagesChanged({kPackageName, kPackageName2});
// Now kPackageName2 is in the pending set.
app_host->OnInstallationStarted(kPackageName2);
EXPECT_EQ(3, delegate()->add_count());
EXPECT_EQ(em::AppInstallReportLogEvent::INSTALLATION_STARTED,
delegate()->last_event().event_type());
EXPECT_EQ(kPackageName2, delegate()->last_request().package_name);
EXPECT_TRUE(delegate()->last_request().add_disk_space_info);
result.package_name = kPackageName2;
result.success = false;
app_host->OnInstallationFinished(
arc::mojom::InstallationResultPtr(result.Clone()));
EXPECT_EQ(4, delegate()->add_count());
EXPECT_EQ(em::AppInstallReportLogEvent::INSTALLATION_FAILED,
delegate()->last_event().event_type());
EXPECT_EQ(kPackageName2, delegate()->last_request().package_name);
EXPECT_TRUE(delegate()->last_request().add_disk_space_info);
EXPECT_EQ(0, delegate()->add_for_all_count());
}
} // namespace policy } // namespace policy
...@@ -260,7 +260,7 @@ void AppInstallEventLogger::OnComplianceReportReceived( ...@@ -260,7 +260,7 @@ void AppInstallEventLogger::OnComplianceReportReceived(
SetPref(arc::prefs::kArcPushInstallAppsPending, current_pending); SetPref(arc::prefs::kArcPushInstallAppsPending, current_pending);
if (!current_pending.empty()) { if (!current_pending.empty()) {
UpdateCollector({} /* added */, removed); UpdateCollector(current_pending);
} else { } else {
StopCollector(); StopCollector();
} }
...@@ -290,13 +290,12 @@ void AppInstallEventLogger::SetPref(const std::string& pref_name, ...@@ -290,13 +290,12 @@ void AppInstallEventLogger::SetPref(const std::string& pref_name,
} }
void AppInstallEventLogger::UpdateCollector( void AppInstallEventLogger::UpdateCollector(
const std::set<std::string>& added, const std::set<std::string>& pending) {
const std::set<std::string>& removed) {
if (!log_collector_) { if (!log_collector_) {
log_collector_ = log_collector_ =
std::make_unique<AppInstallEventLogCollector>(this, profile_, added); std::make_unique<AppInstallEventLogCollector>(this, profile_, pending);
} else { } else {
log_collector_->OnPendingPackagesChanged(added, removed); log_collector_->OnPendingPackagesChanged(pending);
} }
} }
...@@ -329,11 +328,9 @@ void AppInstallEventLogger::EvaluatePolicy(const policy::PolicyMap& policy, ...@@ -329,11 +328,9 @@ void AppInstallEventLogger::EvaluatePolicy(const policy::PolicyMap& policy,
SetPref(arc::prefs::kArcPushInstallAppsPending, current_pending); SetPref(arc::prefs::kArcPushInstallAppsPending, current_pending);
if (!current_pending.empty()) { if (!current_pending.empty()) {
UpdateCollector(current_pending);
if (initial) { if (initial) {
UpdateCollector(current_pending /* added */, {} /* removed */);
log_collector_->AddLoginEvent(); log_collector_->AddLoginEvent();
} else {
UpdateCollector(added, removed);
} }
} else { } else {
StopCollector(); StopCollector();
......
...@@ -104,8 +104,7 @@ class AppInstallEventLogger : public AppInstallEventLogCollector::Delegate, ...@@ -104,8 +104,7 @@ class AppInstallEventLogger : public AppInstallEventLogCollector::Delegate,
// Informs the existing |log_collector_| that the list of pending app // Informs the existing |log_collector_| that the list of pending app
// push-install requests has changed or instantiates a new |log_collector_| if // push-install requests has changed or instantiates a new |log_collector_| if
// none exists yet. // none exists yet.
void UpdateCollector(const std::set<std::string>& added, void UpdateCollector(const std::set<std::string>& pending);
const std::set<std::string>& removed);
// Destroys the |log_collector_|, if it exists. // Destroys the |log_collector_|, if it exists.
void StopCollector(); void StopCollector();
......
...@@ -1565,8 +1565,14 @@ void ArcAppListPrefs::OnInstallationStarted( ...@@ -1565,8 +1565,14 @@ void ArcAppListPrefs::OnInstallationStarted(
const base::Optional<std::string>& package_name) { const base::Optional<std::string>& package_name) {
++installing_packages_count_; ++installing_packages_count_;
if (package_name.has_value() && default_apps_.HasPackage(*package_name)) if (!package_name.has_value())
return;
if (default_apps_.HasPackage(*package_name))
default_apps_installations_.insert(*package_name); default_apps_installations_.insert(*package_name);
for (auto& observer : observer_list_)
observer.OnInstallationStarted(*package_name);
} }
void ArcAppListPrefs::OnInstallationFinished( void ArcAppListPrefs::OnInstallationFinished(
...@@ -1578,6 +1584,11 @@ void ArcAppListPrefs::OnInstallationFinished( ...@@ -1578,6 +1584,11 @@ void ArcAppListPrefs::OnInstallationFinished(
HandlePackageRemoved(result->package_name); HandlePackageRemoved(result->package_name);
} }
if (result) {
for (auto& observer : observer_list_)
observer.OnInstallationFinished(result->package_name, result->success);
}
if (!installing_packages_count_) { if (!installing_packages_count_) {
VLOG(2) << "Received unexpected installation finished event"; VLOG(2) << "Received unexpected installation finished event";
return; return;
......
...@@ -160,6 +160,14 @@ class ArcAppListPrefs : public KeyedService, ...@@ -160,6 +160,14 @@ class ArcAppListPrefs : public KeyedService,
// Notifies sync date type controller the model is ready to start. // Notifies sync date type controller the model is ready to start.
virtual void OnPackageListInitialRefreshed() {} virtual void OnPackageListInitialRefreshed() {}
// Notifies that installation of package started.
virtual void OnInstallationStarted(const std::string& package_name) {}
// Notifies that installation of package finished. |succeed| is set to true
// in case of success.
virtual void OnInstallationFinished(const std::string& package_name,
bool success) {}
protected: protected:
virtual ~Observer() {} virtual ~Observer() {}
}; };
......
...@@ -1491,6 +1491,12 @@ message AppInstallReportLogEvent { ...@@ -1491,6 +1491,12 @@ message AppInstallReportLogEvent {
CONNECTIVITY_CHANGE = 8; CONNECTIVITY_CHANGE = 8;
// Session state changed // Session state changed
SESSION_STATE_CHANGE = 9; SESSION_STATE_CHANGE = 9;
// Package installation started
INSTALLATION_STARTED = 10;
// Package installation finished
INSTALLATION_FINISHED = 11;
// Package installation failed
INSTALLATION_FAILED = 12;
} }
// Enumerates the possible changes in session state. // Enumerates the possible changes in session state.
...@@ -1515,7 +1521,8 @@ message AppInstallReportLogEvent { ...@@ -1515,7 +1521,8 @@ message AppInstallReportLogEvent {
optional EventType event_type = 2; optional EventType event_type = 2;
// Total and available space on the stateful partition, in bytes. Set for // Total and available space on the stateful partition, in bytes. Set for
// event types SERVER_REQUEST, CLOUDDPS_RESPONSE and SUCCESS. // event types SERVER_REQUEST, CLOUDDPS_RESPONSE, INSTALLATION_STARTED,
// INSTALLATION_FINISHED, INSTALLATION_FAILED and SUCCESS.
optional int64 stateful_total = 3; optional int64 stateful_total = 3;
optional int64 stateful_free = 4; optional int64 stateful_free = 4;
......
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