diff options
| author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-17 09:08:08 +0000 |
|---|---|---|
| committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-17 09:08:08 +0000 |
| commit | ff15ed15d73214c7de7162ba030585150779760c (patch) | |
| tree | 23c68876b3f5457996dec7d5cb2bee0c8fc257f9 | |
| parent | 1b21e59f6bc50afea13e6283365149aa97dd87fb (diff) | |
| parent | e92e5ade5b91144cfd02a8e122e2242fa608efec (diff) | |
| download | platform_system_hardware_interfaces-main-cg-testing-release.tar.gz platform_system_hardware_interfaces-main-cg-testing-release.tar.bz2 platform_system_hardware_interfaces-main-cg-testing-release.zip | |
Snap for 7831146 from e92e5ade5b91144cfd02a8e122e2242fa608efec to main-cg-testing-releasemain-cg-testing-release
Change-Id: I5db3a7b7aedc4ef93424c53d268b216a9107cc75
| -rw-r--r-- | suspend/1.0/default/SuspendControlService.cpp | 6 | ||||
| -rw-r--r-- | suspend/1.0/default/SuspendControlService.h | 7 | ||||
| -rw-r--r-- | suspend/1.0/default/SystemSuspend.cpp | 97 | ||||
| -rw-r--r-- | suspend/1.0/default/SystemSuspend.h | 16 | ||||
| -rw-r--r-- | suspend/1.0/default/SystemSuspendUnitTest.cpp | 76 | ||||
| -rw-r--r-- | suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl | 4 | ||||
| -rw-r--r-- | wifi/keystore/1.0/vts/functional/OWNERS | 3 |
7 files changed, 168 insertions, 41 deletions
diff --git a/suspend/1.0/default/SuspendControlService.cpp b/suspend/1.0/default/SuspendControlService.cpp index a9939858..faadecb9 100644 --- a/suspend/1.0/default/SuspendControlService.cpp +++ b/suspend/1.0/default/SuspendControlService.cpp @@ -151,9 +151,11 @@ void SuspendControlServiceInternal::setSuspendService(const wp<SystemSuspend>& s mSuspend = suspend; } -binder::Status SuspendControlServiceInternal::enableAutosuspend(bool* _aidl_return) { +binder::Status SuspendControlServiceInternal::enableAutosuspend(const sp<IBinder>& token, + bool* _aidl_return) { const auto suspendService = mSuspend.promote(); - return retOk(suspendService != nullptr && suspendService->enableAutosuspend(), _aidl_return); + return retOk(suspendService != nullptr && suspendService->enableAutosuspend(token), + _aidl_return); } binder::Status SuspendControlServiceInternal::forceSuspend(bool* _aidl_return) { diff --git a/suspend/1.0/default/SuspendControlService.h b/suspend/1.0/default/SuspendControlService.h index 072b2e6d..7d7e0ae2 100644 --- a/suspend/1.0/default/SuspendControlService.h +++ b/suspend/1.0/default/SuspendControlService.h @@ -66,20 +66,17 @@ class SuspendControlService : public BnSuspendControlService, } }; -class SuspendControlServiceInternal : public BnSuspendControlServiceInternal, - public virtual IBinder::DeathRecipient { +class SuspendControlServiceInternal : public BnSuspendControlServiceInternal { public: SuspendControlServiceInternal() = default; ~SuspendControlServiceInternal() override = default; - binder::Status enableAutosuspend(bool* _aidl_return) override; + binder::Status enableAutosuspend(const sp<IBinder>& token, bool* _aidl_return) override; binder::Status forceSuspend(bool* _aidl_return) override; binder::Status getSuspendStats(SuspendInfo* _aidl_return) override; binder::Status getWakeLockStats(std::vector<WakeLockInfo>* _aidl_return) override; binder::Status getWakeupStats(std::vector<WakeupInfo>* _aidl_return) override; - void binderDied([[maybe_unused]] const wp<IBinder>& who) override {} - void setSuspendService(const wp<SystemSuspend>& suspend); status_t dump(int fd, const Vector<String16>& args) override; diff --git a/suspend/1.0/default/SystemSuspend.cpp b/suspend/1.0/default/SystemSuspend.cpp index 9335862e..73718bc4 100644 --- a/suspend/1.0/default/SystemSuspend.cpp +++ b/suspend/1.0/default/SystemSuspend.cpp @@ -23,13 +23,14 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android/binder_manager.h> - #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> +#include <chrono> #include <string> #include <thread> +using namespace std::chrono_literals; using ::aidl::android::system::suspend::ISystemSuspend; using ::aidl::android::system::suspend::IWakeLock; @@ -156,25 +157,69 @@ SystemSuspend::SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, unique_ } } -bool SystemSuspend::enableAutosuspend() { - if (mAutosuspendEnabled.test_and_set()) { +bool SystemSuspend::enableAutosuspend(const sp<IBinder>& token) { + auto autosuspendLock = std::lock_guard(mAutosuspendLock); + + bool hasToken = std::find(mDisableAutosuspendTokens.begin(), mDisableAutosuspendTokens.end(), + token) != mDisableAutosuspendTokens.end(); + + if (!hasToken) { + mDisableAutosuspendTokens.push_back(token); + } + + if (mAutosuspendEnabled) { LOG(ERROR) << "Autosuspend already started."; return false; } - initAutosuspend(); + mAutosuspendEnabled = true; + initAutosuspendLocked(); return true; } +void SystemSuspend::disableAutosuspendLocked() { + mDisableAutosuspendTokens.clear(); + if (mAutosuspendEnabled) { + mAutosuspendEnabled = false; + mAutosuspendCondVar.notify_all(); + LOG(INFO) << "automatic system suspend disabled"; + } +} + +void SystemSuspend::disableAutosuspend() { + auto autosuspendLock = std::lock_guard(mAutosuspendLock); + disableAutosuspendLocked(); +} + +bool SystemSuspend::hasAliveAutosuspendTokenLocked() { + mDisableAutosuspendTokens.erase( + std::remove_if(mDisableAutosuspendTokens.begin(), mDisableAutosuspendTokens.end(), + [](const sp<IBinder>& token) { return token->pingBinder() != OK; }), + mDisableAutosuspendTokens.end()); + + return !mDisableAutosuspendTokens.empty(); +} + +SystemSuspend::~SystemSuspend(void) { + auto autosuspendLock = std::unique_lock(mAutosuspendLock); + + // signal autosuspend thread to shut down + disableAutosuspendLocked(); + + // wait for autosuspend thread to exit + mAutosuspendCondVar.wait_for(autosuspendLock, 100ms, + [this] { return !mAutosuspendThreadCreated; }); +} + bool SystemSuspend::forceSuspend() { // We are forcing the system to suspend. This particular call ignores all // existing wakelocks (full or partial). It does not cancel the wakelocks // or reset mSuspendCounter, it just ignores them. When the system // returns from suspend, the wakelocks and SuspendCounter will not have // changed. - auto counterLock = std::unique_lock(mCounterLock); + auto autosuspendLock = std::unique_lock(mAutosuspendLock); bool success = WriteStringToFd(kSleepState, mStateFd); - counterLock.unlock(); + autosuspendLock.unlock(); if (!success) { PLOG(VERBOSE) << "error writing to /sys/power/state for forceSuspend"; @@ -183,7 +228,7 @@ bool SystemSuspend::forceSuspend() { } void SystemSuspend::incSuspendCounter(const string& name) { - auto l = std::lock_guard(mCounterLock); + auto l = std::lock_guard(mAutosuspendLock); if (mUseSuspendCounter) { mSuspendCounter++; } else { @@ -194,10 +239,10 @@ void SystemSuspend::incSuspendCounter(const string& name) { } void SystemSuspend::decSuspendCounter(const string& name) { - auto l = std::lock_guard(mCounterLock); + auto l = std::lock_guard(mAutosuspendLock); if (mUseSuspendCounter) { if (--mSuspendCounter == 0) { - mCounterCondVar.notify_one(); + mAutosuspendCondVar.notify_one(); } } else { if (!WriteStringToFd(name, mWakeUnlockFd)) { @@ -217,10 +262,25 @@ unique_fd SystemSuspend::reopenFileUsingFd(const int fd, const int permission) { return tempFd; } -void SystemSuspend::initAutosuspend() { +void SystemSuspend::initAutosuspendLocked() { + if (mAutosuspendThreadCreated) { + LOG(INFO) << "Autosuspend thread already started."; + return; + } + std::thread autosuspendThread([this] { while (true) { - std::this_thread::sleep_for(mSleepTime); + auto autosuspendLock = std::unique_lock(mAutosuspendLock); + if (!mAutosuspendEnabled) { + mAutosuspendThreadCreated = false; + return; + } + + mAutosuspendCondVar.wait_for(autosuspendLock, mSleepTime, + [this] { return !mAutosuspendEnabled; }); + if (!mAutosuspendEnabled) continue; + autosuspendLock.unlock(); + lseek(mWakeupCountFd, 0, SEEK_SET); const string wakeupCount = readFd(mWakeupCountFd); if (wakeupCount.empty()) { @@ -228,18 +288,26 @@ void SystemSuspend::initAutosuspend() { continue; } - auto counterLock = std::unique_lock(mCounterLock); - mCounterCondVar.wait(counterLock, [this] { return mSuspendCounter == 0; }); + autosuspendLock.lock(); + mAutosuspendCondVar.wait( + autosuspendLock, [this] { return mSuspendCounter == 0 || !mAutosuspendEnabled; }); // The mutex is locked and *MUST* remain locked until we write to /sys/power/state. // Otherwise, a WakeLock might be acquired after we check mSuspendCounter and before we // write to /sys/power/state. + if (!mAutosuspendEnabled) continue; + + if (!hasAliveAutosuspendTokenLocked()) { + disableAutosuspendLocked(); + continue; + } + if (!WriteStringToFd(wakeupCount, mWakeupCountFd)) { PLOG(VERBOSE) << "error writing from /sys/power/wakeup_count"; continue; } bool success = WriteStringToFd(kSleepState, mStateFd); - counterLock.unlock(); + autosuspendLock.unlock(); if (!success) { PLOG(VERBOSE) << "error writing to /sys/power/state"; @@ -261,6 +329,7 @@ void SystemSuspend::initAutosuspend() { } }); autosuspendThread.detach(); + mAutosuspendThreadCreated = true; LOG(INFO) << "automatic system suspend enabled"; } diff --git a/suspend/1.0/default/SystemSuspend.h b/suspend/1.0/default/SystemSuspend.h index 51eb7fad..ddcee24b 100644 --- a/suspend/1.0/default/SystemSuspend.h +++ b/suspend/1.0/default/SystemSuspend.h @@ -83,7 +83,8 @@ class SystemSuspend : public RefBase { bool useSuspendCounter = true); void incSuspendCounter(const std::string& name); void decSuspendCounter(const std::string& name); - bool enableAutosuspend(); + bool enableAutosuspend(const sp<IBinder>& token); + void disableAutosuspend(); bool forceSuspend(); const WakeupList& getWakeupList() const; @@ -97,10 +98,13 @@ class SystemSuspend : public RefBase { unique_fd reopenFileUsingFd(const int fd, int permission); private: - void initAutosuspend(); + ~SystemSuspend(void) override; + void initAutosuspendLocked(); + void disableAutosuspendLocked(); + bool hasAliveAutosuspendTokenLocked(); - std::mutex mCounterLock; - std::condition_variable mCounterCondVar; + std::mutex mAutosuspendLock; + std::condition_variable mAutosuspendCondVar; uint32_t mSuspendCounter; unique_fd mWakeupCountFd; unique_fd mStateFd; @@ -134,7 +138,9 @@ class SystemSuspend : public RefBase { unique_fd mWakeUnlockFd; unique_fd mWakeupReasonsFd; - std::atomic_flag mAutosuspendEnabled = ATOMIC_FLAG_INIT; + std::atomic<bool> mAutosuspendEnabled{false}; + std::atomic<bool> mAutosuspendThreadCreated{false}; + std::vector<sp<IBinder>> mDisableAutosuspendTokens; }; } // namespace V1_0 diff --git a/suspend/1.0/default/SystemSuspendUnitTest.cpp b/suspend/1.0/default/SystemSuspendUnitTest.cpp index 533afae1..c779623b 100644 --- a/suspend/1.0/default/SystemSuspendUnitTest.cpp +++ b/suspend/1.0/default/SystemSuspendUnitTest.cpp @@ -144,6 +144,9 @@ class SystemSuspendTest : public ::testing::Test { Socketpair(SOCK_STREAM, &wakeupCountFds[0], &wakeupCountFds[1]); Socketpair(SOCK_STREAM, &stateFds[0], &stateFds[1]); + wakeupCountFd = wakeupCountFds[0]; + stateFd = stateFds[0]; + registerTestService(); std::shared_ptr<ISystemSuspend> suspendService = ISystemSuspend::fromBinder( ndk::SpAIBinder(AServiceManager_waitForService(kServiceName))); @@ -162,10 +165,15 @@ class SystemSuspendTest : public ::testing::Test { // Start auto-suspend. bool enabled = false; - controlServiceInternal->enableAutosuspend(&enabled); + controlServiceInternal->enableAutosuspend(new BBinder(), &enabled); ASSERT_EQ(enabled, true) << "failed to start autosuspend"; } + static void TearDownTestSuite() { + unblockSystemSuspendFromWakeupCount(); + systemSuspend->disableAutosuspend(); + } + public: virtual void SetUp() override { suspendService = ISystemSuspend::fromBinder( @@ -182,8 +190,7 @@ class SystemSuspendTest : public ::testing::Test { ASSERT_NE(controlInternal, nullptr) << "failed to get the suspend control internal service"; controlServiceInternal = interface_cast<ISuspendControlServiceInternal>(controlInternal); - wakeupCountFd = wakeupCountFds[0]; - stateFd = stateFds[0]; + systemSuspend->enableAutosuspend(new BBinder()); // SystemSuspend HAL should not have written back to wakeupCountFd or stateFd yet. ASSERT_TRUE(isReadBlocked(wakeupCountFd)); @@ -197,7 +204,7 @@ class SystemSuspendTest : public ::testing::Test { ASSERT_TRUE(isReadBlocked(stateFd)); } - void unblockSystemSuspendFromWakeupCount() { + static void unblockSystemSuspendFromWakeupCount() { std::string wakeupCount = std::to_string(rand()); ASSERT_TRUE(WriteStringToFd(wakeupCount, wakeupCountFd)); } @@ -291,10 +298,43 @@ TemporaryFile SystemSuspendTest::suspendTimeFile; // Tests that autosuspend thread can only be enabled once. TEST_F(SystemSuspendTest, OnlyOneEnableAutosuspend) { bool enabled = false; - controlServiceInternal->enableAutosuspend(&enabled); + controlServiceInternal->enableAutosuspend(new BBinder(), &enabled); ASSERT_EQ(enabled, false); } +// Tests that autosuspend thread can only enabled again after its been disabled. +TEST_F(SystemSuspendTest, EnableAutosuspendAfterDisableAutosuspend) { + bool enabled = false; + unblockSystemSuspendFromWakeupCount(); + systemSuspend->disableAutosuspend(); + controlServiceInternal->enableAutosuspend(new BBinder(), &enabled); + ASSERT_EQ(enabled, true); +} + +TEST_F(SystemSuspendTest, DisableAutosuspendBlocksSuspend) { + checkLoop(1); + systemSuspend->disableAutosuspend(); + ASSERT_TRUE(isSystemSuspendBlocked()); +} + +TEST_F(SystemSuspendTest, BlockAutosuspendIfBinderIsDead) { + class DeadBinder : public BBinder { + android::status_t pingBinder() override { return android::UNKNOWN_ERROR; } + }; + + auto token = sp<DeadBinder>::make(); + + systemSuspend->disableAutosuspend(); + unblockSystemSuspendFromWakeupCount(); + ASSERT_TRUE(isSystemSuspendBlocked()); + + bool enabled = false; + controlServiceInternal->enableAutosuspend(token, &enabled); + unblockSystemSuspendFromWakeupCount(); + + ASSERT_TRUE(isSystemSuspendBlocked(150)); +} + TEST_F(SystemSuspendTest, AutosuspendLoop) { checkLoop(5); } @@ -940,17 +980,18 @@ class SystemSuspendSameThreadTest : public ::testing::Test { new SuspendControlServiceInternal(); controlService = suspendControl; controlServiceInternal = suspendControlInternal; - systemSuspend = - new SystemSuspend(unique_fd(-1) /* wakeupCountFd */, unique_fd(-1) /* stateFd */, - unique_fd(dup(suspendStatsFd)), 1 /* maxNativeStatsEntries */, - unique_fd(dup(kernelWakelockStatsFd.get())), - unique_fd(-1) /* wakeupReasonsFd */, unique_fd(-1) /*suspendTimeFd*/, - kSleepTimeConfig, suspendControl, suspendControlInternal); + systemSuspend = new SystemSuspend( + unique_fd(-1) /* wakeupCountFd */, unique_fd(-1) /* stateFd */, + unique_fd(dup(suspendStatsFd)), 1 /* maxNativeStatsEntries */, + unique_fd(dup(kernelWakelockStatsFd.get())), unique_fd(-1) /* wakeupReasonsFd */, + unique_fd(-1) /* suspendTimeFd */, kSleepTimeConfig, suspendControl, + suspendControlInternal); suspendService = ndk::SharedRefBase::make<SystemSuspendAidl>(systemSuspend.get()); } virtual void TearDown() override { + systemSuspend->disableAutosuspend(); ASSERT_TRUE(clearDirectory(kernelWakelockStatsDir.path)); ASSERT_TRUE(clearDirectory(suspendStatsDir.path)); } @@ -1221,17 +1262,24 @@ class SuspendWakeupTest : public ::testing::Test { systemSuspend = new SystemSuspend( std::move(wakeupCountServiceFd), std::move(stateServiceFd), - unique_fd(-1) /*suspendStatsFd*/, 100 /* maxStatsEntries */, + unique_fd(-1) /* suspendStatsFd */, 100 /* maxStatsEntries */, unique_fd(-1) /* kernelWakelockStatsFd */, std::move(wakeupReasonsFd), std::move(suspendTimeFd), kSleepTimeConfig, suspendControl, suspendControlInternal); // Start auto-suspend. bool enabled = false; - suspendControlInternal->enableAutosuspend(&enabled); + suspendControlInternal->enableAutosuspend(new BBinder(), &enabled); ASSERT_EQ(enabled, true) << "failed to start autosuspend"; } - virtual void TearDown() override {} + virtual void TearDown() override { systemSuspend->disableAutosuspend(); } + + std::shared_ptr<IWakeLock> acquireWakeLock(const std::string& name = "TestLock") { + auto suspendService = ndk::SharedRefBase::make<SystemSuspendAidl>(systemSuspend.get()); + std::shared_ptr<IWakeLock> wl = nullptr; + auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name, &wl); + return wl; + } void wakeup(std::string wakeupReason) { ASSERT_TRUE(WriteStringToFile(wakeupReason, wakeupReasonsFile.path)); diff --git a/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl b/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl index 99ac5254..8e0a9a2b 100644 --- a/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl +++ b/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl @@ -29,9 +29,11 @@ interface ISuspendControlServiceInternal { /** * Starts automatic system suspension. * + * @param token token registering automatic system suspension. + * When all registered tokens die automatic system suspension is disabled. * @return true on success, false otherwise. */ - boolean enableAutosuspend(); + boolean enableAutosuspend(IBinder token); /** * Suspends the system even if there are wakelocks being held. diff --git a/wifi/keystore/1.0/vts/functional/OWNERS b/wifi/keystore/1.0/vts/functional/OWNERS new file mode 100644 index 00000000..3f5fd4a1 --- /dev/null +++ b/wifi/keystore/1.0/vts/functional/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 189335 +haishalom@google.com +etancohen@google.com |
