• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2020 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 #include "misc_info.h"
17 
18 #include <algorithm>
19 
20 #include <android-base/logging.h>
21 #include <android-base/stringprintf.h>
22 #include <android-base/strings.h>
23 
24 namespace cuttlefish {
25 
ParseMiscInfo(const std::string & misc_info_contents)26 MiscInfo ParseMiscInfo(const std::string& misc_info_contents) {
27   auto lines = android::base::Split(misc_info_contents, "\n");
28   MiscInfo misc_info;
29   for (auto& line : lines) {
30     line = android::base::Trim(line);
31     if (line.size() == 0) {
32       continue;
33     }
34     auto eq_pos = line.find('=');
35     if (eq_pos == std::string::npos) {
36       LOG(WARNING) << "Line in unknown format: \"" << line << "\"";
37       continue;
38     }
39     // Not using android::base::Split here to only capture the first =
40     auto key = android::base::Trim(line.substr(0, eq_pos));
41     auto value = android::base::Trim(line.substr(eq_pos + 1));
42     if (misc_info.find(key) != misc_info.end() && misc_info[key] != value) {
43       LOG(ERROR) << "Duplicate key: \"" << key << "\". First value: \""
44                  << misc_info[key] << "\", Second value: \"" << value << "\"";
45       return {};
46     }
47     misc_info[key] = value;
48   }
49   return misc_info;
50 }
51 
WriteMiscInfo(const MiscInfo & misc_info)52 std::string WriteMiscInfo(const MiscInfo& misc_info) {
53   std::stringstream out;
54   for (const auto& entry : misc_info) {
55     out << entry.first << "=" << entry.second << "\n";
56   }
57   return out.str();
58 }
59 
60 static const std::string kDynamicPartitions = "dynamic_partition_list";
61 
SuperPartitionComponents(const MiscInfo & info)62 std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) {
63   auto value_it = info.find(kDynamicPartitions);
64   if (value_it == info.end()) {
65     return {};
66   }
67   auto components = android::base::Split(value_it->second, " ");
68   for (auto& component : components) {
69     component = android::base::Trim(component);
70   }
71   components.erase(std::remove(components.begin(), components.end(), ""),
72                    components.end());
73   return components;
74 }
75 
76 static constexpr const char* kGoogleDynamicPartitions =
77     "google_dynamic_partitions";
78 static constexpr const char* kSuperPartitionGroups = "super_partition_groups";
79 
SetSuperPartitionComponents(const std::vector<std::string> & components,MiscInfo * misc_info)80 bool SetSuperPartitionComponents(const std::vector<std::string>& components,
81                                  MiscInfo* misc_info) {
82   auto super_partition_groups = misc_info->find(kSuperPartitionGroups);
83   if (super_partition_groups == misc_info->end()) {
84     LOG(ERROR) << "Failed to find super partition groups in misc_info";
85     return false;
86   }
87 
88   // Remove all existing update groups in misc_info
89   auto update_groups =
90       android::base::Split(super_partition_groups->second, " ");
91   for (const auto& group_name : update_groups) {
92     auto partition_list = android::base::StringPrintf("super_%s_partition_list",
93                                                       group_name.c_str());
94     auto partition_size =
95         android::base::StringPrintf("super_%s_group_size", group_name.c_str());
96     for (const auto& key : {partition_list, partition_size}) {
97       auto it = misc_info->find(key);
98       if (it == misc_info->end()) {
99         LOG(ERROR) << "Failed to find " << key << " in misc_info";
100         return false;
101       }
102       misc_info->erase(it);
103     }
104   }
105 
106   // For merged target-file, put all dynamic partitions under the
107   // google_dynamic_partitions update group.
108   // TODO(xunchang) use different update groups for system and vendor images.
109   (*misc_info)[kDynamicPartitions] = android::base::Join(components, " ");
110   (*misc_info)[kSuperPartitionGroups] = kGoogleDynamicPartitions;
111   std::string partitions_list_key = android::base::StringPrintf(
112       "super_%s_partition_list", kGoogleDynamicPartitions);
113   (*misc_info)[partitions_list_key] = android::base::Join(components, " ");
114 
115   // Use the entire super partition as the group size
116   std::string group_size_key = android::base::StringPrintf(
117       "super_%s_group_size", kGoogleDynamicPartitions);
118   auto super_size_it = misc_info->find("super_partition_size");
119   if (super_size_it == misc_info->end()) {
120     LOG(ERROR) << "Failed to find super partition size";
121     return false;
122   }
123   (*misc_info)[group_size_key] = super_size_it->second;
124   return true;
125 }
126 
127 } // namespace cuttlefish
128