1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/policy/status_uploader.h"
10 #include "base/bind_helpers.h"
11 #include "base/location.h"
12 #include "base/sequenced_task_runner.h"
13 #include "chrome/browser/chromeos/policy/device_local_account.h"
14 #include "chrome/browser/chromeos/policy/device_status_collector.h"
15 #include "chromeos/settings/cros_settings_names.h"
16 #include "chromeos/settings/cros_settings_provider.h"
17 #include "components/policy/core/common/cloud/cloud_policy_client.h"
18 #include "components/policy/core/common/cloud/device_management_service.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/media_request_state.h"
21 #include "content/public/common/media_stream_request.h"
22 #include "ui/base/user_activity/user_activity_detector.h"
25 const int kMinUploadDelayMs
= 60 * 1000; // 60 seconds
30 const int64
StatusUploader::kDefaultUploadDelayMs
=
31 3 * 60 * 60 * 1000; // 3 hours
33 StatusUploader::StatusUploader(
34 CloudPolicyClient
* client
,
35 scoped_ptr
<DeviceStatusCollector
> collector
,
36 const scoped_refptr
<base::SequencedTaskRunner
>& task_runner
)
38 collector_(collector
.Pass()),
39 task_runner_(task_runner
),
41 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs
)),
42 has_captured_media_(false),
44 // StatusUploader is currently only created for registered clients, and
45 // it is currently safe to assume that the client will not unregister while
46 // StatusUploader is alive.
48 // If future changes result in StatusUploader's lifetime extending beyond
49 // unregistration events, then this class should be updated
50 // to skip status uploads for unregistered clients, and to observe the client
51 // and kick off an upload when registration happens.
52 DCHECK(client
->is_registered());
54 // Track whether any media capture devices are in use - this changes what
55 // type of information we are allowed to upload.
56 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
58 // Listen for changes to the upload delay, and start sending updates to the
60 upload_frequency_observer_
=
61 chromeos::CrosSettings::Get()->AddSettingsObserver(
62 chromeos::kReportUploadFrequency
,
63 base::Bind(&StatusUploader::RefreshUploadFrequency
,
64 base::Unretained(this)));
66 // Update the upload frequency from settings.
67 RefreshUploadFrequency();
69 // Immediately schedule our next status upload (last_upload_ is set to the
70 // start of the epoch, so this will trigger an update in the immediate
72 ScheduleNextStatusUpload();
75 StatusUploader::~StatusUploader() {
76 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
79 void StatusUploader::ScheduleNextStatusUpload() {
80 // Calculate when to fire off the next update (if it should have already
81 // happened, this yields a TimeDelta of 0).
82 base::TimeDelta delay
= std::max(
83 (last_upload_
+ upload_frequency_
) - base::Time::NowFromSystemTime(),
85 upload_callback_
.Reset(base::Bind(&StatusUploader::UploadStatus
,
86 base::Unretained(this)));
87 task_runner_
->PostDelayedTask(FROM_HERE
, upload_callback_
.callback(), delay
);
90 void StatusUploader::RefreshUploadFrequency() {
91 // Attempt to fetch the current value of the reporting settings.
92 // If trusted values are not available, register this function to be called
93 // back when they are available.
94 chromeos::CrosSettings
* settings
= chromeos::CrosSettings::Get();
95 if (chromeos::CrosSettingsProvider::TRUSTED
!= settings
->PrepareTrustedValues(
96 base::Bind(&StatusUploader::RefreshUploadFrequency
,
97 weak_factory_
.GetWeakPtr()))) {
101 // CrosSettings are trusted - update our cached upload_frequency (we cache the
102 // value because CrosSettings can become untrusted at arbitrary times and we
103 // want to use the last trusted value).
105 if (settings
->GetInteger(chromeos::kReportUploadFrequency
, &frequency
)) {
106 upload_frequency_
= base::TimeDelta::FromMilliseconds(
107 std::max(kMinUploadDelayMs
, frequency
));
110 // Schedule a new upload with the new frequency - only do this if we've
111 // already performed the initial upload, because we want the initial upload
112 // to happen immediately on startup and not get cancelled by settings changes.
113 if (!last_upload_
.is_null())
114 ScheduleNextStatusUpload();
117 bool StatusUploader::IsSessionDataUploadAllowed() {
118 // Check if we're in an auto-launched kiosk session.
119 scoped_ptr
<DeviceLocalAccount
> account
=
120 collector_
->GetAutoLaunchedKioskSessionInfo();
124 // Check if there has been any user input.
125 if (!ui::UserActivityDetector::Get()->last_activity_time().is_null())
128 // Screenshot is allowed as long as we have not captured media.
129 return !has_captured_media_
;
132 void StatusUploader::OnRequestUpdate(int render_process_id
,
134 content::MediaStreamType stream_type
,
135 const content::MediaRequestState state
) {
136 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
137 // If a video or audio capture stream is opened, set a flag so we disallow
138 // upload of potentially sensitive data.
139 if (state
== content::MEDIA_REQUEST_STATE_OPENING
&&
140 (stream_type
== content::MEDIA_DEVICE_AUDIO_CAPTURE
||
141 stream_type
== content::MEDIA_DEVICE_VIDEO_CAPTURE
)) {
142 has_captured_media_
= true;
146 void StatusUploader::UploadStatus() {
147 enterprise_management::DeviceStatusReportRequest device_status
;
148 bool have_device_status
= collector_
->GetDeviceStatus(&device_status
);
149 enterprise_management::SessionStatusReportRequest session_status
;
150 bool have_session_status
= collector_
->GetDeviceSessionStatus(
152 if (!have_device_status
&& !have_session_status
) {
153 // Don't have any status to upload - just set our timer for next time.
154 last_upload_
= base::Time::NowFromSystemTime();
155 ScheduleNextStatusUpload();
159 client_
->UploadDeviceStatus(
160 have_device_status
? &device_status
: nullptr,
161 have_session_status
? &session_status
: nullptr,
162 base::Bind(&StatusUploader::OnUploadCompleted
,
163 weak_factory_
.GetWeakPtr()));
166 void StatusUploader::OnUploadCompleted(bool success
) {
167 // Set the last upload time, regardless of whether the upload was successful
168 // or not (we don't change the time of the next upload based on whether this
169 // upload succeeded or not - if a status upload fails, we just skip it and
170 // wait until it's time to try again.
171 last_upload_
= base::Time::NowFromSystemTime();
173 // If the upload was successful, tell the collector so it can clear its cache
176 collector_
->OnSubmittedSuccessfully();
178 ScheduleNextStatusUpload();
181 } // namespace policy