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 |