| // Copyright 2015 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/task_manager/providers/task.h" |
| |
| #include <stddef.h> |
| |
| #include "base/numerics/safe_conversions.h" |
| #include "base/process/process.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_attributes_entry.h" |
| #include "chrome/browser/profiles/profile_attributes_storage.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/task_manager/providers/task_provider_observer.h" |
| #include "chrome/browser/task_manager/task_manager_observer.h" |
| #include "content/public/common/result_codes.h" |
| #include "ui/base/resource/resource_bundle.h" |
| |
| namespace task_manager { |
| |
| namespace { |
| |
| // The last ID given to the previously created task. |
| int64_t g_last_id = 0; |
| |
| base::ProcessId DetermineProcessId(base::ProcessHandle handle, |
| base::ProcessId process_id) { |
| if (process_id != base::kNullProcessId) |
| return process_id; |
| return base::GetProcId(handle); |
| } |
| |
| } // namespace |
| |
| Task::Task(const std::u16string& title, |
| const gfx::ImageSkia* icon, |
| base::ProcessHandle handle, |
| base::ProcessId process_id) |
| : task_id_(g_last_id++), |
| title_(title), |
| icon_(icon ? *icon : gfx::ImageSkia()), |
| process_handle_(handle), |
| process_id_(DetermineProcessId(handle, process_id)) {} |
| |
| Task::~Task() = default; |
| |
| // static |
| std::u16string Task::GetProfileNameFromProfile(Profile* profile) { |
| DCHECK(profile); |
| ProfileAttributesEntry* entry = |
| g_browser_process->profile_manager() |
| ->GetProfileAttributesStorage() |
| .GetProfileAttributesWithPath( |
| profile->GetOriginalProfile()->GetPath()); |
| return entry ? entry->GetName() : std::u16string(); |
| } |
| |
| void Task::Activate() {} |
| |
| bool Task::IsKillable() { |
| // Protects from trying to kill a task that doesn't have an accurate process |
| // Id yet. This can result in calling "kill 0" which kills all processes in |
| // the process group. |
| if (process_id() == base::kNullProcessId) |
| return false; |
| return true; |
| } |
| |
| bool Task::Kill() { |
| if (!IsKillable()) |
| return false; |
| DCHECK_NE(process_id(), base::GetCurrentProcId()); |
| base::Process process = base::Process::Open(process_id()); |
| return process.Terminate(content::RESULT_CODE_KILLED, false); |
| } |
| |
| void Task::Refresh(const base::TimeDelta& update_interval, |
| int64_t refresh_flags) { |
| if ((refresh_flags & REFRESH_TYPE_NETWORK_USAGE) == 0 || |
| update_interval == base::TimeDelta()) |
| return; |
| |
| base::ByteCount current_cycle_read_byte_count = |
| cumulative_bytes_read_ - last_refresh_cumulative_bytes_read_; |
| network_read_rate_ = base::ByteCount(base::ClampRound<int64_t>( |
| current_cycle_read_byte_count.InBytesF() / update_interval.InSecondsF())); |
| |
| base::ByteCount current_cycle_sent_byte_count = |
| cumulative_bytes_sent_ - last_refresh_cumulative_bytes_sent_; |
| network_sent_rate_ = base::ByteCount(base::ClampRound<int64_t>( |
| current_cycle_sent_byte_count.InBytesF() / update_interval.InSecondsF())); |
| |
| last_refresh_cumulative_bytes_read_ = cumulative_bytes_read_; |
| last_refresh_cumulative_bytes_sent_ = cumulative_bytes_sent_; |
| } |
| |
| void Task::UpdateProcessInfo(base::ProcessHandle handle, |
| base::ProcessId process_id, |
| TaskProviderObserver* observer) { |
| process_id = DetermineProcessId(handle, process_id); |
| |
| // Don't remove the task if there is no change to the process ID. |
| if (process_id == process_id_) |
| return; |
| |
| // TaskManagerImpl and TaskGroup implementations assume that a process ID is |
| // consistent for the lifetime of a Task. So to change the process ID, |
| // temporarily unregister this Task. |
| observer->TaskRemoved(this); |
| process_handle_ = handle; |
| process_id_ = process_id; |
| observer->TaskAdded(this); |
| } |
| |
| void Task::OnNetworkBytesRead(base::ByteCount bytes_read) { |
| cumulative_bytes_read_ += bytes_read; |
| } |
| |
| void Task::OnNetworkBytesSent(base::ByteCount bytes_sent) { |
| cumulative_bytes_sent_ += bytes_sent; |
| } |
| |
| Task::SubType Task::GetSubType() const { |
| return Task::SubType::kNoSubType; |
| } |
| |
| void Task::GetTerminationStatus(base::TerminationStatus* out_status, |
| int* out_error_code) const { |
| DCHECK(out_status); |
| DCHECK(out_error_code); |
| |
| *out_status = base::TERMINATION_STATUS_STILL_RUNNING; |
| *out_error_code = 0; |
| } |
| |
| std::u16string Task::GetProfileName() const { |
| return std::u16string(); |
| } |
| |
| SessionID Task::GetTabId() const { |
| return SessionID::InvalidValue(); |
| } |
| |
| bool Task::HasParentTask() const { |
| return GetParentTask() != nullptr; |
| } |
| |
| base::WeakPtr<Task> Task::GetParentTask() const { |
| return nullptr; |
| } |
| |
| bool Task::ReportsSqliteMemory() const { |
| return !GetSqliteMemoryUsed().is_negative(); |
| } |
| |
| base::ByteCount Task::GetSqliteMemoryUsed() const { |
| return base::ByteCount(-1); |
| } |
| |
| base::ByteCount Task::GetV8MemoryAllocated() const { |
| return base::ByteCount(-1); |
| } |
| |
| base::ByteCount Task::GetV8MemoryUsed() const { |
| return base::ByteCount(-1); |
| } |
| |
| bool Task::ReportsWebCacheStats() const { |
| return false; |
| } |
| |
| blink::WebCacheResourceTypeStats Task::GetWebCacheStats() const { |
| return blink::WebCacheResourceTypeStats(); |
| } |
| |
| int Task::GetKeepaliveCount() const { |
| return -1; |
| } |
| |
| bool Task::IsRunningInVM() const { |
| return false; |
| } |
| |
| base::ByteCount Task::GetNetworkUsageRate() const { |
| return network_sent_rate_ + network_read_rate_; |
| } |
| |
| base::ByteCount Task::GetCumulativeNetworkUsage() const { |
| return cumulative_bytes_sent_ + cumulative_bytes_read_; |
| } |
| |
| // static |
| gfx::ImageSkia* Task::FetchIcon(int id, gfx::ImageSkia** result_image) { |
| if (!*result_image && ui::ResourceBundle::HasSharedInstance()) { |
| *result_image = |
| ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); |
| if (*result_image) |
| (*result_image)->MakeThreadSafe(); |
| } |
| return *result_image; |
| } |
| |
| base::WeakPtr<Task> Task::AsWeakPtr() { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| |
| } // namespace task_manager |