summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-17 09:08:08 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-17 09:08:08 +0000
commitff15ed15d73214c7de7162ba030585150779760c (patch)
tree23c68876b3f5457996dec7d5cb2bee0c8fc257f9
parent1b21e59f6bc50afea13e6283365149aa97dd87fb (diff)
parente92e5ade5b91144cfd02a8e122e2242fa608efec (diff)
downloadplatform_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.cpp6
-rw-r--r--suspend/1.0/default/SuspendControlService.h7
-rw-r--r--suspend/1.0/default/SystemSuspend.cpp97
-rw-r--r--suspend/1.0/default/SystemSuspend.h16
-rw-r--r--suspend/1.0/default/SystemSuspendUnitTest.cpp76
-rw-r--r--suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl4
-rw-r--r--wifi/keystore/1.0/vts/functional/OWNERS3
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