Merge branch android10-qpr2-release

Change-Id: I66c1686129e3559a4e5b3985ba16b33244366a54
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 4f5ca52..589b962 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -93,6 +93,8 @@
 static constexpr const char* kApexStatusStarting = "starting";
 static constexpr const char* kApexStatusReady = "ready";
 
+static constexpr const char* kBuildFingerprintSysprop = "ro.build.fingerprint";
+
 static constexpr const char* kApexVerityOnSystemProp =
     "persist.apexd.verity_on_system";
 static bool gForceDmVerityOnSystem =
@@ -1372,6 +1374,7 @@
 }
 
 void scanStagedSessionsDirAndStage() {
+  using android::base::GetProperty;
   LOG(INFO) << "Scanning " << kApexSessionsDir
             << " looking for sessions to be activated.";
 
@@ -1389,6 +1392,12 @@
     };
     auto scope_guard = android::base::make_scope_guard(session_failed_fn);
 
+    std::string build_fingerprint = GetProperty(kBuildFingerprintSysprop, "");
+    if (session.GetBuildFingerprint().compare(build_fingerprint) != 0) {
+      LOG(ERROR) << "APEX build fingerprint has changed";
+      continue;
+    }
+
     std::vector<std::string> dirsToScan;
     if (session.GetChildSessionIds().empty()) {
       dirsToScan.push_back(std::string(kStagedSessionsDir) + "/session_" +
@@ -1789,6 +1798,7 @@
 
 StatusOr<std::vector<ApexFile>> submitStagedSession(
     const int session_id, const std::vector<int>& child_session_ids) {
+  using android::base::GetProperty;
   bool needsBackup = true;
   Status cleanup_status = ClearSessions();
   if (!cleanup_status.Ok()) {
@@ -1843,6 +1853,8 @@
     return StatusOr<std::vector<ApexFile>>::MakeError(session.ErrorMessage());
   }
   (*session).SetChildSessionIds(child_session_ids);
+  std::string build_fingerprint = GetProperty(kBuildFingerprintSysprop, "");
+  (*session).SetBuildFingerprint(build_fingerprint);
   Status commit_status =
       (*session).UpdateStateAndCommit(SessionState::VERIFIED);
   if (!commit_status.Ok()) {
diff --git a/apexd/apexd_session.cpp b/apexd/apexd_session.cpp
index c94585f..98180b7 100644
--- a/apexd/apexd_session.cpp
+++ b/apexd/apexd_session.cpp
@@ -168,6 +168,10 @@
 
 int ApexSession::GetId() const { return state_.id(); }
 
+std::string ApexSession::GetBuildFingerprint() const {
+  return state_.expected_build_fingerprint();
+}
+
 bool ApexSession::IsFinalized() const {
   switch (GetState()) {
     case SessionState::SUCCESS:
@@ -194,6 +198,10 @@
                                            child_session_ids.end()};
 }
 
+void ApexSession::SetBuildFingerprint(const std::string& fingerprint) {
+  *(state_.mutable_expected_build_fingerprint()) = fingerprint;
+}
+
 Status ApexSession::UpdateStateAndCommit(
     const SessionState::State& session_state) {
   state_.set_state(session_state);
diff --git a/apexd/apexd_session.h b/apexd/apexd_session.h
index 5f32198..7b6b703 100644
--- a/apexd/apexd_session.h
+++ b/apexd/apexd_session.h
@@ -43,9 +43,11 @@
   const google::protobuf::RepeatedField<int> GetChildSessionIds() const;
   ::apex::proto::SessionState::State GetState() const;
   int GetId() const;
+  std::string GetBuildFingerprint() const;
   bool IsFinalized() const;
 
   void SetChildSessionIds(const std::vector<int>& child_session_ids);
+  void SetBuildFingerprint(const std::string& fingerprint);
   Status UpdateStateAndCommit(const ::apex::proto::SessionState::State& state);
 
   Status DeleteSession() const;
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index cad7789..89ca62b 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -565,6 +565,21 @@
   }
 }
 
+TEST_F(ApexServiceTest, SubmitStagedSessionStoresBuildFingerprint) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"),
+                                      "/data/app-staging/session_1547",
+                                      "staging_data_file");
+  if (!installer.Prepare()) {
+    return;
+  }
+  ApexInfoList list;
+  bool success;
+  ASSERT_TRUE(IsOk(service_->submitStagedSession(1547, {}, &list, &success)));
+
+  auto session = ApexSession::GetSession(1547);
+  ASSERT_FALSE(session->GetBuildFingerprint().empty());
+}
+
 TEST_F(ApexServiceTest, SubmitStagedSessionFailDoesNotLeakTempVerityDevices) {
   using android::dm::DeviceMapper;
 
diff --git a/proto/session_state.proto b/proto/session_state.proto
index addb703..f023353 100644
--- a/proto/session_state.proto
+++ b/proto/session_state.proto
@@ -39,4 +39,7 @@
 
   // Child session ids
   repeated int32 child_session_ids = 3;
+
+  // Build fingerprint before reboot
+  string expected_build_fingerprint = 4;
 }