1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/arc/process/arc_process.h"
6 
7 #include <unordered_set>
8 #include <utility>
9 
10 #include "base/no_destructor.h"
11 #include "base/strings/string_util.h"
12 #include "components/arc/mojom/process.mojom.h"
13 
14 namespace arc {
15 
16 using mojom::ProcessState;
17 
18 constexpr char kCloudDpcrocessName[] =
19     "com.google.android.apps.work.clouddpc.arc";
20 
ImportantStates()21 const std::unordered_set<ProcessState>& ImportantStates() {
22   static const base::NoDestructor<std::unordered_set<ProcessState>>
23       kImportantStates({ProcessState::IMPORTANT_FOREGROUND,
24                         ProcessState::BOUND_FOREGROUND_SERVICE,
25                         ProcessState::FOREGROUND_SERVICE, ProcessState::TOP,
26                         ProcessState::PERSISTENT_UI, ProcessState::PERSISTENT});
27   return *kImportantStates;
28 }
29 
PersistentStates()30 const std::unordered_set<ProcessState>& PersistentStates() {
31   static const base::NoDestructor<std::unordered_set<ProcessState>>
32       kPersistentStates(
33           {ProcessState::PERSISTENT_UI, ProcessState::PERSISTENT});
34   return *kPersistentStates;
35 }
36 
37 
ProtectedBackgroundStates()38 const std::unordered_set<ProcessState>& ProtectedBackgroundStates() {
39   static const base::NoDestructor<std::unordered_set<ProcessState>>
40       kProtectedBackgroundStates({ProcessState::TOP,
41                                   ProcessState::FOREGROUND_SERVICE,
42                                   ProcessState::BOUND_FOREGROUND_SERVICE,
43                                   ProcessState::IMPORTANT_FOREGROUND,
44                                   ProcessState::IMPORTANT_BACKGROUND});
45   return *kProtectedBackgroundStates;
46 }
47 
BackgroundStates()48 const std::unordered_set<ProcessState>& BackgroundStates() {
49   static const base::NoDestructor<std::unordered_set<ProcessState>>
50       kBackgroundStates({ProcessState::TRANSIENT_BACKGROUND,
51                          ProcessState::BACKUP, ProcessState::SERVICE,
52                          ProcessState::RECEIVER, ProcessState::TOP_SLEEPING,
53                          ProcessState::HEAVY_WEIGHT, ProcessState::HOME,
54                          ProcessState::LAST_ACTIVITY,
55                          ProcessState::CACHED_ACTIVITY});
56   return *kBackgroundStates;
57 }
58 
CachedStates()59 const std::unordered_set<ProcessState>& CachedStates() {
60   static const base::NoDestructor<std::unordered_set<ProcessState>>
61       kCachedStates({ProcessState::CACHED_ACTIVITY_CLIENT,
62                      ProcessState::CACHED_RECENT, ProcessState::CACHED_EMPTY,
63                      ProcessState::NONEXISTENT});
64   return *kCachedStates;
65 }
66 
ArcProcess(base::ProcessId nspid,base::ProcessId pid,const std::string & process_name,mojom::ProcessState process_state,bool is_focused,int64_t last_activity_time)67 ArcProcess::ArcProcess(base::ProcessId nspid,
68                        base::ProcessId pid,
69                        const std::string& process_name,
70                        mojom::ProcessState process_state,
71                        bool is_focused,
72                        int64_t last_activity_time)
73     : nspid_(nspid),
74       pid_(pid),
75       process_name_(process_name),
76       process_state_(process_state),
77       is_focused_(is_focused),
78       last_activity_time_(last_activity_time) {}
79 
80 ArcProcess::~ArcProcess() = default;
81 
82 // Sort by (process_state, last_activity_time) pair.
83 // Smaller process_state value means higher priority as defined in Android.
84 // Larger last_activity_time means more recently used.
operator <(const ArcProcess & rhs) const85 bool ArcProcess::operator<(const ArcProcess& rhs) const {
86   return std::make_pair(process_state(), -last_activity_time()) <
87          std::make_pair(rhs.process_state(), -rhs.last_activity_time());
88 }
89 
90 ArcProcess::ArcProcess(ArcProcess&& other) = default;
91 ArcProcess& ArcProcess::operator=(ArcProcess&& other) = default;
92 
93 // TODO(wvk): Use a simple switch/case instead of std::unordered_set lookup,
94 // it will likely be faster.
IsImportant() const95 bool ArcProcess::IsImportant() const {
96   return ImportantStates().count(process_state()) == 1 || IsArcProtected();
97 }
98 
IsPersistent() const99 bool ArcProcess::IsPersistent() const {
100   // Protect PERSISTENT, PERSISTENT_UI, our HOME and custom set of ARC processes
101   // since they should have lower priority to be killed.
102   return PersistentStates().count(process_state()) == 1 || IsArcProtected();
103 }
104 
IsCached() const105 bool ArcProcess::IsCached() const {
106   return CachedStates().count(process_state()) == 1;
107 }
108 
IsBackgroundProtected() const109 bool ArcProcess::IsBackgroundProtected() const {
110   return ProtectedBackgroundStates().count(process_state()) == 1;
111 }
112 
IsArcProtected() const113 bool ArcProcess::IsArcProtected() const {
114   return process_name() == kCloudDpcrocessName;
115 }
116 
operator <<(std::ostream & out,const ArcProcess & arc_process)117 std::ostream& operator<<(std::ostream& out, const ArcProcess& arc_process) {
118   out << "process_name: " << arc_process.process_name()
119       << ", pid: " << arc_process.pid()
120       << ", process_state: " << arc_process.process_state()
121       << ", is_focused: " << arc_process.is_focused()
122       << ", last_activity_time: " << arc_process.last_activity_time()
123       << ", packages: " << base::JoinString(arc_process.packages(), ",");
124   return out;
125 }
126 
127 }  // namespace arc
128