Merge "Add a switch to enforce avb for DSU in userdebug"
diff --git a/adb/Android.bp b/adb/Android.bp
index 5073568..675525c 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -696,10 +696,10 @@
test_suites: ["general-tests"],
version: {
py2: {
- enabled: true,
+ enabled: false,
},
py3: {
- enabled: false,
+ enabled: true,
},
},
}
diff --git a/adb/test_device.py b/adb/test_device.py
index 083adce..6a9ff89 100755
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 The Android Open Source Project
@@ -81,6 +81,13 @@
self.device = adb.get_device()
+class AbbTest(DeviceTest):
+ def test_smoke(self):
+ result = subprocess.run(['adb', 'abb'], capture_output=True)
+ self.assertEqual(1, result.returncode)
+ expected_output = b"cmd: No service specified; use -l to list all services\n"
+ self.assertEqual(expected_output, result.stderr)
+
class ForwardReverseTest(DeviceTest):
def _test_no_rebind(self, description, direction_list, direction,
direction_no_rebind, direction_remove_all):
@@ -246,7 +253,7 @@
# Accept the client connection.
accepted_connection, addr = listener.accept()
with contextlib.closing(accepted_connection) as server:
- data = 'hello'
+ data = b'hello'
# Send data into the port setup by adb forward.
client.sendall(data)
@@ -254,7 +261,7 @@
client.close()
# Verify that the data came back via adb reverse.
- self.assertEqual(data, server.makefile().read())
+ self.assertEqual(data, server.makefile().read().encode("utf8"))
finally:
if reverse_setup:
self.device.reverse_remove(forward_spec)
@@ -268,7 +275,7 @@
Args:
shell_args: List of string arguments to `adb shell`.
- input: String input to send to the interactive shell.
+ input: bytes input to send to the interactive shell.
Returns:
The remote exit code.
@@ -286,7 +293,7 @@
# Closing host-side stdin doesn't trigger a PTY shell to exit so we need
# to explicitly add an exit command to close the session from the device
# side, plus the necessary newline to complete the interactive command.
- proc.communicate(input + '; exit\n')
+ proc.communicate(input + b'; exit\n')
return proc.returncode
def test_cat(self):
@@ -419,7 +426,7 @@
self.assertEqual('foo' + self.device.linesep, result[1])
self.assertEqual('bar' + self.device.linesep, result[2])
- self.assertEqual(17, self._interactive_shell([], 'exit 17'))
+ self.assertEqual(17, self._interactive_shell([], b'exit 17'))
# -x flag should disable shell protocol.
result = self.device.shell_nocheck(
@@ -428,7 +435,7 @@
self.assertEqual('foo{0}bar{0}'.format(self.device.linesep), result[1])
self.assertEqual('', result[2])
- self.assertEqual(0, self._interactive_shell(['-x'], 'exit 17'))
+ self.assertEqual(0, self._interactive_shell(['-x'], b'exit 17'))
def test_non_interactive_sigint(self):
"""Tests that SIGINT in a non-interactive shell kills the process.
@@ -447,7 +454,7 @@
self.device.adb_cmd + shlex.split('shell echo $$; sleep 60'),
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
- remote_pid = sleep_proc.stdout.readline().strip()
+ remote_pid = sleep_proc.stdout.readline().strip().decode("utf8")
self.assertIsNone(sleep_proc.returncode, 'subprocess terminated early')
proc_query = shlex.split('ps {0} | grep {0}'.format(remote_pid))
@@ -469,9 +476,10 @@
'on this device')
# Test both small and large inputs.
- small_input = 'foo'
- large_input = '\n'.join(c * 100 for c in (string.ascii_letters +
- string.digits))
+ small_input = b'foo'
+ characters = [c.encode("utf8") for c in string.ascii_letters + string.digits]
+ large_input = b'\n'.join(characters)
+
for input in (small_input, large_input):
proc = subprocess.Popen(self.device.adb_cmd + ['shell', 'cat'],
@@ -480,7 +488,7 @@
stderr=subprocess.PIPE)
stdout, stderr = proc.communicate(input)
self.assertEqual(input.splitlines(), stdout.splitlines())
- self.assertEqual('', stderr)
+ self.assertEqual(b'', stderr)
def test_sighup(self):
"""Ensure that SIGHUP gets sent upon non-interactive ctrl-c"""
@@ -502,7 +510,7 @@
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
- self.assertEqual("Waiting\n", process.stdout.readline())
+ self.assertEqual(b"Waiting\n", process.stdout.readline())
process.send_signal(signal.SIGINT)
process.wait()
@@ -533,7 +541,7 @@
threads.append(thread)
for thread in threads:
thread.join()
- for i, success in result.iteritems():
+ for i, success in result.items():
self.assertTrue(success)
def disabled_test_parallel(self):
@@ -546,24 +554,24 @@
n_procs = 2048
procs = dict()
- for i in xrange(0, n_procs):
+ for i in range(0, n_procs):
procs[i] = subprocess.Popen(
['adb', 'shell', 'read foo; echo $foo; read rc; exit $rc'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE
)
- for i in xrange(0, n_procs):
+ for i in range(0, n_procs):
procs[i].stdin.write("%d\n" % i)
- for i in xrange(0, n_procs):
+ for i in range(0, n_procs):
response = procs[i].stdout.readline()
assert(response == "%d\n" % i)
- for i in xrange(0, n_procs):
+ for i in range(0, n_procs):
procs[i].stdin.write("%d\n" % (i % 256))
- for i in xrange(0, n_procs):
+ for i in range(0, n_procs):
assert(procs[i].wait() == i % 256)
@@ -602,14 +610,14 @@
def test_install_argument_escaping(self):
"""Make sure that install argument escaping works."""
# http://b/20323053, http://b/3090932.
- for file_suffix in ('-text;ls;1.apk', "-Live Hold'em.apk"):
+ for file_suffix in (b'-text;ls;1.apk', b"-Live Hold'em.apk"):
tf = tempfile.NamedTemporaryFile('wb', suffix=file_suffix,
delete=False)
tf.close()
# Installing bogus .apks fails if the device supports exit codes.
try:
- output = self.device.install(tf.name)
+ output = self.device.install(tf.name.decode("utf8"))
except subprocess.CalledProcessError as e:
output = e.output
@@ -712,7 +720,7 @@
max_size = 16 * (1 << 10)
files = []
- for _ in xrange(num_files):
+ for _ in range(num_files):
file_handle = tempfile.NamedTemporaryFile(dir=in_dir, delete=False)
size = random.randrange(min_size, max_size, 1024)
@@ -731,7 +739,7 @@
max_size = 16 * (1 << 10)
files = []
- for file_num in xrange(num_files):
+ for file_num in range(num_files):
size = random.randrange(min_size, max_size, 1024)
base_name = prefix + str(file_num)
@@ -878,7 +886,7 @@
subdir_temp_files = make_random_host_files(in_dir=subdir,
num_files=4)
- paths = map(lambda temp_file: temp_file.full_path, temp_files)
+ paths = [x.full_path for x in temp_files]
paths.append(subdir)
self.device._simple_call(['push'] + paths + [self.DEVICE_TEMP_DIR])
@@ -907,7 +915,7 @@
Bug: http://b/26816782
"""
with tempfile.NamedTemporaryFile() as tmp_file:
- tmp_file.write('\0' * 1024 * 1024)
+ tmp_file.write(b'\0' * 1024 * 1024)
tmp_file.flush()
try:
self.device.push(local=tmp_file.name, remote='/system/')
@@ -915,8 +923,8 @@
except subprocess.CalledProcessError as e:
output = e.output
- self.assertTrue('Permission denied' in output or
- 'Read-only file system' in output)
+ self.assertTrue(b'Permission denied' in output or
+ b'Read-only file system' in output)
@requires_non_root
def test_push_directory_creation(self):
@@ -925,7 +933,7 @@
Bug: http://b/110953234
"""
with tempfile.NamedTemporaryFile() as tmp_file:
- tmp_file.write('\0' * 1024 * 1024)
+ tmp_file.write(b'\0' * 1024 * 1024)
tmp_file.flush()
remote_path = self.DEVICE_TEMP_DIR + '/test_push_directory_creation'
self.device.shell(['rm', '-rf', remote_path])
@@ -967,7 +975,7 @@
except subprocess.CalledProcessError as e:
output = e.output
- self.assertIn('Permission denied', output)
+ self.assertIn(b'Permission denied', output)
self.device.shell(['rm', '-f', self.DEVICE_TEMP_FILE])
@@ -1166,7 +1174,7 @@
subdir_temp_files = make_random_device_files(
self.device, in_dir=subdir, num_files=4, prefix='subdir_')
- paths = map(lambda temp_file: temp_file.full_path, temp_files)
+ paths = [x.full_path for x in temp_files]
paths.append(subdir)
self.device._simple_call(['pull'] + paths + [host_dir])
@@ -1355,7 +1363,7 @@
"""
# The values that trigger things are 507 (512 - 5 bytes from shell protocol) + 1024*n
# Probe some surrounding values as well, for the hell of it.
- for base in [512] + range(1024, 1024 * 16, 1024):
+ for base in [512] + list(range(1024, 1024 * 16, 1024)):
for offset in [-6, -5, -4]:
length = base + offset
cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
@@ -1390,10 +1398,10 @@
sock = socket.create_connection(("localhost", local_port))
with contextlib.closing(sock):
- bytesWritten = sock.send("a" * size)
+ bytesWritten = sock.send(b"a" * size)
self.assertEqual(size, bytesWritten)
readBytes = sock.recv(4096)
- self.assertEqual("foo\n", readBytes)
+ self.assertEqual(b"foo\n", readBytes)
thread.join()
finally:
@@ -1424,13 +1432,13 @@
s.sendall(adb_length_prefixed(transport_string))
response = s.recv(4)
- self.assertEquals(b"OKAY", response)
+ self.assertEqual(b"OKAY", response)
shell_string = "shell:sleep 0.5; dd if=/dev/zero bs=1m count=1 status=none; echo foo"
s.sendall(adb_length_prefixed(shell_string))
response = s.recv(4)
- self.assertEquals(b"OKAY", response)
+ self.assertEqual(b"OKAY", response)
# Spawn a thread that dumps garbage into the socket until failure.
def spam():
@@ -1453,7 +1461,7 @@
break
received += read
- self.assertEquals(1024 * 1024 + len("foo\n"), len(received))
+ self.assertEqual(1024 * 1024 + len("foo\n"), len(received))
thread.join()
diff --git a/base/expected_test.cpp b/base/expected_test.cpp
index 6c3d421..47e396a 100644
--- a/base/expected_test.cpp
+++ b/base/expected_test.cpp
@@ -408,11 +408,11 @@
TEST(Expected, testTest) {
exp_int e = 10;
- EXPECT_TRUE(e);
+ EXPECT_TRUE(e.ok());
EXPECT_TRUE(e.has_value());
exp_int e2 = unexpected(10);
- EXPECT_FALSE(e2);
+ EXPECT_FALSE(e2.ok());
EXPECT_FALSE(e2.has_value());
}
@@ -571,11 +571,11 @@
}
};
- EXPECT_FALSE(divide(10, 0));
+ EXPECT_FALSE(divide(10, 0).ok());
EXPECT_EQ("divide by zero", divide(10, 0).error().message);
EXPECT_EQ(-1, divide(10, 0).error().cause);
- EXPECT_TRUE(divide(10, 3));
+ EXPECT_TRUE(divide(10, 3).ok());
EXPECT_EQ(QR(3, 1), *divide(10, 3));
}
@@ -589,7 +589,7 @@
};
auto r = test(true);
- EXPECT_TRUE(r);
+ EXPECT_TRUE(r.ok());
EXPECT_EQ("yes", r->first);
}
@@ -603,9 +603,9 @@
};
auto r = test(true);
- EXPECT_TRUE(r);
+ EXPECT_TRUE(r.ok());
r = test(false);
- EXPECT_FALSE(r);
+ EXPECT_FALSE(r.ok());
EXPECT_EQ(10, r.error());
}
@@ -754,7 +754,7 @@
ConstructorTracker::Reset();
auto result1 = test("");
- ASSERT_TRUE(result1);
+ ASSERT_TRUE(result1.ok());
EXPECT_EQ("literal string", result1->string);
EXPECT_EQ(1U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -764,7 +764,7 @@
ConstructorTracker::Reset();
auto result2 = test("test2");
- ASSERT_TRUE(result2);
+ ASSERT_TRUE(result2.ok());
EXPECT_EQ("test2test22", result2->string);
EXPECT_EQ(1U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -774,7 +774,7 @@
ConstructorTracker::Reset();
auto result3 = test("test3");
- ASSERT_TRUE(result3);
+ ASSERT_TRUE(result3.ok());
EXPECT_EQ("test3 test3", result3->string);
EXPECT_EQ(1U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -786,22 +786,22 @@
TEST(Expected, testNested) {
expected<exp_string, std::string> e = "hello";
+ EXPECT_TRUE(e.ok());
EXPECT_TRUE(e.has_value());
EXPECT_TRUE(e.value().has_value());
- EXPECT_TRUE(e);
- EXPECT_TRUE(*e);
+ EXPECT_TRUE(e->ok());
EXPECT_EQ("hello", e.value().value());
expected<exp_string, std::string> e2 = unexpected("world");
EXPECT_FALSE(e2.has_value());
- EXPECT_FALSE(e2);
+ EXPECT_FALSE(e2.ok());
EXPECT_EQ("world", e2.error());
expected<exp_string, std::string> e3 = exp_string(unexpected("world"));
EXPECT_TRUE(e3.has_value());
EXPECT_FALSE(e3.value().has_value());
- EXPECT_TRUE(e3);
- EXPECT_FALSE(*e3);
+ EXPECT_TRUE(e3.ok());
+ EXPECT_FALSE(e3->ok());
EXPECT_EQ("world", e3.value().error());
}
diff --git a/base/include/android-base/expected.h b/base/include/android-base/expected.h
index 44e0b4a..9603bb1 100644
--- a/base/include/android-base/expected.h
+++ b/base/include/android-base/expected.h
@@ -331,6 +331,7 @@
constexpr explicit operator bool() const noexcept { return has_value(); }
constexpr bool has_value() const noexcept { return var_.index() == 0; }
+ constexpr bool ok() const noexcept { return has_value(); }
constexpr const T& value() const& { return std::get<T>(var_); }
constexpr T& value() & { return std::get<T>(var_); }
@@ -557,6 +558,7 @@
// observers
constexpr explicit operator bool() const noexcept { return has_value(); }
constexpr bool has_value() const noexcept { return var_.index() == 0; }
+ constexpr bool ok() const noexcept { return has_value(); }
constexpr void value() const& { if (!has_value()) std::get<0>(var_); }
diff --git a/base/include/android-base/result.h b/base/include/android-base/result.h
index b6d26e7..4a59552 100644
--- a/base/include/android-base/result.h
+++ b/base/include/android-base/result.h
@@ -156,11 +156,11 @@
Error& operator=(const Error&) = delete;
Error& operator=(Error&&) = delete;
- template <typename... Args>
- friend Error Errorf(const char* fmt, const Args&... args);
+ template <typename T, typename... Args>
+ friend Error ErrorfImpl(const T&& fmt, const Args&... args);
- template <typename... Args>
- friend Error ErrnoErrorf(const char* fmt, const Args&... args);
+ template <typename T, typename... Args>
+ friend Error ErrnoErrorfImpl(const T&& fmt, const Args&... args);
private:
Error(bool append_errno, int errno_to_append, const std::string& message)
@@ -191,18 +191,49 @@
return ErrorCode(code, args...);
}
-template <typename... Args>
-inline Error Errorf(const char* fmt, const Args&... args) {
+// TODO(tomcherry): Remove this once we've removed all `using android::base::Errorf` and `using
+// android::base::ErrnoErrorf` lines.
+enum Errorf {};
+enum ErrnoErrorf {};
+
+template <typename T, typename... Args>
+inline Error ErrorfImpl(const T&& fmt, const Args&... args) {
return Error(false, ErrorCode(0, args...), fmt::format(fmt, args...));
}
-template <typename... Args>
-inline Error ErrnoErrorf(const char* fmt, const Args&... args) {
+template <typename T, typename... Args>
+inline Error ErrnoErrorfImpl(const T&& fmt, const Args&... args) {
return Error(true, errno, fmt::format(fmt, args...));
}
+#define Errorf(fmt, ...) android::base::ErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
+#define ErrnoErrorf(fmt, ...) android::base::ErrnoErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
+
template <typename T>
using Result = android::base::expected<T, ResultError>;
+// Macros for testing the results of functions that return android::base::Result.
+// These also work with base::android::expected.
+
+#define CHECK_RESULT_OK(stmt) \
+ do { \
+ const auto& tmp = (stmt); \
+ CHECK(tmp.ok()) << tmp.error(); \
+ } while (0)
+
+#define ASSERT_RESULT_OK(stmt) \
+ do { \
+ const auto& tmp = (stmt); \
+ ASSERT_TRUE(tmp.ok()) << tmp.error(); \
+ } while (0)
+
+#define EXPECT_RESULT_OK(stmt) \
+ do { \
+ auto tmp = (stmt); \
+ EXPECT_TRUE(tmp.ok()) << tmp.error(); \
+ } while (0)
+
+// TODO: Maybe add RETURN_IF_ERROR() and ASSIGN_OR_RETURN()
+
} // namespace base
} // namespace android
diff --git a/base/result_test.cpp b/base/result_test.cpp
index 2ee4057..c0ac0fd 100644
--- a/base/result_test.cpp
+++ b/base/result_test.cpp
@@ -30,7 +30,7 @@
TEST(result, result_accessors) {
Result<std::string> result = "success";
- ASSERT_TRUE(result);
+ ASSERT_RESULT_OK(result);
ASSERT_TRUE(result.has_value());
EXPECT_EQ("success", *result);
@@ -40,7 +40,7 @@
}
TEST(result, result_accessors_rvalue) {
- ASSERT_TRUE(Result<std::string>("success"));
+ ASSERT_TRUE(Result<std::string>("success").ok());
ASSERT_TRUE(Result<std::string>("success").has_value());
EXPECT_EQ("success", *Result<std::string>("success"));
@@ -51,12 +51,12 @@
TEST(result, result_void) {
Result<void> ok = {};
- EXPECT_TRUE(ok);
+ EXPECT_RESULT_OK(ok);
ok.value(); // should not crash
ASSERT_DEATH(ok.error(), "");
Result<void> fail = Error() << "failure" << 1;
- EXPECT_FALSE(fail);
+ EXPECT_FALSE(fail.ok());
EXPECT_EQ("failure1", fail.error().message());
EXPECT_EQ(0, fail.error().code());
EXPECT_TRUE(ok != fail);
@@ -66,8 +66,8 @@
if (ok) return {};
else return Error() << "failure" << 1;
};
- EXPECT_TRUE(test(true));
- EXPECT_FALSE(test(false));
+ EXPECT_TRUE(test(true).ok());
+ EXPECT_FALSE(test(false).ok());
test(true).value(); // should not crash
ASSERT_DEATH(test(true).error(), "");
ASSERT_DEATH(test(false).value(), "");
@@ -76,7 +76,7 @@
TEST(result, result_error) {
Result<void> result = Error() << "failure" << 1;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
EXPECT_EQ(0, result.error().code());
@@ -85,7 +85,7 @@
TEST(result, result_error_empty) {
Result<void> result = Error();
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
EXPECT_EQ(0, result.error().code());
@@ -100,7 +100,7 @@
// create is.
auto MakeRvalueErrorResult = []() -> Result<void> { return Error() << "failure" << 1; };
- ASSERT_FALSE(MakeRvalueErrorResult());
+ ASSERT_FALSE(MakeRvalueErrorResult().ok());
ASSERT_FALSE(MakeRvalueErrorResult().has_value());
EXPECT_EQ(0, MakeRvalueErrorResult().error().code());
@@ -112,7 +112,7 @@
errno = test_errno;
Result<void> result = ErrnoError() << "failure" << 1;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
EXPECT_EQ(test_errno, result.error().code());
@@ -124,7 +124,7 @@
errno = test_errno;
Result<void> result = ErrnoError();
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
EXPECT_EQ(test_errno, result.error().code());
@@ -135,12 +135,12 @@
auto error_text = "test error"s;
Result<void> result = Error() << error_text;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
Result<std::string> result2 = result.error();
- ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.ok());
ASSERT_FALSE(result2.has_value());
EXPECT_EQ(0, result2.error().code());
@@ -151,12 +151,12 @@
auto error_text = "test error"s;
Result<void> result = Error() << error_text;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
Result<std::string> result2 = Error() << result.error();
- ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.ok());
ASSERT_FALSE(result2.has_value());
EXPECT_EQ(0, result2.error().code());
@@ -171,12 +171,12 @@
errno = 0;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_FALSE(result.has_value());
Result<std::string> result2 = Error() << result.error();
- ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.ok());
ASSERT_FALSE(result2.has_value());
EXPECT_EQ(test_errno, result2.error().code());
@@ -186,7 +186,7 @@
TEST(result, constructor_forwarding) {
auto result = Result<std::string>(std::in_place, 5, 'a');
- ASSERT_TRUE(result);
+ ASSERT_RESULT_OK(result);
ASSERT_TRUE(result.has_value());
EXPECT_EQ("aaaaa", *result);
@@ -254,7 +254,7 @@
// are called.
auto result1 = ReturnConstructorTracker("");
- ASSERT_TRUE(result1);
+ ASSERT_RESULT_OK(result1);
EXPECT_EQ("literal string", result1->string);
EXPECT_EQ(1U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -263,7 +263,7 @@
EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
auto result2 = ReturnConstructorTracker("test2");
- ASSERT_TRUE(result2);
+ ASSERT_RESULT_OK(result2);
EXPECT_EQ("test2test22", result2->string);
EXPECT_EQ(2U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -272,7 +272,7 @@
EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
auto result3 = ReturnConstructorTracker("test3");
- ASSERT_TRUE(result3);
+ ASSERT_RESULT_OK(result3);
EXPECT_EQ("test3 test3", result3->string);
EXPECT_EQ(3U, ConstructorTracker::constructor_called);
EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
@@ -287,11 +287,11 @@
TEST(result, result_result_with_success) {
auto return_result_result_with_success = []() -> Result<Result<void>> { return Result<void>(); };
auto result = return_result_result_with_success();
- ASSERT_TRUE(result);
- ASSERT_TRUE(*result);
+ ASSERT_RESULT_OK(result);
+ ASSERT_RESULT_OK(*result);
auto inner_result = result.value();
- ASSERT_TRUE(inner_result);
+ ASSERT_RESULT_OK(inner_result);
}
TEST(result, result_result_with_failure) {
@@ -299,8 +299,8 @@
return Result<void>(ResultError("failure string", 6));
};
auto result = return_result_result_with_error();
- ASSERT_TRUE(result);
- ASSERT_FALSE(*result);
+ ASSERT_RESULT_OK(result);
+ ASSERT_FALSE(result->ok());
EXPECT_EQ("failure string", (*result).error().message());
EXPECT_EQ(6, (*result).error().code());
}
@@ -320,7 +320,7 @@
};
auto result = return_test_struct();
- ASSERT_TRUE(result);
+ ASSERT_RESULT_OK(result);
EXPECT_EQ(36, result->value_);
}
@@ -344,13 +344,13 @@
errno = 1;
int old_errno = errno;
Result<int> result = Error() << "Failed" << SetErrnoToTwo<char>;
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
EXPECT_EQ(old_errno, errno);
errno = 1;
old_errno = errno;
Result<int> result2 = ErrnoError() << "Failed" << SetErrnoToTwo<char>;
- ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.ok());
EXPECT_EQ(old_errno, errno);
EXPECT_EQ(old_errno, result2.error().code());
}
@@ -362,7 +362,7 @@
result = Errorf("{} {}!", std::string("hello"), std::string("world"));
EXPECT_EQ("hello world!", result.error().message());
- result = Errorf("{h} {w}!", fmt::arg("w", "world"), fmt::arg("h", "hello"));
+ result = Errorf("{1} {0}!", "world", "hello");
EXPECT_EQ("hello world!", result.error().message());
result = Errorf("hello world!");
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 6b8a09a..9ffe5dd 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -32,6 +32,8 @@
#include <memory>
#include <regex>
#include <string>
+#include <string_view>
+#include <unordered_map>
#include <utility>
#include <vector>
@@ -50,16 +52,133 @@
namespace {
+struct AtomInfo {
+ int32_t atom;
+ int32_t event;
+};
+
+// Maps BootEvent used inside bootstat into statsd atom defined in
+// frameworks/base/cmds/statsd/src/atoms.proto.
+const std::unordered_map<std::string_view, AtomInfo> kBootEventToAtomInfo = {
+ // ELAPSED_TIME
+ {"ro.boottime.init",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ANDROID_INIT_STAGE_1}},
+ {"boot_complete",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE}},
+ {"boot_decryption_complete",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE_ENCRYPTION}},
+ {"boot_complete_no_encryption",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE_NO_ENCRYPTION}},
+ {"boot_complete_post_decrypt",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE_POST_DECRYPT}},
+ {"factory_reset_boot_complete",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE}},
+ {"factory_reset_boot_complete_no_encryption",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::
+ BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION}},
+ {"factory_reset_boot_complete_post_decrypt",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::
+ BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT}},
+ {"ota_boot_complete",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE}},
+ {"ota_boot_complete_no_encryption",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE_NO_ENCRYPTION}},
+ {"ota_boot_complete_post_decrypt",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE_POST_DECRYPT}},
+ {"post_decrypt_time_elapsed",
+ {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__POST_DECRYPT}},
+ // DURATION
+ {"absolute_boot_time",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__ABSOLUTE_BOOT_TIME}},
+ {"boottime.bootloader.1BLE",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_EXEC}},
+ {"boottime.bootloader.1BLL",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_LOAD}},
+ {"boottime.bootloader.KL",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_KERNEL_LOAD}},
+ {"boottime.bootloader.2BLE",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_EXEC}},
+ {"boottime.bootloader.2BLL",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_LOAD}},
+ {"boottime.bootloader.SW",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_UI_WAIT}},
+ {"boottime.bootloader.total",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_TOTAL}},
+ {"boottime.init.cold_boot_wait",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__COLDBOOT_WAIT}},
+ {"time_since_factory_reset",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__FACTORY_RESET_TIME_SINCE_RESET}},
+ {"ro.boottime.init.first_stage",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__ANDROID_INIT_STAGE_1}},
+ {"ro.boottime.init.selinux",
+ {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
+ android::util::BOOT_TIME_EVENT_DURATION__EVENT__SELINUX_INIT}},
+ // UTC_TIME
+ {"factory_reset",
+ {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RESET_TIME}},
+ {"factory_reset_current_time",
+ {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME}},
+ {"factory_reset_record_value",
+ {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
+ android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE}},
+ // ERROR_CODE
+ {"factory_reset_current_time_failure",
+ {android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED,
+ android::util::BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE}},
+};
+
// Scans the boot event record store for record files and logs each boot event
// via EventLog.
void LogBootEvents() {
BootEventRecordStore boot_event_store;
-
auto events = boot_event_store.GetAllBootEvents();
- // TODO(b/148575354): Replace with statsd.
- // for (auto i = events.cbegin(); i != events.cend(); ++i) {
- // android::metricslogger::LogHistogram(i->first, i->second);
- // }
+ std::vector<std::string_view> notSupportedEvents;
+ for (const auto& event : events) {
+ const auto& name = event.first;
+ const auto& info = kBootEventToAtomInfo.find(name);
+ if (info != kBootEventToAtomInfo.end()) {
+ if (info->second.atom == android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED) {
+ android::util::stats_write(static_cast<int32_t>(info->second.atom),
+ static_cast<int32_t>(info->second.event),
+ static_cast<int32_t>(event.second));
+ } else {
+ android::util::stats_write(static_cast<int32_t>(info->second.atom),
+ static_cast<int32_t>(info->second.event),
+ static_cast<int64_t>(event.second));
+ }
+ } else {
+ notSupportedEvents.push_back(name);
+ }
+ }
+ if (!notSupportedEvents.empty()) {
+ LOG(WARNING) << "LogBootEvents, atomInfo not defined for events:"
+ << android::base::Join(notSupportedEvents, ',');
+ }
}
// Records the named boot |event| to the record store. If |value| is non-empty
@@ -1250,10 +1369,13 @@
time_t current_time_utc = time(nullptr);
if (current_time_utc < 0) {
- // TODO(b/148575354): Replace with statsd.
// UMA does not display negative values in buckets, so convert to positive.
- // android::metricslogger::LogHistogram("factory_reset_current_time_failure",
- // std::abs(current_time_utc));
+ // Logging via BootEventRecordStore.
+ android::util::stats_write(
+ static_cast<int32_t>(android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED),
+ static_cast<int32_t>(
+ android::util::BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE),
+ static_cast<int32_t>(std::abs(current_time_utc)));
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
@@ -1261,8 +1383,11 @@
std::abs(current_time_utc));
return;
} else {
- // TODO(b/148575354): Replace with statsd.
- // android::metricslogger::LogHistogram("factory_reset_current_time", current_time_utc);
+ android::util::stats_write(
+ static_cast<int32_t>(android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
+ static_cast<int32_t>(
+ android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME),
+ static_cast<int64_t>(current_time_utc));
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
@@ -1282,8 +1407,11 @@
// Calculate and record the difference in time between now and the
// factory_reset time.
time_t factory_reset_utc = record.second;
- // TODO(b/148575354): Replace with statsd.
- // android::metricslogger::LogHistogram("factory_reset_record_value", factory_reset_utc);
+ android::util::stats_write(
+ static_cast<int32_t>(android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
+ static_cast<int32_t>(
+ android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE),
+ static_cast<int64_t>(factory_reset_utc));
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
diff --git a/fastboot/constants.h b/fastboot/constants.h
index aefd448..ba43ca5 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -42,7 +42,7 @@
#define RESPONSE_INFO "INFO"
#define FB_COMMAND_SZ 64
-#define FB_RESPONSE_SZ 64
+#define FB_RESPONSE_SZ 256
#define FB_VAR_VERSION "version"
#define FB_VAR_VERSION_BOOTLOADER "version-bootloader"
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index b9784fe..d9167e7 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -227,13 +227,6 @@
TEST_F(LogicalPartitionCompliance, FastbootRebootTest) {
ASSERT_TRUE(UserSpaceFastboot());
- GTEST_LOG_(INFO) << "Rebooting to bootloader mode";
- // Test 'fastboot reboot bootloader' from fastbootd
- fb->RebootTo("bootloader");
-
- // Test fastboot reboot fastboot from bootloader
- ReconnectFastbootDevice();
- ASSERT_FALSE(UserSpaceFastboot());
GTEST_LOG_(INFO) << "Rebooting back to fastbootd mode";
fb->RebootTo("fastboot");
@@ -268,23 +261,6 @@
GTEST_LOG_(INFO) << "Flashing a logical partition..";
EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), SUCCESS)
<< "flash logical -partition failed";
- GTEST_LOG_(INFO) << "Rebooting to bootloader mode";
- // Reboot to bootloader mode and attempt to flash the logical partitions
- fb->RebootTo("bootloader");
-
- ReconnectFastbootDevice();
- ASSERT_FALSE(UserSpaceFastboot());
- GTEST_LOG_(INFO) << "Attempt to flash a logical partition..";
- EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), DEVICE_FAIL)
- << "flash logical partition must fail in bootloader";
- GTEST_LOG_(INFO) << "Rebooting back to fastbootd mode";
- fb->RebootTo("fastboot");
-
- ReconnectFastbootDevice();
- ASSERT_TRUE(UserSpaceFastboot());
- GTEST_LOG_(INFO) << "Testing 'fastboot delete-logical-partition' command";
- EXPECT_EQ(fb->DeletePartition(test_partition_name), SUCCESS)
- << "delete logical-partition failed";
}
// Conformance tests
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 60e3226..705d4e3 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -11,6 +11,9 @@
},
{
"name": "fiemap_writer_test"
+ },
+ {
+ "name": "vts_libsnapshot_test_presubmit"
}
]
}
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index 1297cf9..5d504ab 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -342,7 +342,7 @@
// or a string indicating multiple keys separated by ':'.
std::vector<std::string> allowed_avb_keys;
auto list_avb_keys_in_dir = ListFiles(fstab_entry.avb_keys);
- if (list_avb_keys_in_dir) {
+ if (list_avb_keys_in_dir.ok()) {
std::sort(list_avb_keys_in_dir->begin(), list_avb_keys_in_dir->end());
allowed_avb_keys = *list_avb_keys_in_dir;
} else {
diff --git a/fs_mgr/libfs_avb/tests/util_test.cpp b/fs_mgr/libfs_avb/tests/util_test.cpp
index e64282b..5c388aa 100644
--- a/fs_mgr/libfs_avb/tests/util_test.cpp
+++ b/fs_mgr/libfs_avb/tests/util_test.cpp
@@ -232,8 +232,7 @@
// List files for comparison.
auto result = ListFiles(test_dir.value());
- ASSERT_TRUE(result);
- ASSERT_TRUE(result.has_value());
+ ASSERT_RESULT_OK(result);
auto files = result.value();
EXPECT_EQ(3UL, files.size());
// Sort them offline for comparison.
@@ -266,8 +265,7 @@
// List files for comparison.
auto result = ListFiles(test_dir.value());
- ASSERT_TRUE(result);
- ASSERT_TRUE(result.has_value());
+ ASSERT_RESULT_OK(result);
auto files = result.value();
EXPECT_EQ(2UL, files.size()); // Should not include the symlink file.
// Sort them offline for comparison.
@@ -287,7 +285,7 @@
base::FilePath no_such_dir = tmp_dir.Append("not_such_dir");
auto fail = ListFiles(no_such_dir.value());
- ASSERT_FALSE(fail);
+ ASSERT_FALSE(fail.ok());
EXPECT_EQ(ENOENT, fail.error().code());
EXPECT_TRUE(android::base::StartsWith(fail.error().message(), "Failed to opendir: "));
}
@@ -303,8 +301,7 @@
// List files without sorting.
auto result = ListFiles(test_dir.value());
- ASSERT_TRUE(result);
- ASSERT_TRUE(result.has_value());
+ ASSERT_RESULT_OK(result);
auto files = result.value();
EXPECT_EQ(0UL, files.size());
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index c58101a..adfee1d 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -160,8 +160,8 @@
],
}
-cc_test {
- name: "libsnapshot_test",
+cc_defaults {
+ name: "libsnapshot_test_defaults",
defaults: ["libsnapshot_defaults"],
srcs: [
"partition_cow_creator_test.cpp",
@@ -173,10 +173,7 @@
"android.hardware.boot@1.1",
"libbinder",
"libcrypto",
- "libfs_mgr",
- "libgsi",
"libhidlbase",
- "liblp",
"libprotobuf-cpp-lite",
"libsparse",
"libutils",
@@ -186,16 +183,38 @@
"libutilscallstack",
],
static_libs: [
+ "libfs_mgr",
+ "libgsi",
"libgmock",
+ "liblp",
"libsnapshot",
"libsnapshot_test_helpers",
],
header_libs: [
"libstorage_literals_headers",
],
+ test_suites: [
+ "vts-core",
+ "device-tests"
+ ],
+ test_min_api_level: 29,
+ auto_gen_config: true,
require_root: true,
}
+cc_test {
+ name: "vts_libsnapshot_test",
+ defaults: ["libsnapshot_test_defaults"],
+}
+
+cc_test {
+ name: "vts_libsnapshot_test_presubmit",
+ defaults: ["libsnapshot_test_defaults"],
+ cppflags: [
+ "-DSKIP_TEST_IN_PRESUBMIT",
+ ],
+}
+
cc_binary {
name: "snapshotctl",
srcs: [
@@ -211,7 +230,6 @@
"android.hardware.boot@1.1",
"libbase",
"libbinder",
- "libbinderthreadstate",
"libext2_uuid",
"libext4_utils",
"libfs_mgr_binder",
diff --git a/fs_mgr/libsnapshot/device_info.cpp b/fs_mgr/libsnapshot/device_info.cpp
index bacb41c..0e90100 100644
--- a/fs_mgr/libsnapshot/device_info.cpp
+++ b/fs_mgr/libsnapshot/device_info.cpp
@@ -22,6 +22,7 @@
namespace snapshot {
#ifdef LIBSNAPSHOT_USE_HAL
+using android::hardware::boot::V1_0::BoolResult;
using android::hardware::boot::V1_0::CommandResult;
#endif
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index e786bc9..ed92dd7 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -174,6 +174,7 @@
// See InitiateMerge() and ProcessUpdateState() for details.
// Returns:
// - None if no merge to initiate
+ // - Unverified if called on the source slot
// - MergeCompleted if merge is completed
// - other states indicating an error has occurred
UpdateState InitiateMergeAndWait();
@@ -273,6 +274,7 @@
FRIEND_TEST(SnapshotTest, UpdateBootControlHal);
FRIEND_TEST(SnapshotUpdateTest, DataWipeAfterRollback);
FRIEND_TEST(SnapshotUpdateTest, DataWipeRollbackInRecovery);
+ FRIEND_TEST(SnapshotUpdateTest, FullUpdateFlow);
FRIEND_TEST(SnapshotUpdateTest, MergeCannotRemoveCow);
FRIEND_TEST(SnapshotUpdateTest, MergeInRecovery);
FRIEND_TEST(SnapshotUpdateTest, SnapshotStatusFileWithoutCow);
@@ -374,7 +376,7 @@
bool HandleCancelledUpdate(LockedFile* lock);
// Helper for HandleCancelledUpdate. Assumes booting from new slot.
- bool HandleCancelledUpdateOnNewSlot(LockedFile* lock);
+ bool AreAllSnapshotsCancelled(LockedFile* lock);
// Remove artifacts created by the update process, such as snapshots, and
// set the update state to None.
@@ -439,7 +441,7 @@
std::string GetSnapshotStatusFilePath(const std::string& name);
std::string GetSnapshotBootIndicatorPath();
- void RemoveSnapshotBootIndicator();
+ std::string GetRollbackIndicatorPath();
// Return the name of the device holding the "snapshot" or "snapshot-merge"
// target. This may not be the final device presented via MapSnapshot(), if
@@ -503,6 +505,8 @@
friend std::ostream& operator<<(std::ostream& os, SnapshotManager::Slot slot);
Slot GetCurrentSlot();
+ std::string ReadUpdateSourceSlotSuffix();
+
std::string gsid_dir_;
std::string metadata_dir_;
std::unique_ptr<IDeviceInfo> device_;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 63a9302..a937b43 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -188,11 +188,19 @@
return true;
}
-SnapshotManager::Slot SnapshotManager::GetCurrentSlot() {
+std::string SnapshotManager::ReadUpdateSourceSlotSuffix() {
auto boot_file = GetSnapshotBootIndicatorPath();
std::string contents;
if (!android::base::ReadFileToString(boot_file, &contents)) {
PLOG(WARNING) << "Cannot read " << boot_file;
+ return {};
+ }
+ return contents;
+}
+
+SnapshotManager::Slot SnapshotManager::GetCurrentSlot() {
+ auto contents = ReadUpdateSourceSlotSuffix();
+ if (contents.empty()) {
return Slot::Unknown;
}
if (device_->GetSlotSuffix() == contents) {
@@ -201,6 +209,15 @@
return Slot::Target;
}
+static bool RemoveFileIfExists(const std::string& path) {
+ std::string message;
+ if (!android::base::RemoveFileIfExists(path, &message)) {
+ LOG(ERROR) << "Remove failed: " << path << ": " << message;
+ return false;
+ }
+ return true;
+}
+
bool SnapshotManager::RemoveAllUpdateState(LockedFile* lock) {
LOG(INFO) << "Removing all update state.";
@@ -223,7 +240,13 @@
return false;
}
- RemoveSnapshotBootIndicator();
+ // It's okay if these fail - first-stage init performs a deeper check after
+ // reading the indicator file, so it's not a problem if it still exists
+ // after the update completes.
+ std::vector<std::string> files = {GetSnapshotBootIndicatorPath(), GetRollbackIndicatorPath()};
+ for (const auto& file : files) {
+ RemoveFileIfExists(file);
+ }
// If this fails, we'll keep trying to remove the update state (as the
// device reboots or starts a new update) until it finally succeeds.
@@ -250,6 +273,13 @@
return false;
}
+ // This file is written on boot to detect whether a rollback occurred. It
+ // MUST NOT exist before rebooting, otherwise, we're at risk of deleting
+ // snapshots too early.
+ if (!RemoveFileIfExists(GetRollbackIndicatorPath())) {
+ return false;
+ }
+
// This file acts as both a quick indicator for init (it can use access(2)
// to decide how to do first-stage mounts), and it stores the old slot, so
// we can tell whether or not we performed a rollback.
@@ -966,14 +996,8 @@
return metadata_dir_ + "/" + android::base::Basename(kBootIndicatorPath);
}
-void SnapshotManager::RemoveSnapshotBootIndicator() {
- // It's okay if this fails - first-stage init performs a deeper check after
- // reading the indicator file, so it's not a problem if it still exists
- // after the update completes.
- auto boot_file = GetSnapshotBootIndicatorPath();
- if (unlink(boot_file.c_str()) == -1 && errno != ENOENT) {
- PLOG(ERROR) << "unlink " << boot_file;
- }
+std::string SnapshotManager::GetRollbackIndicatorPath() {
+ return metadata_dir_ + "/rollback-indicator";
}
void SnapshotManager::AcknowledgeMergeSuccess(LockedFile* lock) {
@@ -1144,25 +1168,18 @@
if (slot == Slot::Unknown) {
return false;
}
- if (slot == Slot::Target) {
- // We're booted into the target slot, which means we just rebooted
- // after applying the update.
- if (!HandleCancelledUpdateOnNewSlot(lock)) {
- return false;
- }
+
+ // If all snapshots were reflashed, then cancel the entire update.
+ if (AreAllSnapshotsCancelled(lock)) {
+ RemoveAllUpdateState(lock);
+ return true;
}
- // The only way we can get here is if:
- // (1) The device rolled back to the previous slot.
- // (2) This function was called prematurely before rebooting the device.
- // (3) fastboot set_active was used.
- // (4) The device updates to the new slot but re-flashed *all* partitions
- // in the new slot.
- //
- // In any case, delete the snapshots. It may be worth using the boot_control
- // HAL to differentiate case (2).
- RemoveAllUpdateState(lock);
- return true;
+ // This unverified update might be rolled back, or it might not (b/147347110
+ // comment #77). Take no action, as update_engine is responsible for deciding
+ // whether to cancel.
+ LOG(ERROR) << "Update state is being processed before reboot, taking no action.";
+ return false;
}
std::unique_ptr<LpMetadata> SnapshotManager::ReadCurrentMetadata() {
@@ -1187,7 +1204,7 @@
return MetadataPartitionState::Flashed;
}
-bool SnapshotManager::HandleCancelledUpdateOnNewSlot(LockedFile* lock) {
+bool SnapshotManager::AreAllSnapshotsCancelled(LockedFile* lock) {
std::vector<std::string> snapshots;
if (!ListSnapshots(lock, &snapshots)) {
LOG(WARNING) << "Failed to list snapshots to determine whether device has been flashed "
@@ -1196,35 +1213,45 @@
return true;
}
+ auto source_slot_suffix = ReadUpdateSourceSlotSuffix();
+ if (source_slot_suffix.empty()) {
+ return false;
+ }
+ uint32_t source_slot = SlotNumberForSlotSuffix(source_slot_suffix);
+ uint32_t target_slot = (source_slot == 0) ? 1 : 0;
+
// Attempt to detect re-flashing on each partition.
// - If all partitions are re-flashed, we can proceed to cancel the whole update.
// - If only some of the partitions are re-flashed, snapshots for re-flashed partitions are
// deleted. Caller is responsible for merging the rest of the snapshots.
// - If none of the partitions are re-flashed, caller is responsible for merging the snapshots.
- auto metadata = ReadCurrentMetadata();
- if (!metadata) return false;
- bool all_snapshot_cancelled = true;
+ //
+ // Note that we use target slot metadata, since if an OTA has been applied
+ // to the target slot, we can detect the UPDATED flag. Any kind of flash
+ // operation against dynamic partitions ensures that all copies of the
+ // metadata are in sync, so flashing all partitions on the source slot will
+ // remove the UPDATED flag on the target slot as well.
+ const auto& opener = device_->GetPartitionOpener();
+ auto super_device = device_->GetSuperDevice(target_slot);
+ auto metadata = android::fs_mgr::ReadMetadata(opener, super_device, target_slot);
+ if (!metadata) {
+ return false;
+ }
+
+ bool all_snapshots_cancelled = true;
for (const auto& snapshot_name : snapshots) {
if (GetMetadataPartitionState(*metadata, snapshot_name) ==
MetadataPartitionState::Updated) {
- LOG(WARNING) << "Cannot cancel update because snapshot" << snapshot_name
- << " is in use.";
- all_snapshot_cancelled = false;
+ all_snapshots_cancelled = false;
continue;
}
// Delete snapshots for partitions that are re-flashed after the update.
- LOG(INFO) << "Detected re-flashing of partition " << snapshot_name << ".";
- if (!DeleteSnapshot(lock, snapshot_name)) {
- // This is an error, but it is okay to leave the snapshot in the short term.
- // However, if all_snapshot_cancelled == false after exiting the loop, caller may
- // initiate merge for this unused snapshot, which is likely to fail.
- LOG(WARNING) << "Failed to delete snapshot for re-flashed partition " << snapshot_name;
- }
+ LOG(WARNING) << "Detected re-flashing of partition " << snapshot_name << ".";
}
- if (!all_snapshot_cancelled) return false;
-
- LOG(INFO) << "All partitions are re-flashed after update, removing all update states.";
- return true;
+ if (all_snapshots_cancelled) {
+ LOG(WARNING) << "All partitions are re-flashed after update, removing all update states.";
+ }
+ return all_snapshots_cancelled;
}
bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) {
@@ -1344,7 +1371,16 @@
// the reason be clearer? Because the indicator file still exists, and
// if this was FATAL, reverting to the old slot would be broken.
auto slot = GetCurrentSlot();
+
if (slot != Slot::Target) {
+ if (slot == Slot::Source && !device_->IsRecovery()) {
+ // Device is rebooting into the original slot, so mark this as a
+ // rollback.
+ auto path = GetRollbackIndicatorPath();
+ if (!android::base::WriteStringToFile("1", path)) {
+ PLOG(ERROR) << "Unable to write rollback indicator: " << path;
+ }
+ }
LOG(INFO) << "Not booting from new slot. Will not mount snapshots.";
return false;
}
@@ -2370,6 +2406,10 @@
return state;
}
if (state == UpdateState::Unverified) {
+ if (GetCurrentSlot() != Slot::Target) {
+ LOG(INFO) << "Cannot merge until device reboots.";
+ return state;
+ }
if (!InitiateMerge()) {
LOG(ERROR) << "Failed to initiate merge.";
return state;
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index c5ad44c..d87274d 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -447,6 +447,9 @@
auto sm = SnapshotManager::NewForFirstStageMount(info);
ASSERT_NE(sm, nullptr);
ASSERT_FALSE(sm->NeedSnapshotsInFirstStageMount());
+
+ auto indicator = sm->GetRollbackIndicatorPath();
+ ASSERT_EQ(access(indicator.c_str(), R_OK), 0);
}
TEST_F(SnapshotTest, Merge) {
@@ -503,6 +506,9 @@
}
TEST_F(SnapshotTest, FirstStageMountAndMerge) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
ASSERT_TRUE(AcquireLock());
static const uint64_t kDeviceSize = 1024 * 1024;
@@ -559,6 +565,9 @@
}
TEST_F(SnapshotTest, FlashSuperDuringMerge) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
ASSERT_TRUE(AcquireLock());
static const uint64_t kDeviceSize = 1024 * 1024;
@@ -970,6 +979,9 @@
// Also test UnmapUpdateSnapshot unmaps everything.
// Also test first stage mount and merge after this.
TEST_F(SnapshotUpdateTest, FullUpdateFlow) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
// OTA client blindly unmaps all partitions that are possibly mapped.
for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
@@ -1015,6 +1027,9 @@
ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
+ auto indicator = sm->GetRollbackIndicatorPath();
+ ASSERT_NE(access(indicator.c_str(), R_OK), 0);
+
// Check that the target partitions have the same content.
for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
ASSERT_TRUE(IsPartitionUnchanged(name));
@@ -1114,6 +1129,9 @@
// Test that the old partitions are not modified.
TEST_F(SnapshotUpdateTest, TestRollback) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
// Execute the update.
ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->UnmapUpdateSnapshot("sys_b"));
@@ -1291,6 +1309,9 @@
}
TEST_F(SnapshotUpdateTest, MergeCannotRemoveCow) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
// Make source partitions as big as possible to force COW image to be created.
SetSize(sys_, 5_MiB);
SetSize(vnd_, 5_MiB);
@@ -1565,6 +1586,9 @@
}
TEST_F(SnapshotUpdateTest, WaitForMerge) {
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ GTEST_SKIP() << "WIP failure b/148889015";
+#endif
AddOperationForPartitions();
// Execute the update.
@@ -1681,9 +1705,11 @@
ASSERT_NE(nullptr, flashed_builder->FindPartition("prd" + flashed_slot_suffix));
flashed_builder->RemovePartition("prd" + flashed_slot_suffix);
+ // Note that fastbootd always updates the partition table of both slots.
auto flashed_metadata = flashed_builder->Export();
ASSERT_NE(nullptr, flashed_metadata);
- ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, flashed_slot));
+ ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 0));
+ ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 1));
std::string path;
for (const auto& name : {"sys", "vnd"}) {
@@ -1782,6 +1808,10 @@
std::vector<uint64_t> ret;
for (uint64_t size = 1_MiB; size <= 512_MiB; size *= 2) {
ret.push_back(size);
+#ifdef SKIP_TEST_IN_PRESUBMIT
+ // BUG(148889015);
+ break;
+#endif
}
return ret;
}
diff --git a/fs_mgr/libsnapshot/snapshotctl.cpp b/fs_mgr/libsnapshot/snapshotctl.cpp
index 9f23c45..d724be3 100644
--- a/fs_mgr/libsnapshot/snapshotctl.cpp
+++ b/fs_mgr/libsnapshot/snapshotctl.cpp
@@ -112,7 +112,9 @@
auto state = SnapshotManager::New()->InitiateMergeAndWait();
- if (state == UpdateState::None) {
+ // We could wind up in the Unverified state if the device rolled back or
+ // hasn't fully rebooted. Ignore this.
+ if (state == UpdateState::None || state == UpdateState::Unverified) {
return true;
}
if (state == UpdateState::MergeCompleted) {
diff --git a/fs_mgr/libvbmeta/builder.cpp b/fs_mgr/libvbmeta/builder.cpp
index a901a4f..e6576ce 100644
--- a/fs_mgr/libvbmeta/builder.cpp
+++ b/fs_mgr/libvbmeta/builder.cpp
@@ -40,18 +40,18 @@
Result<void> SuperVBMetaBuilder::Build() {
for (const auto& [vbmeta_name, file_path] : images_path_) {
Result<std::string> content = ReadVBMetaImageFromFile(file_path);
- if (!content) {
+ if (!content.ok()) {
return content.error();
}
Result<uint8_t> vbmeta_index = AddVBMetaImage(vbmeta_name);
- if (!vbmeta_index) {
+ if (!vbmeta_index.ok()) {
return vbmeta_index.error();
}
Result<void> rv_export_vbmeta_image =
ExportVBMetaImageToFile(vbmeta_index.value(), content.value());
- if (!rv_export_vbmeta_image) {
+ if (!rv_export_vbmeta_image.ok()) {
return rv_export_vbmeta_image;
}
}
@@ -65,7 +65,7 @@
}
Result<uint64_t> file_size = GetFileSize(source_fd);
- if (!file_size) {
+ if (!file_size.ok()) {
return file_size.error();
}
@@ -98,7 +98,7 @@
slot_number = desc->vbmeta_index;
} else {
Result<uint8_t> new_slot = GetEmptySlot();
- if (!new_slot) {
+ if (!new_slot.ok()) {
return new_slot;
}
slot_number = new_slot.value();
@@ -162,7 +162,7 @@
android::base::Result<void> rv_write_primary_vbmeta_table =
WritePrimaryVBMetaTable(super_vbmeta_fd_, serialized_table);
- if (!rv_write_primary_vbmeta_table) {
+ if (!rv_write_primary_vbmeta_table.ok()) {
return rv_write_primary_vbmeta_table;
}
@@ -175,7 +175,7 @@
const std::string& vbmeta_image) {
Result<void> rv_write_vbmeta_image =
WriteVBMetaImage(super_vbmeta_fd_, vbmeta_index, vbmeta_image);
- if (!rv_write_vbmeta_image) {
+ if (!rv_write_vbmeta_image.ok()) {
return rv_write_vbmeta_image;
}
@@ -196,13 +196,13 @@
SuperVBMetaBuilder builder(super_vbmeta_fd, images_path);
Result<void> rv_build = builder.Build();
- if (!rv_build) {
+ if (!rv_build.ok()) {
LERROR << rv_build.error();
return false;
}
Result<void> rv_export = builder.ExportVBMetaTableToFile();
- if (!rv_export) {
+ if (!rv_export.ok()) {
LERROR << rv_export.error();
return false;
}
@@ -211,4 +211,4 @@
}
} // namespace fs_mgr
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/fs_mgr/libvbmeta/builder_test.cpp b/fs_mgr/libvbmeta/builder_test.cpp
index 9a015fd..487bece 100644
--- a/fs_mgr/libvbmeta/builder_test.cpp
+++ b/fs_mgr/libvbmeta/builder_test.cpp
@@ -26,24 +26,20 @@
std::unique_ptr<SuperVBMetaBuilder> builder = std::make_unique<SuperVBMetaBuilder>();
ASSERT_NE(builder, nullptr);
- Result<uint8_t> vbmeta_index = builder->AddVBMetaImage("vbmeta" /* vbmeta_name */
- );
- EXPECT_TRUE(vbmeta_index);
+ Result<uint8_t> vbmeta_index = builder->AddVBMetaImage("vbmeta" /* vbmeta_name */);
+ EXPECT_RESULT_OK(vbmeta_index);
- Result<uint8_t> vbmeta_system_slot = builder->AddVBMetaImage("vbmeta_system" /* vbmeta_name */
- );
- EXPECT_TRUE(vbmeta_system_slot);
+ Result<uint8_t> vbmeta_system_slot = builder->AddVBMetaImage("vbmeta_system" /* vbmeta_name */);
+ EXPECT_RESULT_OK(vbmeta_system_slot);
- Result<uint8_t> vbmeta_vendor_slot = builder->AddVBMetaImage("vbmeta_vendor" /* vbmeta_name */
- );
- EXPECT_TRUE(vbmeta_vendor_slot);
+ Result<uint8_t> vbmeta_vendor_slot = builder->AddVBMetaImage("vbmeta_vendor" /* vbmeta_name */);
+ EXPECT_RESULT_OK(vbmeta_vendor_slot);
- builder->DeleteVBMetaImage("vbmeta_system" /* vbmeta_name */
- );
+ builder->DeleteVBMetaImage("vbmeta_system" /* vbmeta_name */);
- Result<uint8_t> vbmeta_product_slot = builder->AddVBMetaImage("vbmeta_product" /* vbmeta_name */
- );
- EXPECT_TRUE(vbmeta_product_slot);
+ Result<uint8_t> vbmeta_product_slot =
+ builder->AddVBMetaImage("vbmeta_product" /* vbmeta_name */);
+ EXPECT_RESULT_OK(vbmeta_product_slot);
std::unique_ptr<VBMetaTable> table = builder->ExportVBMetaTable();
ASSERT_NE(table, nullptr);
@@ -77,4 +73,4 @@
for (int i = 0; i < sizeof(table->descriptors[2].reserved); i++)
EXPECT_EQ(table->descriptors[2].reserved[i], 0);
EXPECT_EQ(table->descriptors[2].vbmeta_name, "vbmeta_product");
-}
\ No newline at end of file
+}
diff --git a/fs_mgr/libvbmeta/reader.cpp b/fs_mgr/libvbmeta/reader.cpp
index 212d186..7b5ed93 100644
--- a/fs_mgr/libvbmeta/reader.cpp
+++ b/fs_mgr/libvbmeta/reader.cpp
@@ -64,7 +64,7 @@
}
Result<void> rv_header = LoadAndVerifySuperVBMetaHeader(header_buffer.get(), &table->header);
- if (!rv_header) {
+ if (!rv_header.ok()) {
return rv_header;
}
@@ -104,7 +104,7 @@
Result<void> ValidateVBMetaImage(int super_vbmeta_fd, int vbmeta_index,
const std::string& vbmeta_image) {
Result<std::string> content = ReadVBMetaImage(super_vbmeta_fd, vbmeta_index);
- if (!content) {
+ if (!content.ok()) {
return content.error();
}
diff --git a/fs_mgr/libvbmeta/super_vbmeta_test.cpp b/fs_mgr/libvbmeta/super_vbmeta_test.cpp
index 6b4fc5d..daed0d1 100644
--- a/fs_mgr/libvbmeta/super_vbmeta_test.cpp
+++ b/fs_mgr/libvbmeta/super_vbmeta_test.cpp
@@ -77,7 +77,7 @@
android::base::unique_fd fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
EXPECT_GT(fd, 0);
Result<uint64_t> file_size = GetFileSize(fd);
- EXPECT_TRUE(file_size);
+ EXPECT_RESULT_OK(file_size);
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(VBMETA_IMAGE_MAX_SIZE);
EXPECT_TRUE(android::base::ReadFully(fd, buffer.get(), file_size.value()));
return std::string(reinterpret_cast<char*>(buffer.get()), VBMETA_IMAGE_MAX_SIZE);
@@ -138,15 +138,15 @@
// Check the size of vbmeta table
Result<uint64_t> super_vbmeta_size = GetFileSize(fd);
- EXPECT_TRUE(super_vbmeta_size);
+ EXPECT_RESULT_OK(super_vbmeta_size);
EXPECT_EQ(super_vbmeta_size.value(),
SUPER_VBMETA_TABLE_MAX_SIZE * 2 + VBMETA_IMAGE_MAX_SIZE * 3);
// Check Primary vbmeta table is equal to Backup one
VBMetaTable table;
- EXPECT_TRUE(android::fs_mgr::ReadPrimaryVBMetaTable(fd, &table));
+ EXPECT_RESULT_OK(android::fs_mgr::ReadPrimaryVBMetaTable(fd, &table));
VBMetaTable table_backup;
- EXPECT_TRUE(android::fs_mgr::ReadBackupVBMetaTable(fd, &table_backup));
+ EXPECT_RESULT_OK(android::fs_mgr::ReadBackupVBMetaTable(fd, &table_backup));
EXPECT_EQ(android::fs_mgr::SerializeVBMetaTable(table),
android::fs_mgr::SerializeVBMetaTable(table_backup));
@@ -167,25 +167,25 @@
EXPECT_EQ(table.descriptors[0].vbmeta_name_length, 14);
EXPECT_EQ(table.descriptors[0].vbmeta_name, "vbmeta_product");
Result<std::string> vbmeta_product_content = ReadVBMetaImage(fd, 0);
- EXPECT_TRUE(vbmeta_product_content);
+ EXPECT_RESULT_OK(vbmeta_product_content);
EXPECT_EQ(ReadVBMetaImageFromFile(vbmeta_product_path), vbmeta_product_content.value());
EXPECT_EQ(table.descriptors[1].vbmeta_index, 1);
EXPECT_EQ(table.descriptors[1].vbmeta_name_length, 13);
EXPECT_EQ(table.descriptors[1].vbmeta_name, "vbmeta_system");
Result<std::string> vbmeta_system_content = ReadVBMetaImage(fd, 1);
- EXPECT_TRUE(vbmeta_system_content);
+ EXPECT_RESULT_OK(vbmeta_system_content);
EXPECT_EQ(ReadVBMetaImageFromFile(vbmeta_system_path), vbmeta_system_content.value());
EXPECT_EQ(table.descriptors[2].vbmeta_index, 2);
EXPECT_EQ(table.descriptors[2].vbmeta_name_length, 13);
EXPECT_EQ(table.descriptors[2].vbmeta_name, "vbmeta_vendor");
Result<std::string> vbmeta_vendor_content = ReadVBMetaImage(fd, 2);
- EXPECT_TRUE(vbmeta_vendor_content);
+ EXPECT_RESULT_OK(vbmeta_vendor_content);
EXPECT_EQ(ReadVBMetaImageFromFile(vbmeta_vendor_path), vbmeta_vendor_content.value());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/init/Android.bp b/init/Android.bp
index 42d0b33..f28934e 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -14,6 +14,61 @@
// limitations under the License.
//
+init_common_sources = [
+ "action.cpp",
+ "action_manager.cpp",
+ "action_parser.cpp",
+ "capabilities.cpp",
+ "epoll.cpp",
+ "import_parser.cpp",
+ "interface_utils.cpp",
+ "keychords.cpp",
+ "parser.cpp",
+ "property_type.cpp",
+ "rlimit_parser.cpp",
+ "service.cpp",
+ "service_list.cpp",
+ "service_parser.cpp",
+ "service_utils.cpp",
+ "subcontext.cpp",
+ "subcontext.proto",
+ "tokenizer.cpp",
+ "util.cpp",
+]
+init_device_sources = [
+ "bootchart.cpp",
+ "builtins.cpp",
+ "devices.cpp",
+ "firmware_handler.cpp",
+ "first_stage_init.cpp",
+ "first_stage_mount.cpp",
+ "fscrypt_init_extensions.cpp",
+ "init.cpp",
+ "lmkd_service.cpp",
+ "modalias_handler.cpp",
+ "mount_handler.cpp",
+ "mount_namespace.cpp",
+ "persistent_properties.cpp",
+ "persistent_properties.proto",
+ "property_service.cpp",
+ "property_service.proto",
+ "reboot.cpp",
+ "reboot_utils.cpp",
+ "security.cpp",
+ "selabel.cpp",
+ "selinux.cpp",
+ "sigchld_handler.cpp",
+ "switch_root.cpp",
+ "uevent_listener.cpp",
+ "ueventd.cpp",
+ "ueventd_parser.cpp",
+]
+init_host_sources = [
+ "check_builtins.cpp",
+ "host_import_parser.cpp",
+ "host_init_verifier.cpp",
+]
+
cc_defaults {
name: "init_defaults",
cpp_std: "experimental",
@@ -103,53 +158,7 @@
"init_defaults",
"selinux_policy_version",
],
- srcs: [
- "action.cpp",
- "action_manager.cpp",
- "action_parser.cpp",
- "bootchart.cpp",
- "builtins.cpp",
- "capabilities.cpp",
- "devices.cpp",
- "epoll.cpp",
- "firmware_handler.cpp",
- "first_stage_init.cpp",
- "first_stage_mount.cpp",
- "fscrypt_init_extensions.cpp",
- "import_parser.cpp",
- "init.cpp",
- "interface_utils.cpp",
- "keychords.cpp",
- "lmkd_service.cpp",
- "modalias_handler.cpp",
- "mount_handler.cpp",
- "mount_namespace.cpp",
- "parser.cpp",
- "persistent_properties.cpp",
- "persistent_properties.proto",
- "property_service.cpp",
- "property_service.proto",
- "property_type.cpp",
- "reboot.cpp",
- "reboot_utils.cpp",
- "security.cpp",
- "selabel.cpp",
- "selinux.cpp",
- "service.cpp",
- "service_list.cpp",
- "service_parser.cpp",
- "service_utils.cpp",
- "sigchld_handler.cpp",
- "subcontext.cpp",
- "subcontext.proto",
- "switch_root.cpp",
- "rlimit_parser.cpp",
- "tokenizer.cpp",
- "uevent_listener.cpp",
- "ueventd.cpp",
- "ueventd_parser.cpp",
- "util.cpp",
- ],
+ srcs: init_common_sources + init_device_sources,
whole_static_libs: [
"libcap",
"com.android.sysprop.apex",
@@ -297,30 +306,7 @@
"libprocessgroup",
"libprotobuf-cpp-lite",
],
- srcs: [
- "action.cpp",
- "action_manager.cpp",
- "action_parser.cpp",
- "capabilities.cpp",
- "check_builtins.cpp",
- "epoll.cpp",
- "keychords.cpp",
- "import_parser.cpp",
- "interface_utils.cpp",
- "host_import_parser.cpp",
- "host_init_verifier.cpp",
- "parser.cpp",
- "property_type.cpp",
- "rlimit_parser.cpp",
- "tokenizer.cpp",
- "service.cpp",
- "service_list.cpp",
- "service_parser.cpp",
- "service_utils.cpp",
- "subcontext.cpp",
- "subcontext.proto",
- "util.cpp",
- ],
+ srcs: init_common_sources + init_host_sources,
proto: {
type: "lite",
},
diff --git a/init/action.cpp b/init/action.cpp
index f05fa7c..1e998ae 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -36,7 +36,7 @@
builtin_arguments.args[0] = args[0];
for (std::size_t i = 1; i < args.size(); ++i) {
auto expanded_arg = ExpandProps(args[i]);
- if (!expanded_arg) {
+ if (!expanded_arg.ok()) {
return expanded_arg.error();
}
builtin_arguments.args[i] = std::move(*expanded_arg);
@@ -59,7 +59,7 @@
}
auto expanded_args = subcontext->ExpandArgs(args_);
- if (!expanded_args) {
+ if (!expanded_args.ok()) {
return expanded_args.error();
}
return RunBuiltinFunction(func_, *expanded_args, subcontext->context());
@@ -75,7 +75,7 @@
builtin_arguments.args[0] = args_[0];
for (size_t i = 1; i < args_.size(); ++i) {
auto expanded_arg = ExpandProps(args_[i]);
- if (!expanded_arg) {
+ if (!expanded_arg.ok()) {
if (expanded_arg.error().message().find("doesn't exist while expanding") !=
std::string::npos) {
// If we failed because we won't have a property, use an empty string, which is
@@ -114,7 +114,7 @@
}
auto map_result = function_map_->Find(args);
- if (!map_result) {
+ if (!map_result.ok()) {
return Error() << map_result.error();
}
@@ -134,7 +134,7 @@
size_t Action::CheckAllCommands() const {
size_t failures = 0;
for (const auto& command : commands_) {
- if (auto result = command.CheckCommand(); !result) {
+ if (auto result = command.CheckCommand(); !result.ok()) {
LOG(ERROR) << "Command '" << command.BuildCommandString() << "' (" << filename_ << ":"
<< command.line() << ") failed: " << result.error();
++failures;
@@ -169,7 +169,7 @@
LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
<< ":" << command.line() << ") took " << duration.count() << "ms and "
- << (result ? "succeeded" : "failed: " + result.error().message());
+ << (result.ok() ? "succeeded" : "failed: " + result.error().message());
}
}
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index a8e1e09..f316871 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -110,14 +110,14 @@
if (!args[i].compare(0, prop_str.length(), prop_str)) {
if (auto result = ParsePropertyTrigger(args[i], subcontext, property_triggers);
- !result) {
+ !result.ok()) {
return result;
}
} else {
if (!event_trigger->empty()) {
return Error() << "multiple event triggers are not allowed";
}
- if (auto result = ValidateEventTrigger(args[i]); !result) {
+ if (auto result = ValidateEventTrigger(args[i]); !result.ok()) {
return result;
}
@@ -145,8 +145,9 @@
std::string event_trigger;
std::map<std::string, std::string> property_triggers;
- if (auto result = ParseTriggers(triggers, action_subcontext, &event_trigger, &property_triggers);
- !result) {
+ if (auto result =
+ ParseTriggers(triggers, action_subcontext, &event_trigger, &property_triggers);
+ !result.ok()) {
return Error() << "ParseTriggers() failed: " << result.error();
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 742e089..200bfff 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -164,7 +164,7 @@
// They must be started individually.
for (const auto& service : ServiceList::GetInstance()) {
if (service->classnames().count(args[1])) {
- if (auto result = service->StartIfNotDisabled(); !result) {
+ if (auto result = service->StartIfNotDisabled(); !result.ok()) {
LOG(ERROR) << "Could not start service '" << service->name()
<< "' as part of class '" << args[1] << "': " << result.error();
}
@@ -186,7 +186,7 @@
}
for (const auto& service : ServiceList::GetInstance()) {
if (service->classnames().count(args[1])) {
- if (auto result = service->StartIfPostData(); !result) {
+ if (auto result = service->StartIfPostData(); !result.ok()) {
LOG(ERROR) << "Could not start service '" << service->name()
<< "' as part of class '" << args[1] << "': " << result.error();
}
@@ -227,7 +227,7 @@
}
static Result<void> do_domainname(const BuiltinArguments& args) {
- if (auto result = WriteFile("/proc/sys/kernel/domainname", args[1]); !result) {
+ if (auto result = WriteFile("/proc/sys/kernel/domainname", args[1]); !result.ok()) {
return Error() << "Unable to write to /proc/sys/kernel/domainname: " << result.error();
}
return {};
@@ -237,7 +237,7 @@
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "Could not find service";
- if (auto result = svc->Enable(); !result) {
+ if (auto result = svc->Enable(); !result.ok()) {
return Error() << "Could not enable service: " << result.error();
}
@@ -246,10 +246,10 @@
static Result<void> do_exec(const BuiltinArguments& args) {
auto service = Service::MakeTemporaryOneshotService(args.args);
- if (!service) {
+ if (!service.ok()) {
return Error() << "Could not create exec service: " << service.error();
}
- if (auto result = (*service)->ExecStart(); !result) {
+ if (auto result = (*service)->ExecStart(); !result.ok()) {
return Error() << "Could not start exec service: " << result.error();
}
@@ -259,10 +259,10 @@
static Result<void> do_exec_background(const BuiltinArguments& args) {
auto service = Service::MakeTemporaryOneshotService(args.args);
- if (!service) {
+ if (!service.ok()) {
return Error() << "Could not create exec background service: " << service.error();
}
- if (auto result = (*service)->Start(); !result) {
+ if (auto result = (*service)->Start(); !result.ok()) {
return Error() << "Could not start exec background service: " << result.error();
}
@@ -276,7 +276,7 @@
return Error() << "Service not found";
}
- if (auto result = service->ExecStart(); !result) {
+ if (auto result = service->ExecStart(); !result.ok()) {
return Error() << "Could not start exec service: " << result.error();
}
@@ -291,7 +291,7 @@
}
static Result<void> do_hostname(const BuiltinArguments& args) {
- if (auto result = WriteFile("/proc/sys/kernel/hostname", args[1]); !result) {
+ if (auto result = WriteFile("/proc/sys/kernel/hostname", args[1]); !result.ok()) {
return Error() << "Unable to write to /proc/sys/kernel/hostname: " << result.error();
}
return {};
@@ -349,7 +349,7 @@
static Result<void> do_interface_start(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
if (!svc) return Error() << "interface " << args[1] << " not found";
- if (auto result = svc->Start(); !result) {
+ if (auto result = svc->Start(); !result.ok()) {
return Error() << "Could not start interface: " << result.error();
}
return {};
@@ -413,7 +413,7 @@
// mkdir <path> [mode] [owner] [group] [<option> ...]
static Result<void> do_mkdir(const BuiltinArguments& args) {
auto options = ParseMkdir(args.args);
- if (!options) return options.error();
+ if (!options.ok()) return options.error();
return make_dir_with_options(*options);
}
@@ -681,7 +681,7 @@
* and return processed return code*/
initial_mount_fstab_return_code = mount_fstab_return_code;
auto queue_fs_result = queue_fs_event(mount_fstab_return_code, false);
- if (!queue_fs_result) {
+ if (!queue_fs_result.ok()) {
return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
}
}
@@ -731,7 +731,7 @@
static Result<void> do_setrlimit(const BuiltinArguments& args) {
auto rlimit = ParseRlimit(args.args);
- if (!rlimit) return rlimit.error();
+ if (!rlimit.ok()) return rlimit.error();
if (setrlimit(rlimit->first, &rlimit->second) == -1) {
return ErrnoError() << "setrlimit failed";
@@ -742,7 +742,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";
- if (auto result = svc->Start(); !result) {
+ if (auto result = svc->Start(); !result.ok()) {
return ErrorIgnoreEnoent() << "Could not start service: " << result.error();
}
return {};
@@ -846,7 +846,7 @@
}
static Result<void> do_write(const BuiltinArguments& args) {
- if (auto result = WriteFile(args[1], args[2]); !result) {
+ if (auto result = WriteFile(args[1], args[2]); !result.ok()) {
return ErrorIgnoreEnoent()
<< "Unable to write to file '" << args[1] << "': " << result.error();
}
@@ -904,7 +904,7 @@
}
android::base::Timer t;
if (S_ISREG(sb.st_mode)) {
- if (auto result = readahead_file(args[1], readfully); !result) {
+ if (auto result = readahead_file(args[1], readfully); !result.ok()) {
LOG(WARNING) << "Unable to readahead '" << args[1] << "': " << result.error();
_exit(EXIT_FAILURE);
}
@@ -921,7 +921,7 @@
ftsent = fts_read(fts.get())) {
if (ftsent->fts_info & FTS_F) {
const std::string filename = ftsent->fts_accpath;
- if (auto result = readahead_file(filename, readfully); !result) {
+ if (auto result = readahead_file(filename, readfully); !result.ok()) {
LOG(WARNING)
<< "Unable to readahead '" << filename << "': " << result.error();
}
@@ -938,10 +938,10 @@
static Result<void> do_copy(const BuiltinArguments& args) {
auto file_contents = ReadFile(args[1]);
- if (!file_contents) {
+ if (!file_contents.ok()) {
return Error() << "Could not read input file '" << args[1] << "': " << file_contents.error();
}
- if (auto result = WriteFile(args[2], *file_contents); !result) {
+ if (auto result = WriteFile(args[2], *file_contents); !result.ok()) {
return Error() << "Could not write to output file '" << args[2] << "': " << result.error();
}
@@ -950,7 +950,7 @@
static Result<void> do_chown(const BuiltinArguments& args) {
auto uid = DecodeUid(args[1]);
- if (!uid) {
+ if (!uid.ok()) {
return Error() << "Unable to decode UID for '" << args[1] << "': " << uid.error();
}
@@ -960,7 +960,7 @@
if (args.size() == 4) {
gid = DecodeUid(args[2]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to decode GID for '" << args[2] << "': " << gid.error();
}
}
@@ -995,7 +995,7 @@
static Result<void> do_restorecon(const BuiltinArguments& args) {
auto restorecon_info = ParseRestorecon(args.args);
- if (!restorecon_info) {
+ if (!restorecon_info.ok()) {
return restorecon_info.error();
}
@@ -1103,7 +1103,7 @@
static Result<void> ExecWithFunctionOnFailure(const std::vector<std::string>& args,
std::function<void(const std::string&)> function) {
auto service = Service::MakeTemporaryOneshotService(args);
- if (!service) {
+ if (!service.ok()) {
function("MakeTemporaryOneshotService failed: " + service.error().message());
}
(*service)->AddReapCallback([function](const siginfo_t& siginfo) {
@@ -1111,7 +1111,7 @@
function(StringPrintf("Exec service failed, status %d", siginfo.si_status));
}
});
- if (auto result = (*service)->ExecStart(); !result) {
+ if (auto result = (*service)->ExecStart(); !result.ok()) {
function("ExecStart failed: " + result.error().message());
}
ServiceList::GetInstance().AddService(std::move(*service));
@@ -1133,7 +1133,7 @@
LOG(ERROR) << message << ": Rebooting into recovery, reason: " << reboot_reason;
if (auto result = reboot_into_recovery(
{"--prompt_and_wipe_data", "--reason="s + reboot_reason});
- !result) {
+ !result.ok()) {
LOG(FATAL) << "Could not reboot into recovery: " << result.error();
}
} else {
@@ -1162,7 +1162,7 @@
if (auto rc = fs_mgr_remount_userdata_into_checkpointing(&fstab); rc < 0) {
trigger_shutdown("reboot,mount_userdata_failed");
}
- if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result) {
+ if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result.ok()) {
return Error() << "queue_fs_event() failed: " << result.error();
}
return {};
@@ -1285,16 +1285,16 @@
static Result<void> do_perform_apex_config(const BuiltinArguments& args) {
auto create_dirs = create_apex_data_dirs();
- if (!create_dirs) {
+ if (!create_dirs.ok()) {
return create_dirs.error();
}
auto parse_configs = parse_apex_configs();
- if (!parse_configs) {
+ if (!parse_configs.ok()) {
return parse_configs.error();
}
auto update_linker_config = do_update_linker_config(args);
- if (!update_linker_config) {
+ if (!update_linker_config.ok()) {
return update_linker_config.error();
}
@@ -1309,17 +1309,6 @@
}
}
-static Result<void> do_finish_userspace_reboot(const BuiltinArguments&) {
- LOG(INFO) << "Userspace reboot successfully finished";
- boot_clock::time_point now = boot_clock::now();
- SetProperty("sys.init.userspace_reboot.last_finished",
- std::to_string(now.time_since_epoch().count()));
- if (!android::sysprop::InitProperties::userspace_reboot_in_progress(false)) {
- return Error() << "Failed to set sys.init.userspace_reboot.in_progress property";
- }
- return {};
-}
-
// Builtin-function-map start
const BuiltinFunctionMap& GetBuiltinFunctionMap() {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@@ -1341,7 +1330,6 @@
{"exec_background", {1, kMax, {false, do_exec_background}}},
{"exec_start", {1, 1, {false, do_exec_start}}},
{"export", {2, 2, {false, do_export}}},
- {"finish_userspace_reboot", {0, 0, {false, do_finish_userspace_reboot}}},
{"hostname", {1, 1, {true, do_hostname}}},
{"ifup", {1, 1, {true, do_ifup}}},
{"init_user0", {0, 0, {false, do_init_user0}}},
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index bef6966..d62ecb0 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -52,7 +52,7 @@
Result<void> check_chown(const BuiltinArguments& args) {
if (!args[1].empty()) {
auto uid = DecodeUid(args[1]);
- if (!uid) {
+ if (!uid.ok()) {
return Error() << "Unable to decode UID for '" << args[1] << "': " << uid.error();
}
}
@@ -60,7 +60,7 @@
// GID is optional and pushes the index of path out by one if specified.
if (args.size() == 4 && !args[2].empty()) {
auto gid = DecodeUid(args[2]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to decode GID for '" << args[2] << "': " << gid.error();
}
}
@@ -72,7 +72,7 @@
ReturnIfAnyArgsEmpty();
auto result = Service::MakeTemporaryOneshotService(args.args);
- if (!result) {
+ if (!result.ok()) {
return result.error();
}
@@ -93,7 +93,7 @@
}
Result<void> check_interface_restart(const BuiltinArguments& args) {
- if (auto result = IsKnownInterface(args[1]); !result) {
+ if (auto result = IsKnownInterface(args[1]); !result.ok()) {
return result.error();
}
return {};
@@ -124,7 +124,7 @@
Result<void> check_mkdir(const BuiltinArguments& args) {
auto options = ParseMkdir(args.args);
- if (!options) {
+ if (!options.ok()) {
return options.error();
}
return {};
@@ -134,7 +134,7 @@
ReturnIfAnyArgsEmpty();
auto restorecon_info = ParseRestorecon(args.args);
- if (!restorecon_info) {
+ if (!restorecon_info.ok()) {
return restorecon_info.error();
}
@@ -157,7 +157,7 @@
}
if (!value.empty()) {
- if (auto result = IsLegalPropertyValue(name, value); !result) {
+ if (auto result = IsLegalPropertyValue(name, value); !result.ok()) {
return result.error();
}
}
@@ -189,7 +189,7 @@
ReturnIfAnyArgsEmpty();
auto rlimit = ParseRlimit(args.args);
- if (!rlimit) return rlimit.error();
+ if (!rlimit.ok()) return rlimit.error();
return {};
}
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 1dce2d5..dff7b69 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -165,7 +165,7 @@
auto result =
RunExternalHandler(external_handler.handler_path, external_handler.uid, uevent);
- if (!result) {
+ if (!result.ok()) {
LOG(ERROR) << "Using default firmware; External firmware handler failed: "
<< result.error();
return uevent.firmware;
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index 22de846..0bd4df4 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -248,7 +248,7 @@
}
auto interface_inheritance_hierarchy_map = ReadInterfaceInheritanceHierarchy();
- if (!interface_inheritance_hierarchy_map) {
+ if (!interface_inheritance_hierarchy_map.ok()) {
LOG(ERROR) << interface_inheritance_hierarchy_map.error();
return EXIT_FAILURE;
}
diff --git a/init/import_parser.cpp b/init/import_parser.cpp
index 1a43508..e4b25ca 100644
--- a/init/import_parser.cpp
+++ b/init/import_parser.cpp
@@ -30,7 +30,7 @@
}
auto conf_file = ExpandProps(args[1]);
- if (!conf_file) {
+ if (!conf_file.ok()) {
return Error() << "Could not expand import: " << conf_file.error();
}
diff --git a/init/init.cpp b/init/init.cpp
index 10701da..5bf1b36 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -237,7 +237,7 @@
auto restart_time = s->time_started() + s->restart_period();
if (boot_clock::now() > restart_time) {
- if (auto result = s->Start(); !result) {
+ if (auto result = s->Start(); !result.ok()) {
LOG(ERROR) << "Could not restart process '" << s->name() << "': " << result.error();
}
} else {
@@ -333,7 +333,7 @@
return false;
}
- if (auto result = function.action(svc); !result) {
+ if (auto result = function.action(svc); !result.ok()) {
LOG(ERROR) << "Control message: Could not ctl." << msg << " for '" << name
<< "' from pid: " << pid << " (" << process_cmdline << "): " << result.error();
return false;
@@ -478,7 +478,7 @@
PLOG(FATAL) << "failed to create signalfd";
}
- if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result) {
+ if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
LOG(FATAL) << result.error();
}
}
@@ -499,7 +499,7 @@
found = true;
LOG(INFO) << "Starting service '" << svc->name() << "' from keychord "
<< android::base::Join(keycodes, ' ');
- if (auto result = svc->Start(); !result) {
+ if (auto result = svc->Start(); !result.ok()) {
LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord "
<< android::base::Join(keycodes, ' ') << ": " << result.error();
}
@@ -558,7 +558,7 @@
void SendLoadPersistentPropertiesMessage() {
auto init_message = InitMessage{};
init_message.set_load_persistent_properties(true);
- if (auto result = SendMessage(property_fd, init_message); !result) {
+ if (auto result = SendMessage(property_fd, init_message); !result.ok()) {
LOG(ERROR) << "Failed to send load persistent properties message: " << result.error();
}
}
@@ -566,7 +566,7 @@
void SendStopSendingMessagesMessage() {
auto init_message = InitMessage{};
init_message.set_stop_sending_messages(true);
- if (auto result = SendMessage(property_fd, init_message); !result) {
+ if (auto result = SendMessage(property_fd, init_message); !result.ok()) {
LOG(ERROR) << "Failed to send 'stop sending messages' message: " << result.error();
}
}
@@ -574,14 +574,14 @@
void SendStartSendingMessagesMessage() {
auto init_message = InitMessage{};
init_message.set_start_sending_messages(true);
- if (auto result = SendMessage(property_fd, init_message); !result) {
+ if (auto result = SendMessage(property_fd, init_message); !result.ok()) {
LOG(ERROR) << "Failed to send 'start sending messages' message: " << result.error();
}
}
static void HandlePropertyFd() {
auto message = ReadMessage(property_fd);
- if (!message) {
+ if (!message.ok()) {
LOG(ERROR) << "Could not read message from property service: " << message.error();
return;
}
@@ -636,7 +636,7 @@
// Set init and its forked children's oom_adj.
if (auto result =
WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST));
- !result) {
+ !result.ok()) {
LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST
<< " to /proc/1/oom_score_adj: " << result.error();
}
@@ -679,14 +679,14 @@
SelinuxRestoreContext();
Epoll epoll;
- if (auto result = epoll.Open(); !result) {
+ if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
InstallSignalFdHandler(&epoll);
StartPropertyService(&property_fd);
- if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) {
+ if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result.ok()) {
LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error();
}
@@ -797,7 +797,7 @@
}
auto pending_functions = epoll.Wait(epoll_timeout);
- if (!pending_functions) {
+ if (!pending_functions.ok()) {
LOG(ERROR) << pending_functions.error();
} else if (!pending_functions->empty()) {
// We always reap children before responding to the other pending functions. This is to
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 9f63e4f..caf3e03 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -204,9 +204,9 @@
"execute 3";
// clang-format on
// WriteFile() ensures the right mode is set
- ASSERT_TRUE(WriteFile(std::string(dir.path) + "/a.rc", dir_a_script));
+ ASSERT_RESULT_OK(WriteFile(std::string(dir.path) + "/a.rc", dir_a_script));
- ASSERT_TRUE(WriteFile(std::string(dir.path) + "/b.rc", "on boot\nexecute 5"));
+ ASSERT_RESULT_OK(WriteFile(std::string(dir.path) + "/b.rc", "on boot\nexecute 5"));
// clang-format off
std::string start_script = "import " + std::string(first_import.path) + "\n"
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 5f2682b..adec383 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -187,7 +187,7 @@
LambdaCheck();
}
if (auto result = epoll_->RegisterHandler(fd, [this, fd]() { this->LambdaHandler(fd); });
- !result) {
+ !result.ok()) {
LOG(WARNING) << "Could not register keychord epoll handler: " << result.error();
return false;
}
@@ -272,7 +272,7 @@
if (inotify_fd_ >= 0) {
if (auto result =
epoll_->RegisterHandler(inotify_fd_, [this]() { this->InotifyHandler(); });
- !result) {
+ !result.ok()) {
LOG(WARNING) << "Could not register keychord epoll handler: " << result.error();
}
}
diff --git a/init/keychords_test.cpp b/init/keychords_test.cpp
index 6e9b337..8a333a2 100644
--- a/init/keychords_test.cpp
+++ b/init/keychords_test.cpp
@@ -204,7 +204,7 @@
TestFrame::TestFrame(const std::vector<const std::vector<int>>& chords, EventHandler* ev)
: ev_(ev) {
- if (!epoll_.Open()) return;
+ if (!epoll_.Open().ok()) return;
for (const auto& keycodes : chords) keychords_.Register(keycodes);
keychords_.Start(&epoll_, [this](const std::vector<int>& keycodes) {
this->keycodes_.emplace_back(keycodes);
@@ -213,7 +213,7 @@
void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
auto pending_functions = epoll_.Wait(wait);
- ASSERT_TRUE(pending_functions) << pending_functions.error();
+ ASSERT_RESULT_OK(pending_functions);
for (const auto& function : *pending_functions) {
(*function)();
}
diff --git a/init/mount_handler.cpp b/init/mount_handler.cpp
index 0e4e024..01abba8 100644
--- a/init/mount_handler.cpp
+++ b/init/mount_handler.cpp
@@ -116,7 +116,7 @@
if (!fp_) PLOG(FATAL) << "Could not open /proc/mounts";
auto result = epoll->RegisterHandler(
fileno(fp_.get()), [this]() { this->MountHandlerFunction(); }, EPOLLERR | EPOLLPRI);
- if (!result) LOG(FATAL) << result.error();
+ if (!result.ok()) LOG(FATAL) << result.error();
}
MountHandler::~MountHandler() {
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index 1a474fb..0749fe3 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -141,12 +141,12 @@
if (entry->d_type == DT_DIR) {
const std::string apex_path = from_dir + "/" + entry->d_name;
const auto apex_name = GetApexName(apex_path);
- if (!apex_name) {
+ if (!apex_name.ok()) {
LOG(ERROR) << apex_path << " is not an APEX directory: " << apex_name.error();
continue;
}
const std::string mount_path = to_dir + "/" + (*apex_name);
- if (auto result = MountDir(apex_path, mount_path); !result) {
+ if (auto result = MountDir(apex_path, mount_path); !result.ok()) {
return result;
}
}
@@ -168,7 +168,7 @@
};
for (const auto& dir : kBuiltinDirsForApexes) {
- if (auto result = ActivateFlattenedApexesFrom(dir, kApexTop); !result) {
+ if (auto result = ActivateFlattenedApexesFrom(dir, kApexTop); !result.ok()) {
LOG(ERROR) << result.error();
return false;
}
@@ -295,7 +295,7 @@
return false;
}
- if (auto result = MountLinkerConfigForDefaultNamespace(); !result) {
+ if (auto result = MountLinkerConfigForDefaultNamespace(); !result.ok()) {
LOG(ERROR) << result.error();
return false;
}
diff --git a/init/parser.cpp b/init/parser.cpp
index 6ab61cb..507ee4a 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -61,7 +61,7 @@
bad_section_found = false;
if (section_parser == nullptr) return;
- if (auto result = section_parser->EndSection(); !result) {
+ if (auto result = section_parser->EndSection(); !result.ok()) {
parse_error_count_++;
LOG(ERROR) << filename << ": " << section_start_line << ": " << result.error();
}
@@ -92,7 +92,7 @@
if (line_callback != line_callbacks_.end()) {
end_section();
- if (auto result = line_callback->second(std::move(args)); !result) {
+ if (auto result = line_callback->second(std::move(args)); !result.ok()) {
parse_error_count_++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
}
@@ -101,8 +101,8 @@
section_parser = section_parsers_[args[0]].get();
section_start_line = state.line;
if (auto result =
- section_parser->ParseSection(std::move(args), filename, state.line);
- !result) {
+ section_parser->ParseSection(std::move(args), filename, state.line);
+ !result.ok()) {
parse_error_count_++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
section_parser = nullptr;
@@ -110,7 +110,7 @@
}
} else if (section_parser) {
if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
- !result) {
+ !result.ok()) {
parse_error_count_++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
}
@@ -143,7 +143,7 @@
LOG(INFO) << "Parsing file " << path << "...";
android::base::Timer t;
auto config_contents = ReadFile(path);
- if (!config_contents) {
+ if (!config_contents.ok()) {
LOG(INFO) << "Unable to read config file '" << path << "': " << config_contents.error();
return false;
}
diff --git a/init/persistent_properties.cpp b/init/persistent_properties.cpp
index 1758cfa..716f62e 100644
--- a/init/persistent_properties.cpp
+++ b/init/persistent_properties.cpp
@@ -149,7 +149,7 @@
unlink(temp_filename.c_str());
}
auto file_contents = ReadFile(persistent_property_filename);
- if (!file_contents) {
+ if (!file_contents.ok()) {
return Error() << "Unable to read persistent property file: " << file_contents.error();
}
return *file_contents;
@@ -159,7 +159,7 @@
Result<PersistentProperties> LoadPersistentPropertyFile() {
auto file_contents = ReadPersistentPropertyFile();
- if (!file_contents) return file_contents.error();
+ if (!file_contents.ok()) return file_contents.error();
PersistentProperties persistent_properties;
if (persistent_properties.ParseFromString(*file_contents)) return persistent_properties;
@@ -212,7 +212,7 @@
void WritePersistentProperty(const std::string& name, const std::string& value) {
auto persistent_properties = LoadPersistentPropertyFile();
- if (!persistent_properties) {
+ if (!persistent_properties.ok()) {
LOG(ERROR) << "Recovering persistent properties from memory: "
<< persistent_properties.error();
persistent_properties = LoadPersistentPropertiesFromMemory();
@@ -227,7 +227,7 @@
AddPersistentProperty(name, value, &persistent_properties.value());
}
- if (auto result = WritePersistentPropertyFile(*persistent_properties); !result) {
+ if (auto result = WritePersistentPropertyFile(*persistent_properties); !result.ok()) {
LOG(ERROR) << "Could not store persistent property: " << result.error();
}
}
@@ -235,16 +235,16 @@
PersistentProperties LoadPersistentProperties() {
auto persistent_properties = LoadPersistentPropertyFile();
- if (!persistent_properties) {
+ if (!persistent_properties.ok()) {
LOG(ERROR) << "Could not load single persistent property file, trying legacy directory: "
<< persistent_properties.error();
persistent_properties = LoadLegacyPersistentProperties();
- if (!persistent_properties) {
+ if (!persistent_properties.ok()) {
LOG(ERROR) << "Unable to load legacy persistent properties: "
<< persistent_properties.error();
return {};
}
- if (auto result = WritePersistentPropertyFile(*persistent_properties); result) {
+ if (auto result = WritePersistentPropertyFile(*persistent_properties); result.ok()) {
RemoveLegacyPersistentPropertyFiles();
} else {
LOG(ERROR) << "Unable to write single persistent property file: " << result.error();
diff --git a/init/persistent_properties_test.cpp b/init/persistent_properties_test.cpp
index 13796a6..60cecde 100644
--- a/init/persistent_properties_test.cpp
+++ b/init/persistent_properties_test.cpp
@@ -83,7 +83,8 @@
{"persist.\x00\x01\x02\xFF\xFE\xFD\x7F\x8F\x9F", "non-ascii-name"},
};
- ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
+ ASSERT_RESULT_OK(
+ WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
auto read_back_properties = LoadPersistentProperties();
CheckPropertiesEqual(persistent_properties, read_back_properties);
@@ -97,7 +98,8 @@
std::vector<std::pair<std::string, std::string>> persistent_properties = {
{"persist.sys.timezone", "America/Los_Angeles"},
};
- ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
+ ASSERT_RESULT_OK(
+ WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
WritePersistentProperty("persist.sys.locale", "pt-BR");
@@ -119,7 +121,8 @@
{"persist.sys.locale", "en-US"},
{"persist.sys.timezone", "America/Los_Angeles"},
};
- ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
+ ASSERT_RESULT_OK(
+ WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
WritePersistentProperty("persist.sys.locale", "pt-BR");
@@ -137,7 +140,7 @@
ASSERT_TRUE(tf.fd != -1);
persistent_property_filename = tf.path;
- ASSERT_TRUE(WriteFile(tf.path, "ab"));
+ ASSERT_RESULT_OK(WriteFile(tf.path, "ab"));
WritePersistentProperty("persist.sys.locale", "pt-BR");
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 5b35ad2..84644e8 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -153,7 +153,7 @@
changed_message->set_name(name);
changed_message->set_value(value);
- if (auto result = SendMessage(init_socket, property_msg); !result) {
+ if (auto result = SendMessage(init_socket, property_msg); !result.ok()) {
LOG(ERROR) << "Failed to send property changed message: " << result.error();
}
}
@@ -166,7 +166,7 @@
return PROP_ERROR_INVALID_NAME;
}
- if (auto result = IsLegalPropertyValue(name, value); !result) {
+ if (auto result = IsLegalPropertyValue(name, value); !result.ok()) {
*error = result.error().message();
return PROP_ERROR_INVALID_VALUE;
}
@@ -392,7 +392,7 @@
control_message->set_fd(fd);
}
- if (auto result = SendMessage(init_socket, property_msg); !result) {
+ if (auto result = SendMessage(init_socket, property_msg); !result.ok()) {
// We've already released the fd above, so if we fail to send the message to init, we need
// to manually free it here.
if (fd != -1) {
@@ -670,7 +670,7 @@
std::string raw_filename(fn);
auto expanded_filename = ExpandProps(raw_filename);
- if (!expanded_filename) {
+ if (!expanded_filename.ok()) {
LOG(ERROR) << "Could not expand filename ': " << expanded_filename.error();
continue;
}
@@ -726,7 +726,7 @@
std::map<std::string, std::string>* properties) {
Timer t;
auto file_contents = ReadFile(filename);
- if (!file_contents) {
+ if (!file_contents.ok()) {
PLOG(WARNING) << "Couldn't load property file '" << filename
<< "': " << file_contents.error();
return false;
@@ -1084,7 +1084,7 @@
static void HandleInitSocket() {
auto message = ReadMessage(init_socket);
- if (!message) {
+ if (!message.ok()) {
LOG(ERROR) << "Could not read message from init_dedicated_recv_socket: " << message.error();
return;
}
@@ -1123,21 +1123,22 @@
static void PropertyServiceThread() {
Epoll epoll;
- if (auto result = epoll.Open(); !result) {
+ if (auto result = epoll.Open(); !result.ok()) {
LOG(FATAL) << result.error();
}
- if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd); !result) {
+ if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);
+ !result.ok()) {
LOG(FATAL) << result.error();
}
- if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result) {
+ if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
LOG(FATAL) << result.error();
}
while (true) {
auto pending_functions = epoll.Wait(std::nullopt);
- if (!pending_functions) {
+ if (!pending_functions.ok()) {
LOG(ERROR) << pending_functions.error();
} else {
for (const auto& function : *pending_functions) {
@@ -1159,7 +1160,8 @@
accept_messages = true;
if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- false, 0666, 0, 0, {})) {
+ false, 0666, 0, 0, {});
+ result.ok()) {
property_set_fd = *result;
} else {
LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 8b239fe..38e8227 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -180,7 +180,7 @@
LOG(WARNING) << "cannot find blank_screen in TurnOffBacklight";
return;
}
- if (auto result = service->Start(); !result) {
+ if (auto result = service->Start(); !result.ok()) {
LOG(WARNING) << "Could not start blank_screen service: " << result.error();
}
}
@@ -591,14 +591,14 @@
// keep debugging tools until non critical ones are all gone.
s->SetShutdownCritical();
} else if (to_starts.count(s->name())) {
- if (auto result = s->Start(); !result) {
+ if (auto result = s->Start(); !result.ok()) {
LOG(ERROR) << "Could not start shutdown 'to_start' service '" << s->name()
<< "': " << result.error();
}
s->SetShutdownCritical();
} else if (s->IsShutdownCritical()) {
// Start shutdown critical service if not started.
- if (auto result = s->Start(); !result) {
+ if (auto result = s->Start(); !result.ok()) {
LOG(ERROR) << "Could not start shutdown critical service '" << s->name()
<< "': " << result.error();
}
@@ -731,9 +731,6 @@
static Result<void> DoUserspaceReboot() {
LOG(INFO) << "Userspace reboot initiated";
- boot_clock::time_point now = boot_clock::now();
- SetProperty("sys.init.userspace_reboot.last_started",
- std::to_string(now.time_since_epoch().count()));
auto guard = android::base::make_scope_guard([] {
// Leave shutdown so that we can handle a full reboot.
LeaveShutdown();
@@ -776,10 +773,10 @@
// TODO(b/135984674): store information about offending services for debugging.
return Error() << r << " post-data services are still running";
}
- if (auto result = KillZramBackingDevice(); !result) {
+ if (auto result = KillZramBackingDevice(); !result.ok()) {
return result;
}
- if (auto result = CallVdc("volume", "reset"); !result) {
+ if (auto result = CallVdc("volume", "reset"); !result.ok()) {
return result;
}
if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), 5s,
@@ -794,7 +791,7 @@
sync();
LOG(INFO) << "sync() took " << sync_timer;
}
- if (auto result = UnmountAllApexes(); !result) {
+ if (auto result = UnmountAllApexes(); !result.ok()) {
return result;
}
if (!SwitchToBootstrapMountNamespaceIfNeeded()) {
diff --git a/init/result.h b/init/result.h
index b70dd1b..8c1f91e 100644
--- a/init/result.h
+++ b/init/result.h
@@ -22,8 +22,6 @@
#include <android-base/result.h>
using android::base::ErrnoError;
-using android::base::ErrnoErrorf;
using android::base::Error;
-using android::base::Errorf;
using android::base::Result;
using android::base::ResultError;
diff --git a/init/rlimit_parser_test.cpp b/init/rlimit_parser_test.cpp
index 6a16d3b..3c3f848 100644
--- a/init/rlimit_parser_test.cpp
+++ b/init/rlimit_parser_test.cpp
@@ -29,7 +29,7 @@
ASSERT_EQ(4U, input.size());
auto result = ParseRlimit(input);
- ASSERT_TRUE(result) << "input: " << input[1];
+ ASSERT_TRUE(result.ok()) << "input: " << input[1];
const auto& [resource, rlimit] = *result;
const auto& [expected_resource, expected_rlimit] = expected_result;
EXPECT_EQ(expected_resource, resource);
@@ -42,7 +42,7 @@
ASSERT_EQ(4U, input.size());
auto result = ParseRlimit(input);
- ASSERT_FALSE(result) << "input: " << input[1];
+ ASSERT_FALSE(result.ok()) << "input: " << input[1];
EXPECT_EQ(expected_result, result.error().message());
EXPECT_EQ(0, result.error().code());
}
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 852d6ca..41007c1 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -477,7 +477,7 @@
}
}
- if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
+ if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result.ok()) {
LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
}
}
diff --git a/init/service.cpp b/init/service.cpp
index 0e27ff1..665a1b0 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -106,7 +106,7 @@
c_strings.push_back(const_cast<char*>(args[0].data()));
for (std::size_t i = 1; i < args.size(); ++i) {
auto expanded_arg = ExpandProps(args[i]);
- if (!expanded_arg) {
+ if (!expanded_arg.ok()) {
LOG(FATAL) << args[0] << ": cannot expand arguments': " << expanded_arg.error();
}
expanded_args[i] = *expanded_arg;
@@ -232,7 +232,7 @@
}
}
- if (auto result = SetProcessAttributes(proc_attr_); !result) {
+ if (auto result = SetProcessAttributes(proc_attr_); !result.ok()) {
LOG(FATAL) << "cannot set attribute for " << name_ << ": " << result.error();
}
@@ -374,7 +374,7 @@
flags_ |= SVC_ONESHOT;
- if (auto result = Start(); !result) {
+ if (auto result = Start(); !result.ok()) {
return result;
}
@@ -449,7 +449,7 @@
scon = seclabel_;
} else {
auto result = ComputeContextFromExecutable(args_[0]);
- if (!result) {
+ if (!result.ok()) {
return result.error();
}
scon = *result;
@@ -469,7 +469,7 @@
std::vector<Descriptor> descriptors;
for (const auto& socket : sockets_) {
- if (auto result = socket.Create(scon)) {
+ if (auto result = socket.Create(scon); result.ok()) {
descriptors.emplace_back(std::move(*result));
} else {
LOG(INFO) << "Could not create socket '" << socket.name << "': " << result.error();
@@ -477,7 +477,7 @@
}
for (const auto& file : files_) {
- if (auto result = file.Create()) {
+ if (auto result = file.Create(); result.ok()) {
descriptors.emplace_back(std::move(*result));
} else {
LOG(INFO) << "Could not open file '" << file.name << "': " << result.error();
@@ -494,7 +494,7 @@
if (pid == 0) {
umask(077);
- if (auto result = EnterNamespaces(namespaces_, name_, pre_apexd_); !result) {
+ if (auto result = EnterNamespaces(namespaces_, name_, pre_apexd_); !result.ok()) {
LOG(FATAL) << "Service '" << name_
<< "' failed to set up namespaces: " << result.error();
}
@@ -507,7 +507,7 @@
descriptor.Publish();
}
- if (auto result = WritePidToFiles(&writepid_files_); !result) {
+ if (auto result = WritePidToFiles(&writepid_files_); !result.ok()) {
LOG(ERROR) << "failed to write pid to files: " << result.error();
}
@@ -669,7 +669,7 @@
StopOrReset(SVC_RESTART);
} else if (!(flags_ & SVC_RESTARTING)) {
/* Just start the service since it's not running. */
- if (auto result = Start(); !result) {
+ if (auto result = Start(); !result.ok()) {
LOG(ERROR) << "Could not restart '" << name_ << "': " << result.error();
}
} /* else: Service is restarting anyways. */
@@ -742,7 +742,7 @@
Result<uid_t> uid = 0;
if (command_arg > 3) {
uid = DecodeUid(args[2]);
- if (!uid) {
+ if (!uid.ok()) {
return Error() << "Unable to decode UID for '" << args[2] << "': " << uid.error();
}
}
@@ -750,13 +750,13 @@
std::vector<gid_t> supp_gids;
if (command_arg > 4) {
gid = DecodeUid(args[3]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to decode GID for '" << args[3] << "': " << gid.error();
}
std::size_t nr_supp_gids = command_arg - 1 /* -- */ - 4 /* exec SECLABEL UID GID */;
for (size_t i = 0; i < nr_supp_gids; ++i) {
auto supp_gid = DecodeUid(args[4 + i]);
- if (!supp_gid) {
+ if (!supp_gid.ok()) {
return Error() << "Unable to decode GID for '" << args[4 + i]
<< "': " << supp_gid.error();
}
diff --git a/init/service_list.cpp b/init/service_list.cpp
index c51a9cf..3047821 100644
--- a/init/service_list.cpp
+++ b/init/service_list.cpp
@@ -86,7 +86,7 @@
LOG(ERROR) << "delayed service '" << name << "' could not be found.";
continue;
}
- if (auto result = service->Start(); !result) {
+ if (auto result = service->Start(); !result.ok()) {
LOG(ERROR) << result.error().message();
}
}
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 3f81792..4b04ba0 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -119,14 +119,14 @@
Result<void> ServiceParser::ParseGroup(std::vector<std::string>&& args) {
auto gid = DecodeUid(args[1]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to decode GID for '" << args[1] << "': " << gid.error();
}
service_->proc_attr_.gid = *gid;
for (std::size_t n = 2; n < args.size(); n++) {
gid = DecodeUid(args[n]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to decode GID for '" << args[n] << "': " << gid.error();
}
service_->proc_attr_.supp_gids.emplace_back(*gid);
@@ -202,7 +202,7 @@
auto it = args.begin() + 1;
if (args.size() == 2 && StartsWith(args[1], "$")) {
auto expanded = ExpandProps(args[1]);
- if (!expanded) {
+ if (!expanded.ok()) {
return expanded.error();
}
@@ -240,7 +240,7 @@
Result<void> ServiceParser::ParseOnrestart(std::vector<std::string>&& args) {
args.erase(args.begin());
int line = service_->onrestart_.NumCommands() + 1;
- if (auto result = service_->onrestart_.AddCommand(std::move(args), line); !result) {
+ if (auto result = service_->onrestart_.AddCommand(std::move(args), line); !result.ok()) {
return Error() << "cannot add Onrestart command: " << result.error();
}
return {};
@@ -310,7 +310,7 @@
Result<void> ServiceParser::ParseProcessRlimit(std::vector<std::string>&& args) {
auto rlimit = ParseRlimit(args);
- if (!rlimit) return rlimit.error();
+ if (!rlimit.ok()) return rlimit.error();
service_->proc_attr_.rlimits.emplace_back(*rlimit);
return {};
@@ -407,7 +407,7 @@
if (args.size() > 4) {
auto uid = DecodeUid(args[4]);
- if (!uid) {
+ if (!uid.ok()) {
return Error() << "Unable to find UID for '" << args[4] << "': " << uid.error();
}
socket.uid = *uid;
@@ -415,7 +415,7 @@
if (args.size() > 5) {
auto gid = DecodeUid(args[5]);
- if (!gid) {
+ if (!gid.ok()) {
return Error() << "Unable to find GID for '" << args[5] << "': " << gid.error();
}
socket.gid = *gid;
@@ -453,7 +453,7 @@
file.type = args[2];
auto file_name = ExpandProps(args[1]);
- if (!file_name) {
+ if (!file_name.ok()) {
return Error() << "Could not expand file path ': " << file_name.error();
}
file.name = *file_name;
@@ -475,7 +475,7 @@
Result<void> ServiceParser::ParseUser(std::vector<std::string>&& args) {
auto uid = DecodeUid(args[1]);
- if (!uid) {
+ if (!uid.ok()) {
return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
}
service_->proc_attr_.uid = *uid;
@@ -580,7 +580,7 @@
auto parser = GetParserMap().Find(args);
- if (!parser) return parser.error();
+ if (!parser.ok()) return parser.error();
return std::invoke(*parser, this, std::move(args));
}
@@ -593,7 +593,7 @@
if (interface_inheritance_hierarchy_) {
if (const auto& check_hierarchy_result = CheckInterfaceInheritanceHierarchy(
service_->interfaces(), *interface_inheritance_hierarchy_);
- !check_hierarchy_result) {
+ !check_hierarchy_result.ok()) {
return Error() << check_hierarchy_result.error();
}
}
diff --git a/init/service_test.cpp b/init/service_test.cpp
index c158b0a..22ee844 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -76,15 +76,15 @@
TEST(service, make_temporary_oneshot_service_invalid_syntax) {
std::vector<std::string> args;
// Nothing.
- ASSERT_FALSE(Service::MakeTemporaryOneshotService(args));
+ ASSERT_FALSE(Service::MakeTemporaryOneshotService(args).ok());
// No arguments to 'exec'.
args.push_back("exec");
- ASSERT_FALSE(Service::MakeTemporaryOneshotService(args));
+ ASSERT_FALSE(Service::MakeTemporaryOneshotService(args).ok());
// No command in "exec --".
args.push_back("--");
- ASSERT_FALSE(Service::MakeTemporaryOneshotService(args));
+ ASSERT_FALSE(Service::MakeTemporaryOneshotService(args).ok());
}
TEST(service, make_temporary_oneshot_service_too_many_supplementary_gids) {
@@ -98,7 +98,7 @@
}
args.push_back("--");
args.push_back("/system/bin/id");
- ASSERT_FALSE(Service::MakeTemporaryOneshotService(args));
+ ASSERT_FALSE(Service::MakeTemporaryOneshotService(args).ok());
}
static void Test_make_temporary_oneshot_service(bool dash_dash, bool seclabel, bool uid, bool gid,
@@ -124,7 +124,7 @@
args.push_back("/system/bin/toybox");
args.push_back("id");
auto service_ret = Service::MakeTemporaryOneshotService(args);
- ASSERT_TRUE(service_ret);
+ ASSERT_RESULT_OK(service_ret);
auto svc = std::move(*service_ret);
if (seclabel) {
@@ -134,14 +134,14 @@
}
if (uid) {
auto decoded_uid = DecodeUid("log");
- ASSERT_TRUE(decoded_uid);
+ ASSERT_RESULT_OK(decoded_uid);
ASSERT_EQ(*decoded_uid, svc->uid());
} else {
ASSERT_EQ(0U, svc->uid());
}
if (gid) {
auto decoded_uid = DecodeUid("shell");
- ASSERT_TRUE(decoded_uid);
+ ASSERT_RESULT_OK(decoded_uid);
ASSERT_EQ(*decoded_uid, svc->gid());
} else {
ASSERT_EQ(0U, svc->gid());
@@ -150,11 +150,11 @@
ASSERT_EQ(2U, svc->supp_gids().size());
auto decoded_uid = DecodeUid("system");
- ASSERT_TRUE(decoded_uid);
+ ASSERT_RESULT_OK(decoded_uid);
ASSERT_EQ(*decoded_uid, svc->supp_gids()[0]);
decoded_uid = DecodeUid("adb");
- ASSERT_TRUE(decoded_uid);
+ ASSERT_RESULT_OK(decoded_uid);
ASSERT_EQ(*decoded_uid, svc->supp_gids()[1]);
} else {
ASSERT_EQ(0U, svc->supp_gids().size());
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index 93cffd8..484c2c8 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -167,7 +167,7 @@
Result<Descriptor> SocketDescriptor::Create(const std::string& global_context) const {
const auto& socket_context = context.empty() ? global_context : context;
auto result = CreateSocket(name, type | SOCK_CLOEXEC, passcred, perm, uid, gid, socket_context);
- if (!result) {
+ if (!result.ok()) {
return result.error();
}
@@ -196,7 +196,7 @@
Result<void> EnterNamespaces(const NamespaceInfo& info, const std::string& name, bool pre_apexd) {
for (const auto& [nstype, path] : info.namespaces_to_enter) {
- if (auto result = EnterNamespace(nstype, path.c_str()); !result) {
+ if (auto result = EnterNamespace(nstype, path.c_str()); !result.ok()) {
return result;
}
}
@@ -214,14 +214,14 @@
bool remount_sys =
std::any_of(info.namespaces_to_enter.begin(), info.namespaces_to_enter.end(),
[](const auto& entry) { return entry.first == CLONE_NEWNET; });
- if (auto result = SetUpMountNamespace(remount_proc, remount_sys); !result) {
+ if (auto result = SetUpMountNamespace(remount_proc, remount_sys); !result.ok()) {
return result;
}
}
if (info.flags & CLONE_NEWPID) {
// This will fork again to run an init process inside the PID namespace.
- if (auto result = SetUpPidNamespace(name.c_str()); !result) {
+ if (auto result = SetUpPidNamespace(name.c_str()); !result.ok()) {
return result;
}
}
@@ -249,9 +249,8 @@
for (const auto& rlimit : attr.rlimits) {
if (setrlimit(rlimit.first, &rlimit.second) == -1) {
- return ErrnoError() << StringPrintf(
- "setrlimit(%d, {rlim_cur=%ld, rlim_max=%ld}) failed", rlimit.first,
- rlimit.second.rlim_cur, rlimit.second.rlim_max);
+ return ErrnoErrorf("setrlimit({}, {{rlim_cur={}, rlim_max={}}}) failed", rlimit.first,
+ rlimit.second.rlim_cur, rlimit.second.rlim_max);
}
}
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index f3f759d..3260159 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -80,13 +80,13 @@
auto map_result = function_map_->Find(args);
Result<void> result;
- if (!map_result) {
+ if (!map_result.ok()) {
result = Error() << "Cannot find command: " << map_result.error();
} else {
result = RunBuiltinFunction(map_result->function, args, context_);
}
- if (result) {
+ if (result.ok()) {
reply->set_success(true);
} else {
auto* failure = reply->mutable_failure();
@@ -99,7 +99,7 @@
SubcontextReply* reply) const {
for (const auto& arg : expand_args_command.args()) {
auto expanded_arg = ExpandProps(arg);
- if (!expanded_arg) {
+ if (!expanded_arg.ok()) {
auto* failure = reply->mutable_failure();
failure->set_error_string(expanded_arg.error().message());
failure->set_error_errno(0);
@@ -125,7 +125,7 @@
}
auto init_message = ReadMessage(init_fd_);
- if (!init_message) {
+ if (!init_message.ok()) {
if (init_message.error().code() == 0) {
// If the init file descriptor was closed, let's exit quietly. If
// this was accidental, init will restart us. If init died, this
@@ -160,7 +160,7 @@
shutdown_command.clear();
}
- if (auto result = SendMessage(init_fd_, reply); !result) {
+ if (auto result = SendMessage(init_fd_, reply); !result.ok()) {
LOG(FATAL) << "Failed to send message to init: " << result.error();
}
}
@@ -246,13 +246,13 @@
}
Result<SubcontextReply> Subcontext::TransmitMessage(const SubcontextCommand& subcontext_command) {
- if (auto result = SendMessage(socket_, subcontext_command); !result) {
+ if (auto result = SendMessage(socket_, subcontext_command); !result.ok()) {
Restart();
return ErrnoError() << "Failed to send message to subcontext";
}
auto subcontext_message = ReadMessage(socket_);
- if (!subcontext_message) {
+ if (!subcontext_message.ok()) {
Restart();
return Error() << "Failed to receive result from subcontext: " << subcontext_message.error();
}
@@ -277,7 +277,7 @@
RepeatedPtrFieldBackInserter(subcontext_command.mutable_execute_command()->mutable_args()));
auto subcontext_reply = TransmitMessage(subcontext_command);
- if (!subcontext_reply) {
+ if (!subcontext_reply.ok()) {
return subcontext_reply.error();
}
@@ -301,7 +301,7 @@
subcontext_command.mutable_expand_args_command()->mutable_args()));
auto subcontext_reply = TransmitMessage(subcontext_command);
- if (!subcontext_reply) {
+ if (!subcontext_reply.ok()) {
return subcontext_reply.error();
}
diff --git a/init/subcontext_test.cpp b/init/subcontext_test.cpp
index 2e5a256..ee765a7 100644
--- a/init/subcontext_test.cpp
+++ b/init/subcontext_test.cpp
@@ -55,7 +55,7 @@
TEST(subcontext, CheckDifferentPid) {
RunTest([](auto& subcontext) {
auto result = subcontext.Execute(std::vector<std::string>{"return_pids_as_error"});
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
auto pids = Split(result.error().message(), " ");
ASSERT_EQ(2U, pids.size());
@@ -81,7 +81,7 @@
"success",
};
auto result = subcontext.Execute(args);
- ASSERT_TRUE(result) << result.error();
+ ASSERT_RESULT_OK(result);
EXPECT_TRUE(WaitForProperty("init.test.subcontext", "success", 10s));
});
@@ -104,11 +104,11 @@
word,
};
auto result = subcontext.Execute(args);
- ASSERT_TRUE(result) << result.error();
+ ASSERT_RESULT_OK(result);
}
auto result = subcontext.Execute(std::vector<std::string>{"return_words_as_error"});
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
EXPECT_EQ(Join(expected_words, " "), result.error().message());
EXPECT_EQ(first_pid, subcontext.pid());
});
@@ -119,10 +119,10 @@
auto first_pid = subcontext.pid();
auto result = subcontext.Execute(std::vector<std::string>{"cause_log_fatal"});
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
auto result2 = subcontext.Execute(std::vector<std::string>{"generate_sane_error"});
- ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.ok());
EXPECT_EQ("Sane error!", result2.error().message());
EXPECT_NE(subcontext.pid(), first_pid);
});
@@ -131,7 +131,7 @@
TEST(subcontext, ContextString) {
RunTest([](auto& subcontext) {
auto result = subcontext.Execute(std::vector<std::string>{"return_context_as_error"});
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
ASSERT_EQ(kTestContext, result.error().message());
});
}
@@ -143,7 +143,7 @@
RunTest([](auto& subcontext) {
auto result = subcontext.Execute(
std::vector<std::string>{"trigger_shutdown", kTestShutdownCommand});
- ASSERT_TRUE(result);
+ ASSERT_RESULT_OK(result);
});
EXPECT_EQ(kTestShutdownCommand, trigger_shutdown_command);
}
@@ -156,7 +156,7 @@
"$$third",
};
auto result = subcontext.ExpandArgs(args);
- ASSERT_TRUE(result) << result.error();
+ ASSERT_RESULT_OK(result);
ASSERT_EQ(3U, result->size());
EXPECT_EQ(args[0], result->at(0));
EXPECT_EQ(GetProperty("ro.hardware", ""), result->at(1));
@@ -171,7 +171,7 @@
"${",
};
auto result = subcontext.ExpandArgs(args);
- ASSERT_FALSE(result);
+ ASSERT_FALSE(result.ok());
EXPECT_EQ("unexpected end of string in '" + args[1] + "', looking for }",
result.error().message());
});
diff --git a/init/test_utils/include/init-test-utils/service_utils.h b/init/test_utils/include/init-test-utils/service_utils.h
index 3ec61d4..f9366ea 100644
--- a/init/test_utils/include/init-test-utils/service_utils.h
+++ b/init/test_utils/include/init-test-utils/service_utils.h
@@ -20,12 +20,20 @@
#include <set>
#include <android-base/result.h>
-#include <hidl-util/FqInstance.h>
namespace android {
namespace init {
-using ServiceInterfacesMap = std::map<std::string, std::set<android::FqInstance>>;
+// this is service name -> interface declaration
+//
+// So, for:
+// service foo ..
+// interface aidl baz
+// interface android.hardware.foo@1.0 IFoo
+//
+// We have:
+// foo -> { aidl/baz, android.hardware.foo@1.0/IFoo }
+using ServiceInterfacesMap = std::map<std::string, std::set<std::string>>;
android::base::Result<ServiceInterfacesMap> GetOnDeviceServiceInterfacesMap();
} // namespace init
diff --git a/init/test_utils/service_utils.cpp b/init/test_utils/service_utils.cpp
index bc00702..ae68679 100644
--- a/init/test_utils/service_utils.cpp
+++ b/init/test_utils/service_utils.cpp
@@ -47,14 +47,7 @@
for (const auto& service : service_list.services()) {
// Create an entry for all services, including services that may not
// have any declared interfaces.
- result[service->name()] = std::set<android::FqInstance>();
- for (const auto& intf : service->interfaces()) {
- android::FqInstance fqInstance;
- if (!fqInstance.setTo(intf)) {
- return android::base::Error() << "Unable to parse interface: '" << intf << "'";
- }
- result[service->name()].insert(fqInstance);
- }
+ result[service->name()] = service->interfaces();
}
return result;
}
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index a74b247..09dce44 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -209,7 +209,7 @@
auto parser = parser_map.Find(args);
- if (!parser) return Error() << parser.error();
+ if (!parser.ok()) return Error() << parser.error();
return std::invoke(*parser, this, std::move(args));
}
diff --git a/init/util.cpp b/init/util.cpp
index 0ca0da5..503c705 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -497,14 +497,14 @@
break;
case 3:
uid = DecodeUid(args[3]);
- if (!uid) {
+ if (!uid.ok()) {
return Error()
<< "Unable to decode UID for '" << args[3] << "': " << uid.error();
}
break;
case 4:
gid = DecodeUid(args[4]);
- if (!gid) {
+ if (!gid.ok()) {
return Error()
<< "Unable to decode GID for '" << args[4] << "': " << gid.error();
}
diff --git a/init/util_test.cpp b/init/util_test.cpp
index a8fcc87..96a5b55 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -33,7 +33,7 @@
errno = 0;
auto file_contents = ReadFile("/proc/does-not-exist");
EXPECT_EQ(ENOENT, errno);
- ASSERT_FALSE(file_contents);
+ ASSERT_FALSE(file_contents.ok());
EXPECT_EQ("open() failed: No such file or directory", file_contents.error().message());
}
@@ -41,10 +41,10 @@
std::string s("hello");
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
- EXPECT_TRUE(WriteFile(tf.path, s)) << strerror(errno);
+ EXPECT_RESULT_OK(WriteFile(tf.path, s));
EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0620, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
auto file_contents = ReadFile(tf.path);
- ASSERT_FALSE(file_contents) << strerror(errno);
+ ASSERT_FALSE(file_contents.ok()) << strerror(errno);
EXPECT_EQ("Skipping insecure file", file_contents.error().message());
}
@@ -52,10 +52,10 @@
std::string s("hello");
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
- EXPECT_TRUE(WriteFile(tf.path, s)) << strerror(errno);
+ EXPECT_RESULT_OK(WriteFile(tf.path, s));
EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0602, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
auto file_contents = ReadFile(tf.path);
- ASSERT_FALSE(file_contents) << strerror(errno);
+ ASSERT_FALSE(file_contents.ok());
EXPECT_EQ("Skipping insecure file", file_contents.error().message());
}
@@ -64,14 +64,14 @@
// lrw------- 1 root root 23 2008-12-31 19:00 default.prop -> system/etc/prop.default
auto file_contents = ReadFile("/default.prop");
EXPECT_EQ(ELOOP, errno);
- ASSERT_FALSE(file_contents);
+ ASSERT_FALSE(file_contents.ok());
EXPECT_EQ("open() failed: Too many symbolic links encountered",
file_contents.error().message());
}
TEST(util, ReadFileSuccess) {
auto file_contents = ReadFile("/proc/version");
- ASSERT_TRUE(file_contents);
+ ASSERT_TRUE(file_contents.ok());
EXPECT_GT(file_contents->length(), 6U);
EXPECT_EQ('\n', file_contents->at(file_contents->length() - 1));
(*file_contents)[5] = 0;
@@ -87,10 +87,10 @@
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
- EXPECT_TRUE(WriteFile(tf.path, contents)) << strerror(errno);
+ EXPECT_RESULT_OK(WriteFile(tf.path, contents));
auto read_back_contents = ReadFile(tf.path);
- ASSERT_TRUE(read_back_contents) << strerror(errno);
+ ASSERT_RESULT_OK(read_back_contents);
EXPECT_EQ(contents, *read_back_contents);
EXPECT_EQ(10u, read_back_contents->size());
}
@@ -99,14 +99,15 @@
std::string s("hello");
TemporaryDir test_dir;
std::string path = android::base::StringPrintf("%s/does-not-exist", test_dir.path);
- EXPECT_TRUE(WriteFile(path, s));
+ EXPECT_RESULT_OK(WriteFile(path, s));
auto file_contents = ReadFile(path);
- ASSERT_TRUE(file_contents);
+ ASSERT_RESULT_OK(file_contents);
EXPECT_EQ(s, *file_contents);
struct stat sb;
int fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
EXPECT_NE(-1, fd);
EXPECT_EQ(0, fstat(fd, &sb));
+ EXPECT_EQ(0, close(fd));
EXPECT_EQ((const unsigned int)(S_IRUSR | S_IWUSR), sb.st_mode & 0777);
EXPECT_EQ(0, unlink(path.c_str()));
}
@@ -114,27 +115,27 @@
TEST(util, WriteFileExist) {
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
- EXPECT_TRUE(WriteFile(tf.path, "1hello1")) << strerror(errno);
+ EXPECT_RESULT_OK(WriteFile(tf.path, "1hello1"));
auto file_contents = ReadFile(tf.path);
- ASSERT_TRUE(file_contents);
+ ASSERT_RESULT_OK(file_contents);
EXPECT_EQ("1hello1", *file_contents);
- EXPECT_TRUE(WriteFile(tf.path, "2ll2"));
+ EXPECT_RESULT_OK(WriteFile(tf.path, "2ll2"));
file_contents = ReadFile(tf.path);
- ASSERT_TRUE(file_contents);
+ ASSERT_RESULT_OK(file_contents);
EXPECT_EQ("2ll2", *file_contents);
}
TEST(util, DecodeUid) {
auto decoded_uid = DecodeUid("root");
- EXPECT_TRUE(decoded_uid);
+ EXPECT_TRUE(decoded_uid.ok());
EXPECT_EQ(0U, *decoded_uid);
decoded_uid = DecodeUid("toot");
- EXPECT_FALSE(decoded_uid);
+ EXPECT_FALSE(decoded_uid.ok());
EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error().message());
decoded_uid = DecodeUid("123");
- EXPECT_TRUE(decoded_uid);
+ EXPECT_RESULT_OK(decoded_uid);
EXPECT_EQ(123U, *decoded_uid);
}
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index fd9a3eb..c4e4f85 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -74,6 +74,8 @@
{ 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" },
+ { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest" },
+ { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64" },
{ 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
{ 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" },
@@ -145,6 +147,8 @@
{ 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" },
+ { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest/*" },
+ { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64/*" },
{ 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, // legacy
{ 00600, AID_ROOT, AID_ROOT, 0, "system/etc/prop.default" },
{ 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, // legacy; only for P release
diff --git a/libcutils/trace-container.cpp b/libcutils/trace-container.cpp
index c23d5e2..f7eed48 100644
--- a/libcutils/trace-container.cpp
+++ b/libcutils/trace-container.cpp
@@ -87,24 +87,28 @@
static void atrace_init_once()
{
- atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
+ atrace_marker_fd = open("/sys/kernel/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
if (atrace_marker_fd < 0) {
- // We're in container, ftrace may be disabled. In such case, we use the
- // socket to write trace event.
+ // try debugfs
+ atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
+ if (atrace_marker_fd < 0) {
+ // We're in container, ftrace may be disabled. In such case, we use the
+ // socket to write trace event.
- // Protect the initialization of container socket from
- // atrace_set_tracing_enabled.
- pthread_mutex_lock(&atrace_enabling_mutex);
- atrace_use_container_sock = true;
- bool success = false;
- if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
- success = atrace_init_container_sock();
- }
- pthread_mutex_unlock(&atrace_enabling_mutex);
+ // Protect the initialization of container socket from
+ // atrace_set_tracing_enabled.
+ pthread_mutex_lock(&atrace_enabling_mutex);
+ atrace_use_container_sock = true;
+ bool success = false;
+ if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
+ success = atrace_init_container_sock();
+ }
+ pthread_mutex_unlock(&atrace_enabling_mutex);
- if (!success) {
- atrace_enabled_tags = 0;
- goto done;
+ if (!success) {
+ atrace_enabled_tags = 0;
+ goto done;
+ }
}
}
atrace_enabled_tags = atrace_get_property();
diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp
index a0c526b..4937042 100644
--- a/liblog/logger_read.cpp
+++ b/liblog/logger_read.cpp
@@ -109,8 +109,8 @@
return ret;
}
- if (ret > (int)sizeof(*log_msg)) {
- ret = sizeof(*log_msg);
+ if (ret > LOGGER_ENTRY_MAX_LEN) {
+ ret = LOGGER_ENTRY_MAX_LEN;
}
if (ret < static_cast<int>(sizeof(log_msg->entry))) {
@@ -118,7 +118,7 @@
}
if (log_msg->entry.hdr_size < sizeof(log_msg->entry) ||
- log_msg->entry.hdr_size >= sizeof(struct log_msg) - sizeof(log_msg->entry)) {
+ log_msg->entry.hdr_size >= LOGGER_ENTRY_MAX_LEN - sizeof(log_msg->entry)) {
return -EINVAL;
}
@@ -126,6 +126,8 @@
return -EINVAL;
}
+ log_msg->buf[log_msg->entry.len + log_msg->entry.hdr_size] = '\0';
+
return ret;
}
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 31ca138..540dcf4 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -18,8 +18,8 @@
#define LOG_TAG "libutils.threads"
#include <assert.h>
-#include <utils/Thread.h>
#include <utils/AndroidThreads.h>
+#include <utils/Thread.h>
#if !defined(_WIN32)
# include <sys/resource.h>
@@ -36,7 +36,10 @@
#include <utils/Log.h>
+#if defined(__ANDROID__)
+#include <processgroup/processgroup.h>
#include <processgroup/sched_policy.h>
+#endif
#if defined(__ANDROID__)
# define __android_unused
@@ -64,6 +67,7 @@
typedef void* (*android_pthread_entry)(void*);
+#if defined(__ANDROID__)
struct thread_data_t {
thread_func_t entryFunction;
void* userData;
@@ -79,10 +83,11 @@
char * name = t->threadName;
delete t;
setpriority(PRIO_PROCESS, 0, prio);
+
+ // A new thread will be in its parent's sched group by default,
+ // so we just need to handle the background case.
if (prio >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(0, SP_BACKGROUND);
- } else {
- set_sched_policy(0, SP_FOREGROUND);
+ SetTaskProfiles(0, {"SCHED_SP_BACKGROUND"}, true);
}
if (name) {
@@ -92,6 +97,7 @@
return f(u);
}
};
+#endif
void androidSetThreadName(const char* name) {
#if defined(__linux__)
@@ -300,11 +306,19 @@
{
int rc = 0;
int lasterr = 0;
+ int curr_pri = getpriority(PRIO_PROCESS, tid);
+
+ if (curr_pri == pri) {
+ return rc;
+ }
if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(tid, SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(tid, SP_FOREGROUND);
+ rc = SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true) ? 0 : -1;
+ } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
+ SchedPolicy policy = SP_FOREGROUND;
+ // Change to the sched policy group of the process.
+ get_sched_policy(getpid(), &policy);
+ rc = SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true) ? 0 : -1;
}
if (rc) {
diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h
index adc3e7d..27eca0c 100644
--- a/libutils/include/utils/String16.h
+++ b/libutils/include/utils/String16.h
@@ -25,18 +25,10 @@
// ---------------------------------------------------------------------------
-extern "C" {
-
-}
-
-// ---------------------------------------------------------------------------
-
namespace android {
// ---------------------------------------------------------------------------
-class String8;
-
template <size_t N>
class StaticString16;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 5fbad75..d6ce0d2 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -114,15 +114,6 @@
symlink /proc/self/fd/1 /dev/stdout
symlink /proc/self/fd/2 /dev/stderr
- symlink /system/bin /bin
- symlink /system/etc /etc
-
- # Backward compatibility.
- symlink /sys/kernel/debug /d
-
- # Link /vendor to /system/vendor for devices without a vendor partition.
- symlink /system/vendor /vendor
-
# Create energy-aware scheduler tuning nodes
mkdir /dev/stune/foreground
mkdir /dev/stune/background
@@ -144,6 +135,14 @@
chmod 0664 /dev/stune/top-app/tasks
chmod 0664 /dev/stune/rt/tasks
+ # Create an stune group for NNAPI HAL processes
+ mkdir /dev/stune/nnapi-hal
+ chown system system /dev/stune/nnapi-hal
+ chown system system /dev/stune/nnapi-hal/tasks
+ chmod 0664 /dev/stune/nnapi-hal/tasks
+ write /dev/stune/nnapi-hal/schedtune.boost 1
+ write /dev/stune/nnapi-hal/schedtune.prefer_idle 1
+
# Create blkio group and apply initial settings.
# This feature needs kernel to support it, and the
# device's init.rc must actually set the correct values.
@@ -211,7 +210,6 @@
mkdir /mnt/runtime/full/self 0755 root root
# Symlink to keep legacy apps working in multi-user world
- symlink /storage/self/primary /sdcard
symlink /storage/self/primary /mnt/sdcard
symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
@@ -614,6 +612,8 @@
mkdir /data/misc/apexdata 0711 root root
mkdir /data/misc/apexrollback 0700 root root
mkdir /data/misc/snapshotctl_log 0770 root root
+ # create location to store pre-reboot information
+ mkdir /data/misc/prereboot 0700 system system
mkdir /data/preloads 0775 system system encryption=None
@@ -1033,6 +1033,7 @@
on userspace-reboot-requested
# TODO(b/135984674): reset all necessary properties here.
setprop sys.boot_completed ""
+ setprop dev.bootcomplete ""
setprop sys.init.updatable_crashing ""
setprop sys.init.updatable_crashing_process_name ""
setprop apexd.status ""
@@ -1058,4 +1059,4 @@
trigger boot
on property:sys.boot_completed=1 && property:sys.init.userspace_reboot.in_progress=1
- finish_userspace_reboot
+ setprop sys.init.userspace_reboot.in_progress ""