Chromium Code Reviews| Index: chrome/browser/memory/tab_manager_delegate_chromeos.h |
| diff --git a/chrome/browser/memory/tab_manager_delegate_chromeos.h b/chrome/browser/memory/tab_manager_delegate_chromeos.h |
| index 3722980f7c7d0ee85a1c2ac20cf506401fdd008f..8dc68bacb0010002f2dcbdbb7befd1aef10a708b 100644 |
| --- a/chrome/browser/memory/tab_manager_delegate_chromeos.h |
| +++ b/chrome/browser/memory/tab_manager_delegate_chromeos.h |
| @@ -11,11 +11,13 @@ |
| #include "base/containers/hash_tables.h" |
| #include "base/gtest_prod_util.h" |
| +#include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/process/process.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/chromeos/arc/arc_process.h" |
| +#include "chrome/browser/memory/arc_process_adj_level.h" |
| #include "chrome/browser/memory/tab_manager.h" |
| #include "chrome/browser/memory/tab_stats.h" |
| #include "chrome/browser/ui/browser_list_observer.h" |
| @@ -26,47 +28,19 @@ |
| namespace memory { |
| -// The importance of tabs/apps. The lower the value, the more likely a process |
| -// is to be selected on memory pressure. The values is additive, for example, |
| -// one tab could be of value (CHROME_NORMAL | CHROME_PINNED). |
| -// TODO(cylee): Refactor this CL so the prioritize logic is unified in |
| -// TabManager. |
| -enum ProcessPriority { |
| - // Processes on Android side which generally don't have an app window, and |
| - // possibly be auto relaunched if killed. |
| - ANDROID_BACKGROUND = 1, |
| - ANDROID_SERVICE = 1 << 1, |
| - ANDROID_CANT_SAVE_STATE = 1 << 2, |
| - ANDROID_PERCEPTIBLE = 1 << 3, |
| - ANDROID_VISIBLE = 1 << 4, |
| - ANDROID_TOP_SLEEPING = 1 << 5, |
| - ANDROID_FOREGROUND_SERVICE = 1 << 6, |
| - ANDROID_FOREGROUND = 1 << 7, |
| - // A chrome window can be one of the 3 exclusive types below: |
| - // internal page, normal page, or chrome app. |
| - CHROME_INTERNAL = 1 << 8, |
| - CHROME_NORMAL = 1 << 9, |
| - CHROME_APP = 1 << 10, |
| - // An android app which is on top of screen from Android's point of view, |
| - // but the app window is inactive from Chrome OS's point of view. |
| - // Give it a higher priority then normal chrome tab since it could not be |
| - // reloaded if killed. |
| - ANDROID_TOP_INACTIVE = CHROME_APP, |
| - // A chrome tab could have following 3 additional attributes |
| - // (not exclusive). |
| - CHROME_PINNED = 1 << 11, |
| - CHROME_MEDIA = 1 << 12, |
| - CHROME_CANT_SAVE_STATE = 1 << 13, |
| - // The highest level of priority. Either a selected tab or an Android app in |
| - // an active window. In theory there should be at most one process with this |
| - // priority at a time, but at the time of writing Chrome couldn't get Android |
| - // window stack info yet so there may be multiple Android apps be token as on |
| - // top of screen for now. |
| - CHROME_SELECTED = 1 << 14, |
| - ANDROID_TOP = CHROME_SELECTED, |
| - |
| - ANDROID_PERSISTENT = 1 << 30, |
| - ANDROID_NON_EXISTS = 0x7FFFFFFF |
| +// Possible types of Apps/Tabs processes. From most important to least |
| +// important. |
| +enum ProcessType { |
| + // There can be only one process having process type "FOCUSED_APP" |
| + // or "FOCUSED_TAB" in the system at any give time (i.e., The focused window |
| + // could be either a chrome window or an Android app. But not both. |
| + FOCUSED_APP = 1, |
| + FOCUSED_TAB = FOCUSED_APP, |
| + |
| + VISIBLE_APP = 2, |
| + BACKGROUND_TAB = 3, |
| + BACKGROUND_APP = 4, |
| + UNKNOWN_TYPE = 5, |
| }; |
| // The Chrome OS TabManagerDelegate is responsible for keeping the |
| @@ -132,7 +106,7 @@ class TabManagerDelegate : public arc::ArcBridgeService::Observer, |
| FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, KillMultipleProcesses); |
| FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, SetOomScoreAdj); |
| - struct Candidate; |
| + class Candidate; |
| class FocusedProcess; |
| class UmaReporter; |
| @@ -150,7 +124,7 @@ class TabManagerDelegate : public arc::ArcBridgeService::Observer, |
| // Cache OOM scores in memory. |
| typedef base::hash_map<base::ProcessHandle, int> ProcessScoreMap; |
| - // Get the list of candidates to kill, sorted by reversed importance. |
| + // Get the list of candidates to kill, sorted by importance descendingly. |
| static std::vector<Candidate> GetSortedCandidates( |
| const TabStatsList& tab_list, |
| const std::vector<arc::ArcProcess>& arc_processes); |
| @@ -188,8 +162,8 @@ class TabManagerDelegate : public arc::ArcBridgeService::Observer, |
| // distributed evenly in [|range_begin|, |range_end|). |
| // The new score is set in |new_map|. |
| void DistributeOomScoreInRange( |
| - std::vector<TabManagerDelegate::Candidate>::reverse_iterator rbegin, |
| - std::vector<TabManagerDelegate::Candidate>::reverse_iterator rend, |
| + std::vector<TabManagerDelegate::Candidate>::const_iterator begin, |
| + std::vector<TabManagerDelegate::Candidate>::const_iterator end, |
| int range_begin, |
| int range_end, |
| ProcessScoreMap* new_map); |
| @@ -234,25 +208,61 @@ class TabManagerDelegate : public arc::ArcBridgeService::Observer, |
| }; |
| // On ARC enabled machines, either a tab or an app could be a possible |
| -// victim of low memory kill process. This is a helper struct which holds a |
| +// victim of low memory kill process. This is a helper class which holds a |
| // pointer to an app or a tab (but not both) to facilitate prioritizing the |
| // victims. |
| -struct TabManagerDelegate::Candidate { |
| - Candidate(const TabStats* _tab, int _priority) |
| - : tab(_tab), priority(_priority), is_arc_app(false) {} |
| - Candidate(const arc::ArcProcess* _app, int _priority) |
| - : app(_app), priority(_priority), is_arc_app(true) {} |
| +class TabManagerDelegate::Candidate { |
| + public: |
| + explicit Candidate(const TabStats* tab) |
| + : tab_(tab), app_(NULL), process_type_(GetProcessType()) { |
|
Georges Khalil
2016/06/27 20:15:05
nit: NULL -> nullptr.
cylee1
2016/07/14 19:15:24
Done.
|
| + } |
| + explicit Candidate(const arc::ArcProcess* app) |
| + : tab_(NULL), app_(app), process_type_(GetProcessType()) { |
|
Georges Khalil
2016/06/27 20:15:05
nit: same as above.
cylee1
2016/07/14 19:15:25
Done.
|
| + } |
| + // Higher priority first. |
| bool operator<(const Candidate& rhs) const { |
| - return priority < rhs.priority; |
| + if (app() && rhs.app()) { |
| + // Sort by (adj, last_activity_time) pair. |
| + // Larger adj value means lower priority as defined in Android. |
| + if (app()->adj() != rhs.app()->adj()) |
|
Luis Héctor Chávez
2016/06/28 15:43:53
You can replace all this by:
// Larger adj value
cylee1
2016/07/14 19:15:24
tie() requires non-const reference since it expect
|
| + return app()->adj() < rhs.app()->adj(); |
| + // LRU manner. |
| + return app()->last_activity_time() > rhs.app()->last_activity_time(); |
| + } else if (tab() && rhs.tab()) { |
| + return TabManager::CompareTabStats(*tab(), *rhs.tab()); |
| + } |
| + // If one is tab and the other is Android app, simply sort by their process |
| + // type for now. |
| + return process_type() < rhs.process_type(); |
| + } |
| + |
| + const TabStats* tab() const { return tab_; } |
| + const arc::ArcProcess* app() const { return app_; } |
| + ProcessType process_type() const { return process_type_; } |
| + |
| + private: |
| + ProcessType GetProcessType() { |
| + if (app()) { |
| + if (app()->adj() == ArcProcessAdjLevel::FOREGROUND_APP_ADJ) { |
| + return ProcessType::FOCUSED_APP; |
| + } else if (app()->adj() == ArcProcessAdjLevel::VISIBLE_APP_ADJ) { |
|
Georges Khalil
2016/06/27 20:15:05
nit: No need for else here. Also allows the remova
cylee1
2016/07/14 19:15:24
Done.
|
| + return ProcessType::VISIBLE_APP; |
| + } |
| + return ProcessType::BACKGROUND_APP; |
| + } else if (tab()) { |
| + if (tab()->is_selected) { |
| + return ProcessType::FOCUSED_TAB; |
|
Georges Khalil
2016/06/27 20:15:05
nit: no braces.
cylee1
2016/07/14 19:15:25
Done.
|
| + } |
| + return ProcessType::BACKGROUND_TAB; |
| + } |
| + NOTREACHED() << "Unexpected process type"; |
| + return ProcessType::UNKNOWN_TYPE; |
| } |
| - union { |
| - const TabStats* tab; |
| - const arc::ArcProcess* app; |
| - }; |
| - int priority; |
| - bool is_arc_app; |
| + const TabStats* tab_; |
| + const arc::ArcProcess* app_; |
| + ProcessType process_type_; |
| }; |
| // A thin wrapper over library process_metric.h to get memory status so unit |