• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H
18 #define ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H
19 
20 #include <android-base/result.h>
21 #include <android-base/thread_annotations.h>
22 #include <android-base/unique_fd.h>
23 #include <android/system/suspend/internal/SuspendInfo.h>
24 #include <utils/RefBase.h>
25 
26 #include <atomic>
27 #include <condition_variable>
28 #include <mutex>
29 #include <string>
30 
31 #include "SuspendControlService.h"
32 #include "WakeLockEntryList.h"
33 #include "WakeupList.h"
34 
35 namespace android {
36 namespace system {
37 namespace suspend {
38 namespace V1_0 {
39 
40 using ::android::base::Result;
41 using ::android::base::unique_fd;
42 using ::android::system::suspend::internal::SuspendInfo;
43 
44 using namespace std::chrono_literals;
45 
46 class SystemSuspend;
47 
48 struct SuspendStats {
49     int success = 0;
50     int fail = 0;
51     int failedFreeze = 0;
52     int failedPrepare = 0;
53     int failedSuspend = 0;
54     int failedSuspendLate = 0;
55     int failedSuspendNoirq = 0;
56     int failedResume = 0;
57     int failedResumeEarly = 0;
58     int failedResumeNoirq = 0;
59     std::string lastFailedDev;
60     int lastFailedErrno = 0;
61     std::string lastFailedStep;
62 };
63 
64 struct SleepTimeConfig {
65     std::chrono::milliseconds baseSleepTime;
66     std::chrono::milliseconds maxSleepTime;
67     double sleepTimeScaleFactor;
68     uint32_t backoffThreshold;
69     std::chrono::milliseconds shortSuspendThreshold;
70     bool failedSuspendBackoffEnabled;
71     bool shortSuspendBackoffEnabled;
72 };
73 
74 std::string readFd(int fd);
75 
76 class SystemSuspend : public RefBase {
77    public:
78     SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, unique_fd suspendStatsFd,
79                   size_t maxStatsEntries, unique_fd kernelWakelockStatsFd,
80                   unique_fd wakeupReasonsFd, unique_fd suspendTimeFd,
81                   const SleepTimeConfig& sleepTimeConfig,
82                   const sp<SuspendControlService>& controlService,
83                   const sp<SuspendControlServiceInternal>& controlServiceInternal,
84                   bool useSuspendCounter = true);
85     void incSuspendCounter(const std::string& name);
86     void decSuspendCounter(const std::string& name);
87     bool enableAutosuspend(const sp<IBinder>& token);
88     void disableAutosuspend();
89     bool forceSuspend();
90 
91     const WakeupList& getWakeupList() const;
92     const WakeLockEntryList& getStatsList() const;
93     void updateWakeLockStatOnAcquire(const std::string& name, int pid);
94     void updateWakeLockStatOnRelease(const std::string& name, int pid);
95     void updateStatsNow();
96     Result<SuspendStats> getSuspendStats();
97     void getSuspendInfo(SuspendInfo* info);
98     std::chrono::milliseconds getSleepTime() const;
99     unique_fd reopenFileUsingFd(const int fd, int permission);
100 
101    private:
102     ~SystemSuspend(void) override;
103 
104     std::mutex mAutosuspendClientTokensLock;
105     std::mutex mAutosuspendLock ACQUIRED_AFTER(mAutosuspendClientTokensLock);
106     std::mutex mSuspendInfoLock;
107 
108     void initAutosuspendLocked()
109         EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock, mAutosuspendLock);
110     void disableAutosuspendLocked()
111         EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock, mAutosuspendLock);
112     void checkAutosuspendClientsLivenessLocked()
113         EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock);
114     bool hasAliveAutosuspendTokenLocked() EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock);
115 
116     std::condition_variable mAutosuspendCondVar GUARDED_BY(mAutosuspendLock);
117     uint32_t mSuspendCounter GUARDED_BY(mAutosuspendLock);
118 
119     std::vector<sp<IBinder>> mAutosuspendClientTokens GUARDED_BY(mAutosuspendClientTokensLock);
GUARDED_BY(mAutosuspendLock)120     std::atomic<bool> mAutosuspendEnabled GUARDED_BY(mAutosuspendLock){false};
GUARDED_BY(mAutosuspendLock)121     std::atomic<bool> mAutosuspendThreadCreated GUARDED_BY(mAutosuspendLock){false};
122 
123     unique_fd mWakeupCountFd;
124     unique_fd mStateFd;
125 
126     unique_fd mSuspendStatsFd;
127     unique_fd mSuspendTimeFd;
128 
129     SuspendInfo mSuspendInfo GUARDED_BY(mSuspendInfoLock);
130 
131     const SleepTimeConfig kSleepTimeConfig;
132 
133     // Amount of thread sleep time between consecutive iterations of the suspend loop
134     std::chrono::milliseconds mSleepTime;
135     int32_t mNumConsecutiveBadSuspends GUARDED_BY(mSuspendInfoLock);
136 
137     // Updates thread sleep time and suspend stats depending on the result of suspend attempt
138     void updateSleepTime(bool success, const struct SuspendTime& suspendTime);
139 
140     sp<SuspendControlService> mControlService;
141     sp<SuspendControlServiceInternal> mControlServiceInternal;
142 
143     WakeLockEntryList mStatsList;
144     WakeupList mWakeupList;
145 
146     // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on
147     // /sys/power/wake_lock interface to block suspend.
148     // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface.
149     bool mUseSuspendCounter;
150     unique_fd mWakeLockFd;
151     unique_fd mWakeUnlockFd;
152     unique_fd mWakeupReasonsFd;
153 };
154 
155 }  // namespace V1_0
156 }  // namespace suspend
157 }  // namespace system
158 }  // namespace android
159 
160 #endif  // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H
161