• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <libsnapshot/snapshot_stats.h>
16 
17 #include <sstream>
18 
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include "utility.h"
22 
23 namespace android {
24 namespace snapshot {
25 
GetInstance(SnapshotManager & parent)26 SnapshotMergeStats* SnapshotMergeStats::GetInstance(SnapshotManager& parent) {
27     static std::unique_ptr<SnapshotMergeStats> g_instance;
28 
29     if (!g_instance || g_instance->path_ != parent.GetMergeStateFilePath()) {
30         g_instance = std::make_unique<SnapshotMergeStats>(parent.GetMergeStateFilePath());
31     }
32     return g_instance.get();
33 }
34 
SnapshotMergeStats(const std::string & path)35 SnapshotMergeStats::SnapshotMergeStats(const std::string& path) : path_(path), running_(false) {}
36 
ReadState()37 bool SnapshotMergeStats::ReadState() {
38     std::string contents;
39     if (!android::base::ReadFileToString(path_, &contents)) {
40         PLOG(INFO) << "Read merge statistics file failed";
41         return false;
42     }
43     if (!report_.ParseFromString(contents)) {
44         LOG(ERROR) << "Unable to parse merge statistics file as SnapshotMergeReport";
45         return false;
46     }
47     return true;
48 }
49 
WriteState()50 bool SnapshotMergeStats::WriteState() {
51     std::string contents;
52     if (!report_.SerializeToString(&contents)) {
53         LOG(ERROR) << "Unable to serialize SnapshotMergeStats.";
54         return false;
55     }
56     if (!WriteStringToFileAtomic(contents, path_)) {
57         PLOG(ERROR) << "Could not write to merge statistics file";
58         return false;
59     }
60     return true;
61 }
62 
DeleteState()63 bool SnapshotMergeStats::DeleteState() {
64     std::string error;
65     if (!android::base::RemoveFileIfExists(path_, &error)) {
66         LOG(ERROR) << "Failed to remove merge statistics file " << path_ << ": " << error;
67         return false;
68     }
69     return true;
70 }
71 
Start()72 bool SnapshotMergeStats::Start() {
73     if (running_) {
74         LOG(ERROR) << "SnapshotMergeStats running_ == " << running_;
75         return false;
76     }
77     running_ = true;
78 
79     start_time_ = std::chrono::steady_clock::now();
80     if (ReadState()) {
81         report_.set_resume_count(report_.resume_count() + 1);
82     } else {
83         report_.set_resume_count(0);
84         report_.set_state(UpdateState::None);
85     }
86 
87     return WriteState();
88 }
89 
set_state(android::snapshot::UpdateState state)90 void SnapshotMergeStats::set_state(android::snapshot::UpdateState state) {
91     report_.set_state(state);
92 }
93 
cow_file_size()94 uint64_t SnapshotMergeStats::cow_file_size() {
95     return report_.cow_file_size();
96 }
97 
total_cow_size_bytes()98 uint64_t SnapshotMergeStats::total_cow_size_bytes() {
99     return report_.total_cow_size_bytes();
100 }
101 
estimated_cow_size_bytes()102 uint64_t SnapshotMergeStats::estimated_cow_size_bytes() {
103     return report_.estimated_cow_size_bytes();
104 }
105 
set_boot_complete_time_ms(uint32_t ms)106 void SnapshotMergeStats::set_boot_complete_time_ms(uint32_t ms) {
107     report_.set_boot_complete_time_ms(ms);
108 }
109 
boot_complete_time_ms()110 uint32_t SnapshotMergeStats::boot_complete_time_ms() {
111     return report_.boot_complete_time_ms();
112 }
113 
set_boot_complete_to_merge_start_time_ms(uint32_t ms)114 void SnapshotMergeStats::set_boot_complete_to_merge_start_time_ms(uint32_t ms) {
115     report_.set_boot_complete_to_merge_start_time_ms(ms);
116 }
117 
boot_complete_to_merge_start_time_ms()118 uint32_t SnapshotMergeStats::boot_complete_to_merge_start_time_ms() {
119     return report_.boot_complete_to_merge_start_time_ms();
120 }
121 
set_merge_failure_code(MergeFailureCode code)122 void SnapshotMergeStats::set_merge_failure_code(MergeFailureCode code) {
123     report_.set_merge_failure_code(code);
124 }
125 
merge_failure_code()126 MergeFailureCode SnapshotMergeStats::merge_failure_code() {
127     return report_.merge_failure_code();
128 }
129 
set_source_build_fingerprint(const std::string & fingerprint)130 void SnapshotMergeStats::set_source_build_fingerprint(const std::string& fingerprint) {
131     report_.set_source_build_fingerprint(fingerprint);
132 }
133 
source_build_fingerprint()134 std::string SnapshotMergeStats::source_build_fingerprint() {
135     return report_.source_build_fingerprint();
136 }
137 
138 class SnapshotMergeStatsResultImpl : public SnapshotMergeStats::Result {
139   public:
SnapshotMergeStatsResultImpl(const SnapshotMergeReport & report,std::chrono::steady_clock::duration merge_time)140     SnapshotMergeStatsResultImpl(const SnapshotMergeReport& report,
141                                  std::chrono::steady_clock::duration merge_time)
142         : report_(report), merge_time_(merge_time) {}
report() const143     const SnapshotMergeReport& report() const override { return report_; }
merge_time() const144     std::chrono::steady_clock::duration merge_time() const override { return merge_time_; }
145 
146   private:
147     SnapshotMergeReport report_;
148     std::chrono::steady_clock::duration merge_time_;
149 };
150 
Finish()151 std::unique_ptr<SnapshotMergeStats::Result> SnapshotMergeStats::Finish() {
152     if (!running_) {
153         LOG(ERROR) << "SnapshotMergeStats running_ == " << running_;
154         return nullptr;
155     }
156     running_ = false;
157 
158     auto result = std::make_unique<SnapshotMergeStatsResultImpl>(
159             report_, std::chrono::steady_clock::now() - start_time_);
160 
161     // We still want to report result if state is not deleted. Just leave
162     // it there and move on. A side effect is that it may be reported over and
163     // over again in the future, but there is nothing we can do.
164     (void)DeleteState();
165 
166     return result;
167 }
168 
169 }  // namespace snapshot
170 }  // namespace android
171