aboutsummaryrefslogtreecommitdiff
path: root/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp
blob: f529f7954c5d5f92c7702b8cb0aa11294b161a92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

#include <android-base/file.h>
#include <android-base/logging.h>
#include <protos/aconfig_storage_metadata.pb.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "rust/cxx.h"
#include "aconfig_storage/lib.rs.h"
#include "aconfig_storage/aconfig_storage_write_api.hpp"

using storage_records_pb = android::aconfig_storage_metadata::storage_files;
using storage_record_pb = android::aconfig_storage_metadata::storage_file_info;
using namespace android::base;

namespace aconfig_storage {

/// Map a storage file
Result<MutableMappedStorageFile*> map_mutable_storage_file(std::string const& file) {
  struct stat file_stat;
  if (stat(file.c_str(), &file_stat) < 0) {
    return ErrnoError() << "stat failed";
  }

  if ((file_stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0) {
    return Error() << "cannot map nonwriteable file";
  }

  size_t file_size = file_stat.st_size;

  const int fd = open(file.c_str(), O_RDWR | O_NOFOLLOW | O_CLOEXEC);
  if (fd == -1) {
    return ErrnoError() << "failed to open " << file;
  };

  void* const map_result =
      mmap(nullptr, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (map_result == MAP_FAILED) {
    return ErrnoError() << "mmap failed";
  }

  auto mapped_file = new MutableMappedStorageFile();
  mapped_file->file_ptr = map_result;
  mapped_file->file_size = file_size;

  return mapped_file;
}

/// Set boolean flag value
Result<void> set_boolean_flag_value(
    const MutableMappedStorageFile& file,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
      static_cast<uint8_t*>(file.file_ptr), file.file_size);
  auto update_cxx = update_boolean_flag_value_cxx(content, offset, value);
  if (!update_cxx.update_success) {
    return Error() << std::string(update_cxx.error_message.c_str());
  }
  return {};
}

/// Set if flag has server override
Result<void> set_flag_has_server_override(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
      static_cast<uint8_t*>(file.file_ptr), file.file_size);
  auto update_cxx = update_flag_has_server_override_cxx(
      content, static_cast<uint16_t>(value_type), offset, value);
  if (!update_cxx.update_success) {
    return Error() << std::string(update_cxx.error_message.c_str());
  }
  return {};
}

/// Set if flag has local override
Result<void> set_flag_has_local_override(
    const MutableMappedStorageFile& file,
    FlagValueType value_type,
    uint32_t offset,
    bool value) {
  auto content = rust::Slice<uint8_t>(
      static_cast<uint8_t*>(file.file_ptr), file.file_size);
  auto update_cxx = update_flag_has_local_override_cxx(
      content, static_cast<uint16_t>(value_type), offset, value);
  if (!update_cxx.update_success) {
    return Error() << std::string(update_cxx.error_message.c_str());
  }
  return {};
}

Result<void> create_flag_info(
    std::string const& package_map,
    std::string const& flag_map,
    std::string const& flag_info_out) {
  auto creation_cxx = create_flag_info_cxx(
      rust::Str(package_map.c_str()),
      rust::Str(flag_map.c_str()),
      rust::Str(flag_info_out.c_str()));
  if (creation_cxx.success) {
    return {};
  } else {
    return android::base::Error() << creation_cxx.error_message;
  }
}
} // namespace aconfig_storage