1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_APEXD_APEXD_SESSION_H_
18 #define ANDROID_APEXD_APEXD_SESSION_H_
19 
20 #include <android-base/result.h>
21 
22 #include "apex_constants.h"
23 
24 #include "session_state.pb.h"
25 
26 #include <optional>
27 
28 namespace android {
29 namespace apex {
30 
31 // Starting from R, apexd prefers /metadata partition (kNewApexSessionsDir) as
32 // location for sessions-related information. For devices that don't have
33 // /metadata partition, apexd will fallback to the /data one
34 // (kOldApexSessionsDir).
35 static constexpr const char* kOldApexSessionsDir = "/data/apex/sessions";
36 static constexpr const char* kNewApexSessionsDir = "/metadata/apex/sessions";
37 
38 // Returns top-level directory to store sessions metadata in.
39 // If device has /metadata partition, this will return
40 // /metadata/apex/sessions, on all other devices it will return
41 // /data/apex/sessions.
42 std::string GetSessionsDir();
43 
44 // TODO(b/288309411): remove static functions in this class.
45 class ApexSession {
46  public:
47   // Migrates content of /data/apex/sessions to /metadata/apex/sessions.
48   // If device doesn't have /metadata partition this call will be a no-op.
49   // If /data/apex/sessions this call will also be a no-op.
50   static android::base::Result<void> MigrateToMetadataSessionsDir();
51 
52   static android::base::Result<ApexSession> CreateSession(int session_id);
53   static android::base::Result<ApexSession> GetSession(int session_id);
54   static std::vector<ApexSession> GetSessions();
55   static std::vector<ApexSession> GetSessionsInState(
56       ::apex::proto::SessionState::State state);
57   ApexSession() = delete;
58 
59   const google::protobuf::RepeatedField<int> GetChildSessionIds() const;
60   ::apex::proto::SessionState::State GetState() const;
61   int GetId() const;
62   const std::string& GetBuildFingerprint() const;
63   const std::string& GetCrashingNativeProcess() const;
64   const std::string& GetErrorMessage() const;
65   bool IsFinalized() const;
66   bool HasRollbackEnabled() const;
67   bool IsRollback() const;
68   int GetRollbackId() const;
69   const google::protobuf::RepeatedPtrField<std::string> GetApexNames() const;
70   const std::string& GetSessionDir() const;
71 
72   void SetChildSessionIds(const std::vector<int>& child_session_ids);
73   void SetBuildFingerprint(const std::string& fingerprint);
74   void SetHasRollbackEnabled(const bool enabled);
75   void SetIsRollback(const bool is_rollback);
76   void SetRollbackId(const int rollback_id);
77   void SetCrashingNativeProcess(const std::string& crashing_process);
78   void SetErrorMessage(const std::string& error_message);
79   void AddApexName(const std::string& apex_name);
80 
81   android::base::Result<void> UpdateStateAndCommit(
82       const ::apex::proto::SessionState::State& state);
83 
84   android::base::Result<void> DeleteSession() const;
85   static void DeleteFinalizedSessions();
86 
87   // Returns the directories containing the apexes staged for this session.
88   std::vector<std::string> GetStagedApexDirs(
89       const std::string& staged_session_dir) const;
90 
91   friend class ApexSessionManager;
92 
93  private:
94   ApexSession(::apex::proto::SessionState state, std::string session_dir);
95   ::apex::proto::SessionState state_;
96   std::string session_dir_;
97 
98   static android::base::Result<ApexSession> GetSessionFromDir(
99       const std::string& session_dir);
100 };
101 
102 class ApexSessionManager {
103  public:
104   ApexSessionManager(ApexSessionManager&&) noexcept;
105   ApexSessionManager& operator=(ApexSessionManager&&) noexcept;
106 
107   static std::unique_ptr<ApexSessionManager> Create(
108       std::string sessions_base_dir);
109 
110   android::base::Result<ApexSession> CreateSession(int session_id);
111   android::base::Result<ApexSession> GetSession(int session_id) const;
112   std::vector<ApexSession> GetSessions() const;
113   std::vector<ApexSession> GetSessionsInState(
114       const ::apex::proto::SessionState::State& state) const;
115 
116   android::base::Result<void> MigrateFromOldSessionsDir(
117       const std::string& old_sessions_base_dir);
118 
119  private:
120   explicit ApexSessionManager(std::string sessions_base_dir);
121   ApexSessionManager(const ApexSessionManager&) = delete;
122   ApexSessionManager& operator=(const ApexSessionManager&) = delete;
123 
124   std::string sessions_base_dir_;
125 };
126 
127 std::ostream& operator<<(std::ostream& out, const ApexSession& session);
128 
129 }  // namespace apex
130 }  // namespace android
131 
132 #endif  // ANDROID_APEXD_APEXD_SESSION_H
133