system/hardware/interfaces
Revision | a833d47822343c18d398e464dac1b0f7b09b5643 (tree) |
---|---|
Zeit | 2019-03-22 07:42:13 |
Autor | Tri Vo <trong@goog...> |
Commiter | Tri Vo |
Ability to choose either suspend counter or /sys/power/wake_lock.
Suspend blocker that are kept track of by SystemSuspend can now be
backed by either a ref-counter OR /sys/power/wake_lock interface.
We need /sys/power/wake_[un]lock to export debugging info via
/sys/kernel/debug/wakeup_sources. We do this to preserve the workflow
with existing toolchains.
In the future, we want to keep all native wake lock debugging info in
SystemSuspend. That info will then be exposed directly to our tools.
Debug info in /d/wakeup_sources might be misaligned if there wake locks
with colliding names on the device. There are no such cases in Android
platform or pixel devices.
Bug: 128923994
Test: SystemSuspendV1_0UnitTest
Test: device suspends if left alone
Test: /d/wakeup_sources keeps track of all native wake locks
Change-Id: I7d15fca42efca945122ec0671f424e75e186f5d8
@@ -42,6 +42,10 @@ namespace suspend { | ||
42 | 42 | namespace V1_0 { |
43 | 43 | |
44 | 44 | static const char kSleepState[] = "mem"; |
45 | +// TODO(b/128923994): we only need /sys/power/wake_[un]lock to export debugging info via | |
46 | +// /sys/kernel/debug/wakeup_sources. | |
47 | +static constexpr char kSysPowerWakeLock[] = "/sys/power/wake_lock"; | |
48 | +static constexpr char kSysPowerWakeUnlock[] = "/sys/power/wake_unlock"; | |
45 | 49 | |
46 | 50 | // This function assumes that data in fd is small enough that it can be read in one go. |
47 | 51 | // We use this function instead of the ones available in libbase because it doesn't block |
@@ -67,9 +71,9 @@ TimestampType getEpochTimeNow() { | ||
67 | 71 | return std::chrono::duration_cast<std::chrono::microseconds>(timeSinceEpoch).count(); |
68 | 72 | } |
69 | 73 | |
70 | -WakeLock::WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id) | |
71 | - : mReleased(), mSystemSuspend(systemSuspend), mId(id) { | |
72 | - mSystemSuspend->incSuspendCounter(); | |
74 | +WakeLock::WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id, const string& name) | |
75 | + : mReleased(), mSystemSuspend(systemSuspend), mId(id), mName(name) { | |
76 | + mSystemSuspend->incSuspendCounter(mName); | |
73 | 77 | } |
74 | 78 | |
75 | 79 | WakeLock::~WakeLock() { |
@@ -83,22 +87,37 @@ Return<void> WakeLock::release() { | ||
83 | 87 | |
84 | 88 | void WakeLock::releaseOnce() { |
85 | 89 | std::call_once(mReleased, [this]() { |
86 | - mSystemSuspend->decSuspendCounter(); | |
90 | + mSystemSuspend->decSuspendCounter(mName); | |
87 | 91 | mSystemSuspend->deleteWakeLockStatsEntry(mId); |
88 | 92 | }); |
89 | 93 | } |
90 | 94 | |
91 | 95 | SystemSuspend::SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, size_t maxStatsEntries, |
92 | 96 | std::chrono::milliseconds baseSleepTime, |
93 | - const sp<SuspendControlService>& controlService) | |
97 | + const sp<SuspendControlService>& controlService, | |
98 | + bool useSuspendCounter) | |
94 | 99 | : mSuspendCounter(0), |
95 | 100 | mWakeupCountFd(std::move(wakeupCountFd)), |
96 | 101 | mStateFd(std::move(stateFd)), |
97 | 102 | mMaxStatsEntries(maxStatsEntries), |
98 | 103 | mBaseSleepTime(baseSleepTime), |
99 | 104 | mSleepTime(baseSleepTime), |
100 | - mControlService(controlService) { | |
105 | + mControlService(controlService), | |
106 | + mUseSuspendCounter(useSuspendCounter), | |
107 | + mWakeLockFd(-1), | |
108 | + mWakeUnlockFd(-1) { | |
101 | 109 | mControlService->setSuspendService(this); |
110 | + | |
111 | + if (!mUseSuspendCounter) { | |
112 | + mWakeLockFd.reset(TEMP_FAILURE_RETRY(open(kSysPowerWakeLock, O_CLOEXEC | O_RDWR))); | |
113 | + if (mWakeLockFd < 0) { | |
114 | + PLOG(ERROR) << "error opening " << kSysPowerWakeLock; | |
115 | + } | |
116 | + mWakeUnlockFd.reset(TEMP_FAILURE_RETRY(open(kSysPowerWakeUnlock, O_CLOEXEC | O_RDWR))); | |
117 | + if (mWakeUnlockFd < 0) { | |
118 | + PLOG(ERROR) << "error opening " << kSysPowerWakeUnlock; | |
119 | + } | |
120 | + } | |
102 | 121 | } |
103 | 122 | |
104 | 123 | bool SystemSuspend::enableAutosuspend() { |
@@ -117,7 +136,7 @@ Return<sp<IWakeLock>> SystemSuspend::acquireWakeLock(WakeLockType /* type */, | ||
117 | 136 | const hidl_string& name) { |
118 | 137 | auto pid = getCallingPid(); |
119 | 138 | auto wlId = getWakeLockId(pid, name); |
120 | - IWakeLock* wl = new WakeLock{this, wlId}; | |
139 | + IWakeLock* wl = new WakeLock{this, wlId, name}; | |
121 | 140 | { |
122 | 141 | auto l = std::lock_guard(mStatsLock); |
123 | 142 |
@@ -158,15 +177,27 @@ Return<void> SystemSuspend::debug(const hidl_handle& handle, | ||
158 | 177 | return Void(); |
159 | 178 | } |
160 | 179 | |
161 | -void SystemSuspend::incSuspendCounter() { | |
180 | +void SystemSuspend::incSuspendCounter(const string& name) { | |
162 | 181 | auto l = std::lock_guard(mCounterLock); |
163 | - mSuspendCounter++; | |
182 | + if (mUseSuspendCounter) { | |
183 | + mSuspendCounter++; | |
184 | + } else { | |
185 | + if (!WriteStringToFd(name, mWakeLockFd)) { | |
186 | + PLOG(ERROR) << "error writing " << name << " to " << kSysPowerWakeLock; | |
187 | + } | |
188 | + } | |
164 | 189 | } |
165 | 190 | |
166 | -void SystemSuspend::decSuspendCounter() { | |
191 | +void SystemSuspend::decSuspendCounter(const string& name) { | |
167 | 192 | auto l = std::lock_guard(mCounterLock); |
168 | - if (--mSuspendCounter == 0) { | |
169 | - mCounterCondVar.notify_one(); | |
193 | + if (mUseSuspendCounter) { | |
194 | + if (--mSuspendCounter == 0) { | |
195 | + mCounterCondVar.notify_one(); | |
196 | + } | |
197 | + } else { | |
198 | + if (!WriteStringToFd(name, mWakeUnlockFd)) { | |
199 | + PLOG(ERROR) << "error writing " << name << " to " << kSysPowerWakeUnlock; | |
200 | + } | |
170 | 201 | } |
171 | 202 | } |
172 | 203 |
@@ -53,7 +53,7 @@ TimestampType getEpochTimeNow(); | ||
53 | 53 | |
54 | 54 | class WakeLock : public IWakeLock { |
55 | 55 | public: |
56 | - WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id); | |
56 | + WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id, const std::string& name); | |
57 | 57 | ~WakeLock(); |
58 | 58 | |
59 | 59 | Return<void> release(); |
@@ -64,17 +64,18 @@ class WakeLock : public IWakeLock { | ||
64 | 64 | |
65 | 65 | SystemSuspend* mSystemSuspend; |
66 | 66 | WakeLockIdType mId; |
67 | + std::string mName; | |
67 | 68 | }; |
68 | 69 | |
69 | 70 | class SystemSuspend : public ISystemSuspend { |
70 | 71 | public: |
71 | 72 | SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, size_t maxStatsEntries, |
72 | 73 | std::chrono::milliseconds baseSleepTime, |
73 | - const sp<SuspendControlService>& controlService); | |
74 | + const sp<SuspendControlService>& controlService, bool useSuspendCounter = true); | |
74 | 75 | Return<sp<IWakeLock>> acquireWakeLock(WakeLockType type, const hidl_string& name) override; |
75 | 76 | Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override; |
76 | - void incSuspendCounter(); | |
77 | - void decSuspendCounter(); | |
77 | + void incSuspendCounter(const std::string& name); | |
78 | + void decSuspendCounter(const std::string& name); | |
78 | 79 | void deleteWakeLockStatsEntry(WakeLockIdType id); |
79 | 80 | bool enableAutosuspend(); |
80 | 81 |
@@ -106,6 +107,13 @@ class SystemSuspend : public ISystemSuspend { | ||
106 | 107 | void updateSleepTime(bool success); |
107 | 108 | |
108 | 109 | sp<SuspendControlService> mControlService; |
110 | + | |
111 | + // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on | |
112 | + // /sys/power/wake_lock interface to block suspend. | |
113 | + // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface. | |
114 | + bool mUseSuspendCounter; | |
115 | + unique_fd mWakeLockFd; | |
116 | + unique_fd mWakeUnlockFd; | |
109 | 117 | }; |
110 | 118 | |
111 | 119 | } // namespace V1_0 |
@@ -1,4 +1,5 @@ | ||
1 | 1 | service system_suspend /system/bin/hw/android.system.suspend@1.0-service |
2 | 2 | class hal |
3 | 3 | user system |
4 | - group system | |
4 | + group system wakelock | |
5 | + capabilities BLOCK_SUSPEND |
@@ -81,7 +81,7 @@ int main() { | ||
81 | 81 | |
82 | 82 | sp<SystemSuspend> suspend = |
83 | 83 | new SystemSuspend(std::move(wakeupCountFd), std::move(stateFd), 100 /* maxStatsEntries */, |
84 | - 100ms /* baseSleepTime */, suspendControl); | |
84 | + 100ms /* baseSleepTime */, suspendControl, false /* mUseSuspendCounter*/); | |
85 | 85 | status_t status = suspend->registerAsService(); |
86 | 86 | if (android::OK != status) { |
87 | 87 | LOG(FATAL) << "Unable to register system-suspend service: " << status; |