1 /*
2  * Copyright (C) 2022 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 #include "StatsReporter.h"
18 #include <android-base/logging.h>
19 #include <stdlib.h>
20 #include <string>
21 #include <sys/stat.h>
22 
23 // Keep these constants in sync with those in OdsignStatsLogger.java.
24 constexpr const char* kOdsignMetricsFile = "/data/misc/odsign/metrics/odsign-metrics.txt";
25 constexpr const char* kComposMetricName = "comp_os_artifacts_check_record";
26 constexpr const char* kOdsignMetricName = "odsign_record";
27 
~StatsReporter()28 StatsReporter::~StatsReporter() {
29     if (comp_os_artifacts_check_record_ == nullptr && !odsign_record_enabled_) {
30         LOG(INFO) << "Metrics report is empty";
31 
32         // Remove the metrics file if any old version of the file already exists
33         if (std::filesystem::remove(kOdsignMetricsFile) != 0 &&
34             !((errno = ENOENT) || errno == ENOTDIR)) {
35             PLOG(ERROR) << "Could not remove already present file";
36         }
37         return;
38     }
39 
40     std::ofstream odsign_metrics_file_;
41     odsign_metrics_file_.open(kOdsignMetricsFile, std::ios::trunc);
42     if (!odsign_metrics_file_) {
43         PLOG(ERROR) << "Could not open file: " << kOdsignMetricsFile;
44         return;
45     }
46     if (chmod(kOdsignMetricsFile, 0644) != 0) {
47         PLOG(ERROR) << "Could not set correct file permissions for " << kOdsignMetricsFile;
48         return;
49     }
50 
51     if (comp_os_artifacts_check_record_ != nullptr) {
52         odsign_metrics_file_ << kComposMetricName << ' '
53                              << comp_os_artifacts_check_record_->current_artifacts_ok << ' '
54                              << comp_os_artifacts_check_record_->comp_os_pending_artifacts_exists
55                              << ' '
56                              << comp_os_artifacts_check_record_->use_comp_os_generated_artifacts
57                              << '\n';
58     }
59 
60     if (odsign_record_enabled_) {
61         odsign_metrics_file_ << kOdsignMetricName << ' ' << odsign_record_.status << '\n';
62     }
63 
64     odsign_metrics_file_.close();
65     if (!odsign_metrics_file_) {
66         PLOG(ERROR) << "Failed to close the file";
67     }
68 }
69 
GetOrCreateComposArtifactsCheckRecord()70 StatsReporter::CompOsArtifactsCheckRecord* StatsReporter::GetOrCreateComposArtifactsCheckRecord() {
71     if (comp_os_artifacts_check_record_ == nullptr) {
72         comp_os_artifacts_check_record_ = std::make_unique<CompOsArtifactsCheckRecord>();
73     }
74     return comp_os_artifacts_check_record_.get();
75 }
76