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 "SuspendControlService.h" 21 22 #include <android-base/unique_fd.h> 23 #include <android/system/suspend/1.0/ISystemSuspend.h> 24 #include <hidl/HidlTransportSupport.h> 25 #include <system/hardware/interfaces/suspend/1.0/default/SystemSuspendStats.pb.h> 26 27 #include <condition_variable> 28 #include <mutex> 29 #include <string> 30 31 namespace android { 32 namespace system { 33 namespace suspend { 34 namespace V1_0 { 35 36 using ::android::base::unique_fd; 37 using ::android::hardware::hidl_death_recipient; 38 using ::android::hardware::hidl_handle; 39 using ::android::hardware::hidl_string; 40 using ::android::hardware::hidl_vec; 41 using ::android::hardware::interfacesEqual; 42 using ::android::hardware::Return; 43 44 using TimestampType = uint64_t; 45 using WakeLockIdType = std::string; 46 47 using namespace std::chrono_literals; 48 49 class SystemSuspend; 50 51 std::string readFd(int fd); 52 TimestampType getEpochTimeNow(); 53 54 class WakeLock : public IWakeLock { 55 public: 56 WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id, const std::string& name); 57 ~WakeLock(); 58 59 Return<void> release(); 60 61 private: 62 inline void releaseOnce(); 63 std::once_flag mReleased; 64 65 SystemSuspend* mSystemSuspend; 66 WakeLockIdType mId; 67 std::string mName; 68 }; 69 70 class SystemSuspend : public ISystemSuspend { 71 public: 72 SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, size_t maxStatsEntries, 73 std::chrono::milliseconds baseSleepTime, 74 const sp<SuspendControlService>& controlService, bool useSuspendCounter = true); 75 Return<sp<IWakeLock>> acquireWakeLock(WakeLockType type, const hidl_string& name) override; 76 Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override; 77 void incSuspendCounter(const std::string& name); 78 void decSuspendCounter(const std::string& name); 79 void deleteWakeLockStatsEntry(WakeLockIdType id); 80 bool enableAutosuspend(); 81 bool forceSuspend(); 82 83 private: 84 void initAutosuspend(); 85 86 std::mutex mCounterLock; 87 std::condition_variable mCounterCondVar; 88 uint32_t mSuspendCounter; 89 unique_fd mWakeupCountFd; 90 unique_fd mStateFd; 91 92 // mStats can be inconsistent with with mSuspendCounter since we use two separate locks to 93 // protect these. However, since mStats is only for debugging we prioritize performance. 94 // Never hold both locks at the same time to avoid deadlock. 95 std::mutex mStatsLock; 96 // We don't want mStats to grow unboundedly in memory. This constant limits amount of 97 // information mStats can collect on the device. 98 size_t mMaxStatsEntries; 99 // Used to evict the least recently used wake lock stats entry in case mMaxStatsEntries is 100 // reached. 101 std::map<TimestampType, WakeLockIdType> mLruWakeLockId; 102 SystemSuspendStats mStats; 103 104 // Amount of sleep time between consecutive iterations of the suspend loop. 105 std::chrono::milliseconds mBaseSleepTime; 106 std::chrono::milliseconds mSleepTime; 107 // Updates sleep time depending on the result of suspend attempt. 108 void updateSleepTime(bool success); 109 110 sp<SuspendControlService> mControlService; 111 112 // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on 113 // /sys/power/wake_lock interface to block suspend. 114 // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface. 115 bool mUseSuspendCounter; 116 unique_fd mWakeLockFd; 117 unique_fd mWakeUnlockFd; 118 }; 119 120 } // namespace V1_0 121 } // namespace suspend 122 } // namespace system 123 } // namespace android 124 125 #endif // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 126