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 uint64_t lastHwSleep = 0; 63 uint64_t totalHwSleep = 0; 64 uint64_t maxHwSleep = 0; 65 }; 66 67 struct SleepTimeConfig { 68 std::chrono::milliseconds baseSleepTime; 69 std::chrono::milliseconds maxSleepTime; 70 double sleepTimeScaleFactor; 71 uint32_t backoffThreshold; 72 std::chrono::milliseconds shortSuspendThreshold; 73 bool failedSuspendBackoffEnabled; 74 bool shortSuspendBackoffEnabled; 75 }; 76 77 std::string readFd(int fd); 78 79 class SystemSuspend : public RefBase { 80 public: 81 SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, unique_fd suspendStatsFd, 82 size_t maxStatsEntries, unique_fd kernelWakelockStatsFd, 83 unique_fd wakeupReasonsFd, unique_fd suspendTimeFd, 84 const SleepTimeConfig& sleepTimeConfig, 85 const sp<SuspendControlService>& controlService, 86 const sp<SuspendControlServiceInternal>& controlServiceInternal, 87 bool useSuspendCounter = true); 88 void incSuspendCounter(const std::string& name); 89 void decSuspendCounter(const std::string& name); 90 bool enableAutosuspend(const sp<IBinder>& token); 91 void disableAutosuspend(); 92 bool forceSuspend(); 93 94 const WakeupList& getWakeupList() const; 95 const WakeLockEntryList& getStatsList() const; 96 void updateWakeLockStatOnAcquire(const std::string& name, int pid); 97 void updateWakeLockStatOnRelease(const std::string& name, int pid); 98 void updateStatsNow(); 99 Result<SuspendStats> getSuspendStats(); 100 void getSuspendInfo(SuspendInfo* info); 101 std::chrono::milliseconds getSleepTime() const; 102 unique_fd reopenFileUsingFd(const int fd, int permission); 103 104 private: 105 ~SystemSuspend(void) override; 106 107 std::mutex mAutosuspendClientTokensLock; 108 std::mutex mAutosuspendLock ACQUIRED_AFTER(mAutosuspendClientTokensLock); 109 std::mutex mSuspendInfoLock; 110 111 void initAutosuspendLocked() 112 EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock, mAutosuspendLock); 113 void disableAutosuspendLocked() 114 EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock, mAutosuspendLock); 115 void checkAutosuspendClientsLivenessLocked() 116 EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock); 117 bool hasAliveAutosuspendTokenLocked() EXCLUSIVE_LOCKS_REQUIRED(mAutosuspendClientTokensLock); 118 void logKernelWakeLockStats(); 119 120 std::condition_variable mAutosuspendCondVar GUARDED_BY(mAutosuspendLock); 121 uint32_t mSuspendCounter GUARDED_BY(mAutosuspendLock); 122 123 std::vector<sp<IBinder>> mAutosuspendClientTokens GUARDED_BY(mAutosuspendClientTokensLock); GUARDED_BY(mAutosuspendLock)124 std::atomic<bool> mAutosuspendEnabled GUARDED_BY(mAutosuspendLock){false}; GUARDED_BY(mAutosuspendLock)125 std::atomic<bool> mAutosuspendThreadCreated GUARDED_BY(mAutosuspendLock){false}; 126 127 unique_fd mWakeupCountFd; 128 unique_fd mStateFd; 129 130 unique_fd mSuspendStatsFd; 131 unique_fd mSuspendTimeFd; 132 133 SuspendInfo mSuspendInfo GUARDED_BY(mSuspendInfoLock); 134 135 const SleepTimeConfig kSleepTimeConfig; 136 137 // Amount of thread sleep time between consecutive iterations of the suspend loop 138 std::chrono::milliseconds mSleepTime; 139 int32_t mNumConsecutiveBadSuspends GUARDED_BY(mSuspendInfoLock); 140 141 // Updates thread sleep time and suspend stats depending on the result of suspend attempt 142 void updateSleepTime(bool success, const struct SuspendTime& suspendTime); 143 144 sp<SuspendControlService> mControlService; 145 sp<SuspendControlServiceInternal> mControlServiceInternal; 146 147 WakeLockEntryList mStatsList; 148 WakeupList mWakeupList; 149 150 // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on 151 // /sys/power/wake_lock interface to block suspend. 152 // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface. 153 bool mUseSuspendCounter; 154 unique_fd mWakeLockFd; 155 unique_fd mWakeUnlockFd; 156 unique_fd mWakeupReasonsFd; 157 }; 158 159 } // namespace V1_0 160 } // namespace suspend 161 } // namespace system 162 } // namespace android 163 164 #endif // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 165