Merge "Lose convertToResPath to aapt." into main
diff --git a/fastboot/README.md b/fastboot/README.md
index 63db5c3..55583eb 100644
--- a/fastboot/README.md
+++ b/fastboot/README.md
@@ -165,6 +165,28 @@
using the new bootloader.
+## Flashing Logic
+
+Fastboot binary will follow directions listed out fastboot-info.txt
+build artifact for fastboot flashall && fastboot update comamnds.
+This build artifact will live inside of ANDROID_PRODUCT_OUT &&
+target_files_package && updatepackage.
+
+
+The currently defined commands are:
+
+ flash %s Flash a given partition. Optional arguments include
+ --slot-other, {filename_path}, --apply-vbmeta
+
+ reboot %s Reboot to either bootloader or fastbootd
+
+ update-super Updates the super partition
+
+ if-wipe Conditionally run some other functionality if
+ wipe is specified
+
+ erase %s Erase a given partition (can only be used in conjunction)
+ with if-wipe -> eg. if-wipe erase cache
## Client Variables
diff --git a/fs_mgr/libsnapshot/OWNERS b/fs_mgr/libsnapshot/OWNERS
index 1ee4175..c8b1003 100644
--- a/fs_mgr/libsnapshot/OWNERS
+++ b/fs_mgr/libsnapshot/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 30545
+# Bug component: 1014951
balsini@google.com
dvander@google.com
elsk@google.com
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
index 97974c4..cf65615 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
@@ -17,7 +17,6 @@
#pragma once
#include <memory>
-#include <string_view>
#include "libsnapshot/cow_format.h"
namespace android {
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
index d3c3d59..ee445a2 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
@@ -174,7 +174,7 @@
current_data_pos_ = next_data_pos_;
}
- LOG_INFO << "Batch writes: " << batch_write_ ? "enabled" : "disabled";
+ LOG_INFO << "Batch writes: " << (batch_write_ ? "enabled" : "disabled");
}
void CowWriterV2::InitWorkers() {
diff --git a/fs_mgr/libsnapshot/tools/Android.bp b/fs_mgr/libsnapshot/tools/Android.bp
new file mode 100644
index 0000000..cfa0cef
--- /dev/null
+++ b/fs_mgr/libsnapshot/tools/Android.bp
@@ -0,0 +1,22 @@
+
+cc_binary {
+ name: "cow_benchmark",
+ host_supported: true,
+ defaults: [
+ "fs_mgr_defaults",
+ "libsnapshot_cow_defaults",
+ ],
+
+ srcs: ["cow_benchmark.cpp"],
+
+ static_libs: [
+ "libsnapshot_cow",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+
+ cflags: ["-Werror"],
+}
diff --git a/fs_mgr/libsnapshot/tools/cow_benchmark.cpp b/fs_mgr/libsnapshot/tools/cow_benchmark.cpp
new file mode 100644
index 0000000..da2b879
--- /dev/null
+++ b/fs_mgr/libsnapshot/tools/cow_benchmark.cpp
@@ -0,0 +1,188 @@
+
+#include <memory>
+
+#include <array>
+#include <iostream>
+#include <random>
+
+#include <libsnapshot/cow_compress.h>
+#include <libsnapshot/cow_format.h>
+
+static const uint32_t BLOCK_SZ = 4096;
+static const uint32_t SEED_NUMBER = 10;
+
+namespace android {
+namespace snapshot {
+
+static std::string CompressionToString(CowCompression& compression) {
+ std::string output;
+ switch (compression.algorithm) {
+ case kCowCompressBrotli:
+ output.append("brotli");
+ break;
+ case kCowCompressGz:
+ output.append("gz");
+ break;
+ case kCowCompressLz4:
+ output.append("lz4");
+ break;
+ case kCowCompressZstd:
+ output.append("zstd");
+ break;
+ case kCowCompressNone:
+ return "No Compression";
+ }
+ output.append(" " + std::to_string(compression.compression_level));
+ return output;
+}
+
+void OneShotCompressionTest() {
+ std::cout << "\n-------One Shot Compressor Perf Analysis-------\n";
+
+ std::vector<CowCompression> compression_list = {
+ {kCowCompressLz4, 0}, {kCowCompressBrotli, 1}, {kCowCompressBrotli, 3},
+ {kCowCompressBrotli, 11}, {kCowCompressZstd, 3}, {kCowCompressZstd, 6},
+ {kCowCompressZstd, 9}, {kCowCompressZstd, 22}, {kCowCompressGz, 1},
+ {kCowCompressGz, 3}, {kCowCompressGz, 6}, {kCowCompressGz, 9}};
+ std::vector<std::unique_ptr<ICompressor>> compressors;
+ for (auto i : compression_list) {
+ compressors.emplace_back(ICompressor::Create(i, BLOCK_SZ));
+ }
+
+ // Allocate a buffer of size 8 blocks.
+ std::array<char, 32768> buffer;
+
+ // Generate a random 4k buffer of characters
+ std::default_random_engine gen(SEED_NUMBER);
+ std::uniform_int_distribution<int> distribution(0, 10);
+ for (int i = 0; i < buffer.size(); i++) {
+ buffer[i] = static_cast<char>(distribution(gen));
+ }
+
+ std::vector<std::pair<double, std::string>> latencies;
+ std::vector<std::pair<double, std::string>> ratios;
+
+ for (size_t i = 0; i < compressors.size(); i++) {
+ const auto start = std::chrono::steady_clock::now();
+ std::basic_string<uint8_t> compressed_data =
+ compressors[i]->Compress(buffer.data(), buffer.size());
+ const auto end = std::chrono::steady_clock::now();
+ const auto latency =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(end - start) / 1000.0;
+ const double compression_ratio =
+ static_cast<uint16_t>(compressed_data.size()) * 1.00 / buffer.size();
+
+ std::cout << "Metrics for " << CompressionToString(compression_list[i]) << ": latency -> "
+ << latency.count() << "ms "
+ << " compression ratio ->" << compression_ratio << " \n";
+
+ latencies.emplace_back(
+ std::make_pair(latency.count(), CompressionToString(compression_list[i])));
+ ratios.emplace_back(
+ std::make_pair(compression_ratio, CompressionToString(compression_list[i])));
+ }
+
+ int best_speed = 0;
+ int best_ratio = 0;
+
+ for (size_t i = 1; i < latencies.size(); i++) {
+ if (latencies[i].first < latencies[best_speed].first) {
+ best_speed = i;
+ }
+ if (ratios[i].first < ratios[best_ratio].first) {
+ best_ratio = i;
+ }
+ }
+
+ std::cout << "BEST SPEED: " << latencies[best_speed].first << "ms "
+ << latencies[best_speed].second << "\n";
+ std::cout << "BEST RATIO: " << ratios[best_ratio].first << " " << ratios[best_ratio].second
+ << "\n";
+}
+
+void IncrementalCompressionTest() {
+ std::cout << "\n-------Incremental Compressor Perf Analysis-------\n";
+
+ std::vector<CowCompression> compression_list = {
+ {kCowCompressLz4, 0}, {kCowCompressBrotli, 1}, {kCowCompressBrotli, 3},
+ {kCowCompressBrotli, 11}, {kCowCompressZstd, 3}, {kCowCompressZstd, 6},
+ {kCowCompressZstd, 9}, {kCowCompressZstd, 22}, {kCowCompressGz, 1},
+ {kCowCompressGz, 3}, {kCowCompressGz, 6}, {kCowCompressGz, 9}};
+ std::vector<std::unique_ptr<ICompressor>> compressors;
+ for (auto i : compression_list) {
+ compressors.emplace_back(ICompressor::Create(i, BLOCK_SZ));
+ }
+
+ // Allocate a buffer of size 8 blocks.
+ std::array<char, 32768> buffer;
+
+ // Generate a random 4k buffer of characters
+ std::default_random_engine gen(SEED_NUMBER);
+ std::uniform_int_distribution<int> distribution(0, 10);
+ for (int i = 0; i < buffer.size(); i++) {
+ buffer[i] = static_cast<char>(distribution(gen));
+ }
+
+ std::vector<std::pair<double, std::string>> latencies;
+ std::vector<std::pair<double, std::string>> ratios;
+
+ for (size_t i = 0; i < compressors.size(); i++) {
+ std::vector<std::basic_string<uint8_t>> compressed_data_vec;
+ int num_blocks = buffer.size() / BLOCK_SZ;
+ const uint8_t* iter = reinterpret_cast<const uint8_t*>(buffer.data());
+
+ const auto start = std::chrono::steady_clock::now();
+ while (num_blocks > 0) {
+ std::basic_string<uint8_t> compressed_data = compressors[i]->Compress(iter, BLOCK_SZ);
+ compressed_data_vec.emplace_back(compressed_data);
+ num_blocks--;
+ iter += BLOCK_SZ;
+ }
+
+ const auto end = std::chrono::steady_clock::now();
+ const auto latency =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(end - start) / 1000.0;
+
+ size_t size = 0;
+ for (auto& i : compressed_data_vec) {
+ size += i.size();
+ }
+ const double compression_ratio = size * 1.00 / buffer.size();
+
+ std::cout << "Metrics for " << CompressionToString(compression_list[i]) << ": latency -> "
+ << latency.count() << "ms "
+ << " compression ratio ->" << compression_ratio << " \n";
+
+ latencies.emplace_back(
+ std::make_pair(latency.count(), CompressionToString(compression_list[i])));
+ ratios.emplace_back(
+ std::make_pair(compression_ratio, CompressionToString(compression_list[i])));
+ }
+
+ int best_speed = 0;
+ int best_ratio = 0;
+
+ for (size_t i = 1; i < latencies.size(); i++) {
+ if (latencies[i].first < latencies[best_speed].first) {
+ best_speed = i;
+ }
+ if (ratios[i].first < ratios[best_ratio].first) {
+ best_ratio = i;
+ }
+ }
+
+ std::cout << "BEST SPEED: " << latencies[best_speed].first << "ms "
+ << latencies[best_speed].second << "\n";
+ std::cout << "BEST RATIO: " << ratios[best_ratio].first << " " << ratios[best_ratio].second
+ << "\n";
+}
+
+} // namespace snapshot
+} // namespace android
+
+int main() {
+ android::snapshot::OneShotCompressionTest();
+ android::snapshot::IncrementalCompressionTest();
+
+ return 0;
+}
\ No newline at end of file
diff --git a/init/builtins.cpp b/init/builtins.cpp
index a5b762c..a70e866 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -746,6 +746,7 @@
static Result<void> do_start(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "service " << args[1] << " not found";
+ errno = 0;
if (auto result = svc->Start(); !result.ok()) {
return ErrorIgnoreEnoent() << "Could not start service: " << result.error();
}
@@ -1304,8 +1305,7 @@
}
if (!bootstrap) {
- // Now start delayed services
- ServiceList::GetInstance().MarkServicesUpdate();
+ ServiceList::GetInstance().StartDelayedServices();
}
return {};
}
diff --git a/init/service.cpp b/init/service.cpp
index a0b3478..5e900ee 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -420,7 +420,7 @@
}
});
- if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
+ if (is_updatable() && !IsDefaultMountNamespaceReady()) {
// Don't delay the service for ExecStart() as the semantic is that
// the caller might depend on the side effect of the execution.
return Error() << "Cannot start an updatable service '" << name_
@@ -581,7 +581,7 @@
}
});
- if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
+ if (is_updatable() && !IsDefaultMountNamespaceReady()) {
ServiceList::GetInstance().DelayService(*this);
return Error() << "Cannot start an updatable service '" << name_
<< "' before configs from APEXes are all loaded. "
diff --git a/init/service_list.cpp b/init/service_list.cpp
index 937d82e..1c56e8a 100644
--- a/init/service_list.cpp
+++ b/init/service_list.cpp
@@ -76,10 +76,7 @@
return post_data_;
}
-void ServiceList::MarkServicesUpdate() {
- services_update_finished_ = true;
-
- // start the delayed services
+void ServiceList::StartDelayedServices() {
for (const auto& name : delayed_service_names_) {
Service* service = FindService(name);
if (service == nullptr) {
@@ -94,7 +91,7 @@
}
void ServiceList::DelayService(const Service& service) {
- if (services_update_finished_) {
+ if (IsDefaultMountNamespaceReady()) {
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
<< "' because all services are already updated. Ignoring.";
return;
diff --git a/init/service_list.h b/init/service_list.h
index f858bc3..44e8453 100644
--- a/init/service_list.h
+++ b/init/service_list.h
@@ -85,14 +85,10 @@
void MarkPostData();
bool IsPostData();
- void MarkServicesUpdate();
- bool IsServicesUpdated() const { return services_update_finished_; }
void DelayService(const Service& service);
+ void StartDelayedServices();
- void ResetState() {
- post_data_ = false;
- services_update_finished_ = false;
- }
+ void ResetState() { post_data_ = false; }
auto size() const { return services_.size(); }
@@ -100,7 +96,6 @@
std::vector<std::unique_ptr<Service>> services_;
bool post_data_ = false;
- bool services_update_finished_ = false;
std::vector<std::string> delayed_service_names_;
};
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index 43909f7..a628bb4 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -52,8 +52,6 @@
explicit String8(const char32_t* o, size_t numChars);
~String8();
- static inline const String8 empty();
-
static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
static String8 formatV(const char* fmt, va_list args);
@@ -231,10 +229,6 @@
return compare_type(lhs, rhs) < 0;
}
-inline const String8 String8::empty() {
- return String8();
-}
-
inline const char* String8::c_str() const
{
return mString;
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index e98733a..c8a3cd6 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -17,12 +17,30 @@
}
prebuilt_etc {
+ name: "init.boringssl.zygote64_32.rc",
+ src: "init.boringssl.zygote64_32.rc",
+ sub_dir: "init/hw",
+ symlinks: [
+ "init.boringssl.zygote32.rc",
+ "init.boringssl.no_zygote.rc",
+ ],
+}
+
+prebuilt_etc {
+ name: "init.boringssl.zygote64.rc",
+ src: "init.boringssl.zygote64.rc",
+ sub_dir: "init/hw",
+}
+
+prebuilt_etc {
name: "init.rc",
src: "init.rc",
sub_dir: "init/hw",
required: [
"fsverity_init",
"platform-bootclasspath",
+ "init.boringssl.zygote64.rc",
+ "init.boringssl.zygote64_32.rc",
],
}
diff --git a/rootdir/init.boringssl.zygote64.rc b/rootdir/init.boringssl.zygote64.rc
new file mode 100644
index 0000000..3f49fea
--- /dev/null
+++ b/rootdir/init.boringssl.zygote64.rc
@@ -0,0 +1,4 @@
+on init && property:ro.product.cpu.abilist64=*
+ exec_start boringssl_self_test64
+on property:apexd.status=ready && property:ro.product.cpu.abilist64=*
+ exec_start boringssl_self_test_apex64
diff --git a/rootdir/init.boringssl.zygote64_32.rc b/rootdir/init.boringssl.zygote64_32.rc
new file mode 100644
index 0000000..c0be42d
--- /dev/null
+++ b/rootdir/init.boringssl.zygote64_32.rc
@@ -0,0 +1,8 @@
+on init && property:ro.product.cpu.abilist32=*
+ exec_start boringssl_self_test32
+on init && property:ro.product.cpu.abilist64=*
+ exec_start boringssl_self_test64
+on property:apexd.status=ready && property:ro.product.cpu.abilist32=*
+ exec_start boringssl_self_test_apex32
+on property:apexd.status=ready && property:ro.product.cpu.abilist64=*
+ exec_start boringssl_self_test_apex64
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 0d31cdc..487e5da 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -459,14 +459,7 @@
start vndservicemanager
# Run boringssl self test for each ABI. Any failures trigger reboot to firmware.
-on init && property:ro.product.cpu.abilist32=*
- exec_start boringssl_self_test32
-on init && property:ro.product.cpu.abilist64=*
- exec_start boringssl_self_test64
-on property:apexd.status=ready && property:ro.product.cpu.abilist32=*
- exec_start boringssl_self_test_apex32
-on property:apexd.status=ready && property:ro.product.cpu.abilist64=*
- exec_start boringssl_self_test_apex64
+import /system/etc/init/hw/init.boringssl.${ro.zygote}.rc
service boringssl_self_test32 /system/bin/boringssl_self_test32
reboot_on_failure reboot,boringssl-self-check-failed