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