Commit bdf91bc3 authored by xiyuan's avatar xiyuan Committed by Commit bot

kiosk: Add status report for os update and running app

- Update chrome_device_settings.proto to include report setting
  for os_update_status and running_kiosk_app;
- Update device_management_backend.proto to include os_update_status
  and running_kiosk_app in DeviceStatusReportRequest;

BUG=577800
TEST=browser_tests --gtest_filter=DeviceStatusCollectorTest.*OsUpdateStatus*:
    DeviceStatusCollectorTest.*RunningKioskApp*

Review-Url: https://codereview.chromium.org/2132663002
Cr-Commit-Position: refs/heads/master@{#405196}
parent ad824435
......@@ -477,6 +477,20 @@ void KioskAppData::SetStatusForTest(Status status) {
SetStatus(status);
}
// static
std::unique_ptr<KioskAppData> KioskAppData::CreateForTest(
KioskAppDataDelegate* delegate,
const std::string& app_id,
const AccountId& account_id,
const GURL& update_url,
const std::string& required_platform_version) {
std::unique_ptr<KioskAppData> data(new KioskAppData(
delegate, app_id, account_id, update_url, base::FilePath()));
data->status_ = STATUS_LOADED;
data->required_platform_version_ = required_platform_version;
return data;
}
void KioskAppData::SetStatus(Status status) {
if (status_ == status)
return;
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_DATA_H_
#define CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_DATA_H_
#include <memory>
#include <string>
#include "base/files/file_path.h"
......@@ -86,6 +87,13 @@ class KioskAppData : public base::SupportsWeakPtr<KioskAppData>,
void SetStatusForTest(Status status);
static std::unique_ptr<KioskAppData> CreateForTest(
KioskAppDataDelegate* delegate,
const std::string& app_id,
const AccountId& account_id,
const GURL& update_url,
const std::string& required_platform_version);
private:
class CrxLoader;
class IconLoader;
......
......@@ -238,6 +238,22 @@ void KioskAppManager::InitSession(Profile* profile,
app_session_->Init(profile, app_id);
}
void KioskAppManager::AddAppForTest(
const std::string& app_id,
const AccountId& account_id,
const GURL& update_url,
const std::string& required_platform_version) {
for (auto it = apps_.begin(); it != apps_.end(); ++it) {
if ((*it)->app_id() == app_id) {
apps_.erase(it);
break;
}
}
apps_.emplace_back(KioskAppData::CreateForTest(
this, app_id, account_id, update_url, required_platform_version));
}
void KioskAppManager::EnableConsumerKioskAutoLaunch(
const KioskAppManager::EnableKioskAutoLaunchCallback& callback) {
policy::BrowserPolicyConnectorChromeOS* connector =
......
......@@ -22,6 +22,7 @@
#include "components/signin/core/account_id/account_id.h"
#include "ui/gfx/image/image_skia.h"
class GURL;
class PrefRegistrySimple;
class Profile;
......@@ -234,6 +235,13 @@ class KioskAppManager : public KioskAppDataDelegate,
// Initialize |app_session_|.
void InitSession(Profile* profile, const std::string& app_id);
// Adds an app with the given meta data directly and skips meta data fetching
// for test.
void AddAppForTest(const std::string& app_id,
const AccountId& account_id,
const GURL& update_url,
const std::string& required_platform_version);
AppSession* app_session() { return app_session_.get(); }
bool external_loader_created() const { return external_loader_created_; }
bool secondary_app_external_loader_created() const {
......
......@@ -25,9 +25,11 @@
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/task_runner_util.h"
#include "base/values.h"
#include "base/version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
......@@ -36,6 +38,8 @@
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/common/pref_names.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/update_engine_client.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_handler.h"
......@@ -238,6 +242,16 @@ std::unique_ptr<policy::DeviceLocalAccount> GetCurrentKioskDeviceLocalAccount(
return std::unique_ptr<policy::DeviceLocalAccount>();
}
base::Version GetPlatformVersion() {
int32_t major_version;
int32_t minor_version;
int32_t bugfix_version;
base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
&bugfix_version);
return base::Version(base::StringPrintf("%d.%d.%d", major_version,
minor_version, bugfix_version));
}
} // namespace
namespace policy {
......@@ -253,24 +267,12 @@ DeviceStatusCollector::DeviceStatusCollector(
max_stored_future_activity_days_(kMaxStoredFutureActivityDays),
local_state_(local_state),
last_idle_check_(Time()),
last_reported_day_(0),
duration_for_last_reported_day_(0),
geolocation_update_in_progress_(false),
volume_info_fetcher_(volume_info_fetcher),
cpu_statistics_fetcher_(cpu_statistics_fetcher),
cpu_temp_fetcher_(cpu_temp_fetcher),
statistics_provider_(provider),
last_cpu_active_(0),
last_cpu_idle_(0),
cros_settings_(chromeos::CrosSettings::Get()),
location_update_requester_(location_update_requester),
report_version_info_(false),
report_activity_times_(false),
report_boot_mode_(false),
report_location_(false),
report_network_interfaces_(false),
report_users_(false),
report_hardware_status_(false),
report_session_status_(false),
weak_factory_(this) {
if (volume_info_fetcher_.is_null())
volume_info_fetcher_ = base::Bind(&GetVolumeInfo);
......@@ -289,9 +291,6 @@ DeviceStatusCollector::DeviceStatusCollector(
TimeDelta::FromSeconds(kHardwareStatusSampleIntervalSeconds),
this, &DeviceStatusCollector::SampleHardwareStatus);
cros_settings_ = chromeos::CrosSettings::Get();
// Watch for changes to the individual policies that control what the status
// reports contain.
base::Closure callback =
......@@ -313,6 +312,10 @@ DeviceStatusCollector::DeviceStatusCollector(
chromeos::kReportDeviceHardwareStatus, callback);
session_status_subscription_ = cros_settings_->AddSettingsObserver(
chromeos::kReportDeviceSessionStatus, callback);
os_update_status_subscription_ = cros_settings_->AddSettingsObserver(
chromeos::kReportOsUpdateStatus, callback);
running_kiosk_app_subscription_ = cros_settings_->AddSettingsObserver(
chromeos::kReportRunningKioskApp, callback);
// The last known location is persisted in local state. This makes location
// information available immediately upon startup and avoids the need to
......@@ -438,6 +441,16 @@ void DeviceStatusCollector::UpdateReportingSettings() {
// immediately instead of waiting for the sampling timer to fire.
SampleHardwareStatus();
}
// Os update status and running kiosk app reporting are disabled by default.
if (!cros_settings_->GetBoolean(chromeos::kReportOsUpdateStatus,
&report_os_update_status_)) {
report_os_update_status_ = false;
}
if (!cros_settings_->GetBoolean(chromeos::kReportRunningKioskApp,
&report_running_kiosk_app_)) {
report_running_kiosk_app_ = false;
}
}
Time DeviceStatusCollector::GetCurrentTime() {
......@@ -907,6 +920,89 @@ void DeviceStatusCollector::GetHardwareStatus(
}
}
bool DeviceStatusCollector::GetOsUpdateStatus(
em::DeviceStatusReportRequest* status) {
const base::Version platform_version(GetPlatformVersion());
if (!platform_version.IsValid())
return false;
const std::string required_platform_version_string =
chromeos::KioskAppManager::Get()
->GetAutoLaunchAppRequiredPlatformVersion();
if (required_platform_version_string.empty())
return false;
const base::Version required_platfrom_version(
required_platform_version_string);
em::OsUpdateStatus* os_update_status = status->mutable_os_update_status();
os_update_status->set_new_required_platform_version(
required_platfrom_version.GetString());
if (platform_version == required_platfrom_version) {
os_update_status->set_update_status(em::OsUpdateStatus::OS_UP_TO_DATE);
return true;
}
const chromeos::UpdateEngineClient::Status update_engine_status =
chromeos::DBusThreadManager::Get()
->GetUpdateEngineClient()
->GetLastStatus();
if (update_engine_status.status ==
chromeos::UpdateEngineClient::UPDATE_STATUS_DOWNLOADING ||
update_engine_status.status ==
chromeos::UpdateEngineClient::UPDATE_STATUS_VERIFYING ||
update_engine_status.status ==
chromeos::UpdateEngineClient::UPDATE_STATUS_FINALIZING) {
os_update_status->set_update_status(
em::OsUpdateStatus::OS_IMAGE_DOWNLOAD_IN_PROGRESS);
os_update_status->set_new_platform_version(
update_engine_status.new_version);
} else if (update_engine_status.status ==
chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
os_update_status->set_update_status(
em::OsUpdateStatus::OS_UPDATE_NEED_REBOOT);
// Note the new_version could be a dummy "0.0.0.0" for some edge cases,
// e.g. update engine is somehow restarted without a reboot.
os_update_status->set_new_platform_version(
update_engine_status.new_version);
} else {
os_update_status->set_update_status(
em::OsUpdateStatus::OS_IMAGE_DOWNLOAD_NOT_STARTED);
}
return true;
}
bool DeviceStatusCollector::GetRunningKioskApp(
em::DeviceStatusReportRequest* status) {
std::unique_ptr<const DeviceLocalAccount> account =
GetAutoLaunchedKioskSessionInfo();
// Only generate running kiosk app reports if we are in an auto-launched kiosk
// session.
if (!account)
return false;
em::AppStatus* running_kiosk_app = status->mutable_running_kiosk_app();
running_kiosk_app->set_app_id(account->kiosk_app_id);
const std::string app_version = GetAppVersion(account->kiosk_app_id);
if (app_version.empty()) {
DLOG(ERROR) << "Unable to get version for extension: "
<< account->kiosk_app_id;
} else {
running_kiosk_app->set_extension_version(app_version);
}
chromeos::KioskAppManager::App app_info;
if (chromeos::KioskAppManager::Get()->GetApp(account->kiosk_app_id,
&app_info)) {
running_kiosk_app->set_required_platform_version(
app_info.required_platform_version);
}
return true;
}
bool DeviceStatusCollector::GetDeviceStatus(
em::DeviceStatusReportRequest* status) {
if (report_activity_times_)
......@@ -930,13 +1026,23 @@ bool DeviceStatusCollector::GetDeviceStatus(
if (report_hardware_status_)
GetHardwareStatus(status);
bool os_update_status_reported = false;
if (report_os_update_status_)
os_update_status_reported = GetOsUpdateStatus(status);
bool running_kiosk_app_reported = false;
if (report_running_kiosk_app_)
running_kiosk_app_reported = GetRunningKioskApp(status);
return (report_activity_times_ ||
report_version_info_ ||
report_boot_mode_ ||
report_location_ ||
report_network_interfaces_ ||
report_users_ ||
report_hardware_status_);
report_hardware_status_ ||
os_update_status_reported ||
running_kiosk_app_reported);
}
bool DeviceStatusCollector::GetDeviceSessionStatus(
......
......@@ -178,6 +178,10 @@ class DeviceStatusCollector {
enterprise_management::DeviceStatusReportRequest* request);
void GetHardwareStatus(
enterprise_management::DeviceStatusReportRequest* request);
bool GetOsUpdateStatus(
enterprise_management::DeviceStatusReportRequest* request);
bool GetRunningKioskApp(
enterprise_management::DeviceStatusReportRequest* request);
// Update the cached values of the reporting settings.
void UpdateReportingSettings();
......@@ -202,7 +206,7 @@ class DeviceStatusCollector {
// to dBm units expected by server.
int ConvertWifiSignalStrength(int signal_strength);
PrefService* local_state_;
PrefService* const local_state_;
// The last time an idle state check was performed.
base::Time last_idle_check_;
......@@ -211,11 +215,11 @@ class DeviceStatusCollector {
// GetDeviceStatus(), and the duration for it. This is used to trim the
// stored data in OnSubmittedSuccessfully(). Trimming is delayed so
// unsuccessful uploads don't result in dropped data.
int64_t last_reported_day_;
int duration_for_last_reported_day_;
int64_t last_reported_day_ = 0;
int duration_for_last_reported_day_ = 0;
// Whether a geolocation update is currently in progress.
bool geolocation_update_in_progress_;
bool geolocation_update_in_progress_ = false;
base::RepeatingTimer idle_poll_timer_;
base::RepeatingTimer hardware_status_sampling_timer_;
......@@ -254,13 +258,13 @@ class DeviceStatusCollector {
// Callback invoked to fetch information about cpu temperature.
CPUTempFetcher cpu_temp_fetcher_;
chromeos::system::StatisticsProvider* statistics_provider_;
chromeos::system::StatisticsProvider* const statistics_provider_;
chromeos::CrosSettings* cros_settings_;
chromeos::CrosSettings* const cros_settings_;
// The most recent CPU readings.
uint64_t last_cpu_active_;
uint64_t last_cpu_idle_;
uint64_t last_cpu_active_ = 0;
uint64_t last_cpu_idle_ = 0;
// TODO(bartfab): Remove this once crbug.com/125931 is addressed and a proper
// way to mock geolocation exists.
......@@ -270,14 +274,16 @@ class DeviceStatusCollector {
geolocation_subscription_;
// Cached values of the reporting settings from the device policy.
bool report_version_info_;
bool report_activity_times_;
bool report_boot_mode_;
bool report_location_;
bool report_network_interfaces_;
bool report_users_;
bool report_hardware_status_;
bool report_session_status_;
bool report_version_info_ = false;
bool report_activity_times_ = false;
bool report_boot_mode_ = false;
bool report_location_ = false;
bool report_network_interfaces_ = false;
bool report_users_ = false;
bool report_hardware_status_ = false;
bool report_session_status_ = false;
bool report_os_update_status_ = false;
bool report_running_kiosk_app_ = false;
std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
version_info_subscription_;
......@@ -295,6 +301,10 @@ class DeviceStatusCollector {
hardware_status_subscription_;
std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
session_status_subscription_;
std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
os_update_status_subscription_;
std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
running_kiosk_app_subscription_;
base::WeakPtrFactory<DeviceStatusCollector> weak_factory_;
......
......@@ -99,6 +99,8 @@ message DeviceReportingProto {
optional bool report_users = 6 [default = true];
optional bool report_hardware_status = 7 [default = true];
optional bool report_session_status = 8 [default = true];
optional bool report_os_update_status = 10 [default = false];
optional bool report_running_kiosk_app = 11 [default = false];
// Frequency to report device status, default to 3 hours.
optional int64 device_status_frequency = 9 [default = 10800000];
......
......@@ -85,6 +85,8 @@ const char* const kKnownSettings[] = {
kReportDeviceSessionStatus,
kReportDeviceUsers,
kReportDeviceVersionInfo,
kReportOsUpdateStatus,
kReportRunningKioskApp,
kReportUploadFrequency,
kServiceAccountIdentity,
kSignedDataRoamingEnabled,
......@@ -368,6 +370,14 @@ void DecodeReportingPolicies(
kReportDeviceSessionStatus,
reporting_policy.report_session_status());
}
if (reporting_policy.has_report_os_update_status()) {
new_values_cache->SetBoolean(kReportOsUpdateStatus,
reporting_policy.report_os_update_status());
}
if (reporting_policy.has_report_running_kiosk_app()) {
new_values_cache->SetBoolean(kReportRunningKioskApp,
reporting_policy.report_running_kiosk_app());
}
if (reporting_policy.has_device_status_frequency()) {
new_values_cache->SetInteger(
kReportUploadFrequency,
......
......@@ -80,6 +80,8 @@ class DeviceSettingsProviderTest : public DeviceSettingsTestBase {
proto->set_report_users(enable_reporting);
proto->set_report_hardware_status(enable_reporting);
proto->set_report_session_status(enable_reporting);
proto->set_report_os_update_status(enable_reporting);
proto->set_report_running_kiosk_app(enable_reporting);
proto->set_device_status_frequency(frequency);
device_policy_.Build();
device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
......@@ -151,7 +153,9 @@ class DeviceSettingsProviderTest : public DeviceSettingsTestBase {
kReportDeviceNetworkInterfaces,
kReportDeviceUsers,
kReportDeviceHardwareStatus,
kReportDeviceSessionStatus
kReportDeviceSessionStatus,
kReportOsUpdateStatus,
kReportRunningKioskApp
};
const base::FundamentalValue expected_enable_value(expected_enable_state);
......
......@@ -110,6 +110,17 @@ const char kReportDeviceHardwareStatus[] =
const char kReportDeviceSessionStatus[] =
"cros.device_status.report_session_status";
// Determines whether the device reports os update status (update status,
// new platform version and new required platform version of the auto
// launched kiosk app).
const char kReportOsUpdateStatus[] =
"cros.device_status.report_os_update_status";
// Determines whether the device reports the current running kiosk app (
// its app ID, version and required platform version).
const char kReportRunningKioskApp[] =
"cros.device_status.report_running_kiosk_app";
// How frequently device status reports are uploaded, in milliseconds.
const char kReportUploadFrequency[] =
"cros.device_status.report_upload_frequency";
......
......@@ -59,6 +59,8 @@ CHROMEOS_EXPORT extern const char kReportDeviceNetworkInterfaces[];
CHROMEOS_EXPORT extern const char kReportDeviceUsers[];
CHROMEOS_EXPORT extern const char kReportDeviceHardwareStatus[];
CHROMEOS_EXPORT extern const char kReportDeviceSessionStatus[];
CHROMEOS_EXPORT extern const char kReportOsUpdateStatus[];
CHROMEOS_EXPORT extern const char kReportRunningKioskApp[];
CHROMEOS_EXPORT extern const char kReportUploadFrequency[];
CHROMEOS_EXPORT extern const char kHeartbeatEnabled[];
......
......@@ -745,6 +745,36 @@ message DeviceStatusReportRequest {
// CPU temp information.
repeated CPUTempInfo cpu_temp_info = 16;
// This field is set only when an OS update is needed because of the required
// platform version of an updated kiosk app is different from the current
// OS version.
optional OsUpdateStatus os_update_status = 17;
// Set only when there is an auto launched with zero delay kiosk app
// and it is currently running. Otherwise, this field is empty.
optional AppStatus running_kiosk_app = 18;
}
message OsUpdateStatus {
enum UpdateStatus {
OS_UP_TO_DATE = 0;
OS_IMAGE_DOWNLOAD_NOT_STARTED = 1;
OS_IMAGE_DOWNLOAD_IN_PROGRESS = 2;
OS_UPDATE_NEED_REBOOT = 3;
}
optional UpdateStatus update_status = 1;
// New platform version of the os image being downloaded and applied. It
// is only set when update status is OS_IMAGE_DOWNLOAD_IN_PROGRESS or
// OS_UPDATE_NEED_REBOOT. Note this could be a dummy "0.0.0.0" for
// OS_UPDATE_NEED_REBOOT status for some edge cases, e.g. update engine is
// restarted without a reboot.
optional string new_platform_version = 2;
// New required platform version from the pending updated kiosk app.
optional string new_required_platform_version = 3;
}
// Provides status information for an installed app/extension.
......@@ -760,6 +790,9 @@ message AppStatus {
// If true, the application is currently in a self-reported error state.
optional bool error = 4;
// App required Chrome version, specified in app’s manifest file.
optional string required_platform_version = 5;
}
// Report session (a user on one device) level status.
......
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