Merge "Delete finalized apexd sessions after boot complete"
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 5de713c..75fe076 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -2239,6 +2239,7 @@
void bootCompletedCleanup() {
UnmountDanglingMounts();
RemoveOrphanedApexes();
+ ApexSession::DeleteFinalizedSessions();
}
int unmountAll() {
diff --git a/apexd/apexd_session.cpp b/apexd/apexd_session.cpp
index 3d916c4..8ca5fa8 100644
--- a/apexd/apexd_session.cpp
+++ b/apexd/apexd_session.cpp
@@ -259,5 +259,18 @@
<< "]";
}
+void ApexSession::DeleteFinalizedSessions() {
+ auto sessions = GetSessions();
+ for (const ApexSession& session : sessions) {
+ if (!session.IsFinalized()) {
+ continue;
+ }
+ auto result = session.DeleteSession();
+ if (!result.ok()) {
+ LOG(WARNING) << "Failed to delete finalized session: " << session.GetId();
+ }
+ }
+}
+
} // namespace apex
} // namespace android
diff --git a/apexd/apexd_session.h b/apexd/apexd_session.h
index e0cea91..ed045a7 100644
--- a/apexd/apexd_session.h
+++ b/apexd/apexd_session.h
@@ -64,6 +64,7 @@
const ::apex::proto::SessionState::State& state);
android::base::Result<void> DeleteSession() const;
+ static void DeleteFinalizedSessions();
private:
ApexSession(::apex::proto::SessionState state);
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index 5dc2161..1e09aaf 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -1983,6 +1983,42 @@
SessionInfoEq(expected2)));
}
+// Only finalized sessions should be deleted on DeleteFinalizedSessions()
+TEST_F(ApexServiceTest, DeleteFinalizedSessions) {
+ // Fetch list of all session state
+ std::vector<SessionState::State> states;
+ for (int i = SessionState::State_MIN; i < SessionState::State_MAX; i++) {
+ if (!SessionState::State_IsValid(i)) {
+ continue;
+ }
+ states.push_back(SessionState::State(i));
+ }
+
+ // For every session state, create a new session. This is to verify we only
+ // delete sessions in final state.
+ auto nonFinalSessions = 0u;
+ for (auto i = 0u; i < states.size(); i++) {
+ auto session = ApexSession::CreateSession(230 + i);
+ SessionState::State state = states[i];
+ ASSERT_TRUE(IsOk(session->UpdateStateAndCommit(state)));
+ if (!session->IsFinalized()) {
+ nonFinalSessions++;
+ }
+ }
+ std::vector<ApexSession> sessions = ApexSession::GetSessions();
+ ASSERT_EQ(states.size(), sessions.size());
+
+ // Now try cleaning up all finalized sessions
+ ApexSession::DeleteFinalizedSessions();
+ sessions = ApexSession::GetSessions();
+ ASSERT_EQ(nonFinalSessions, sessions.size());
+
+ // Verify only finalized sessions have been deleted
+ for (auto& session : sessions) {
+ ASSERT_FALSE(session.IsFinalized());
+ }
+}
+
TEST_F(ApexServiceTest, BackupActivePackages) {
if (supports_fs_checkpointing_) {
GTEST_SKIP() << "Can't run if filesystem checkpointing is enabled";