Snap for 7483611 from 6b12726ac223fef46b919714b9d35e4854322fa4 to mainline-adbd-release
Change-Id: I8deee347b9ebce237709baf148d64e985c3a9d96
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 00dd274..9c9aeea 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1805,14 +1805,14 @@
}
bool ShouldCompileDexFilesIndividually() const {
- // Compile individually if we are specifically asked to, or
+ // Compile individually if we are allowed to, and
// 1. not building an image, and
// 2. not verifying a vdex file, and
// 3. using multidex, and
// 4. not doing any AOT compilation.
// This means extract, no-vdex verify, and quicken, will use the individual compilation
// mode (to reduce RAM used by the compiler).
- return compile_individually_ ||
+ return compile_individually_ &&
(!IsImage() && !update_input_vdex_ &&
compiler_options_->dex_files_for_oat_file_.size() > 1 &&
!CompilerFilter::IsAotCompilationEnabled(compiler_options_->GetCompilerFilter()));
diff --git a/libartbase/base/flags.cc b/libartbase/base/flags.cc
index 4b7e780..aaa7661 100644
--- a/libartbase/base/flags.cc
+++ b/libartbase/base/flags.cc
@@ -84,10 +84,11 @@
}
template <typename Value>
-Flag<Value>::Flag(const std::string& name, Value default_value) :
+Flag<Value>::Flag(const std::string& name, Value default_value, FlagType type) :
FlagBase(GenerateCmdLineArgName(name),
GenerateSysPropName(name),
- GeneratePhenotypeName(name)),
+ GeneratePhenotypeName(name),
+ type),
initialized_{false},
default_{default_value} {
ALL_FLAGS.push_front(this);
@@ -100,7 +101,12 @@
template <typename Value>
void Flag<Value>::Reload() {
- // The cmdline flags are loaded by the parsed_options infra.
+ initialized_ = true;
+
+ // The cmdline flags are loaded by the parsed_options infra. No action needed here.
+ if (type_ == FlagType::kCmdlineOnly) {
+ return;
+ }
// Load system properties.
from_system_property_ = std::nullopt;
@@ -116,8 +122,6 @@
if (server_config != kUndefinedValue) {
ParseValue(server_config, &from_server_setting_);
}
-
- initialized_ = true;
}
template <typename Value>
@@ -131,8 +135,16 @@
template <typename Value>
void Flag<Value>::Dump(std::ostream& oss) const {
- std::pair<Value, std::string> valueLoc = GetValueLocation();
- oss << "value: " << std::get<0>(valueLoc) << " (from " << std::get<1>(valueLoc) << ")";
+ std::pair<Value, FlagOrigin> valueOrigin = GetValueAndOrigin();
+ std::string origin;
+ switch (std::get<1>(valueOrigin)) {
+ case FlagOrigin::kDefaultValue: origin = "default_value"; break;
+ case FlagOrigin::kCmdlineArg: origin = "cmdline_arg"; break;
+ case FlagOrigin::kSystemProperty: origin = "system_property"; break;
+ case FlagOrigin::kServerSetting: origin = "server_setting"; break;
+ }
+
+ oss << "value: " << std::get<0>(valueOrigin) << " (from " << origin << ")";
oss << "\n default: " << default_;
oss << "\n " << command_line_argument_name_ << ": ";
diff --git a/libartbase/base/flags.h b/libartbase/base/flags.h
index 973a5da0..e71bb4a 100644
--- a/libartbase/base/flags.h
+++ b/libartbase/base/flags.h
@@ -43,6 +43,15 @@
namespace art {
+// Enum representing the type of the ART flag.
+enum class FlagType {
+ // A flag that only looks at the cmdline argument to retrieve its value.
+ kCmdlineOnly,
+ // A flag that also looks at system properties and device config
+ // (phenotype properties) when retrieving its value.
+ kDeviceConfig,
+};
+
// FlagMetaBase handles automatically adding flags to the command line parser. It is parameterized
// by all supported flag types. In general, this should be treated as though it does not exist and
// FlagBase, which is already specialized to the types we support, should be used instead.
@@ -51,10 +60,12 @@
public:
FlagMetaBase(const std::string&& command_line_argument_name,
const std::string&& system_property_name,
- const std::string&& server_setting_name) :
+ const std::string&& server_setting_name,
+ FlagType type) :
command_line_argument_name_(command_line_argument_name),
system_property_name_(system_property_name),
- server_setting_name_(server_setting_name) {}
+ server_setting_name_(server_setting_name),
+ type_(type) {}
virtual ~FlagMetaBase() {}
template <typename Builder>
@@ -124,6 +135,7 @@
const std::string command_line_argument_name_;
const std::string system_property_name_;
const std::string server_setting_name_;
+ FlagType type_;
};
using FlagBase = FlagMetaBase<bool, int, std::string>;
@@ -133,13 +145,21 @@
class FlagsTests;
+// Describes the possible origins of a flag value.
+enum class FlagOrigin {
+ kDefaultValue,
+ kCmdlineArg,
+ kSystemProperty,
+ kServerSetting,
+};
+
// This class defines a flag with a value of a particular type.
template <typename Value>
class Flag : public FlagBase {
public:
// Create a new Flag. The name parameter is used to generate the names from the various parameter
// sources. See the documentation on the Flags struct for an example.
- explicit Flag(const std::string& name, Value default_value = {});
+ Flag(const std::string& name, Value default_value, FlagType type);
virtual ~Flag();
@@ -151,26 +171,41 @@
// 3) cmdline flag
// 4) default value
ALWAYS_INLINE Value GetValue() const {
- return std::get<0>(GetValueLocation());
+ return std::get<0>(GetValueAndOrigin());
}
ALWAYS_INLINE Value operator()() const {
return GetValue();
}
- // Returns the value and the location of that value for the given flag.
- ALWAYS_INLINE std::pair<Value, std::string> GetValueLocation() const {
+ // Return the value of the flag as optional.
+ //
+ // Returns the value of the flag if and only if the flag is set via
+ // a server side setting, system property or a cmdline arg.
+ // Otherwise it returns nullopt (meaning this never returns the default value).
+ //
+ // This is useful for properties that do not have a good default natural value
+ // (e.g. file path arguments).
+ ALWAYS_INLINE std::optional<Value> GetValueOptional() const {
+ std::pair<Value, FlagOrigin> result = GetValueAndOrigin();
+ return std::get<1>(result) == FlagOrigin::kDefaultValue
+ ? std::nullopt
+ : std::make_optional(std::get<0>(result));
+ }
+
+ // Returns the value and the origin of that value for the given flag.
+ ALWAYS_INLINE std::pair<Value, FlagOrigin> GetValueAndOrigin() const {
DCHECK(initialized_);
if (from_server_setting_.has_value()) {
- return std::pair{from_server_setting_.value(), server_setting_name_};
+ return std::pair{from_server_setting_.value(), FlagOrigin::kServerSetting};
}
if (from_system_property_.has_value()) {
- return std::pair{from_system_property_.value(), system_property_name_};
+ return std::pair{from_system_property_.value(), FlagOrigin::kSystemProperty};
}
if (from_command_line_.has_value()) {
- return std::pair{from_command_line_.value(), command_line_argument_name_};
+ return std::pair{from_command_line_.value(), FlagOrigin::kCmdlineArg};
}
- return std::pair{default_, "default_value"};
+ return std::pair{default_, FlagOrigin::kDefaultValue};
}
void Dump(std::ostream& oss) const override;
@@ -199,7 +234,7 @@
//
// Example:
//
-// Flag<int> WriteMetricsToLog{"my-feature-test.flag", 42};
+// Flag<int> WriteMetricsToLog{"my-feature-test.flag", 42, FlagType::kDeviceConfig};
//
// This creates a boolean flag that can be read through gFlags.WriteMetricsToLog(). The default
// value is false. Note that the default value can be left unspecified, in which the value of the
@@ -221,7 +256,13 @@
struct Flags {
// Flag used to test the infra.
// TODO: can be removed once we add real flags.
- Flag<int> MyFeatureTestFlag{"my-feature-test.flag", /*default_value=*/ 42};
+ Flag<int> MyFeatureTestFlag{"my-feature-test.flag", 42, FlagType::kDeviceConfig};
+
+ // Metric infra flags.
+ Flag<bool> WriteMetricsToStatsd{ "metrics.write-to-statsd", false, FlagType::kDeviceConfig};
+ Flag<bool> WriteMetricsToLogcat{ "metrics.write-to-logcat", false, FlagType::kCmdlineOnly};
+ Flag<int> MetricsReportingPeriod{"metrics.reporting-period", 0, FlagType::kCmdlineOnly};
+ Flag<std::string> WriteMetricsToFile{"metrics.write-to-file", "", FlagType::kCmdlineOnly};
};
// This is the actual instance of all the flags.
diff --git a/libartbase/base/flags_test.cc b/libartbase/base/flags_test.cc
index 72f0431..b41df46 100644
--- a/libartbase/base/flags_test.cc
+++ b/libartbase/base/flags_test.cc
@@ -30,7 +30,7 @@
class TestFlag {
public:
// Takes control of the tmp_file pointer.
- explicit TestFlag(ScratchFile* tmp_file) {
+ TestFlag(ScratchFile* tmp_file, FlagType flag_type) {
tmp_file_.reset(tmp_file);
std::string tmp_name = tmp_file_->GetFilename();
@@ -43,7 +43,7 @@
cmd_line_name_ = flag_name_;
std::replace(cmd_line_name_.begin(), cmd_line_name_.end(), '.', '-');
- flag_.reset(new Flag<int>(flag_name_, /*default_value=*/ 42));
+ flag_.reset(new Flag<int>(flag_name_, /*default_value=*/ 42, flag_type));
}
void AssertCmdlineValue(bool has_value, int expected) {
@@ -104,7 +104,7 @@
//
// So we do it in SetUpRuntimeOptions.
virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
- test_flag_.reset(new TestFlag(new ScratchFile()));
+ test_flag_.reset(new TestFlag(new ScratchFile(), FlagType::kDeviceConfig));
CommonRuntimeTest::SetUpRuntimeOptions(options);
}
@@ -116,7 +116,11 @@
std::unique_ptr<TestFlag> test_flag_;
};
-class FlagsTestsWithCmdLine : public FlagsTests {
+class FlagsTestsWithCmdLineBase : public FlagsTests {
+ public:
+ explicit FlagsTestsWithCmdLineBase(FlagType type) : flag_type_(type) {
+ }
+
protected:
virtual void TearDown() {
android::base::SetProperty(test_flag_->SystemProperty(), "");
@@ -125,10 +129,24 @@
}
virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
- test_flag_.reset(new TestFlag(new ScratchFile()));
+ test_flag_.reset(new TestFlag(new ScratchFile(), flag_type_));
std::string option = "-X" + test_flag_->CmdLineName() + ":1";
options->emplace_back(option.c_str(), nullptr);
}
+
+ FlagType flag_type_;
+};
+
+class FlagsTestsWithCmdLine : public FlagsTestsWithCmdLineBase {
+ public:
+ FlagsTestsWithCmdLine() : FlagsTestsWithCmdLineBase(FlagType::kDeviceConfig) {
+ }
+};
+
+class FlagsTestsCmdLineOnly : public FlagsTestsWithCmdLineBase {
+ public:
+ FlagsTestsCmdLineOnly() : FlagsTestsWithCmdLineBase(FlagType::kCmdlineOnly) {
+ }
};
// Validate that when no flag is set, the default is taken and none of the other
@@ -202,4 +220,28 @@
ASSERT_EQ(test_flag_->Value(), 1);
}
+// Validate that cmdline only flags don't read system properties.
+TEST_F(FlagsTestsCmdLineOnly, CmdlineOnlyFlags) {
+ if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
+ LOG(ERROR) << "Release does not support property setting, skipping test: "
+ << test_flag_->SystemProperty();
+ return;
+ }
+
+ if (android::base::SetProperty(test_flag_->ServerSetting(), "3")) {
+ LOG(ERROR) << "Release does not support property setting, skipping test: "
+ << test_flag_->ServerSetting();
+ return;
+ }
+
+ FlagBase::ReloadAllFlags("test");
+
+ test_flag_->AssertCmdlineValue(true, 1);
+ test_flag_->AssertSysPropValue(false, 2);
+ test_flag_->AssertServerSettingValue(false, 3);
+ test_flag_->AssertDefaultValue(42);
+
+ ASSERT_EQ(test_flag_->Value(), 1);
+}
+
} // namespace art
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index 2360819..8b87338 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -344,15 +344,17 @@
}
}
- auto apex_ns_name = FindApexNamespaceName(dex_path);
- if (apex_ns_name.ok()) {
- const auto& jni_libs = apex_jni_libraries(*apex_ns_name);
- if (jni_libs != "") {
- auto apex_ns = NativeLoaderNamespace::GetExportedNamespace(*apex_ns_name, is_bridged);
- if (apex_ns.ok()) {
- linked = app_ns->Link(&apex_ns.value(), jni_libs);
- if (!linked.ok()) {
- return linked.error();
+ for (const std::string& each_jar_path : android::base::Split(dex_path, ":")) {
+ auto apex_ns_name = FindApexNamespaceName(each_jar_path);
+ if (apex_ns_name.ok()) {
+ const auto& jni_libs = apex_jni_libraries(*apex_ns_name);
+ if (jni_libs != "") {
+ auto apex_ns = NativeLoaderNamespace::GetExportedNamespace(*apex_ns_name, is_bridged);
+ if (apex_ns.ok()) {
+ linked = app_ns->Link(&apex_ns.value(), jni_libs);
+ if (!linked.ok()) {
+ return linked.error();
+ }
}
}
}
diff --git a/libnativeloader/native_loader_test.cpp b/libnativeloader/native_loader_test.cpp
index 79e5070..c1dd4aa 100644
--- a/libnativeloader/native_loader_test.cpp
+++ b/libnativeloader/native_loader_test.cpp
@@ -188,6 +188,7 @@
bool expected_link_with_platform_ns = true;
bool expected_link_with_art_ns = true;
bool expected_link_with_i18n_ns = true;
+ bool expected_link_with_conscrypt_ns = false;
bool expected_link_with_sphal_ns = !vendor_public_libraries().empty();
bool expected_link_with_vndk_ns = false;
bool expected_link_with_vndk_product_ns = false;
@@ -196,6 +197,7 @@
std::string expected_shared_libs_to_platform_ns = default_public_libraries();
std::string expected_shared_libs_to_art_ns = apex_public_libraries().at("com_android_art");
std::string expected_shared_libs_to_i18n_ns = apex_public_libraries().at("com_android_i18n");
+ std::string expected_shared_libs_to_conscrypt_ns = apex_jni_libraries("com_android_conscrypt");
std::string expected_shared_libs_to_sphal_ns = vendor_public_libraries();
std::string expected_shared_libs_to_vndk_ns = vndksp_libraries_vendor();
std::string expected_shared_libs_to_vndk_product_ns = vndksp_libraries_product();
@@ -255,6 +257,11 @@
StrEq(expected_shared_libs_to_neuralnetworks_ns)))
.WillOnce(Return(true));
}
+ if (expected_link_with_conscrypt_ns) {
+ EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("com_android_conscrypt"),
+ StrEq(expected_shared_libs_to_conscrypt_ns)))
+ .WillOnce(Return(true));
+ }
}
void RunTest() {
@@ -336,6 +343,17 @@
RunTest();
}
+TEST_P(NativeLoaderTest_Create, SystemServerWithApexJars) {
+ dex_path = "/system/framework/services.jar:/apex/com.android.conscrypt/javalib/service-foo.jar";
+ is_shared = true;
+
+ expected_namespace_name = "classloader-namespace-shared";
+ expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
+ expected_link_with_conscrypt_ns = true;
+ SetExpectations();
+ RunTest();
+}
+
TEST_P(NativeLoaderTest_Create, UnbundledProductApp) {
dex_path = "/product/app/foo/foo.apk";
is_shared = false;
diff --git a/libnativeloader/native_loader_test.h b/libnativeloader/native_loader_test.h
index cab18da..09c56e5 100644
--- a/libnativeloader/native_loader_test.h
+++ b/libnativeloader/native_loader_test.h
@@ -80,6 +80,11 @@
NAMESPACE_ENTRY("com_android_i18n"),
NAMESPACE_ENTRY("com_android_neuralnetworks"),
NAMESPACE_ENTRY("com_android_art"),
+
+ // TODO(b/191644631) This can be removed when the test becomes more test-friendly.
+ // This is added so that the test can exercise the JNI lib related behavior.
+ NAMESPACE_ENTRY("com_android_conscrypt"),
+
NAMESPACE_ENTRY("default"),
NAMESPACE_ENTRY("sphal"),
NAMESPACE_ENTRY("system"),
diff --git a/runtime/metrics/reporter.cc b/runtime/metrics/reporter.cc
index 4cf1ba5..26b55b8 100644
--- a/runtime/metrics/reporter.cc
+++ b/runtime/metrics/reporter.cc
@@ -16,6 +16,7 @@
#include "reporter.h"
+#include "base/flags.h"
#include "runtime.h"
#include "runtime_options.h"
#include "statsd.h"
@@ -121,10 +122,7 @@
LOG_STREAM(DEBUG) << "Shutdown request received";
running = false;
- // Do one final metrics report, if enabled.
- if (config_.report_metrics_on_shutdown) {
- ReportMetrics();
- }
+ ReportMetrics();
},
[&](RequestMetricsReportMessage message) {
LOG_STREAM(DEBUG) << "Explicit report request received";
@@ -178,14 +176,12 @@
}
}
-ReportingConfig ReportingConfig::FromRuntimeArguments(const RuntimeArgumentMap& args) {
- using M = RuntimeArgumentMap;
+ReportingConfig ReportingConfig::FromFlags() {
return {
- .dump_to_logcat = args.Exists(M::WriteMetricsToLog),
- .dump_to_statsd = args.GetOrDefault(M::WriteMetricsToStatsd),
- .dump_to_file = args.GetOptional(M::WriteMetricsToFile),
- .report_metrics_on_shutdown = !args.Exists(M::DisableFinalMetricsReport),
- .periodic_report_seconds = args.GetOptional(M::MetricsReportingPeriod),
+ .dump_to_logcat = gFlags.WriteMetricsToLogcat(),
+ .dump_to_file = gFlags.WriteMetricsToFile.GetValueOptional(),
+ .dump_to_statsd = gFlags.WriteMetricsToStatsd(),
+ .periodic_report_seconds = gFlags.MetricsReportingPeriod.GetValueOptional(),
};
}
diff --git a/runtime/metrics/reporter.h b/runtime/metrics/reporter.h
index 3ad55b0..3e8056b 100644
--- a/runtime/metrics/reporter.h
+++ b/runtime/metrics/reporter.h
@@ -28,7 +28,7 @@
// Defines the set of options for how metrics reporting happens.
struct ReportingConfig {
- static ReportingConfig FromRuntimeArguments(const RuntimeArgumentMap& args);
+ static ReportingConfig FromFlags();
// Causes metrics to be written to the log, which makes them show up in logcat.
bool dump_to_logcat{false};
@@ -39,11 +39,6 @@
// If set, provides a file name to enable metrics logging to a file.
std::optional<std::string> dump_to_file;
- // Indicates whether to report the final state of metrics on shutdown.
- //
- // Note that reporting only happens if some output, such as logcat, is enabled.
- bool report_metrics_on_shutdown{true};
-
// If set, metrics will be reported every time this many seconds elapses.
std::optional<unsigned int> periodic_report_seconds;
};
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 7699b25..c85c951 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -412,25 +412,6 @@
.IntoKey(M::CorePlatformApiPolicy)
.Define("-Xuse-stderr-logger")
.IntoKey(M::UseStderrLogger)
- .Define("-Xwrite-metrics-to-log")
- .WithHelp("Enables writing ART metrics to logcat")
- .IntoKey(M::WriteMetricsToLog)
- .Define("-Xwrite-metrics-to-statsd=_")
- .WithType<bool>()
- .WithValueMap({{"false", false}, {"true", true}})
- .WithHelp("Enables writing ART metrics to statsd")
- .IntoKey(M::WriteMetricsToStatsd)
- .Define("-Xwrite-metrics-to-file=_")
- .WithHelp("Enables writing ART metrics to the given file")
- .WithType<std::string>()
- .IntoKey(M::WriteMetricsToFile)
- .Define("-Xdisable-final-metrics-report")
- .WithHelp("Disables reporting metrics when ART shuts down")
- .IntoKey(M::DisableFinalMetricsReport)
- .Define("-Xmetrics-reporting-period=_")
- .WithHelp("The time in seconds between metrics reports")
- .WithType<unsigned int>()
- .IntoKey(M::MetricsReportingPeriod)
.Define("-Xonly-use-system-oat-files")
.IntoKey(M::OnlyUseTrustedOatFiles)
.Define("-Xverifier-logging-threshold=_")
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 74a563e..ff504e3 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1838,7 +1838,7 @@
// Class-roots are setup, we can now finish initializing the JniIdManager.
GetJniIdManager()->Init(self);
- InitMetrics(runtime_options);
+ InitMetrics();
// Runtime initialization is largely done now.
// We load plugins first since that can modify the runtime state slightly.
@@ -1938,8 +1938,8 @@
return true;
}
-void Runtime::InitMetrics(const RuntimeArgumentMap& runtime_options) {
- auto metrics_config = metrics::ReportingConfig::FromRuntimeArguments(runtime_options);
+void Runtime::InitMetrics() {
+ auto metrics_config = metrics::ReportingConfig::FromFlags();
metrics_reporter_ = metrics::MetricsReporter::Create(metrics_config, this);
}
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 9026e3d..5bea321 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -1028,7 +1028,7 @@
SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
void InitNativeMethods() REQUIRES(!Locks::mutator_lock_);
void RegisterRuntimeNativeMethods(JNIEnv* env);
- void InitMetrics(const RuntimeArgumentMap& runtime_options);
+ void InitMetrics();
void StartDaemonThreads();
void StartSignalCatcher();
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index d1b37e5..b73f5c1 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -191,11 +191,4 @@
// This is to enable/disable Perfetto Java Heap Stack Profiling
RUNTIME_OPTIONS_KEY (bool, PerfettoJavaHeapStackProf, false)
-// Metrics configuration settings
-RUNTIME_OPTIONS_KEY (Unit, WriteMetricsToLog)
-RUNTIME_OPTIONS_KEY (bool, WriteMetricsToStatsd, true)
-RUNTIME_OPTIONS_KEY (std::string, WriteMetricsToFile)
-RUNTIME_OPTIONS_KEY (Unit, DisableFinalMetricsReport)
-RUNTIME_OPTIONS_KEY (unsigned int, MetricsReportingPeriod)
-
#undef RUNTIME_OPTIONS_KEY
diff --git a/test/2232-write-metrics-to-log/run b/test/2232-write-metrics-to-log/run
index b170317..07c1e60 100755
--- a/test/2232-write-metrics-to-log/run
+++ b/test/2232-write-metrics-to-log/run
@@ -15,4 +15,4 @@
# limitations under the License.
export ANDROID_LOG_TAGS="*:i"
-exec ${RUN} $@ --external-log-tags --runtime-option -Xwrite-metrics-to-log
+exec ${RUN} $@ --external-log-tags --runtime-option -Xmetrics-write-to-logcat:true