| 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/memory/tab_manager_delegate_chromeos.h" | 5 #include "chrome/browser/memory/tab_manager_delegate_chromeos.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 const char kExoShellSurfaceWindowName[] = "ExoShellSurface"; | 57 const char kExoShellSurfaceWindowName[] = "ExoShellSurface"; |
| 58 const char kArcProcessNamePrefix[] = "org.chromium.arc."; | 58 const char kArcProcessNamePrefix[] = "org.chromium.arc."; |
| 59 | 59 |
| 60 // When switching to a new tab the tab's renderer's OOM score needs to be | 60 // When switching to a new tab the tab's renderer's OOM score needs to be |
| 61 // updated to reflect its front-most status and protect it from discard. | 61 // updated to reflect its front-most status and protect it from discard. |
| 62 // However, doing this immediately might slow down tab switch time, so wait | 62 // However, doing this immediately might slow down tab switch time, so wait |
| 63 // a little while before doing the adjustment. | 63 // a little while before doing the adjustment. |
| 64 const int kFocusedProcessScoreAdjustIntervalMs = 500; | 64 const int kFocusedProcessScoreAdjustIntervalMs = 500; |
| 65 | 65 |
| 66 const uint32_t kMinVersionForKillProcess = 1; |
| 67 |
| 66 aura::client::ActivationClient* GetActivationClient() { | 68 aura::client::ActivationClient* GetActivationClient() { |
| 67 if (!ash::Shell::HasInstance()) | 69 if (!ash::Shell::HasInstance()) |
| 68 return nullptr; | 70 return nullptr; |
| 69 return aura::client::GetActivationClient(ash::Shell::GetPrimaryRootWindow()); | 71 return aura::client::GetActivationClient(ash::Shell::GetPrimaryRootWindow()); |
| 70 } | 72 } |
| 71 | 73 |
| 72 // Checks if a window renders ARC apps. | 74 // Checks if a window renders ARC apps. |
| 73 bool IsArcWindow(aura::Window* window) { | 75 bool IsArcWindow(aura::Window* window) { |
| 74 if (!window || window->name() != kExoShellSurfaceWindowName) | 76 if (!window || window->name() != kExoShellSurfaceWindowName) |
| 75 return false; | 77 return false; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 const base::WeakPtr<TabManager>& tab_manager) | 307 const base::WeakPtr<TabManager>& tab_manager) |
| 306 : TabManagerDelegate(tab_manager, new MemoryStat()) { | 308 : TabManagerDelegate(tab_manager, new MemoryStat()) { |
| 307 } | 309 } |
| 308 | 310 |
| 309 TabManagerDelegate::TabManagerDelegate( | 311 TabManagerDelegate::TabManagerDelegate( |
| 310 const base::WeakPtr<TabManager>& tab_manager, | 312 const base::WeakPtr<TabManager>& tab_manager, |
| 311 TabManagerDelegate::MemoryStat* mem_stat) | 313 TabManagerDelegate::MemoryStat* mem_stat) |
| 312 : tab_manager_(tab_manager), | 314 : tab_manager_(tab_manager), |
| 313 focused_process_(new FocusedProcess()), | 315 focused_process_(new FocusedProcess()), |
| 314 mem_stat_(mem_stat), | 316 mem_stat_(mem_stat), |
| 315 arc_process_instance_(nullptr), | |
| 316 arc_process_instance_version_(0), | |
| 317 uma_(new UmaReporter()), | 317 uma_(new UmaReporter()), |
| 318 weak_ptr_factory_(this) { | 318 weak_ptr_factory_(this) { |
| 319 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 319 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 320 content::NotificationService::AllBrowserContextsAndSources()); | 320 content::NotificationService::AllBrowserContextsAndSources()); |
| 321 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 321 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 322 content::NotificationService::AllBrowserContextsAndSources()); | 322 content::NotificationService::AllBrowserContextsAndSources()); |
| 323 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 323 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| 324 content::NotificationService::AllBrowserContextsAndSources()); | 324 content::NotificationService::AllBrowserContextsAndSources()); |
| 325 auto* arc_bridge_service = arc::ArcBridgeService::Get(); | |
| 326 if (arc_bridge_service) | |
| 327 arc_bridge_service->process()->AddObserver(this); | |
| 328 auto* activation_client = GetActivationClient(); | 325 auto* activation_client = GetActivationClient(); |
| 329 if (activation_client) | 326 if (activation_client) |
| 330 activation_client->AddObserver(this); | 327 activation_client->AddObserver(this); |
| 331 BrowserList::GetInstance()->AddObserver(this); | 328 BrowserList::GetInstance()->AddObserver(this); |
| 332 } | 329 } |
| 333 | 330 |
| 334 TabManagerDelegate::~TabManagerDelegate() { | 331 TabManagerDelegate::~TabManagerDelegate() { |
| 335 BrowserList::GetInstance()->RemoveObserver(this); | 332 BrowserList::GetInstance()->RemoveObserver(this); |
| 336 auto* activation_client = GetActivationClient(); | 333 auto* activation_client = GetActivationClient(); |
| 337 if (activation_client) | 334 if (activation_client) |
| 338 activation_client->RemoveObserver(this); | 335 activation_client->RemoveObserver(this); |
| 339 auto* arc_bridge_service = arc::ArcBridgeService::Get(); | |
| 340 if (arc_bridge_service) | |
| 341 arc_bridge_service->process()->RemoveObserver(this); | |
| 342 } | 336 } |
| 343 | 337 |
| 344 void TabManagerDelegate::OnBrowserSetLastActive(Browser* browser) { | 338 void TabManagerDelegate::OnBrowserSetLastActive(Browser* browser) { |
| 345 // Set OOM score to the selected tab when a browser window is activated. | 339 // Set OOM score to the selected tab when a browser window is activated. |
| 346 // content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED didn't catch the | 340 // content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED didn't catch the |
| 347 // case (like when switching focus between 2 browser windows) so we need to | 341 // case (like when switching focus between 2 browser windows) so we need to |
| 348 // handle it here. | 342 // handle it here. |
| 349 TabStripModel* tab_strip_model = browser->tab_strip_model(); | 343 TabStripModel* tab_strip_model = browser->tab_strip_model(); |
| 350 int selected_index = tab_strip_model->active_index(); | 344 int selected_index = tab_strip_model->active_index(); |
| 351 content::WebContents* contents = | 345 content::WebContents* contents = |
| 352 tab_strip_model->GetWebContentsAt(selected_index); | 346 tab_strip_model->GetWebContentsAt(selected_index); |
| 353 if (!contents) | 347 if (!contents) |
| 354 return; | 348 return; |
| 355 | 349 |
| 356 base::ProcessHandle pid = contents->GetRenderProcessHost()->GetHandle(); | 350 base::ProcessHandle pid = contents->GetRenderProcessHost()->GetHandle(); |
| 357 AdjustFocusedTabScore(pid); | 351 AdjustFocusedTabScore(pid); |
| 358 } | 352 } |
| 359 | 353 |
| 360 void TabManagerDelegate::OnInstanceReady() { | |
| 361 auto* arc_bridge_service = arc::ArcBridgeService::Get(); | |
| 362 DCHECK(arc_bridge_service); | |
| 363 | |
| 364 arc_process_instance_ = arc_bridge_service->process()->instance(); | |
| 365 arc_process_instance_version_ = arc_bridge_service->process()->version(); | |
| 366 | |
| 367 DCHECK(arc_process_instance_); | |
| 368 } | |
| 369 | |
| 370 void TabManagerDelegate::OnInstanceClosed() { | |
| 371 arc_process_instance_ = nullptr; | |
| 372 arc_process_instance_version_ = 0; | |
| 373 } | |
| 374 | |
| 375 // TODO(cylee): Remove this function if Android process OOM score settings | 354 // TODO(cylee): Remove this function if Android process OOM score settings |
| 376 // is moved back to Android. | 355 // is moved back to Android. |
| 377 // For example, negotiate non-overlapping OOM score ranges so Chrome and Android | 356 // For example, negotiate non-overlapping OOM score ranges so Chrome and Android |
| 378 // can set OOM score for processes in their own world. | 357 // can set OOM score for processes in their own world. |
| 379 void TabManagerDelegate::OnWindowActivated( | 358 void TabManagerDelegate::OnWindowActivated( |
| 380 aura::client::ActivationChangeObserver::ActivationReason reason, | 359 aura::client::ActivationChangeObserver::ActivationReason reason, |
| 381 aura::Window* gained_active, | 360 aura::Window* gained_active, |
| 382 aura::Window* lost_active) { | 361 aura::Window* lost_active) { |
| 383 if (IsArcWindow(gained_active)) { | 362 if (IsArcWindow(gained_active)) { |
| 384 // Currently there is no way to know which app is displayed in the ARC | 363 // Currently there is no way to know which app is displayed in the ARC |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 candidates.emplace_back(&app); | 569 candidates.emplace_back(&app); |
| 591 } | 570 } |
| 592 | 571 |
| 593 // Sort candidates according to priority. | 572 // Sort candidates according to priority. |
| 594 std::sort(candidates.begin(), candidates.end()); | 573 std::sort(candidates.begin(), candidates.end()); |
| 595 | 574 |
| 596 return candidates; | 575 return candidates; |
| 597 } | 576 } |
| 598 | 577 |
| 599 bool TabManagerDelegate::KillArcProcess(const int nspid) { | 578 bool TabManagerDelegate::KillArcProcess(const int nspid) { |
| 600 if (!arc_process_instance_) | 579 auto* arc_bridge_service = arc::ArcBridgeService::Get(); |
| 580 if (!arc_bridge_service) |
| 601 return false; | 581 return false; |
| 602 arc_process_instance_->KillProcess(nspid, "LowMemoryKill"); | 582 |
| 583 auto* arc_process_instance = |
| 584 arc_bridge_service->process()->GetInstanceForMethod( |
| 585 "KillProcess", kMinVersionForKillProcess); |
| 586 if (!arc_process_instance) |
| 587 return false; |
| 588 |
| 589 arc_process_instance->KillProcess(nspid, "LowMemoryKill"); |
| 603 return true; | 590 return true; |
| 604 } | 591 } |
| 605 | 592 |
| 606 bool TabManagerDelegate::KillTab(int64_t tab_id) { | 593 bool TabManagerDelegate::KillTab(int64_t tab_id) { |
| 607 // Check |tab_manager_| is alive before taking tabs into consideration. | 594 // Check |tab_manager_| is alive before taking tabs into consideration. |
| 608 return tab_manager_ && | 595 return tab_manager_ && |
| 609 tab_manager_->CanDiscardTab(tab_id) && | 596 tab_manager_->CanDiscardTab(tab_id) && |
| 610 tab_manager_->DiscardTabById(tab_id); | 597 tab_manager_->DiscardTabById(tab_id); |
| 611 } | 598 } |
| 612 | 599 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 } | 747 } |
| 761 priority += priority_increment; | 748 priority += priority_increment; |
| 762 } | 749 } |
| 763 | 750 |
| 764 if (oom_scores_to_change.size()) | 751 if (oom_scores_to_change.size()) |
| 765 GetDebugDaemonClient()->SetOomScoreAdj( | 752 GetDebugDaemonClient()->SetOomScoreAdj( |
| 766 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); | 753 oom_scores_to_change, base::Bind(&OnSetOomScoreAdj)); |
| 767 } | 754 } |
| 768 | 755 |
| 769 } // namespace memory | 756 } // namespace memory |
| OLD | NEW |