Merge commit '7a65c6bc48c96fa640cbf13d45a692d0a64200e3' into HEAD
Change-Id: If41aa1299ee779171c376f3f4619538d7f380384
diff --git a/.clang-format b/.clang-format
new file mode 120000
index 0000000..f412743
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1 @@
+../../build/tools/brillo-clang-format
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..01d8747
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,299 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Default values for the USE flags. Override these USE flags from your product
+// by setting BRILLO_USE_* values. Note that we define local variables like
+// local_use_* to prevent leaking our default setting for other packages.
+
+libbrillo_core_sources = [
+ "brillo/backoff_entry.cc",
+ "brillo/data_encoding.cc",
+ "brillo/errors/error.cc",
+ "brillo/errors/error_codes.cc",
+ "brillo/flag_helper.cc",
+ "brillo/key_value_store.cc",
+ "brillo/message_loops/base_message_loop.cc",
+ "brillo/message_loops/message_loop.cc",
+ "brillo/message_loops/message_loop_utils.cc",
+ "brillo/mime_utils.cc",
+ "brillo/osrelease_reader.cc",
+ "brillo/process.cc",
+ "brillo/process_information.cc",
+ "brillo/secure_blob.cc",
+ "brillo/strings/string_utils.cc",
+ "brillo/syslog_logging.cc",
+ "brillo/type_name_undecorate.cc",
+ "brillo/url_utils.cc",
+ "brillo/userdb_utils.cc",
+ "brillo/value_conversion.cc",
+]
+
+libbrillo_linux_sources = [
+ "brillo/asynchronous_signal_handler.cc",
+ "brillo/daemons/daemon.cc",
+ "brillo/file_utils.cc",
+ "brillo/process_reaper.cc",
+]
+
+libbrillo_binder_sources = ["brillo/binder_watcher.cc"]
+
+libbrillo_http_sources = [
+ "brillo/http/curl_api.cc",
+ "brillo/http/http_connection_curl.cc",
+ "brillo/http/http_form_data.cc",
+ "brillo/http/http_request.cc",
+ "brillo/http/http_transport.cc",
+ "brillo/http/http_transport_curl.cc",
+ "brillo/http/http_utils.cc",
+]
+
+libbrillo_policy_sources = [
+ "policy/device_policy.cc",
+ "policy/libpolicy.cc",
+]
+
+libbrillo_stream_sources = [
+ "brillo/streams/file_stream.cc",
+ "brillo/streams/input_stream_set.cc",
+ "brillo/streams/memory_containers.cc",
+ "brillo/streams/memory_stream.cc",
+ "brillo/streams/openssl_stream_bio.cc",
+ "brillo/streams/stream.cc",
+ "brillo/streams/stream_errors.cc",
+ "brillo/streams/stream_utils.cc",
+ "brillo/streams/tls_stream.cc",
+]
+
+libbrillo_test_helpers_sources = [
+ "brillo/http/http_connection_fake.cc",
+ "brillo/http/http_transport_fake.cc",
+ "brillo/message_loops/fake_message_loop.cc",
+ "brillo/streams/fake_stream.cc",
+ "brillo/unittest_utils.cc",
+]
+
+libbrillo_test_sources = [
+ "brillo/asynchronous_signal_handler_test.cc",
+ "brillo/backoff_entry_test.cc",
+ "brillo/data_encoding_test.cc",
+ "brillo/enum_flags_test.cc",
+ "brillo/errors/error_codes_test.cc",
+ "brillo/errors/error_test.cc",
+ "brillo/file_utils_test.cc",
+ "brillo/flag_helper_test.cc",
+ "brillo/http/http_connection_curl_test.cc",
+ "brillo/http/http_form_data_test.cc",
+ "brillo/http/http_request_test.cc",
+ "brillo/http/http_transport_curl_test.cc",
+ "brillo/http/http_utils_test.cc",
+ "brillo/key_value_store_test.cc",
+ "brillo/map_utils_test.cc",
+ "brillo/message_loops/base_message_loop_test.cc",
+ "brillo/message_loops/fake_message_loop_test.cc",
+ "brillo/mime_utils_test.cc",
+ "brillo/osrelease_reader_test.cc",
+ "brillo/process_reaper_test.cc",
+ "brillo/process_test.cc",
+ "brillo/secure_blob_test.cc",
+ "brillo/streams/fake_stream_test.cc",
+ "brillo/streams/file_stream_test.cc",
+ "brillo/streams/input_stream_set_test.cc",
+ "brillo/streams/memory_containers_test.cc",
+ "brillo/streams/memory_stream_test.cc",
+ "brillo/streams/openssl_stream_bio_test.cc",
+ "brillo/streams/stream_test.cc",
+ "brillo/streams/stream_utils_test.cc",
+ "brillo/strings/string_utils_test.cc",
+ "brillo/unittest_utils.cc",
+ "brillo/url_utils_test.cc",
+ "brillo/value_conversion_test.cc",
+]
+
+libbrillo_CFLAGS = [
+ "-Wall",
+ "-Werror",
+ "-Wno-non-virtual-dtor",
+ "-Wno-unused-parameter",
+ "-Wno-unused-variable",
+]
+
+libbrillo_shared_libraries = ["libchrome"]
+
+// Main library, shared and static for host and target
+// ========================================================
+cc_library {
+ name: "libbrillo",
+ host_supported: true,
+ recovery_available: true,
+ srcs: libbrillo_core_sources,
+ shared_libs: libbrillo_shared_libraries,
+ static_libs: [
+ "libmodpb64",
+ "libgtest_prod",
+ ],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+
+ target: {
+ host: {
+ cppflags: ["-D__ANDROID_HOST__"],
+ },
+ android: {
+ srcs: libbrillo_linux_sources,
+ },
+ darwin: {
+ enabled: false
+ }
+ },
+}
+
+// Shared binder library for target
+// ========================================================
+cc_library_shared {
+ name: "libbrillo-binder",
+ srcs: libbrillo_binder_sources,
+ shared_libs: libbrillo_shared_libraries + [
+ "libbinder",
+ "libbrillo",
+ "libutils",
+ ],
+ static_libs: ["libgtest_prod"],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+}
+
+// Shared minijail library for target
+// ========================================================
+cc_library_shared {
+ name: "libbrillo-minijail",
+ srcs: [
+ "brillo/minijail/minijail.cc",
+ ],
+ shared_libs: [
+ "libchrome",
+ "libbrillo",
+ "libminijail",
+ ],
+ static_libs: ["libgtest_prod"],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+}
+
+// Shared and static stream library for target and host
+// ========================================================
+cc_library {
+ name: "libbrillo-stream",
+ srcs: libbrillo_stream_sources,
+ shared_libs: libbrillo_shared_libraries + [
+ "libbrillo",
+ "libcrypto",
+ "libssl",
+ ],
+ static_libs: ["libgtest_prod"],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+
+ host_supported: true,
+ recovery_available: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ windows: {
+ enabled: false,
+ },
+ },
+}
+
+// Shared http library for target and host
+// ========================================================
+cc_library_shared {
+ name: "libbrillo-http",
+ srcs: libbrillo_http_sources,
+ shared_libs: libbrillo_shared_libraries + [
+ "libbrillo",
+ "libbrillo-stream",
+ "libcurl",
+ ],
+ static_libs: ["libgtest_prod"],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ windows: {
+ enabled: false,
+ },
+ },
+}
+
+// Shared policy library for target
+// ========================================================
+cc_library_shared {
+ name: "libbrillo-policy",
+ srcs: libbrillo_policy_sources,
+ shared_libs: libbrillo_shared_libraries,
+ static_libs: ["libgtest_prod"],
+ cflags: libbrillo_CFLAGS,
+ export_include_dirs: ["."],
+}
+
+
+// Static test-helpers library for target
+// ========================================================
+cc_library_static {
+ name: "libbrillo-test-helpers",
+ srcs: libbrillo_test_helpers_sources,
+ static_libs: [
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: libbrillo_shared_libraries + [
+ "libbrillo",
+ "libcurl",
+ "libbrillo-http",
+ "libbrillo-stream",
+ "libcrypto",
+ ],
+ cflags: libbrillo_CFLAGS,
+ cppflags: ["-Wno-sign-compare"],
+ export_include_dirs: ["."],
+}
+
+// Unit tests.
+// ========================================================
+cc_test {
+ name: "libbrillo_test",
+ srcs: libbrillo_test_sources,
+ isolated: true,
+ static_libs: [
+ "libgtest",
+ "libchrome_test_helpers",
+ "libbrillo-test-helpers",
+ "libgmock",
+ ],
+ shared_libs: libbrillo_shared_libraries + [
+ "libbrillo",
+ "libcurl",
+ "libbrillo-http",
+ "libbrillo-stream",
+ "libcrypto",
+ "libprotobuf-cpp-lite",
+ ],
+ cflags: libbrillo_CFLAGS,
+ cppflags: ["-Wno-sign-compare"],
+}
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..b9e779f
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/OWNERS b/OWNERS
index 37fa4e3..bd5625e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,9 @@
set noparent
-vapier@chromium.org
-ejcaruso@chromium.org
-hidehiko@chromium.org
+
+# Android owners
+senj@google.com
+
+# Chromium owners
+vapier@google.com
+ejcaruso@google.com
+hidehiko@google.com
diff --git a/brillo/any_internal_impl.h b/brillo/any_internal_impl.h
index cf236d0..f4114e6 100644
--- a/brillo/any_internal_impl.h
+++ b/brillo/any_internal_impl.h
@@ -69,7 +69,8 @@
// IntWrapper when both overloads are provided.
// Also this constructor must NOT be explicit.
// NOLINTNEXTLINE(runtime/explicit)
- IntWrapper(int /* dummy */) {} // do nothing
+ // NOLINT: Allow implicit conversion from int.
+ IntWrapper(int /* dummy */) {} // do nothing, NOLINT
};
// Here is an obscure trick to determine if a type U has operator==().
diff --git a/brillo/backoff_entry_unittest.cc b/brillo/backoff_entry_unittest.cc
new file mode 100644
index 0000000..dcfa0b2
--- /dev/null
+++ b/brillo/backoff_entry_unittest.cc
@@ -0,0 +1,311 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <brillo/backoff_entry.h>
+#include <gtest/gtest.h>
+
+using base::TimeDelta;
+using base::TimeTicks;
+
+namespace brillo {
+
+BackoffEntry::Policy base_policy = { 0, 1000, 2.0, 0.0, 20000, 2000, false };
+
+class TestBackoffEntry : public BackoffEntry {
+ public:
+ explicit TestBackoffEntry(const Policy* const policy)
+ : BackoffEntry(policy),
+ now_(TimeTicks()) {
+ // Work around initialization in constructor not picking up
+ // fake time.
+ SetCustomReleaseTime(TimeTicks());
+ }
+
+ ~TestBackoffEntry() override {}
+
+ TimeTicks ImplGetTimeNow() const override { return now_; }
+
+ void set_now(const TimeTicks& now) {
+ now_ = now;
+ }
+
+ private:
+ TimeTicks now_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestBackoffEntry);
+};
+
+TEST(BackoffEntryTest, BaseTest) {
+ TestBackoffEntry entry(&base_policy);
+ EXPECT_FALSE(entry.ShouldRejectRequest());
+ EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease());
+
+ entry.InformOfRequest(false);
+ EXPECT_TRUE(entry.ShouldRejectRequest());
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+}
+
+TEST(BackoffEntryTest, CanDiscardNeverExpires) {
+ BackoffEntry::Policy never_expires_policy = base_policy;
+ never_expires_policy.entry_lifetime_ms = -1;
+ TestBackoffEntry never_expires(&never_expires_policy);
+ EXPECT_FALSE(never_expires.CanDiscard());
+ never_expires.set_now(TimeTicks() + TimeDelta::FromDays(100));
+ EXPECT_FALSE(never_expires.CanDiscard());
+}
+
+TEST(BackoffEntryTest, CanDiscard) {
+ TestBackoffEntry entry(&base_policy);
+ // Because lifetime is non-zero, we shouldn't be able to discard yet.
+ EXPECT_FALSE(entry.CanDiscard());
+
+ // Test the "being used" case.
+ entry.InformOfRequest(false);
+ EXPECT_FALSE(entry.CanDiscard());
+
+ // Test the case where there are errors but we can time out.
+ entry.set_now(
+ entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1));
+ EXPECT_FALSE(entry.CanDiscard());
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
+ base_policy.maximum_backoff_ms + 1));
+ EXPECT_TRUE(entry.CanDiscard());
+
+ // Test the final case (no errors, dependent only on specified lifetime).
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
+ base_policy.entry_lifetime_ms - 1));
+ entry.InformOfRequest(true);
+ EXPECT_FALSE(entry.CanDiscard());
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(
+ base_policy.entry_lifetime_ms));
+ EXPECT_TRUE(entry.CanDiscard());
+}
+
+TEST(BackoffEntryTest, CanDiscardAlwaysDelay) {
+ BackoffEntry::Policy always_delay_policy = base_policy;
+ always_delay_policy.always_use_initial_delay = true;
+ always_delay_policy.entry_lifetime_ms = 0;
+
+ TestBackoffEntry entry(&always_delay_policy);
+
+ // Because lifetime is non-zero, we shouldn't be able to discard yet.
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
+ EXPECT_TRUE(entry.CanDiscard());
+
+ // Even with no failures, we wait until the delay before we allow discard.
+ entry.InformOfRequest(true);
+ EXPECT_FALSE(entry.CanDiscard());
+
+ // Wait until the delay expires, and we can discard the entry again.
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(1000));
+ EXPECT_TRUE(entry.CanDiscard());
+}
+
+TEST(BackoffEntryTest, CanDiscardNotStored) {
+ BackoffEntry::Policy no_store_policy = base_policy;
+ no_store_policy.entry_lifetime_ms = 0;
+ TestBackoffEntry not_stored(&no_store_policy);
+ EXPECT_TRUE(not_stored.CanDiscard());
+}
+
+TEST(BackoffEntryTest, ShouldIgnoreFirstTwo) {
+ BackoffEntry::Policy lenient_policy = base_policy;
+ lenient_policy.num_errors_to_ignore = 2;
+
+ BackoffEntry entry(&lenient_policy);
+
+ entry.InformOfRequest(false);
+ EXPECT_FALSE(entry.ShouldRejectRequest());
+
+ entry.InformOfRequest(false);
+ EXPECT_FALSE(entry.ShouldRejectRequest());
+
+ entry.InformOfRequest(false);
+ EXPECT_TRUE(entry.ShouldRejectRequest());
+}
+
+TEST(BackoffEntryTest, ReleaseTimeCalculation) {
+ TestBackoffEntry entry(&base_policy);
+
+ // With zero errors, should return "now".
+ TimeTicks result = entry.GetReleaseTime();
+ EXPECT_EQ(entry.ImplGetTimeNow(), result);
+
+ // 1 error.
+ entry.InformOfRequest(false);
+ result = entry.GetReleaseTime();
+ EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(1000), result);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+
+ // 2 errors.
+ entry.InformOfRequest(false);
+ result = entry.GetReleaseTime();
+ EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(2000), result);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
+
+ // 3 errors.
+ entry.InformOfRequest(false);
+ result = entry.GetReleaseTime();
+ EXPECT_EQ(entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease());
+
+ // 6 errors (to check it doesn't pass maximum).
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ result = entry.GetReleaseTime();
+ EXPECT_EQ(
+ entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(20000), result);
+}
+
+TEST(BackoffEntryTest, ReleaseTimeCalculationAlwaysDelay) {
+ BackoffEntry::Policy always_delay_policy = base_policy;
+ always_delay_policy.always_use_initial_delay = true;
+ always_delay_policy.num_errors_to_ignore = 2;
+
+ TestBackoffEntry entry(&always_delay_policy);
+
+ // With previous requests, should return "now".
+ TimeTicks result = entry.GetReleaseTime();
+ EXPECT_EQ(TimeDelta(), entry.GetTimeUntilRelease());
+
+ // 1 error.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+
+ // 2 errors.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+
+ // 3 errors, exponential backoff starts.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
+
+ // 4 errors.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(4000), entry.GetTimeUntilRelease());
+
+ // 8 errors (to check it doesn't pass maximum).
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ result = entry.GetReleaseTime();
+ EXPECT_EQ(TimeDelta::FromMilliseconds(20000), entry.GetTimeUntilRelease());
+}
+
+TEST(BackoffEntryTest, ReleaseTimeCalculationWithJitter) {
+ for (int i = 0; i < 10; ++i) {
+ BackoffEntry::Policy jittery_policy = base_policy;
+ jittery_policy.jitter_factor = 0.2;
+
+ TestBackoffEntry entry(&jittery_policy);
+
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ entry.InformOfRequest(false);
+ TimeTicks result = entry.GetReleaseTime();
+ EXPECT_LE(
+ entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(3200), result);
+ EXPECT_GE(
+ entry.ImplGetTimeNow() + TimeDelta::FromMilliseconds(4000), result);
+ }
+}
+
+TEST(BackoffEntryTest, FailureThenSuccess) {
+ TestBackoffEntry entry(&base_policy);
+
+ // Failure count 1, establishes horizon.
+ entry.InformOfRequest(false);
+ TimeTicks release_time = entry.GetReleaseTime();
+ EXPECT_EQ(TimeTicks() + TimeDelta::FromMilliseconds(1000), release_time);
+
+ // Success, failure count 0, should not advance past
+ // the horizon that was already set.
+ entry.set_now(release_time - TimeDelta::FromMilliseconds(200));
+ entry.InformOfRequest(true);
+ EXPECT_EQ(release_time, entry.GetReleaseTime());
+
+ // Failure, failure count 1.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(release_time + TimeDelta::FromMilliseconds(800),
+ entry.GetReleaseTime());
+}
+
+TEST(BackoffEntryTest, FailureThenSuccessAlwaysDelay) {
+ BackoffEntry::Policy always_delay_policy = base_policy;
+ always_delay_policy.always_use_initial_delay = true;
+ always_delay_policy.num_errors_to_ignore = 1;
+
+ TestBackoffEntry entry(&always_delay_policy);
+
+ // Failure count 1.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+
+ // Failure count 2.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
+
+ // Success. We should go back to the original delay.
+ entry.InformOfRequest(true);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(1000), entry.GetTimeUntilRelease());
+
+ // Failure count reaches 2 again. We should increase the delay once more.
+ entry.InformOfRequest(false);
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2000), entry.GetTimeUntilRelease());
+ entry.set_now(entry.GetReleaseTime() + TimeDelta::FromMilliseconds(2000));
+}
+
+TEST(BackoffEntryTest, RetainCustomHorizon) {
+ TestBackoffEntry custom(&base_policy);
+ TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3);
+ custom.SetCustomReleaseTime(custom_horizon);
+ custom.InformOfRequest(false);
+ custom.InformOfRequest(true);
+ custom.set_now(TimeTicks() + TimeDelta::FromDays(2));
+ custom.InformOfRequest(false);
+ custom.InformOfRequest(true);
+ EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
+
+ // Now check that once we are at or past the custom horizon,
+ // we get normal behavior.
+ custom.set_now(TimeTicks() + TimeDelta::FromDays(3));
+ custom.InformOfRequest(false);
+ EXPECT_EQ(
+ TimeTicks() + TimeDelta::FromDays(3) + TimeDelta::FromMilliseconds(1000),
+ custom.GetReleaseTime());
+}
+
+TEST(BackoffEntryTest, RetainCustomHorizonWhenInitialErrorsIgnored) {
+ // Regression test for a bug discovered during code review.
+ BackoffEntry::Policy lenient_policy = base_policy;
+ lenient_policy.num_errors_to_ignore = 1;
+ TestBackoffEntry custom(&lenient_policy);
+ TimeTicks custom_horizon = TimeTicks() + TimeDelta::FromDays(3);
+ custom.SetCustomReleaseTime(custom_horizon);
+ custom.InformOfRequest(false); // This must not reset the horizon.
+ EXPECT_EQ(custom_horizon, custom.GetReleaseTime());
+}
+
+TEST(BackoffEntryTest, OverflowProtection) {
+ BackoffEntry::Policy large_multiply_policy = base_policy;
+ large_multiply_policy.multiply_factor = 256;
+ TestBackoffEntry custom(&large_multiply_policy);
+
+ // Trigger enough failures such that more than 11 bits of exponent are used
+ // to represent the exponential backoff intermediate values. Given a multiply
+ // factor of 256 (2^8), 129 iterations is enough: 2^(8*(129-1)) = 2^1024.
+ for (int i = 0; i < 129; ++i) {
+ custom.set_now(custom.ImplGetTimeNow() + custom.GetTimeUntilRelease());
+ custom.InformOfRequest(false);
+ ASSERT_TRUE(custom.ShouldRejectRequest());
+ }
+
+ // Max delay should still be respected.
+ EXPECT_EQ(20000, custom.GetTimeUntilRelease().InMilliseconds());
+}
+
+} // namespace
diff --git a/brillo/dbus/data_serialization.h b/brillo/dbus/data_serialization.h
index 4f120f3..a4f49c1 100644
--- a/brillo/dbus/data_serialization.h
+++ b/brillo/dbus/data_serialization.h
@@ -60,6 +60,7 @@
#include <base/files/scoped_file.h>
#include <base/logging.h>
+#include <base/files/scoped_file.h>
#include <brillo/brillo_export.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/type_name_undecorate.h>
diff --git a/brillo/dbus/data_serialization_test.cc b/brillo/dbus/data_serialization_test.cc
index 4d349b7..7e68af5 100644
--- a/brillo/dbus/data_serialization_test.cc
+++ b/brillo/dbus/data_serialization_test.cc
@@ -7,6 +7,7 @@
#include <limits>
#include <tuple>
+#include <base/files/scoped_file.h>
#include <brillo/variant_dictionary.h>
#include <gtest/gtest.h>
diff --git a/brillo/dbus/dbus_method_invoker.h b/brillo/dbus/dbus_method_invoker.h
index 385e98a..08f5781 100644
--- a/brillo/dbus/dbus_method_invoker.h
+++ b/brillo/dbus/dbus_method_invoker.h
@@ -173,7 +173,7 @@
ErrorPtr* error,
std::tuple<ResultTypes...>* val_tuple) {
auto callback = [val_tuple](const ResultTypes&... params) {
- *val_tuple = std::forward_as_tuple(internal::HackMove(params)...);
+ *val_tuple = std::forward_as_tuple(params...);
};
return DBusParamReader<false, ResultTypes...>::Invoke(
callback, reader, error);
@@ -186,7 +186,7 @@
ErrorPtr* error,
std::tuple<ResultTypes&...>* ref_tuple) {
auto callback = [ref_tuple](const ResultTypes&... params) {
- *ref_tuple = std::forward_as_tuple(internal::HackMove(params)...);
+ *ref_tuple = std::forward_as_tuple(params...);
};
return DBusParamReader<false, ResultTypes...>::Invoke(
callback, reader, error);
diff --git a/brillo/file_utils.cc b/brillo/file_utils.cc
index 921fb57..3661551 100644
--- a/brillo/file_utils.cc
+++ b/brillo/file_utils.cc
@@ -508,6 +508,7 @@
}
int64_t ComputeDirectoryDiskUsage(const base::FilePath& root_path) {
+ constexpr size_t S_BLKSIZE = 512;
int64_t running_blocks = 0;
base::FileEnumerator file_iter(root_path, true,
base::FileEnumerator::FILES |
diff --git a/brillo/flag_helper.h b/brillo/flag_helper.h
index 08cc242..c6d63cd 100644
--- a/brillo/flag_helper.h
+++ b/brillo/flag_helper.h
@@ -222,7 +222,7 @@
// for defining bool flags
#define DEFINE_bool(name, value, help) \
bool FLAGS_##name = value; \
- bool FLAGS_no##name = !value; \
+ bool FLAGS_no##name = !(value); \
brillo::FlagHelper::GetInstance()->AddFlag( \
std::unique_ptr<brillo::Flag>(new brillo::BoolFlag( \
#name, &FLAGS_##name, &FLAGS_no##name, #value, help, true))); \
diff --git a/brillo/http/http_connection_fake.cc b/brillo/http/http_connection_fake.cc
index 35c7458..dbd9f90 100644
--- a/brillo/http/http_connection_fake.cc
+++ b/brillo/http/http_connection_fake.cc
@@ -68,9 +68,11 @@
const ErrorCallback& error_callback) {
connection->FinishRequestAsyncHelper(success_callback, error_callback);
};
- transport_->RunCallbackAsync(
- FROM_HERE,
- base::Bind(callback, connection, success_callback, error_callback));
+ transport_->RunCallbackAsync(FROM_HERE,
+ base::Bind(callback,
+ base::Passed(&connection),
+ success_callback,
+ error_callback));
return 1;
}
diff --git a/brillo/http/http_form_data.h b/brillo/http/http_form_data.h
index 55ec150..e12d3d8 100644
--- a/brillo/http/http_form_data.h
+++ b/brillo/http/http_form_data.h
@@ -155,7 +155,7 @@
// content_type: valid content type. If omitted, "multipart/mixed" is used.
// boundary: multipart boundary separator.
// If omitted/empty, a random string is generated.
- MultiPartFormField(const std::string& name,
+ explicit MultiPartFormField(const std::string& name,
const std::string& content_type = {},
const std::string& boundary = {});
diff --git a/brillo/http/http_transport_fake.cc b/brillo/http/http_transport_fake.cc
index deef1f8..8fd9d2c 100644
--- a/brillo/http/http_transport_fake.cc
+++ b/brillo/http/http_transport_fake.cc
@@ -121,14 +121,15 @@
int status_code,
const std::string& reply_text,
const std::string& mime_type) {
- auto handler = [](
- int status_code, const std::string& reply_text,
- const std::string& mime_type, const ServerRequest& /* request */,
- ServerResponse* response) {
+ auto handler = [](int status_code,
+ const std::string& reply_text,
+ const std::string& mime_type,
+ const ServerRequest& /* request */,
+ ServerResponse* response) {
response->ReplyText(status_code, reply_text, mime_type);
};
- AddHandler(url, method,
- base::Bind(handler, status_code, reply_text, mime_type));
+ AddHandler(
+ url, method, base::Bind(handler, status_code, reply_text, mime_type));
}
Transport::HandlerCallback Transport::GetHandler(
diff --git a/brillo/http/http_transport_fake.h b/brillo/http/http_transport_fake.h
index 896a597..56351ec 100644
--- a/brillo/http/http_transport_fake.h
+++ b/brillo/http/http_transport_fake.h
@@ -105,7 +105,7 @@
void SetDefaultTimeout(base::TimeDelta timeout) override;
- void SetLocalIpAddress(const std::string& ip_address) override {}
+ void SetLocalIpAddress(const std::string& /* ip_address */) override {}
void ResolveHostToIp(const std::string& host,
uint16_t port,
diff --git a/brillo/http/http_utils_test.cc b/brillo/http/http_utils_test.cc
index b2993b6..409282c 100644
--- a/brillo/http/http_utils_test.cc
+++ b/brillo/http/http_utils_test.cc
@@ -68,15 +68,14 @@
// Test binary data round-tripping.
std::vector<uint8_t> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};
- auto success_callback =
- base::Bind([](const std::vector<uint8_t>& custom_data,
- RequestID /* id */,
- std::unique_ptr<http::Response> response) {
+ auto success_callback = [](const std::vector<uint8_t>& custom_data,
+ RequestID /* id */,
+ std::unique_ptr<http::Response> response) {
EXPECT_TRUE(response->IsSuccessful());
EXPECT_EQ(brillo::mime::application::kOctet_stream,
response->GetContentType());
EXPECT_EQ(custom_data, response->ExtractData());
- }, custom_data);
+ };
auto error_callback = [](RequestID /* id */, const Error* /* error */) {
FAIL() << "This callback shouldn't have been called";
};
@@ -87,7 +86,7 @@
brillo::mime::application::kOctet_stream,
{},
transport,
- success_callback,
+ base::Bind(success_callback, custom_data),
base::Bind(error_callback));
}
@@ -301,21 +300,22 @@
TEST(HttpUtils, PostText) {
std::string fake_data = "Some data";
- auto post_handler = base::Bind([](const std::string& data,
- const fake::ServerRequest& request,
- fake::ServerResponse* response) {
+ auto PostHandler = [](const std::string& fake_data,
+ const fake::ServerRequest& request,
+ fake::ServerResponse* response) {
EXPECT_EQ(request_type::kPost, request.GetMethod());
- EXPECT_EQ(data.size(),
+ EXPECT_EQ(fake_data.size(),
std::stoul(request.GetHeader(request_header::kContentLength)));
EXPECT_EQ(brillo::mime::text::kPlain,
request.GetHeader(request_header::kContentType));
response->ReplyText(status_code::Ok,
request.GetDataAsString(),
brillo::mime::text::kPlain);
- }, fake_data);
+ };
std::shared_ptr<fake::Transport> transport(new fake::Transport);
- transport->AddHandler(kFakeUrl, request_type::kPost, post_handler);
+ transport->AddHandler(
+ kFakeUrl, request_type::kPost, base::Bind(PostHandler, fake_data));
auto response = http::PostTextAndBlock(kFakeUrl,
fake_data,
diff --git a/brillo/location_logging.h b/brillo/location_logging.h
index 1a9929b..9fb3716 100644
--- a/brillo/location_logging.h
+++ b/brillo/location_logging.h
@@ -9,21 +9,16 @@
#include <base/logging.h>
-#define VLOG_LOC_STREAM(from_here, verbose_level) \
- logging::LogMessage(from_here.file_name(), from_here.line_number(), \
- -verbose_level).stream()
+#define VLOG_LOC_STREAM(from_here, verbose_level) \
+ logging::LogMessage((from_here).file_name(), (from_here).line_number(), \
+ -(verbose_level)).stream()
-#define VLOG_LOC(from_here, verbose_level) \
- LAZY_STREAM(VLOG_LOC_STREAM(from_here, verbose_level), \
+#define VLOG_LOC(from_here, verbose_level) \
+ LAZY_STREAM(VLOG_LOC_STREAM(from_here, verbose_level), \
VLOG_IS_ON(verbose_level))
-#if DCHECK_IS_ON()
+#define DVLOG_LOC(from_here, verbose_level) \
+ LAZY_STREAM(VLOG_LOC_STREAM(from_here, verbose_level), \
+ DCHECK_IS_ON() && VLOG_IS_ON(verbose_level))
-#define DVLOG_LOC(from_here, verbose_level) VLOG_LOC(from_here, verbose_level)
-
-#else // DCHECK_IS_ON()
-
-#define DVLOG_LOC(from_here, verbose_level) EAT_STREAM_PARAMETERS
-
-#endif // DCHECK_IS_ON()
#endif // LIBBRILLO_BRILLO_LOCATION_LOGGING_H_
diff --git a/brillo/message_loops/base_message_loop.cc b/brillo/message_loops/base_message_loop.cc
index 34c6828..c3499ab 100644
--- a/brillo/message_loops/base_message_loop.cc
+++ b/brillo/message_loops/base_message_loop.cc
@@ -10,6 +10,10 @@
#include <sys/types.h>
#include <unistd.h>
+#ifndef __APPLE__
+#include <sys/sysmacros.h>
+#endif
+
#ifndef __ANDROID_HOST__
// Used for MISC_MAJOR. Only required for the target and not always available
// for the host.
diff --git a/brillo/message_loops/base_message_loop.h b/brillo/message_loops/base_message_loop.h
index ae85539..75e4361 100644
--- a/brillo/message_loops/base_message_loop.h
+++ b/brillo/message_loops/base_message_loop.h
@@ -20,6 +20,7 @@
#include <base/location.h>
#include <base/memory/weak_ptr.h>
#include <base/message_loop/message_loop.h>
+#include <base/message_loop/message_pump_for_io.h>
#include <base/time/time.h>
#include <gtest/gtest_prod.h>
diff --git a/brillo/minijail/minijail.cc b/brillo/minijail/minijail.cc
index 09587ee..9f88585 100644
--- a/brillo/minijail/minijail.cc
+++ b/brillo/minijail/minijail.cc
@@ -20,7 +20,8 @@
// static
Minijail* Minijail::GetInstance() {
- return g_minijail.Pointer();
+ static Minijail* minijail = new Minijail();
+ return minijail;
}
struct minijail* Minijail::New() {
diff --git a/brillo/minijail/minijail.h b/brillo/minijail/minijail.h
index e0a0d72..6cdc7ad 100644
--- a/brillo/minijail/minijail.h
+++ b/brillo/minijail/minijail.h
@@ -17,6 +17,8 @@
#include <libminijail.h>
+#include "base/macros.h"
+
namespace brillo {
// A Minijail abstraction allowing Minijail mocking in tests.
diff --git a/brillo/osrelease_reader.cc b/brillo/osrelease_reader.cc
index d9ede3b..7e533c0 100644
--- a/brillo/osrelease_reader.cc
+++ b/brillo/osrelease_reader.cc
@@ -41,9 +41,8 @@
path = enumerator.Next()) {
std::string content;
if (!base::ReadFileToString(path, &content)) {
- // The only way to fail is if a file exist in /etc/os-release.d but we
- // cannot read it.
- PLOG(FATAL) << "Could not read " << path.value();
+ PLOG(ERROR) << "Could not read " << path.value();
+ continue;
}
// There might be a trailing new line. Strip it to keep only the first line
// of the file.
diff --git a/brillo/process.cc b/brillo/process.cc
index a70bfd7..54e91f0 100644
--- a/brillo/process.cc
+++ b/brillo/process.cc
@@ -18,7 +18,9 @@
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
+#include <base/memory/ptr_util.h>
#include <base/posix/eintr_wrapper.h>
+#include <base/posix/file_descriptor_shuffle.h>
#include <base/process/process_metrics.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
@@ -140,20 +142,6 @@
}
bool ProcessImpl::PopulatePipeMap() {
- // Verify all target fds are already open. With this assumption we
- // can be sure that the pipe fds created below do not overlap with
- // any of the target fds which simplifies how we dup2 to them. Note
- // that multi-threaded code could close i->first between this loop
- // and the next.
- for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
- struct stat stat_buffer;
- if (fstat(i->first, &stat_buffer) < 0) {
- int saved_errno = errno;
- LOG(ERROR) << "Unable to fstat fd " << i->first << ": " << saved_errno;
- return false;
- }
- }
-
for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
if (i->second.is_bound_) {
// already have a parent fd, and the child fd gets dup()ed later.
@@ -242,24 +230,19 @@
if (close_unused_file_descriptors_) {
CloseUnusedFileDescriptors();
}
- // Close parent's side of the child pipes. dup2 ours into place and
- // then close our ends.
- for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
- if (i->second.parent_fd_ != -1)
- IGNORE_EINTR(close(i->second.parent_fd_));
- // If we want to bind a fd to the same fd in the child, we don't need to
- // close and dup2 it.
- if (i->second.child_fd_ == i->first)
- continue;
- HANDLE_EINTR(dup2(i->second.child_fd_, i->first));
+
+ base::InjectiveMultimap fd_shuffle;
+ for (const auto& it : pipe_map_) {
+ // Close parent's side of the child pipes.
+ if (it.second.parent_fd_ != -1)
+ IGNORE_EINTR(close(it.second.parent_fd_));
+
+ fd_shuffle.emplace_back(it.second.child_fd_, it.first, true);
}
- // Defer the actual close() of the child fd until afterward; this lets the
- // same child fd be bound to multiple fds using BindFd. Don't close the fd
- // if it was bound to itself.
- for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
- if (i->second.child_fd_ == i->first)
- continue;
- IGNORE_EINTR(close(i->second.child_fd_));
+
+ if (!base::ShuffleFileDescriptors(&fd_shuffle)) {
+ PLOG(ERROR) << "Could not shuffle file descriptors";
+ _exit(kErrorExitStatus);
}
if (!input_file_.empty()) {
diff --git a/brillo/process_test.cc b/brillo/process_test.cc
index 3c1d89f..533a8f0 100644
--- a/brillo/process_test.cc
+++ b/brillo/process_test.cc
@@ -28,7 +28,6 @@
static const char kBinSh[] = SYSTEM_PREFIX "/bin/sh";
static const char kBinCat[] = SYSTEM_PREFIX "/bin/cat";
-static const char kBinCp[] = SYSTEM_PREFIX "/bin/cp";
static const char kBinEcho[] = SYSTEM_PREFIX "/bin/echo";
static const char kBinFalse[] = SYSTEM_PREFIX "/bin/false";
static const char kBinSleep[] = SYSTEM_PREFIX "/bin/sleep";
@@ -181,11 +180,11 @@
}
void ProcessTest::CheckStderrCaptured() {
- std::string contents;
process_.AddArg(kBinSh);
process_.AddArg("-c");
process_.AddArg("echo errormessage 1>&2 && exit 1");
EXPECT_EQ(1, process_.Run());
+ std::string contents;
EXPECT_TRUE(base::ReadFileToString(FilePath(output_file_), &contents));
EXPECT_NE(std::string::npos, contents.find("errormessage"));
EXPECT_EQ("", GetLog());
@@ -207,7 +206,6 @@
}
TEST_F(ProcessTest, RedirectStderrUsingPipe) {
- std::string contents;
process_.RedirectOutput("");
process_.AddArg(kBinSh);
process_.AddArg("-c");
@@ -219,6 +217,7 @@
EXPECT_GE(pipe_fd, 0);
EXPECT_EQ(-1, process_.GetPipe(STDOUT_FILENO));
EXPECT_EQ(-1, process_.GetPipe(STDIN_FILENO));
+ std::string contents;
EXPECT_TRUE(base::ReadFileToString(GetFdPath(pipe_fd), &contents));
EXPECT_NE(std::string::npos, contents.find("errormessage"));
EXPECT_EQ("", GetLog());
@@ -228,15 +227,23 @@
int saved_stderr = dup(STDERR_FILENO);
close(STDERR_FILENO);
process_.RedirectOutput("");
- process_.AddArg(kBinCp);
+ process_.AddArg(kBinSh);
+ process_.AddArg("-c");
+ process_.AddArg("echo errormessage >&2 && exit 1");
process_.RedirectUsingPipe(STDERR_FILENO, false);
- EXPECT_FALSE(process_.Start());
- EXPECT_TRUE(FindLog("Unable to fstat fd 2:"));
+ EXPECT_EQ(1, process_.Run());
+ int pipe_fd = process_.GetPipe(STDERR_FILENO);
+ EXPECT_GE(pipe_fd, 0);
+ EXPECT_EQ(-1, process_.GetPipe(STDOUT_FILENO));
+ EXPECT_EQ(-1, process_.GetPipe(STDIN_FILENO));
+ std::string contents;
+ EXPECT_TRUE(base::ReadFileToString(GetFdPath(pipe_fd), &contents));
+ EXPECT_NE(std::string::npos, contents.find("errormessage"));
+ EXPECT_EQ("", GetLog());
dup2(saved_stderr, STDERR_FILENO);
}
TEST_F(ProcessTest, RedirectStdoutUsingPipe) {
- std::string contents;
process_.RedirectOutput("");
process_.AddArg(kBinEcho);
process_.AddArg("hello world\n");
@@ -247,13 +254,13 @@
EXPECT_GE(pipe_fd, 0);
EXPECT_EQ(-1, process_.GetPipe(STDERR_FILENO));
EXPECT_EQ(-1, process_.GetPipe(STDIN_FILENO));
+ std::string contents;
EXPECT_TRUE(base::ReadFileToString(GetFdPath(pipe_fd), &contents));
EXPECT_NE(std::string::npos, contents.find("hello world\n"));
EXPECT_EQ("", GetLog());
}
TEST_F(ProcessTest, RedirectStdinUsingPipe) {
- std::string contents;
const char kMessage[] = "made it!\n";
process_.AddArg(kBinCat);
process_.RedirectUsingPipe(STDIN_FILENO, true);
diff --git a/brillo/secure_blob.cc b/brillo/secure_blob.cc
index 0c7026a..70950f6 100644
--- a/brillo/secure_blob.cc
+++ b/brillo/secure_blob.cc
@@ -54,25 +54,26 @@
: SecureBlob(data.begin(), data.end()) {}
SecureBlob::~SecureBlob() {
- SecureVector::clear();
+ clear();
}
void SecureBlob::resize(size_type count) {
if (count < size()) {
SecureMemset(data() + count, 0, capacity() - count);
}
- SecureVector::resize(count);
+ Blob::resize(count);
}
void SecureBlob::resize(size_type count, const value_type& value) {
if (count < size()) {
SecureMemset(data() + count, 0, capacity() - count);
}
- SecureVector::resize(count, value);
+ Blob::resize(count, value);
}
void SecureBlob::clear() {
- SecureVector::clear();
+ SecureMemset(data(), 0, capacity());
+ Blob::clear();
}
std::string SecureBlob::to_string() const {
diff --git a/brillo/secure_blob.h b/brillo/secure_blob.h
index 8099c56..7705c1a 100644
--- a/brillo/secure_blob.h
+++ b/brillo/secure_blob.h
@@ -11,19 +11,13 @@
#include <brillo/asan.h>
#include <brillo/brillo_export.h>
-#include <brillo/secure_allocator.h>
namespace brillo {
+// TODO(sarthakkukreti): remove temp. SecureVector once we break SecureBlob's
+// dependence on std::vector<uint8_t>
using Blob = std::vector<uint8_t>;
-
-// Define types based on the SecureAllocator for instantiation.
-// ------------------------------------------------------------
-// Define SecureVector as a vector using a SecureAllocator.
-// Over time, the goal is to remove the differentiating functions
-// from SecureBlob (to_string(), char_data()) till it converges with
-// SecureVector.
-using SecureVector = std::vector<uint8_t, SecureAllocator<uint8_t>>;
+using SecureVector = std::vector<uint8_t>;
// Conversion of Blob to/from std::string, where the string holds raw byte
// contents.
@@ -35,11 +29,10 @@
// SecureBlob erases the contents on destruction. It does not guarantee erasure
// on resize, assign, etc.
-class BRILLO_EXPORT SecureBlob : public SecureVector {
+class BRILLO_EXPORT SecureBlob : public Blob {
public:
SecureBlob() = default;
- // Inherit standard constructors from SecureVector.
- using SecureVector::vector;
+ using Blob::vector; // Inherit standard constructors from vector.
explicit SecureBlob(const Blob& blob);
explicit SecureBlob(const std::string& data);
~SecureBlob();
diff --git a/brillo/streams/fake_stream_test.cc b/brillo/streams/fake_stream_test.cc
index 4faee24..2e83e3b 100644
--- a/brillo/streams/fake_stream_test.cc
+++ b/brillo/streams/fake_stream_test.cc
@@ -289,10 +289,12 @@
(*error_count)++;
};
- EXPECT_TRUE(stream_->ReadAllAsync(buffer.data(), buffer.size(),
- base::Bind(on_success, &success_count),
- base::Bind(on_failure, &error_count),
- nullptr));
+ EXPECT_TRUE(stream_->ReadAllAsync(
+ buffer.data(),
+ buffer.size(),
+ base::Bind(on_success, base::Unretained(&success_count)),
+ base::Bind(on_failure, base::Unretained(&error_count)),
+ nullptr));
mock_loop_.Run();
EXPECT_EQ(1, success_count);
EXPECT_EQ(0, error_count);
@@ -444,10 +446,12 @@
(*error_count)++;
};
- EXPECT_TRUE(stream_->WriteAllAsync(output_data.data(), output_data.size(),
- base::Bind(on_success, &success_count),
- base::Bind(on_failure, &error_count),
- nullptr));
+ EXPECT_TRUE(stream_->WriteAllAsync(
+ output_data.data(),
+ output_data.size(),
+ base::Bind(on_success, base::Unretained(&success_count)),
+ base::Bind(on_failure, base::Unretained(&error_count)),
+ nullptr));
mock_loop_.Run();
EXPECT_EQ(1, success_count);
EXPECT_EQ(0, error_count);
@@ -460,12 +464,12 @@
auto two_sec_delay = base::TimeDelta::FromSeconds(2);
int call_count = 0;
- auto callback = base::Bind([](int* call_count,
- Stream::AccessMode mode,
- Stream::AccessMode expected_mode) {
+ auto callback = [](int* call_count,
+ Stream::AccessMode mode,
+ Stream::AccessMode expected_mode) {
(*call_count)++;
EXPECT_EQ(static_cast<int>(expected_mode), static_cast<int>(mode));
- }, &call_count);
+ };
stream_->AddReadPacketString(one_sec_delay, "foo");
stream_->ExpectWritePacketString(two_sec_delay, "bar");
@@ -473,6 +477,7 @@
EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
base::Bind(callback,
+ base::Unretained(&call_count),
Stream::AccessMode::READ),
nullptr));
mock_loop_.Run();
@@ -484,6 +489,7 @@
EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
base::Bind(callback,
+ base::Unretained(&call_count),
Stream::AccessMode::WRITE),
nullptr));
mock_loop_.Run();
@@ -494,6 +500,7 @@
EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1);
EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
base::Bind(callback,
+ base::Unretained(&call_count),
Stream::AccessMode::READ_WRITE),
nullptr));
mock_loop_.Run();
@@ -507,6 +514,7 @@
EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
base::Bind(callback,
+ base::Unretained(&call_count),
Stream::AccessMode::READ_WRITE),
nullptr));
mock_loop_.Run();
diff --git a/brillo/streams/file_stream_test.cc b/brillo/streams/file_stream_test.cc
index 593b1f7..23ef64c 100644
--- a/brillo/streams/file_stream_test.cc
+++ b/brillo/streams/file_stream_test.cc
@@ -1073,7 +1073,9 @@
};
MessageLoopRunUntil(&brillo_loop,
base::TimeDelta::FromSeconds(1),
- base::Bind(end_condition, &failed, &succeeded));
+ base::Bind(end_condition,
+ base::Unretained(&failed),
+ base::Unretained(&succeeded)));
EXPECT_TRUE(succeeded);
EXPECT_FALSE(failed);
@@ -1093,8 +1095,10 @@
ASSERT_EQ(0, pipe(fds));
- auto success_callback = [](bool* succeeded, const std::string& data,
- int read_fd, size_t /* size */) {
+ auto success_callback = [](bool* succeeded,
+ const std::string& data,
+ int read_fd,
+ size_t /* size */) {
char buffer[100];
EXPECT_TRUE(base::ReadFromFD(read_fd, buffer, data.size()));
EXPECT_EQ(data, (std::string{buffer, buffer + data.size()}));
@@ -1104,16 +1108,20 @@
StreamPtr stream = FileStream::FromFileDescriptor(fds[1], true, nullptr);
EXPECT_TRUE(stream->WriteAsync(
- data.data(), data.size(),
- base::Bind(success_callback, &succeeded, data, fds[0]),
- base::Bind(&SetToTrue, &failed), nullptr));
+ data.data(),
+ data.size(),
+ base::Bind(success_callback, base::Unretained(&succeeded), data, fds[0]),
+ base::Bind(&SetToTrue, &failed),
+ nullptr));
auto end_condition = [](bool* failed, bool* succeeded) {
return *failed || *succeeded;
};
MessageLoopRunUntil(&brillo_loop,
base::TimeDelta::FromSeconds(1),
- base::Bind(end_condition, &failed, &succeeded));
+ base::Bind(end_condition,
+ base::Unretained(&failed),
+ base::Unretained(&succeeded)));
EXPECT_TRUE(succeeded);
EXPECT_FALSE(failed);
diff --git a/policy/libpolicy.cc b/policy/libpolicy.cc
index 9bdb578..e972814 100644
--- a/policy/libpolicy.cc
+++ b/policy/libpolicy.cc
@@ -25,8 +25,14 @@
PolicyProvider::PolicyProvider(std::unique_ptr<DevicePolicy> device_policy)
: device_policy_(std::move(device_policy)),
+#ifdef __ANDROID__
+ device_policy_is_loaded_(true) {
+}
+#else
device_policy_is_loaded_(true),
- install_attributes_reader_(std::make_unique<InstallAttributesReader>()) {}
+ install_attributes_reader_(std::make_unique<InstallAttributesReader>()) {
+}
+#endif // __ANDROID__
PolicyProvider::~PolicyProvider() {}
@@ -51,13 +57,17 @@
}
bool PolicyProvider::IsConsumerDevice() const {
+#ifdef __ANDROID__
+ return true;
+#else
if (!install_attributes_reader_->IsLocked())
return false;
const std::string& device_mode = install_attributes_reader_->GetAttribute(
InstallAttributesReader::kAttrMode);
return device_mode != InstallAttributesReader::kDeviceModeEnterprise &&
- device_mode != InstallAttributesReader::kDeviceModeEnterpriseAD;
+ device_mode != InstallAttributesReader::kDeviceModeEnterpriseAD;
+#endif // __ANDROID__
}
void PolicyProvider::SetDevicePolicyForTesting(
diff --git a/policy/tests/libpolicy_test.cc b/policy/tests/libpolicy_test.cc
index 137e505..b8414bb 100644
--- a/policy/tests/libpolicy_test.cc
+++ b/policy/tests/libpolicy_test.cc
@@ -193,6 +193,9 @@
EXPECT_EQ(3, intervals[1].end_day_of_week);
EXPECT_EQ(base::TimeDelta::FromMinutes(20), intervals[1].end_time);
+ ASSERT_TRUE(policy.GetAutoLaunchedKioskAppId(&string_value));
+ ASSERT_EQ("my_kiosk_app", string_value);
+
// Reloading the protobuf should succeed.
EXPECT_TRUE(provider.Reload());
}
diff --git a/testrunner_android.cc b/testrunner_android.cc
new file mode 100644
index 0000000..93377bf
--- /dev/null
+++ b/testrunner_android.cc
@@ -0,0 +1,26 @@
+//Copyright (C) 2015 The Android Open Source Project
+//
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+
+// based on testrunner.cc with the glib bits removed.
+
+#include <gtest/gtest.h>
+
+#include <base/at_exit.h>
+#include <brillo/test_helpers.h>
+
+int main(int argc, char** argv) {
+ base::AtExitManager at_exit_manager;
+ SetUpTests(&argc, argv, true);
+ return RUN_ALL_TESTS();
+}