| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/policy/remote_commands/device_command_screensh
ot_job.h" | 5 #include "chrome/browser/chromeos/policy/remote_commands/device_command_screensh
ot_job.h" |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/json/json_reader.h" | 12 #include "base/json/json_reader.h" |
| 13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 17 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
| 18 #include "base/threading/sequenced_worker_pool.h" | 19 #include "base/threading/sequenced_worker_pool.h" |
| 19 #include "base/values.h" | 20 #include "base/values.h" |
| 20 #include "chrome/browser/chromeos/policy/upload_job_impl.h" | 21 #include "chrome/browser/chromeos/policy/upload_job_impl.h" |
| 21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 22 #include "net/http/http_request_headers.h" | 23 #include "net/http/http_request_headers.h" |
| 23 #include "policy/proto/device_management_backend.pb.h" | 24 #include "policy/proto/device_management_backend.pb.h" |
| 24 | 25 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 66 |
| 66 } // namespace | 67 } // namespace |
| 67 | 68 |
| 68 class DeviceCommandScreenshotJob::Payload | 69 class DeviceCommandScreenshotJob::Payload |
| 69 : public RemoteCommandJob::ResultPayload { | 70 : public RemoteCommandJob::ResultPayload { |
| 70 public: | 71 public: |
| 71 explicit Payload(ResultCode result_code); | 72 explicit Payload(ResultCode result_code); |
| 72 ~Payload() override {} | 73 ~Payload() override {} |
| 73 | 74 |
| 74 // RemoteCommandJob::ResultPayload: | 75 // RemoteCommandJob::ResultPayload: |
| 75 scoped_ptr<std::string> Serialize() override; | 76 std::unique_ptr<std::string> Serialize() override; |
| 76 | 77 |
| 77 private: | 78 private: |
| 78 std::string payload_; | 79 std::string payload_; |
| 79 | 80 |
| 80 DISALLOW_COPY_AND_ASSIGN(Payload); | 81 DISALLOW_COPY_AND_ASSIGN(Payload); |
| 81 }; | 82 }; |
| 82 | 83 |
| 83 DeviceCommandScreenshotJob::Payload::Payload(ResultCode result_code) { | 84 DeviceCommandScreenshotJob::Payload::Payload(ResultCode result_code) { |
| 84 base::DictionaryValue root_dict; | 85 base::DictionaryValue root_dict; |
| 85 if (result_code != SUCCESS) | 86 if (result_code != SUCCESS) |
| 86 root_dict.SetInteger(kResultFieldName, result_code); | 87 root_dict.SetInteger(kResultFieldName, result_code); |
| 87 base::JSONWriter::Write(root_dict, &payload_); | 88 base::JSONWriter::Write(root_dict, &payload_); |
| 88 } | 89 } |
| 89 | 90 |
| 90 scoped_ptr<std::string> DeviceCommandScreenshotJob::Payload::Serialize() { | 91 std::unique_ptr<std::string> DeviceCommandScreenshotJob::Payload::Serialize() { |
| 91 return make_scoped_ptr(new std::string(payload_)); | 92 return base::WrapUnique(new std::string(payload_)); |
| 92 } | 93 } |
| 93 | 94 |
| 94 DeviceCommandScreenshotJob::DeviceCommandScreenshotJob( | 95 DeviceCommandScreenshotJob::DeviceCommandScreenshotJob( |
| 95 scoped_ptr<Delegate> screenshot_delegate) | 96 std::unique_ptr<Delegate> screenshot_delegate) |
| 96 : num_pending_screenshots_(0), | 97 : num_pending_screenshots_(0), |
| 97 screenshot_delegate_(std::move(screenshot_delegate)), | 98 screenshot_delegate_(std::move(screenshot_delegate)), |
| 98 weak_ptr_factory_(this) { | 99 weak_ptr_factory_(this) { |
| 99 DCHECK(screenshot_delegate_); | 100 DCHECK(screenshot_delegate_); |
| 100 } | 101 } |
| 101 | 102 |
| 102 DeviceCommandScreenshotJob::~DeviceCommandScreenshotJob() { | 103 DeviceCommandScreenshotJob::~DeviceCommandScreenshotJob() { |
| 103 } | 104 } |
| 104 | 105 |
| 105 enterprise_management::RemoteCommand_Type DeviceCommandScreenshotJob::GetType() | 106 enterprise_management::RemoteCommand_Type DeviceCommandScreenshotJob::GetType() |
| 106 const { | 107 const { |
| 107 return enterprise_management::RemoteCommand_Type_DEVICE_SCREENSHOT; | 108 return enterprise_management::RemoteCommand_Type_DEVICE_SCREENSHOT; |
| 108 } | 109 } |
| 109 | 110 |
| 110 void DeviceCommandScreenshotJob::OnSuccess() { | 111 void DeviceCommandScreenshotJob::OnSuccess() { |
| 111 base::ThreadTaskRunnerHandle::Get()->PostTask( | 112 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 112 FROM_HERE, | 113 FROM_HERE, |
| 113 base::Bind(succeeded_callback_, | 114 base::Bind(succeeded_callback_, |
| 114 base::Passed(make_scoped_ptr(new Payload(SUCCESS))))); | 115 base::Passed(base::WrapUnique(new Payload(SUCCESS))))); |
| 115 } | 116 } |
| 116 | 117 |
| 117 void DeviceCommandScreenshotJob::OnFailure(UploadJob::ErrorCode error_code) { | 118 void DeviceCommandScreenshotJob::OnFailure(UploadJob::ErrorCode error_code) { |
| 118 ResultCode result_code = FAILURE_CLIENT; | 119 ResultCode result_code = FAILURE_CLIENT; |
| 119 switch (error_code) { | 120 switch (error_code) { |
| 120 case UploadJob::AUTHENTICATION_ERROR: | 121 case UploadJob::AUTHENTICATION_ERROR: |
| 121 result_code = FAILURE_AUTHENTICATION; | 122 result_code = FAILURE_AUTHENTICATION; |
| 122 break; | 123 break; |
| 123 case UploadJob::NETWORK_ERROR: | 124 case UploadJob::NETWORK_ERROR: |
| 124 case UploadJob::SERVER_ERROR: | 125 case UploadJob::SERVER_ERROR: |
| 125 result_code = FAILURE_SERVER; | 126 result_code = FAILURE_SERVER; |
| 126 break; | 127 break; |
| 127 } | 128 } |
| 128 base::ThreadTaskRunnerHandle::Get()->PostTask( | 129 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 129 FROM_HERE, | 130 FROM_HERE, |
| 130 base::Bind(failed_callback_, | 131 base::Bind(failed_callback_, |
| 131 base::Passed(make_scoped_ptr(new Payload(result_code))))); | 132 base::Passed(base::WrapUnique(new Payload(result_code))))); |
| 132 } | 133 } |
| 133 | 134 |
| 134 bool DeviceCommandScreenshotJob::IsExpired(base::TimeTicks now) { | 135 bool DeviceCommandScreenshotJob::IsExpired(base::TimeTicks now) { |
| 135 return now > issued_time() + base::TimeDelta::FromMinutes( | 136 return now > issued_time() + base::TimeDelta::FromMinutes( |
| 136 kCommandExpirationTimeInMinutes); | 137 kCommandExpirationTimeInMinutes); |
| 137 } | 138 } |
| 138 | 139 |
| 139 bool DeviceCommandScreenshotJob::ParseCommandPayload( | 140 bool DeviceCommandScreenshotJob::ParseCommandPayload( |
| 140 const std::string& command_payload) { | 141 const std::string& command_payload) { |
| 141 scoped_ptr<base::Value> root(base::JSONReader().ReadToValue(command_payload)); | 142 std::unique_ptr<base::Value> root( |
| 143 base::JSONReader().ReadToValue(command_payload)); |
| 142 if (!root.get()) | 144 if (!root.get()) |
| 143 return false; | 145 return false; |
| 144 base::DictionaryValue* payload = nullptr; | 146 base::DictionaryValue* payload = nullptr; |
| 145 if (!root->GetAsDictionary(&payload)) | 147 if (!root->GetAsDictionary(&payload)) |
| 146 return false; | 148 return false; |
| 147 std::string upload_url; | 149 std::string upload_url; |
| 148 if (!payload->GetString(kUploadUrlFieldName, &upload_url)) | 150 if (!payload->GetString(kUploadUrlFieldName, &upload_url)) |
| 149 return false; | 151 return false; |
| 150 upload_url_ = GURL(upload_url); | 152 upload_url_ = GURL(upload_url); |
| 151 return true; | 153 return true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 164 | 166 |
| 165 void DeviceCommandScreenshotJob::StartScreenshotUpload() { | 167 void DeviceCommandScreenshotJob::StartScreenshotUpload() { |
| 166 for (const auto& screenshot_entry : screenshots_) { | 168 for (const auto& screenshot_entry : screenshots_) { |
| 167 std::map<std::string, std::string> header_fields; | 169 std::map<std::string, std::string> header_fields; |
| 168 header_fields.insert( | 170 header_fields.insert( |
| 169 std::make_pair(kFileTypeHeaderName, kFileTypeScreenshotFile)); | 171 std::make_pair(kFileTypeHeaderName, kFileTypeScreenshotFile)); |
| 170 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType, | 172 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType, |
| 171 kContentTypeImagePng)); | 173 kContentTypeImagePng)); |
| 172 header_fields.insert(std::make_pair(kCommandIdHeaderName, | 174 header_fields.insert(std::make_pair(kCommandIdHeaderName, |
| 173 base::Uint64ToString(unique_id()))); | 175 base::Uint64ToString(unique_id()))); |
| 174 scoped_ptr<std::string> data = make_scoped_ptr( | 176 std::unique_ptr<std::string> data = base::WrapUnique( |
| 175 new std::string((const char*)screenshot_entry.second->front(), | 177 new std::string((const char*)screenshot_entry.second->front(), |
| 176 screenshot_entry.second->size())); | 178 screenshot_entry.second->size())); |
| 177 upload_job_->AddDataSegment( | 179 upload_job_->AddDataSegment( |
| 178 base::StringPrintf(kNameFieldTemplate, screenshot_entry.first), | 180 base::StringPrintf(kNameFieldTemplate, screenshot_entry.first), |
| 179 base::StringPrintf(kFilenameFieldTemplate, screenshot_entry.first), | 181 base::StringPrintf(kFilenameFieldTemplate, screenshot_entry.first), |
| 180 header_fields, std::move(data)); | 182 header_fields, std::move(data)); |
| 181 } | 183 } |
| 182 upload_job_->Start(); | 184 upload_job_->Start(); |
| 183 } | 185 } |
| 184 | 186 |
| 185 void DeviceCommandScreenshotJob::RunImpl( | 187 void DeviceCommandScreenshotJob::RunImpl( |
| 186 const CallbackWithResult& succeeded_callback, | 188 const CallbackWithResult& succeeded_callback, |
| 187 const CallbackWithResult& failed_callback) { | 189 const CallbackWithResult& failed_callback) { |
| 188 succeeded_callback_ = succeeded_callback; | 190 succeeded_callback_ = succeeded_callback; |
| 189 failed_callback_ = failed_callback; | 191 failed_callback_ = failed_callback; |
| 190 | 192 |
| 191 // Fail if the delegate says screenshots are not allowed in this session. | 193 // Fail if the delegate says screenshots are not allowed in this session. |
| 192 if (!screenshot_delegate_->IsScreenshotAllowed()) { | 194 if (!screenshot_delegate_->IsScreenshotAllowed()) { |
| 193 base::ThreadTaskRunnerHandle::Get()->PostTask( | 195 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 194 FROM_HERE, | 196 FROM_HERE, |
| 195 base::Bind(failed_callback_, base::Passed(make_scoped_ptr( | 197 base::Bind(failed_callback_, base::Passed(base::WrapUnique( |
| 196 new Payload(FAILURE_USER_INPUT))))); | 198 new Payload(FAILURE_USER_INPUT))))); |
| 197 } | 199 } |
| 198 | 200 |
| 199 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); | 201 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
| 200 | 202 |
| 201 // Immediately fail if the upload url is invalid. | 203 // Immediately fail if the upload url is invalid. |
| 202 if (!upload_url_.is_valid()) { | 204 if (!upload_url_.is_valid()) { |
| 203 LOG(ERROR) << upload_url_ << " is not a valid URL."; | 205 LOG(ERROR) << upload_url_ << " is not a valid URL."; |
| 204 base::ThreadTaskRunnerHandle::Get()->PostTask( | 206 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 205 FROM_HERE, | 207 FROM_HERE, |
| 206 base::Bind(failed_callback_, base::Passed(make_scoped_ptr( | 208 base::Bind(failed_callback_, base::Passed(base::WrapUnique( |
| 207 new Payload(FAILURE_INVALID_URL))))); | 209 new Payload(FAILURE_INVALID_URL))))); |
| 208 return; | 210 return; |
| 209 } | 211 } |
| 210 | 212 |
| 211 // Immediately fail if there are no attached screens. | 213 // Immediately fail if there are no attached screens. |
| 212 if (root_windows.size() == 0) { | 214 if (root_windows.size() == 0) { |
| 213 base::ThreadTaskRunnerHandle::Get()->PostTask( | 215 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 214 FROM_HERE, | 216 FROM_HERE, |
| 215 base::Bind(failed_callback_, base::Passed(make_scoped_ptr(new Payload( | 217 base::Bind(failed_callback_, base::Passed(base::WrapUnique(new Payload( |
| 216 FAILURE_SCREENSHOT_ACQUISITION))))); | 218 FAILURE_SCREENSHOT_ACQUISITION))))); |
| 217 return; | 219 return; |
| 218 } | 220 } |
| 219 | 221 |
| 220 upload_job_ = screenshot_delegate_->CreateUploadJob(upload_url_, this); | 222 upload_job_ = screenshot_delegate_->CreateUploadJob(upload_url_, this); |
| 221 DCHECK(upload_job_); | 223 DCHECK(upload_job_); |
| 222 | 224 |
| 223 // Post tasks to the sequenced worker pool for taking screenshots on each | 225 // Post tasks to the sequenced worker pool for taking screenshots on each |
| 224 // attached screen. | 226 // attached screen. |
| 225 num_pending_screenshots_ = root_windows.size(); | 227 num_pending_screenshots_ = root_windows.size(); |
| 226 for (size_t screen = 0; screen < root_windows.size(); ++screen) { | 228 for (size_t screen = 0; screen < root_windows.size(); ++screen) { |
| 227 aura::Window* root_window = root_windows[screen]; | 229 aura::Window* root_window = root_windows[screen]; |
| 228 gfx::Rect rect = root_window->bounds(); | 230 gfx::Rect rect = root_window->bounds(); |
| 229 screenshot_delegate_->TakeSnapshot( | 231 screenshot_delegate_->TakeSnapshot( |
| 230 root_window, rect, | 232 root_window, rect, |
| 231 base::Bind(&RunStoreScreenshotOnTaskRunner, | 233 base::Bind(&RunStoreScreenshotOnTaskRunner, |
| 232 base::Bind(&DeviceCommandScreenshotJob::StoreScreenshot, | 234 base::Bind(&DeviceCommandScreenshotJob::StoreScreenshot, |
| 233 weak_ptr_factory_.GetWeakPtr(), screen), | 235 weak_ptr_factory_.GetWeakPtr(), screen), |
| 234 base::ThreadTaskRunnerHandle::Get())); | 236 base::ThreadTaskRunnerHandle::Get())); |
| 235 } | 237 } |
| 236 } | 238 } |
| 237 | 239 |
| 238 void DeviceCommandScreenshotJob::TerminateImpl() { | 240 void DeviceCommandScreenshotJob::TerminateImpl() { |
| 239 weak_ptr_factory_.InvalidateWeakPtrs(); | 241 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 240 } | 242 } |
| 241 | 243 |
| 242 } // namespace policy | 244 } // namespace policy |
| OLD | NEW |