Merge "Add displayPresentTime to NATIVE_WINDOW_GET_FRAME_TIMESTAMPS"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 8b6b2b5..3cd50ba 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -30,7 +30,9 @@
#include <sys/time.h>
#include <time.h>
+#include <chrono>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/errors.h>
@@ -51,6 +53,7 @@
#include <sys/capability.h>
#include <sys/mount.h>
#include <android-base/properties.h>
+using namespace std::chrono_literals;
#endif
std::string adb_version() {
@@ -375,7 +378,7 @@
adbd_auth_verified(t);
t->failed_auth_attempts = 0;
} else {
- if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
+ if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
send_auth_request(t);
}
break;
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 919e1c1..0b1ba32 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/stringprintf.h>
@@ -38,6 +39,7 @@
#include "adb_io.h"
#include "adb_utils.h"
#include "socket_spec.h"
+#include "sysdeps/chrono.h"
static TransportType __adb_transport = kTransportAny;
static const char* __adb_serial = NULL;
@@ -188,8 +190,8 @@
} else {
fprintf(stdout,"* daemon started successfully *\n");
}
- /* give the server some time to start properly and detect devices */
- adb_sleep_ms(3000);
+ // Give the server some time to start properly and detect devices.
+ std::this_thread::sleep_for(3s);
// fall through to _adb_connect
} else {
// If a server is already running, check its version matches.
@@ -234,7 +236,7 @@
}
/* XXX can we better detect its death? */
- adb_sleep_ms(2000);
+ std::this_thread::sleep_for(2s);
goto start_server;
}
}
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index ae16834..ca8729e 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -20,6 +20,8 @@
#include <unistd.h>
+#include <thread>
+
#include <android-base/stringprintf.h>
#include "adb.h"
@@ -104,7 +106,7 @@
if (r == -1) {
D("writex: fd=%d error %d: %s", fd, errno, strerror(errno));
if (errno == EAGAIN) {
- adb_sleep_ms(1); // just yield some cpu time
+ std::this_thread::yield();
continue;
} else if (errno == EPIPE) {
D("writex: fd=%d disconnected", fd);
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index e15bcad..a064de2 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -33,6 +33,7 @@
#include <memory>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/file.h>
@@ -59,6 +60,7 @@
#include "file_sync_service.h"
#include "services.h"
#include "shell_service.h"
+#include "sysdeps/chrono.h"
static int install_app(TransportType t, const char* serial, int argc, const char** argv);
static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
@@ -1080,7 +1082,7 @@
// Give adbd some time to kill itself and come back up.
// We can't use wait-for-device because devices (e.g. adb over network) might not come back.
- adb_sleep_ms(3000);
+ std::this_thread::sleep_for(3s);
return true;
}
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index f1e4179..caa7a5f 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -43,6 +43,7 @@
#include "adb_utils.h"
#include "file_sync_service.h"
#include "line_printer.h"
+#include "sysdeps/stat.h"
#include <android-base/file.h>
#include <android-base/strings.h>
@@ -64,15 +65,11 @@
}
static bool should_pull_file(mode_t mode) {
- return mode & (S_IFREG | S_IFBLK | S_IFCHR);
+ return S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode);
}
static bool should_push_file(mode_t mode) {
- mode_t mask = S_IFREG;
-#if !defined(_WIN32)
- mask |= S_IFLNK;
-#endif
- return mode & mask;
+ return S_ISREG(mode) || S_ISLNK(mode);
}
struct copyinfo {
@@ -149,7 +146,7 @@
void ReportProgress(LinePrinter& lp, const std::string& file, uint64_t file_copied_bytes,
uint64_t file_total_bytes) {
char overall_percentage_str[5] = "?";
- if (bytes_expected != 0) {
+ if (bytes_expected != 0 && bytes_transferred <= bytes_expected) {
int overall_percentage = static_cast<int>(bytes_transferred * 100 / bytes_expected);
// If we're pulling symbolic links, we'll pull the target of the link rather than
// just create a local link, and that will cause us to go over 100%.
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index e2b388b..4975fab 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -106,20 +106,6 @@
namespace {
-void init_subproc_child()
-{
- setsid();
-
- // Set OOM score adjustment to prevent killing
- int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
- if (fd >= 0) {
- adb_write(fd, "0", 1);
- adb_close(fd);
- } else {
- D("adb: unable to update oom_score_adj");
- }
-}
-
// Reads from |fd| until close or failure.
std::string ReadAll(int fd) {
char buffer[512];
@@ -316,7 +302,7 @@
if (pid_ == 0) {
// Subprocess child.
- init_subproc_child();
+ setsid();
if (type_ == SubprocessType::kPty) {
child_stdinout_sfd.reset(OpenPtyChildFd(pts_name, &child_error_sfd));
diff --git a/adb/socket_test.cpp b/adb/socket_test.cpp
index 5e79b5e..f56f7f7 100644
--- a/adb/socket_test.cpp
+++ b/adb/socket_test.cpp
@@ -22,6 +22,7 @@
#include <limits>
#include <queue>
#include <string>
+#include <thread>
#include <vector>
#include <unistd.h>
@@ -31,6 +32,7 @@
#include "fdevent_test.h"
#include "socket.h"
#include "sysdeps.h"
+#include "sysdeps/chrono.h"
struct ThreadArg {
int first_read_fd;
@@ -44,7 +46,7 @@
fdevent_loop();
}
-const size_t SLEEP_FOR_FDEVENT_IN_MS = 100;
+constexpr auto SLEEP_FOR_FDEVENT = 100ms;
TEST_F(LocalSocketTest, smoke) {
// Join two socketpairs with a chain of intermediate socketpairs.
@@ -101,7 +103,7 @@
ASSERT_EQ(0, adb_close(last[1]));
// Wait until the local sockets are closed.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -154,12 +156,12 @@
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -179,9 +181,9 @@
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
// Verify if we can read successfully.
@@ -190,7 +192,7 @@
ASSERT_EQ(true, ReadFdExactly(socket_fd[0], buf.data(), buf.size()));
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -214,11 +216,11 @@
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(2u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -229,7 +231,7 @@
std::string error;
int fd = network_loopback_client(5038, SOCK_STREAM, &error);
ASSERT_GE(fd, 0) << error;
- adb_sleep_ms(200);
+ std::this_thread::sleep_for(200ms);
ASSERT_EQ(0, adb_close(fd));
}
@@ -265,13 +267,13 @@
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
// Wait until the client closes its socket.
ASSERT_TRUE(adb_thread_join(client_thread));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index ad9b9fd..05d9fde 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -180,8 +180,6 @@
/* nothing really */
}
-#define S_ISLNK(m) 0 /* no symlinks on Win32 */
-
extern int adb_unlink(const char* path);
#undef unlink
#define unlink ___xxx_unlink
@@ -248,11 +246,6 @@
int unix_isatty(int fd);
#define isatty ___xxx_isatty
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- Sleep( mseconds );
-}
-
int network_loopback_client(int port, int type, std::string* error);
int network_loopback_server(int port, int type, std::string* error);
int network_inaddr_any_server(int port, int type, std::string* error);
@@ -766,11 +759,6 @@
#define poll ___xxx_poll
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- usleep( mseconds*1000 );
-}
-
static __inline__ int adb_mkdir(const std::string& path, int mode)
{
return mkdir(path.c_str(), mode);
diff --git a/adb/sysdeps/chrono.h b/adb/sysdeps/chrono.h
new file mode 100644
index 0000000..c73a638
--- /dev/null
+++ b/adb/sysdeps/chrono.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <chrono>
+
+#if defined(_WIN32)
+// We don't have C++14 on Windows yet.
+// Reimplement std::chrono_literals ourselves until we do.
+
+// Silence the following warning (which gets promoted to an error):
+// error: literal operator suffixes not preceded by ‘_’ are reserved for future standardization
+#pragma GCC system_header
+
+constexpr std::chrono::seconds operator"" s(unsigned long long s) {
+ return std::chrono::seconds(s);
+}
+
+constexpr std::chrono::duration<long double> operator"" s(long double s) {
+ return std::chrono::duration<long double>(s);
+}
+
+constexpr std::chrono::milliseconds operator"" ms(unsigned long long ms) {
+ return std::chrono::milliseconds(ms);
+}
+
+constexpr std::chrono::duration<long double, std::milli> operator"" ms(long double ms) {
+ return std::chrono::duration<long double, std::milli>(ms);
+}
+#else
+using namespace std::chrono_literals;
+#endif
diff --git a/adb/sysdeps/stat.h b/adb/sysdeps/stat.h
index 5953595..ed2cf25fb 100644
--- a/adb/sysdeps/stat.h
+++ b/adb/sysdeps/stat.h
@@ -43,4 +43,21 @@
// Windows doesn't have lstat.
#define lstat adb_stat
+// mingw doesn't define S_IFLNK or S_ISLNK.
+#define S_IFLNK 0120000
+#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+
+// mingw defines S_IFBLK to a different value from bionic.
+#undef S_IFBLK
+#define S_IFBLK 0060000
+#undef S_ISBLK
+#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif
+
+// Make sure that host file mode values match the ones on the device.
+static_assert(S_IFMT == 00170000, "");
+static_assert(S_IFLNK == 0120000, "");
+static_assert(S_IFREG == 0100000, "");
+static_assert(S_IFBLK == 0060000, "");
+static_assert(S_IFDIR == 0040000, "");
+static_assert(S_IFCHR == 0020000, "");
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
index 9f77942..9007e75 100644
--- a/adb/sysdeps_test.cpp
+++ b/adb/sysdeps_test.cpp
@@ -16,14 +16,17 @@
#include <gtest/gtest.h>
#include <unistd.h>
+
#include <atomic>
#include <condition_variable>
+#include <thread>
#include "adb_io.h"
#include "sysdeps.h"
+#include "sysdeps/chrono.h"
static void increment_atomic_int(void* c) {
- sleep(1);
+ std::this_thread::sleep_for(1s);
reinterpret_cast<std::atomic<int>*>(c)->fetch_add(1);
}
@@ -34,7 +37,7 @@
ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter));
}
- sleep(2);
+ std::this_thread::sleep_for(2s);
ASSERT_EQ(100, counter.load());
}
@@ -255,15 +258,15 @@
ASSERT_FALSE(m.try_lock());
m.lock();
finished.store(true);
- adb_sleep_ms(200);
+ std::this_thread::sleep_for(200ms);
m.unlock();
}, nullptr);
ASSERT_FALSE(finished.load());
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
ASSERT_FALSE(finished.load());
m.unlock();
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
m.lock();
ASSERT_TRUE(finished.load());
m.unlock();
@@ -279,13 +282,13 @@
adb_thread_create([](void*) {
ASSERT_FALSE(m.try_lock());
m.lock();
- adb_sleep_ms(500);
+ std::this_thread::sleep_for(500ms);
m.unlock();
}, nullptr);
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
m.unlock();
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
ASSERT_FALSE(m.try_lock());
m.lock();
m.unlock();
diff --git a/adb/test_device.py b/adb/test_device.py
index 02a16e4..e76aaed 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -890,7 +890,8 @@
except subprocess.CalledProcessError as e:
output = e.output
- self.assertIn('Permission denied', output)
+ self.assertTrue('Permission denied' in output or
+ 'Read-only file system' in output)
def _test_pull(self, remote_file, checksum):
tmp_write = tempfile.NamedTemporaryFile(mode='wb', delete=False)
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index ba2b28d..c17f869 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -27,6 +27,7 @@
#include <condition_variable>
#include <mutex>
+#include <thread>
#include <vector>
#include <android-base/stringprintf.h>
@@ -39,6 +40,7 @@
#include "adb.h"
#include "adb_io.h"
#include "adb_utils.h"
+#include "sysdeps/chrono.h"
#if ADB_HOST
@@ -144,7 +146,7 @@
// Retry the disconnected local port for 60 times, and sleep 1 second between two retries.
constexpr uint32_t LOCAL_PORT_RETRY_COUNT = 60;
-constexpr uint32_t LOCAL_PORT_RETRY_INTERVAL_IN_MS = 1000;
+constexpr auto LOCAL_PORT_RETRY_INTERVAL = 1s;
struct RetryPort {
int port;
@@ -173,7 +175,7 @@
// Sleep here instead of the end of loop, because if we immediately try to reconnect
// the emulator just kicked, the adbd on the emulator may not have time to remove the
// just kicked transport.
- adb_sleep_ms(LOCAL_PORT_RETRY_INTERVAL_IN_MS);
+ std::this_thread::sleep_for(LOCAL_PORT_RETRY_INTERVAL);
// Try connecting retry ports.
std::vector<RetryPort> next_ports;
@@ -214,7 +216,7 @@
serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
if(serverfd < 0) {
D("server: cannot bind socket yet: %s", error.c_str());
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
continue;
}
close_on_exec(serverfd);
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index 3e5028d..e7f1338 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -38,6 +38,7 @@
#include <list>
#include <mutex>
#include <string>
+#include <thread>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
@@ -46,6 +47,7 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
using namespace std::literals;
/* usb scan debugging is waaaay too verbose */
@@ -577,7 +579,7 @@
// TODO: Use inotify.
find_usb_device("/dev/bus/usb", register_device);
kick_disconnected_devices();
- sleep(1);
+ std::this_thread::sleep_for(1s);
}
}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 6de10f5..1cc7f68 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -31,8 +31,10 @@
#include <algorithm>
#include <atomic>
+#include <chrono>
#include <condition_variable>
#include <mutex>
+#include <thread>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -40,6 +42,8 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
+
#define MAX_PACKET_SIZE_FS 64
#define MAX_PACKET_SIZE_HS 512
#define MAX_PACKET_SIZE_SS 1024
@@ -268,7 +272,7 @@
fd = unix_open("/dev/android", O_RDWR);
}
if (fd < 0) {
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
} while (fd < 0);
D("[ opening device succeeded ]");
@@ -476,7 +480,7 @@
if (init_functionfs(usb)) {
break;
}
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
android::base::SetProperty("sys.usb.ffs.ready", "1");
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 2ee2aae..e541f6e 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -30,8 +30,10 @@
#include <stdio.h>
#include <atomic>
+#include <chrono>
#include <memory>
#include <mutex>
+#include <thread>
#include <vector>
#include <android-base/logging.h>
@@ -40,6 +42,8 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
+
struct usb_handle
{
UInt8 bulkIn;
@@ -411,7 +415,7 @@
}
// Signal the parent that we are running
usb_inited_flag = true;
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
VLOG(USB) << "RunLoopThread done";
}
@@ -436,7 +440,7 @@
// Wait for initialization to finish
while (!usb_inited_flag) {
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
}
initialized = true;
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index 755f07e..640e91e 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -28,12 +28,14 @@
#include <stdlib.h>
#include <mutex>
+#include <thread>
#include <adb_api.h>
#include <android-base/errors.h>
#include "adb.h"
+#include "sysdeps/chrono.h"
#include "transport.h"
/** Structure usb_handle describes our connection to the usb device via
@@ -176,9 +178,9 @@
adb_thread_setname("Device Poll");
D("Created device thread");
- while(1) {
+ while (true) {
find_devices();
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
}
diff --git a/base/Android.bp b/base/Android.bp
index e6ad15b..b9a6e0b 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -49,6 +49,11 @@
srcs: ["errors_unix.cpp"],
cppflags: ["-Wexit-time-destructors"],
},
+ linux_bionic: {
+ srcs: ["errors_unix.cpp"],
+ cppflags: ["-Wexit-time-destructors"],
+ enabled: true,
+ },
linux: {
srcs: ["errors_unix.cpp"],
cppflags: ["-Wexit-time-destructors"],
diff --git a/bootstat/histogram_logger.cpp b/bootstat/histogram_logger.cpp
index 6a9ef2b..73f3295 100644
--- a/bootstat/histogram_logger.cpp
+++ b/bootstat/histogram_logger.cpp
@@ -19,13 +19,13 @@
#include <cstdlib>
#include <android-base/logging.h>
-#include <log/log.h>
+#include <log/log_event_list.h>
namespace bootstat {
void LogHistogram(const std::string& event, int32_t data) {
LOG(INFO) << "Logging histogram: " << event << " " << data;
- android_log_event_context log(HISTOGRAM_LOG_TAG);
+ android_log_event_list log(HISTOGRAM_LOG_TAG);
log << event << data << LOG_ID_EVENTS;
}
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 155b309..607745d 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -18,6 +18,7 @@
debuggerd.cpp \
elf_utils.cpp \
getevent.cpp \
+ open_files_list.cpp \
signal_sender.cpp \
tombstone.cpp \
utility.cpp \
@@ -108,9 +109,11 @@
debuggerd_test_src_files := \
utility.cpp \
+ open_files_list.cpp \
test/dump_memory_test.cpp \
test/elf_fake.cpp \
test/log_fake.cpp \
+ test/open_files_list_test.cpp \
test/property_fake.cpp \
test/ptrace_fake.cpp \
test/tombstone_test.cpp \
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 867fd29..9b82f64 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -55,6 +55,7 @@
#include "backtrace.h"
#include "getevent.h"
+#include "open_files_list.h"
#include "signal_sender.h"
#include "tombstone.h"
#include "utility.h"
@@ -480,7 +481,8 @@
}
static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd,
- BacktraceMap* backtrace_map, const std::set<pid_t>& siblings,
+ BacktraceMap* backtrace_map, const OpenFilesList& open_files,
+ const std::set<pid_t>& siblings,
int* crash_signal, std::string* amfd_data) {
if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno));
@@ -499,7 +501,8 @@
case SIGSTOP:
if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
ALOGV("debuggerd: stopped -- dumping to tombstone");
- engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings,
+ engrave_tombstone(tombstone_fd, backtrace_map, open_files,
+ request.pid, request.tid, siblings,
request.abort_msg_address, amfd_data);
} else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
ALOGV("debuggerd: stopped -- dumping to fd");
@@ -526,7 +529,8 @@
case SIGTRAP:
ALOGV("stopped -- fatal signal\n");
*crash_signal = signal;
- engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings,
+ engrave_tombstone(tombstone_fd, backtrace_map, open_files,
+ request.pid, request.tid, siblings,
request.abort_msg_address, amfd_data);
break;
@@ -643,6 +647,10 @@
// Generate the backtrace map before dropping privileges.
std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(request.pid));
+ // Collect the list of open files before dropping privileges.
+ OpenFilesList open_files;
+ populate_open_files_list(request.pid, &open_files);
+
int amfd = -1;
std::unique_ptr<std::string> amfd_data;
if (request.action == DEBUGGER_ACTION_CRASH) {
@@ -660,8 +668,8 @@
}
int crash_signal = SIGKILL;
- succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings,
- &crash_signal, amfd_data.get());
+ succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), open_files,
+ siblings, &crash_signal, amfd_data.get());
if (succeeded) {
if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
if (!tombstone_path.empty()) {
diff --git a/debuggerd/open_files_list.cpp b/debuggerd/open_files_list.cpp
new file mode 100644
index 0000000..5ef2abc
--- /dev/null
+++ b/debuggerd/open_files_list.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DEBUG"
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android/log.h>
+
+#include "open_files_list.h"
+
+#include "utility.h"
+
+void populate_open_files_list(pid_t pid, OpenFilesList* list) {
+ std::string fd_dir_name = "/proc/" + std::to_string(pid) + "/fd";
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(fd_dir_name.c_str()), closedir);
+ if (dir == nullptr) {
+ ALOGE("failed to open directory %s: %s", fd_dir_name.c_str(), strerror(errno));
+ return;
+ }
+
+ struct dirent* de;
+ while ((de = readdir(dir.get())) != nullptr) {
+ if (*de->d_name == '.') {
+ continue;
+ }
+
+ int fd = atoi(de->d_name);
+ std::string path = fd_dir_name + "/" + std::string(de->d_name);
+ std::string target;
+ if (android::base::Readlink(path, &target)) {
+ list->emplace_back(fd, target);
+ } else {
+ ALOGE("failed to readlink %s: %s", path.c_str(), strerror(errno));
+ list->emplace_back(fd, "???");
+ }
+ }
+}
+
+void dump_open_files_list_to_log(const OpenFilesList& files, log_t* log, const char* prefix) {
+ for (auto& file : files) {
+ _LOG(log, logtype::OPEN_FILES, "%sfd %i: %s\n", prefix, file.first, file.second.c_str());
+ }
+}
+
diff --git a/debuggerd/open_files_list.h b/debuggerd/open_files_list.h
new file mode 100644
index 0000000..b37228d
--- /dev/null
+++ b/debuggerd/open_files_list.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DEBUGGERD_OPEN_FILES_LIST_H
+#define _DEBUGGERD_OPEN_FILES_LIST_H
+
+#include <sys/types.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "utility.h"
+
+typedef std::vector<std::pair<int, std::string>> OpenFilesList;
+
+/* Populates the given list with open files for the given process. */
+void populate_open_files_list(pid_t pid, OpenFilesList* list);
+
+/* Dumps the open files list to the log. */
+void dump_open_files_list_to_log(const OpenFilesList& files, log_t* log, const char* prefix);
+
+#endif // _DEBUGGERD_OPEN_FILES_LIST_H
diff --git a/debuggerd/test/open_files_list_test.cpp b/debuggerd/test/open_files_list_test.cpp
new file mode 100644
index 0000000..85e0695
--- /dev/null
+++ b/debuggerd/test/open_files_list_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include "android-base/test_utils.h"
+
+#include "open_files_list.h"
+
+// Check that we can produce a list of open files for the current process, and
+// that it includes a known open file.
+TEST(OpenFilesListTest, BasicTest) {
+ // Open a temporary file that we can check for in the list of open files.
+ TemporaryFile tf;
+
+ // Get the list of open files for this process.
+ OpenFilesList list;
+ populate_open_files_list(getpid(), &list);
+
+ // Verify our open file is in the list.
+ bool found = false;
+ for (auto& file : list) {
+ if (file.first == tf.fd) {
+ EXPECT_EQ(file.second, std::string(tf.path));
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found);
+}
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 1e47483..e76edb9 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -46,6 +46,7 @@
#include "backtrace.h"
#include "elf_utils.h"
#include "machine.h"
+#include "open_files_list.h"
#include "tombstone.h"
#define STACK_WORDS 16
@@ -571,7 +572,7 @@
if (log_entry.id() == LOG_ID_EVENTS) {
if (!g_eventTagMap) {
- g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ g_eventTagMap = android_openEventTagMap(NULL);
}
AndroidLogEntry e;
char buf[512];
@@ -620,7 +621,8 @@
}
// Dumps all information about the specified pid to the tombstone.
-static void dump_crash(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid,
+static void dump_crash(log_t* log, BacktraceMap* map,
+ const OpenFilesList& open_files, pid_t pid, pid_t tid,
const std::set<pid_t>& siblings, uintptr_t abort_msg_address) {
// don't copy log messages to tombstone unless this is a dev device
bool want_logs = __android_log_is_debuggable();
@@ -639,6 +641,9 @@
}
}
+ _LOG(log, logtype::OPEN_FILES, "\nopen files:\n");
+ dump_open_files_list_to_log(open_files, log, " ");
+
if (want_logs) {
dump_logs(log, pid, 0);
}
@@ -697,7 +702,8 @@
return fd;
}
-void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
+void engrave_tombstone(int tombstone_fd, BacktraceMap* map,
+ const OpenFilesList& open_files, pid_t pid, pid_t tid,
const std::set<pid_t>& siblings, uintptr_t abort_msg_address,
std::string* amfd_data) {
log_t log;
@@ -711,5 +717,5 @@
log.tfd = tombstone_fd;
log.amfd_data = amfd_data;
- dump_crash(&log, map, pid, tid, siblings, abort_msg_address);
+ dump_crash(&log, map, open_files, pid, tid, siblings, abort_msg_address);
}
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index e1c39c5..126f804 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -32,7 +32,8 @@
int open_tombstone(std::string* path);
/* Creates a tombstone file and writes the crash dump to it. */
-void engrave_tombstone(int tombstone_fd, BacktraceMap* map, pid_t pid, pid_t tid,
+void engrave_tombstone(int tombstone_fd, BacktraceMap* map,
+ const OpenFilesList& open_files, pid_t pid, pid_t tid,
const std::set<pid_t>& siblings, uintptr_t abort_msg_address,
std::string* amfd_data);
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index d820f0f..f7a3f73 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -70,7 +70,8 @@
MAPS,
MEMORY,
STACK,
- LOGS
+ LOGS,
+ OPEN_FILES
};
// Log information onto the tombstone.
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4cd423a..7f4a0dd 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -43,7 +43,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include <chrono>
#include <functional>
+#include <thread>
#include <utility>
#include <vector>
@@ -301,7 +303,7 @@
announce = false;
fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device");
}
- usleep(1000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 6db1e27..cdab4f1 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -43,11 +43,15 @@
#include <linux/version.h>
#include <linux/usb/ch9.h>
+#include <chrono>
#include <memory>
+#include <thread>
#include "fastboot.h"
#include "usb.h"
+using namespace std::chrono_literals;
+
#define MAX_RETRIES 5
/* Timeout in seconds for usb_wait_for_disconnect.
@@ -426,7 +430,7 @@
return -1;
}
- while(len > 0) {
+ while (len > 0) {
int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
bulk.ep = handle_->ep_in;
@@ -435,18 +439,17 @@
bulk.timeout = 0;
retry = 0;
- do{
- DBG("[ usb read %d fd = %d], fname=%s\n", xfer, handle_->desc, handle_->fname);
- n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk);
- DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, handle_->fname, retry);
+ do {
+ DBG("[ usb read %d fd = %d], fname=%s\n", xfer, handle_->desc, handle_->fname);
+ n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk);
+ DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, handle_->fname, retry);
- if( n < 0 ) {
- DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno));
- if ( ++retry > MAX_RETRIES ) return -1;
- sleep( 1 );
- }
- }
- while( n < 0 );
+ if (n < 0) {
+ DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno));
+ if (++retry > MAX_RETRIES) return -1;
+ std::this_thread::sleep_for(1s);
+ }
+ } while (n < 0);
count += n;
len -= n;
@@ -488,9 +491,8 @@
{
double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT;
while (now() < deadline) {
- if (access(handle_->fname, F_OK))
- return 0;
- usleep(50000);
+ if (access(handle_->fname, F_OK)) return 0;
+ std::this_thread::sleep_for(50ms);
}
return -1;
}
diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp
index 1cdeb32..3dab5ac 100644
--- a/fastboot/usb_windows.cpp
+++ b/fastboot/usb_windows.cpp
@@ -362,9 +362,3 @@
std::unique_ptr<usb_handle> handle = find_usb_device(callback);
return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr;
}
-
-// called from fastboot.c
-void sleep(int seconds)
-{
- Sleep(seconds * 1000);
-}
diff --git a/fingerprintd/Android.mk b/fingerprintd/Android.mk
index 48b9525..55803cf 100644
--- a/fingerprintd/Android.mk
+++ b/fingerprintd/Android.mk
@@ -26,8 +26,11 @@
LOCAL_MODULE := fingerprintd
LOCAL_SHARED_LIBRARIES := \
libbinder \
+ libhidlbase \
+ libhidltransport \
liblog \
libhardware \
libutils \
- libkeystore_binder
+ libkeystore_binder \
+ android.hardware.biometrics.fingerprint@2.1
include $(BUILD_EXECUTABLE)
diff --git a/fingerprintd/FingerprintDaemonProxy.cpp b/fingerprintd/FingerprintDaemonProxy.cpp
index 1c7da30..0119e55 100644
--- a/fingerprintd/FingerprintDaemonProxy.cpp
+++ b/fingerprintd/FingerprintDaemonProxy.cpp
@@ -16,10 +16,10 @@
#define LOG_TAG "fingerprintd"
+#include <android/hardware/biometrics/fingerprint/2.1/types.h>
+#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
+#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.h>
#include <binder/IServiceManager.h>
-#include <hardware/hardware.h>
-#include <hardware/fingerprint.h>
-#include <hardware/hw_auth_token.h>
#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h> // for error codes
#include <utils/Log.h>
@@ -28,12 +28,45 @@
namespace android {
-FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL;
+using hardware::hidl_string;
+using hardware::Return;
+using hardware::biometrics::fingerprint::V2_1::FingerprintMsg;
+using hardware::biometrics::fingerprint::V2_1::RequestStatus;
+using hardware::biometrics::fingerprint::V2_1::FingerprintError;
+using hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
+using Type = hardware::biometrics::fingerprint::V2_1::FingerprintMsgType;
+using IBiometricsFingerprint = hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
-// Supported fingerprint HAL version
-static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0);
+FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = nullptr;
+static sp<IBiometricsFingerprint> gBFP = nullptr;
+static sp<IBiometricsFingerprintClientCallback> gClientCallback = nullptr;
-FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) {
+template <typename E>
+constexpr typename std::underlying_type<E>::type to_native(E e) {
+ return static_cast<typename std::underlying_type<E>::type>(e);
+}
+
+const ssize_t hw_auth_token_size = 69;
+
+namespace hardware {
+
+class BiometricsFingerprintClientCallback : public IBiometricsFingerprintClientCallback {
+ public:
+ BiometricsFingerprintClientCallback() {};
+ virtual ~BiometricsFingerprintClientCallback() = default;
+ Return<void> notify(const FingerprintMsg& msg) {
+ FingerprintDaemonProxy::hal_notify_callback(msg);
+ return Void();
+ }
+};
+
+IBiometricsFingerprintClientCallback* HIDL_FETCH_IBiometricsFingerprintClientCallback(const char* /* name */) {
+ return new BiometricsFingerprintClientCallback();
+}
+
+} // namespace hardware
+
+FingerprintDaemonProxy::FingerprintDaemonProxy() : mCallback(nullptr) {
}
@@ -41,76 +74,75 @@
closeHal();
}
-void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) {
+void FingerprintDaemonProxy::hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg) {
FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance();
const sp<IFingerprintDaemonCallback> callback = instance->mCallback;
- if (callback == NULL) {
+ if (callback == nullptr) {
ALOGE("Invalid callback object");
return;
}
- const int64_t device = (int64_t) instance->mDevice;
- switch (msg->type) {
- case FINGERPRINT_ERROR:
- ALOGD("onError(%d)", msg->data.error);
- callback->onError(device, msg->data.error);
+ switch (msg.type) {
+ case Type::ERROR:
+ ALOGD("onError(%d)", msg.data.error);
+ callback->onError(0, to_native(msg.data.error));
break;
- case FINGERPRINT_ACQUIRED:
- ALOGD("onAcquired(%d)", msg->data.acquired.acquired_info);
- callback->onAcquired(device, msg->data.acquired.acquired_info);
+ case Type::ACQUIRED:
+ ALOGD("onAcquired(%d)", msg.data.acquired.acquiredInfo);
+ callback->onAcquired(0, to_native(msg.data.acquired.acquiredInfo));
break;
- case FINGERPRINT_AUTHENTICATED:
+ case Type::AUTHENTICATED:
ALOGD("onAuthenticated(fid=%d, gid=%d)",
- msg->data.authenticated.finger.fid,
- msg->data.authenticated.finger.gid);
- if (msg->data.authenticated.finger.fid != 0) {
- const uint8_t* hat = reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
- instance->notifyKeystore(hat, sizeof(msg->data.authenticated.hat));
+ msg.data.authenticated.finger.fid,
+ msg.data.authenticated.finger.gid);
+ if (msg.data.authenticated.finger.fid != 0) {
+ const uint8_t* hat = reinterpret_cast<const uint8_t *>(&msg.data.authenticated.hat);
+ instance->notifyKeystore(hat, sizeof(msg.data.authenticated.hat));
}
- callback->onAuthenticated(device,
- msg->data.authenticated.finger.fid,
- msg->data.authenticated.finger.gid);
+ callback->onAuthenticated(0,
+ msg.data.authenticated.finger.fid,
+ msg.data.authenticated.finger.gid);
break;
- case FINGERPRINT_TEMPLATE_ENROLLING:
+ case Type::TEMPLATE_ENROLLING:
ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)",
- msg->data.enroll.finger.fid,
- msg->data.enroll.finger.gid,
- msg->data.enroll.samples_remaining);
- callback->onEnrollResult(device,
- msg->data.enroll.finger.fid,
- msg->data.enroll.finger.gid,
- msg->data.enroll.samples_remaining);
+ msg.data.enroll.finger.fid,
+ msg.data.enroll.finger.gid,
+ msg.data.enroll.samplesRemaining);
+ callback->onEnrollResult(0,
+ msg.data.enroll.finger.fid,
+ msg.data.enroll.finger.gid,
+ msg.data.enroll.samplesRemaining);
break;
- case FINGERPRINT_TEMPLATE_REMOVED:
+ case Type::TEMPLATE_REMOVED:
ALOGD("onRemove(fid=%d, gid=%d)",
- msg->data.removed.finger.fid,
- msg->data.removed.finger.gid);
- callback->onRemoved(device,
- msg->data.removed.finger.fid,
- msg->data.removed.finger.gid);
+ msg.data.removed.finger.fid,
+ msg.data.removed.finger.gid);
+ callback->onRemoved(0,
+ msg.data.removed.finger.fid,
+ msg.data.removed.finger.gid);
break;
- case FINGERPRINT_TEMPLATE_ENUMERATING:
+ case Type::TEMPLATE_ENUMERATING:
ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)",
- msg->data.enumerated.finger.fid,
- msg->data.enumerated.finger.gid,
- msg->data.enumerated.remaining_templates);
- callback->onEnumerate(device,
- msg->data.enumerated.finger.fid,
- msg->data.enumerated.finger.gid,
- msg->data.enumerated.remaining_templates);
+ msg.data.enumerated.finger.fid,
+ msg.data.enumerated.finger.gid,
+ msg.data.enumerated.remainingTemplates);
+ callback->onEnumerate(0,
+ msg.data.enumerated.finger.fid,
+ msg.data.enumerated.finger.gid,
+ msg.data.enumerated.remainingTemplates);
break;
default:
- ALOGE("invalid msg type: %d", msg->type);
+ ALOGE("invalid msg type: %d", msg.type);
return;
}
}
void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) {
- if (auth_token != NULL && auth_token_length > 0) {
+ if (auth_token != nullptr && auth_token_length > 0) {
// TODO: cache service?
sp < IServiceManager > sm = defaultServiceManager();
sp < IBinder > binder = sm->getService(String16("android.security.keystore"));
sp < IKeystoreService > service = interface_cast < IKeystoreService > (binder);
- if (service != NULL) {
+ if (service != nullptr) {
status_t ret = service->addAuthToken(auth_token, auth_token_length);
if (ret != ResponseCode::NO_ERROR) {
ALOGE("Falure sending auth token to KeyStore: %d", ret);
@@ -122,7 +154,7 @@
}
void FingerprintDaemonProxy::init(const sp<IFingerprintDaemonCallback>& callback) {
- if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) {
+ if (mCallback != nullptr && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) {
IInterface::asBinder(mCallback)->unlinkToDeath(this);
}
IInterface::asBinder(callback)->linkToDeath(this);
@@ -132,49 +164,99 @@
int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId,
int32_t timeout) {
ALOG(LOG_VERBOSE, LOG_TAG, "enroll(gid=%d, timeout=%d)\n", groupId, timeout);
- if (tokenSize != sizeof(hw_auth_token_t) ) {
- ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zu\n", tokenSize);
+ if (tokenSize != hw_auth_token_size) {
+ ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zd, expected %zd\n", tokenSize, hw_auth_token_size);
return -1;
}
- const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(token);
- return mDevice->enroll(mDevice, authToken, groupId, timeout);
+
+ hardware::hidl_array<uint8_t, hw_auth_token_size> hat(token);
+ Return<RequestStatus> ret = gBFP->enroll(hat, groupId, timeout);
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
uint64_t FingerprintDaemonProxy::preEnroll() {
- return mDevice->pre_enroll(mDevice);
+ return gBFP->preEnroll();
}
int32_t FingerprintDaemonProxy::postEnroll() {
- return mDevice->post_enroll(mDevice);
+ Return<RequestStatus> ret = gBFP->postEnroll();
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int32_t FingerprintDaemonProxy::stopEnrollment() {
ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n");
- return mDevice->cancel(mDevice);
+ Return<RequestStatus> ret = gBFP->cancel();
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) {
ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId);
- return mDevice->authenticate(mDevice, sessionId, groupId);
+ Return<RequestStatus> ret = gBFP->authenticate(sessionId, groupId);
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int32_t FingerprintDaemonProxy::stopAuthentication() {
ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n");
- return mDevice->cancel(mDevice);
+ Return<RequestStatus> ret = gBFP->cancel();
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) {
ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId);
- return mDevice->remove(mDevice, groupId, fingerId);
+ Return<RequestStatus> ret = gBFP->remove(groupId, fingerId);
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int32_t FingerprintDaemonProxy::enumerate() {
ALOG(LOG_VERBOSE, LOG_TAG, "enumerate()\n");
- return mDevice->enumerate(mDevice);
+ Return<RequestStatus> ret = gBFP->enumerate();
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
uint64_t FingerprintDaemonProxy::getAuthenticatorId() {
- return mDevice->get_authenticator_id(mDevice);
+ return gBFP->getAuthenticatorId();
}
int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path,
@@ -183,74 +265,35 @@
ALOGE("Bad path length: %zd", pathlen);
return -1;
}
- // Convert to null-terminated string
- char path_name[PATH_MAX];
- memcpy(path_name, path, pathlen);
- path_name[pathlen] = '\0';
- ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, path_name, pathlen);
- return mDevice->set_active_group(mDevice, groupId, path_name);
+ hidl_string pathname;
+ pathname.setToExternal(reinterpret_cast<const char*>(path), pathlen);
+ ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, pathname.c_str(), pathlen);
+ Return<RequestStatus> ret = gBFP->setActiveGroup(groupId, pathname);
+ if (!ret.getStatus().isOk()) {
+ ALOGE("Unknown transport error");
+ return -1;
+ }
+
+ RequestStatus status = ret;
+ return to_native(status);
}
int64_t FingerprintDaemonProxy::openHal() {
- ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n");
- int err;
- const hw_module_t *hw_module = NULL;
- if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) {
- ALOGE("Can't open fingerprint HW Module, error: %d", err);
- return 0;
+ if (gBFP == nullptr) {
+ // TODO(b/31632518)
+ gBFP = IBiometricsFingerprint::getService("fingerprint");
+ if(gBFP == nullptr) {
+ ALOGE("Can't get service fingerprint");
+ return 0;
+ }
}
- if (NULL == hw_module) {
- ALOGE("No valid fingerprint module");
- return 0;
- }
-
- mModule = reinterpret_cast<const fingerprint_module_t*>(hw_module);
-
- if (mModule->common.methods->open == NULL) {
- ALOGE("No valid open method");
- return 0;
- }
-
- hw_device_t *device = NULL;
-
- if (0 != (err = mModule->common.methods->open(hw_module, NULL, &device))) {
- ALOGE("Can't open fingerprint methods, error: %d", err);
- return 0;
- }
-
- if (kVersion != device->version) {
- ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
- // return 0; // FIXME
- }
-
- mDevice = reinterpret_cast<fingerprint_device_t*>(device);
- err = mDevice->set_notify(mDevice, hal_notify_callback);
- if (err < 0) {
- ALOGE("Failed in call to set_notify(), err=%d", err);
- return 0;
- }
-
- // Sanity check - remove
- if (mDevice->notify != hal_notify_callback) {
- ALOGE("NOTIFY not set properly: %p != %p", mDevice->notify, hal_notify_callback);
- }
-
- ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized");
- return reinterpret_cast<int64_t>(mDevice); // This is just a handle
+ gClientCallback = hardware::HIDL_FETCH_IBiometricsFingerprintClientCallback(nullptr);
+ gBFP->setNotify(gClientCallback);
+ return reinterpret_cast<int64_t>(gBFP.get());
}
int32_t FingerprintDaemonProxy::closeHal() {
- ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n");
- if (mDevice == NULL) {
- ALOGE("No valid device");
- return -ENOSYS;
- }
- int err;
- if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) {
- ALOGE("Can't close fingerprint module, error: %d", err);
- return err;
- }
- mDevice = NULL;
+ // Obsolete, return 0 for compatibility reasons.
return 0;
}
@@ -261,8 +304,8 @@
ALOGE("Can't close fingerprint device, error: %d", err);
}
if (IInterface::asBinder(mCallback) == who) {
- mCallback = NULL;
+ mCallback = nullptr;
}
}
-}
+} // namespace android
diff --git a/fingerprintd/FingerprintDaemonProxy.h b/fingerprintd/FingerprintDaemonProxy.h
index 145b4c9..715344c 100644
--- a/fingerprintd/FingerprintDaemonProxy.h
+++ b/fingerprintd/FingerprintDaemonProxy.h
@@ -22,6 +22,8 @@
namespace android {
+using hardware::biometrics::fingerprint::V2_1::RequestStatus;
+
class FingerprintDaemonProxy : public BnFingerprintDaemon {
public:
static FingerprintDaemonProxy* getInstance() {
@@ -45,17 +47,16 @@
virtual int32_t setActiveGroup(int32_t groupId, const uint8_t* path, ssize_t pathLen);
virtual int64_t openHal();
virtual int32_t closeHal();
+ static void hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg);
private:
FingerprintDaemonProxy();
virtual ~FingerprintDaemonProxy();
void binderDied(const wp<IBinder>& who);
void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length);
- static void hal_notify_callback(const fingerprint_msg_t *msg);
+ int32_t HandleTransportError(const RequestStatus error);
static FingerprintDaemonProxy* sInstance;
- fingerprint_module_t const* mModule;
- fingerprint_device_t* mDevice;
sp<IFingerprintDaemonCallback> mCallback;
};
diff --git a/fingerprintd/IFingerprintDaemon.h b/fingerprintd/IFingerprintDaemon.h
index 23c36ff..c5cdbfe 100644
--- a/fingerprintd/IFingerprintDaemon.h
+++ b/fingerprintd/IFingerprintDaemon.h
@@ -17,6 +17,8 @@
#ifndef IFINGERPRINT_DAEMON_H_
#define IFINGERPRINT_DAEMON_H_
+#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
+#include <android/hardware/biometrics/fingerprint/2.1/types.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
@@ -69,7 +71,7 @@
// DECLARE_META_INTERFACE - C++ client interface not needed
static const android::String16 descriptor;
- static void hal_notify_callback(const fingerprint_msg_t *msg);
+ static void hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg);
};
// ----------------------------------------------------------------------------
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index b1511fe..f682216 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/swap.h>
@@ -38,6 +39,7 @@
#include <ext4_utils/ext4_sb.h>
#include <ext4_utils/ext4_utils.h>
#include <ext4_utils/wipe.h>
+#include <linux/fs.h>
#include <linux/loop.h>
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
@@ -50,12 +52,14 @@
#define KEY_IN_FOOTER "footer"
#define E2FSCK_BIN "/system/bin/e2fsck"
-#define F2FS_FSCK_BIN "/system/bin/fsck.f2fs"
+#define F2FS_FSCK_BIN "/system/bin/fsck.f2fs"
#define MKSWAP_BIN "/system/bin/mkswap"
+#define TUNE2FS_BIN "/system/bin/tune2fs"
#define FSCK_LOG_FILE "/dev/fscklogs/log"
#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
+#define ZRAM_CONF_MCS "/sys/block/zram0/max_comp_streams"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -179,6 +183,99 @@
return;
}
+/* Function to read the primary superblock */
+static int read_super_block(int fd, struct ext4_super_block *sb)
+{
+ off64_t ret;
+
+ ret = lseek64(fd, 1024, SEEK_SET);
+ if (ret < 0)
+ return ret;
+
+ ret = read(fd, sb, sizeof(*sb));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(*sb))
+ return ret;
+
+ return 0;
+}
+
+static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
+{
+ return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
+ le32_to_cpu(es->s_blocks_count_lo);
+}
+
+static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
+{
+ return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
+ le32_to_cpu(es->s_r_blocks_count_lo);
+}
+
+static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec)
+{
+ /* Check for the types of filesystems we know how to check */
+ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
+ /*
+ * Some system images do not have tune2fs for licensing reasons
+ * Detect these and skip reserve blocks.
+ */
+ if (access(TUNE2FS_BIN, X_OK)) {
+ ERROR("Not running %s on %s (executable not in system image)\n",
+ TUNE2FS_BIN, blk_device);
+ } else {
+ INFO("Running %s on %s\n", TUNE2FS_BIN, blk_device);
+
+ int status = 0;
+ int ret = 0;
+ unsigned long reserved_blocks = 0;
+ int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
+ if (fd >= 0) {
+ struct ext4_super_block sb;
+ ret = read_super_block(fd, &sb);
+ if (ret < 0) {
+ ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno));
+ goto out;
+ }
+ reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
+ unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
+ if (reserved_threshold < reserved_blocks) {
+ WARNING("Reserved blocks %lu is too large\n", reserved_blocks);
+ reserved_blocks = reserved_threshold;
+ }
+
+ if (ext4_r_blocks_count(&sb) == reserved_blocks) {
+ INFO("Have reserved same blocks\n");
+ goto out;
+ }
+ } else {
+ ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno));
+ return;
+ }
+
+ char buf[16] = {0};
+ snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks);
+ char *tune2fs_argv[] = {
+ TUNE2FS_BIN,
+ buf,
+ blk_device,
+ };
+
+ ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv,
+ &status, true, LOG_KLOG | LOG_FILE,
+ true, NULL, NULL, 0);
+
+ if (ret < 0) {
+ /* No need to check for error in fork, we can't really handle it now */
+ ERROR("Failed trying to run %s\n", TUNE2FS_BIN);
+ }
+ out:
+ close(fd);
+ }
+ }
+}
+
static void remove_trailing_slashes(char *n)
{
int len;
@@ -324,6 +421,12 @@
check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
fstab->recs[i].mount_point);
}
+
+ if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
+ do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
+ &fstab->recs[i]);
+ }
+
if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
*attempted_idx = i;
mounted = 1;
@@ -689,6 +792,10 @@
fstab->recs[i].mount_point);
}
+ if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
+ do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]);
+ }
+
if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
int rc = fs_mgr_setup_verity(&fstab->recs[i]);
if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
@@ -802,6 +909,18 @@
* we can assume the device number is 0.
*/
FILE *zram_fp;
+ FILE *zram_mcs_fp;
+
+ if (fstab->recs[i].max_comp_streams >= 0) {
+ zram_mcs_fp = fopen(ZRAM_CONF_MCS, "r+");
+ if (zram_mcs_fp == NULL) {
+ ERROR("Unable to open zram conf comp device %s\n", ZRAM_CONF_MCS);
+ ret = -1;
+ continue;
+ }
+ fprintf(zram_mcs_fp, "%d\n", fstab->recs[i].max_comp_streams);
+ fclose(zram_mcs_fp);
+ }
zram_fp = fopen(ZRAM_CONF_DEV, "r+");
if (zram_fp == NULL) {
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 2434c78..f25d10c 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -31,7 +31,9 @@
char *label;
int partnum;
int swap_prio;
+ int max_comp_streams;
unsigned int zram_size;
+ uint64_t reserved_size;
unsigned int file_encryption_mode;
};
@@ -72,6 +74,7 @@
{ "recoveryonly",MF_RECOVERYONLY },
{ "swapprio=", MF_SWAPPRIO },
{ "zramsize=", MF_ZRAMSIZE },
+ { "max_comp_streams=", MF_MAX_COMP_STREAMS },
{ "verifyatboot", MF_VERIFYATBOOT },
{ "verify", MF_VERIFY },
{ "noemulatedsd", MF_NOEMULATEDSD },
@@ -80,6 +83,7 @@
{ "slotselect", MF_SLOTSELECT },
{ "nofail", MF_NOFAIL },
{ "latemount", MF_LATEMOUNT },
+ { "reservedsize=", MF_RESERVEDSIZE },
{ "defaults", 0 },
{ 0, 0 },
};
@@ -106,6 +110,20 @@
return total;
}
+static uint64_t parse_size(const char *arg)
+{
+ char *endptr;
+ uint64_t size = strtoull(arg, &endptr, 10);
+ if (*endptr == 'k' || *endptr == 'K')
+ size *= 1024LL;
+ else if (*endptr == 'm' || *endptr == 'M')
+ size *= 1024LL * 1024LL;
+ else if (*endptr == 'g' || *endptr == 'G')
+ size *= 1024LL * 1024LL * 1024LL;
+
+ return size;
+}
+
static int parse_flags(char *flags, struct flag_list *fl,
struct fs_mgr_flag_values *flag_vals,
char *fs_options, int fs_options_len)
@@ -206,6 +224,8 @@
}
} else if ((fl[i].flag == MF_SWAPPRIO) && flag_vals) {
flag_vals->swap_prio = strtoll(strchr(p, '=') + 1, NULL, 0);
+ } else if ((fl[i].flag == MF_MAX_COMP_STREAMS) && flag_vals) {
+ flag_vals->max_comp_streams = strtoll(strchr(p, '=') + 1, NULL, 0);
} else if ((fl[i].flag == MF_ZRAMSIZE) && flag_vals) {
int is_percent = !!strrchr(p, '%');
unsigned int val = strtoll(strchr(p, '=') + 1, NULL, 0);
@@ -213,6 +233,11 @@
flag_vals->zram_size = calculate_zram_size(val);
else
flag_vals->zram_size = val;
+ } else if ((fl[i].flag == MF_RESERVEDSIZE) && flag_vals) {
+ /* The reserved flag is followed by an = and the
+ * reserved size of the partition. Get it and return it.
+ */
+ flag_vals->reserved_size = parse_size(strchr(p, '=') + 1);
}
break;
}
@@ -355,7 +380,9 @@
fstab->recs[cnt].label = flag_vals.label;
fstab->recs[cnt].partnum = flag_vals.partnum;
fstab->recs[cnt].swap_prio = flag_vals.swap_prio;
+ fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams;
fstab->recs[cnt].zram_size = flag_vals.zram_size;
+ fstab->recs[cnt].reserved_size = flag_vals.reserved_size;
fstab->recs[cnt].file_encryption_mode = flag_vals.file_encryption_mode;
cnt++;
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 120ec5a..4632521 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -86,6 +86,8 @@
#define MF_LATEMOUNT 0x20000
#define MF_NOFAIL 0x40000
#define MF_VERIFYATBOOT 0x80000
+#define MF_MAX_COMP_STREAMS 0x100000
+#define MF_RESERVEDSIZE 0x200000
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index af57a55..8c47b3c 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -31,8 +31,8 @@
#include <android-base/file.h>
#include <android-base/strings.h>
-#include <crypto_utils/android_pubkey.h>
#include <android-base/unique_fd.h>
+#include <crypto_utils/android_pubkey.h>
#include <cutils/properties.h>
#include <logwrap/logwrap.h>
#include <openssl/obj_mac.h>
@@ -825,7 +825,7 @@
char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
const char *mount_point;
char propbuf[PROPERTY_VALUE_MAX];
- char *status;
+ const char *status;
int fd = -1;
int i;
int mode;
@@ -875,9 +875,13 @@
verity_ioctl_init(io, mount_point, 0);
if (ioctl(fd, DM_TABLE_STATUS, io)) {
- ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
- strerror(errno));
- continue;
+ if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
+ status = "V";
+ } else {
+ ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
+ strerror(errno));
+ continue;
+ }
}
status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
@@ -937,11 +941,11 @@
struct fec_handle *f = NULL;
struct fec_verity_metadata verity;
struct verity_table_params params = { .table = NULL };
- bool verified_at_boot = false;
alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
char *mount_point = basename(fstab->mount_point);
+ bool verified_at_boot = false;
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
FEC_DEFAULT_ROOTS) < 0) {
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 38c931e..8ecc93c 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -73,7 +73,9 @@
char *label;
int partnum;
int swap_prio;
+ int max_comp_streams;
unsigned int zram_size;
+ uint64_t reserved_size;
unsigned int file_encryption_mode;
};
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 3f78955..0dfd9d8 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -33,7 +33,12 @@
libbase \
libutils \
libcrypto \
- libkeystore_binder
+ libkeystore_binder \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ android.hardware.gatekeeper@1.0 \
+
LOCAL_STATIC_LIBRARIES := libscrypt_static
LOCAL_C_INCLUDES := external/scrypt/lib/crypto
LOCAL_INIT_RC := gatekeeperd.rc
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index 4107f55..d2c119d 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -39,6 +39,15 @@
#include "SoftGateKeeperDevice.h"
#include "IUserManager.h"
+#include <hidl/HidlSupport.h>
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+
+using android::sp;
+using android::hardware::gatekeeper::V1_0::IGatekeeper;
+using android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+using android::hardware::gatekeeper::V1_0::GatekeeperResponse;
+using android::hardware::Return;
+
namespace android {
static const String16 KEYGUARD_PERMISSION("android.permission.ACCESS_KEYGUARD_SECURE_STORAGE");
@@ -47,28 +56,22 @@
class GateKeeperProxy : public BnGateKeeperService {
public:
GateKeeperProxy() {
- int ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &module);
- device = NULL;
+ hw_device = IGatekeeper::getService("gatekeeper");
- if (ret < 0) {
+ if (hw_device == nullptr) {
ALOGW("falling back to software GateKeeper");
soft_device.reset(new SoftGateKeeperDevice());
- } else {
- ret = gatekeeper_open(module, &device);
- if (ret < 0)
- LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to open GateKeeper HAL");
}
if (mark_cold_boot()) {
ALOGI("cold boot: clearing state");
- if (device != NULL && device->delete_all_users != NULL) {
- device->delete_all_users(device);
+ if (hw_device != nullptr) {
+ hw_device->deleteAllUsers([](const GatekeeperResponse &){});
}
}
}
virtual ~GateKeeperProxy() {
- if (device) gatekeeper_close(device);
}
void store_sid(uint32_t uid, uint64_t sid) {
@@ -141,7 +144,7 @@
if (desired_password_length == 0) return -EINVAL;
int ret;
- if (device) {
+ if (hw_device != nullptr) {
const gatekeeper::password_handle_t *handle =
reinterpret_cast<const gatekeeper::password_handle_t *>(current_password_handle);
@@ -154,10 +157,37 @@
current_password_length = 0;
}
- ret = device->enroll(device, uid, current_password_handle, current_password_handle_length,
- current_password, current_password_length,
- desired_password, desired_password_length,
- enrolled_password_handle, enrolled_password_handle_length);
+ android::hardware::hidl_vec<uint8_t> curPwdHandle;
+ curPwdHandle.setToExternal(const_cast<uint8_t*>(current_password_handle),
+ current_password_handle_length);
+ android::hardware::hidl_vec<uint8_t> curPwd;
+ curPwd.setToExternal(const_cast<uint8_t*>(current_password),
+ current_password_length);
+ android::hardware::hidl_vec<uint8_t> newPwd;
+ newPwd.setToExternal(const_cast<uint8_t*>(desired_password),
+ desired_password_length);
+
+ Return<void> hwRes = hw_device->enroll(uid, curPwdHandle, curPwd, newPwd,
+ [&ret, enrolled_password_handle, enrolled_password_handle_length]
+ (const GatekeeperResponse &rsp) {
+ ret = static_cast<int>(rsp.code); // propagate errors
+ if (rsp.code >= GatekeeperStatusCode::STATUS_OK) {
+ if (enrolled_password_handle != nullptr &&
+ enrolled_password_handle_length != nullptr) {
+ *enrolled_password_handle = new uint8_t[rsp.data.size()];
+ *enrolled_password_handle_length = rsp.data.size();
+ memcpy(*enrolled_password_handle, rsp.data.data(),
+ *enrolled_password_handle_length);
+ }
+ ret = 0; // all success states are reported as 0
+ } else if (rsp.code == GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
+ ret = rsp.timeout;
+ }
+ });
+ if (!hwRes.getStatus().isOk()) {
+ ALOGE("enroll transaction failed\n");
+ ret = -1;
+ }
} else {
ret = soft_device->enroll(uid,
current_password_handle, current_password_handle_length,
@@ -207,16 +237,40 @@
return -EINVAL;
int ret;
- if (device) {
+ if (hw_device != nullptr) {
const gatekeeper::password_handle_t *handle =
reinterpret_cast<const gatekeeper::password_handle_t *>(enrolled_password_handle);
// handle version 0 does not have hardware backed flag, and thus cannot be upgraded to
// a HAL if there was none before
if (handle->version == 0 || handle->hardware_backed) {
- ret = device->verify(device, uid, challenge,
- enrolled_password_handle, enrolled_password_handle_length,
- provided_password, provided_password_length, auth_token, auth_token_length,
- request_reenroll);
+ android::hardware::hidl_vec<uint8_t> curPwdHandle;
+ curPwdHandle.setToExternal(const_cast<uint8_t*>(enrolled_password_handle),
+ enrolled_password_handle_length);
+ android::hardware::hidl_vec<uint8_t> enteredPwd;
+ enteredPwd.setToExternal(const_cast<uint8_t*>(provided_password),
+ provided_password_length);
+ Return<void> hwRes = hw_device->verify(uid, challenge, curPwdHandle, enteredPwd,
+ [&ret, request_reenroll, auth_token, auth_token_length]
+ (const GatekeeperResponse &rsp) {
+ ret = static_cast<int>(rsp.code); // propagate errors
+ if (auth_token != nullptr && auth_token_length != nullptr &&
+ rsp.code >= GatekeeperStatusCode::STATUS_OK) {
+ *auth_token = new uint8_t[rsp.data.size()];
+ *auth_token_length = rsp.data.size();
+ memcpy(*auth_token, rsp.data.data(), *auth_token_length);
+ if (request_reenroll != nullptr) {
+ *request_reenroll = (rsp.code == GatekeeperStatusCode::STATUS_REENROLL);
+ }
+ ret = 0; // all success states are reported as 0
+ } else if (rsp.code == GatekeeperStatusCode::ERROR_RETRY_TIMEOUT &&
+ rsp.timeout > 0) {
+ ret = rsp.timeout;
+ }
+ });
+ if (!hwRes.getStatus().isOk()) {
+ ALOGE("verify transaction failed\n");
+ ret = -1;
+ }
} else {
// upgrade scenario, a HAL has been added to this device where there was none before
SoftGateKeeperDevice soft_dev;
@@ -288,8 +342,8 @@
}
clear_sid(uid);
- if (device != NULL && device->delete_user != NULL) {
- device->delete_user(device, uid);
+ if (hw_device != nullptr) {
+ hw_device->deleteUser(uid, [] (const GatekeeperResponse &){});
}
}
@@ -301,7 +355,7 @@
return PERMISSION_DENIED;
}
- if (device == NULL) {
+ if (hw_device == NULL) {
const char *result = "Device not available";
write(fd, result, strlen(result) + 1);
} else {
@@ -313,9 +367,8 @@
}
private:
- gatekeeper_device_t *device;
+ sp<IGatekeeper> hw_device;
UniquePtr<SoftGateKeeperDevice> soft_device;
- const hw_module_t *module;
};
}// namespace android
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 1a96e88..8b59964 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -189,7 +189,8 @@
liblog \
libm \
libc \
- libhidl \
+ libhidlbase \
+ libhidltransport \
android.hardware.health@1.0 \
include $(BUILD_EXECUTABLE)
diff --git a/include/cutils/files.h b/include/cutils/android_get_control_file.h
similarity index 87%
rename from include/cutils/files.h
rename to include/cutils/android_get_control_file.h
index 0210e30..ed8fbf8 100644
--- a/include/cutils/files.h
+++ b/include/cutils/android_get_control_file.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef __CUTILS_FILES_H
-#define __CUTILS_FILES_H
+#ifndef __CUTILS_ANDROID_GET_CONTROL_FILE_H
+#define __CUTILS_ANDROID_GET_CONTROL_FILE_H
#define ANDROID_FILE_ENV_PREFIX "ANDROID_FILE_"
@@ -34,4 +34,4 @@
}
#endif
-#endif /* __CUTILS_FILES_H */
+#endif /* __CUTILS_ANDROID_GET_CONTROL_FILE_H */
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index 4626e7a..d724dd6 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -35,6 +35,7 @@
#else
#include <sys/socket.h>
+#include <netinet/in.h>
typedef int cutils_socket_t;
#define INVALID_SOCKET (-1)
diff --git a/include/log/log.h b/include/log/log.h
index a44aba8..d6f0eb5 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -27,15 +27,8 @@
#include <time.h> /* clock_gettime */
#include <unistd.h>
-#include <log/uio.h> /* helper to define iovec for portability */
-
-#if (defined(__cplusplus) && defined(_USING_LIBCXX))
-extern "C++" {
-#include <string>
-}
-#endif
-
#include <android/log.h>
+#include <log/uio.h> /* helper to define iovec for portability */
#ifdef __cplusplus
extern "C" {
@@ -774,207 +767,6 @@
/* --------------------------------------------------------------------- */
-#ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE
-#ifndef __ANDROID_API__
-#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
-#elif __ANDROID_API__ > 23 /* > Marshmallow */
-#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
-#else
-#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0
-#endif
-#endif
-
-#if __ANDROID_USE_LIBLOG_EVENT_INTERFACE
-
-/* For manipulating lists of events. */
-
-#define ANDROID_MAX_LIST_NEST_DEPTH 8
-
-/*
- * The opaque context used to manipulate lists of events.
- */
-#ifndef __android_log_context_defined
-#define __android_log_context_defined
-typedef struct android_log_context_internal* android_log_context;
-#endif
-
-/*
- * Elements returned when reading a list of events.
- */
-#ifndef __android_log_list_element_defined
-#define __android_log_list_element_defined
-typedef struct {
- AndroidEventLogType type;
- uint16_t complete;
- uint16_t len;
- union {
- int32_t int32;
- int64_t int64;
- char* string;
- float float32;
- } data;
-} android_log_list_element;
-#endif
-
-/*
- * Creates a context associated with an event tag to write elements to
- * the list of events.
- */
-android_log_context create_android_logger(uint32_t tag);
-
-/* All lists must be braced by a begin and end call */
-/*
- * NB: If the first level braces are missing when specifying multiple
- * elements, we will manufacturer a list to embrace it for your API
- * convenience. For a single element, it will remain solitary.
- */
-int android_log_write_list_begin(android_log_context ctx);
-int android_log_write_list_end(android_log_context ctx);
-
-int android_log_write_int32(android_log_context ctx, int32_t value);
-int android_log_write_int64(android_log_context ctx, int64_t value);
-int android_log_write_string8(android_log_context ctx, const char* value);
-int android_log_write_string8_len(android_log_context ctx,
- const char* value, size_t maxlen);
-int android_log_write_float32(android_log_context ctx, float value);
-
-/* Submit the composed list context to the specified logger id */
-/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
-int android_log_write_list(android_log_context ctx, log_id_t id);
-
-/*
- * Creates a context from a raw buffer representing a list of events to be read.
- */
-android_log_context create_android_log_parser(const char* msg, size_t len);
-
-android_log_list_element android_log_read_next(android_log_context ctx);
-android_log_list_element android_log_peek_next(android_log_context ctx);
-
-/* Finished with reader or writer context */
-int android_log_destroy(android_log_context* ctx);
-
-#ifdef __cplusplus
-#ifndef __class_android_log_event_context
-#define __class_android_log_event_context
-/* android_log_context C++ helpers */
-extern "C++" {
-class android_log_event_context {
- android_log_context ctx;
- int ret;
-
- android_log_event_context(const android_log_event_context&) = delete;
- void operator =(const android_log_event_context&) = delete;
-
-public:
- explicit android_log_event_context(int tag) : ret(0) {
- ctx = create_android_logger(static_cast<uint32_t>(tag));
- }
- explicit android_log_event_context(log_msg& log_msg) : ret(0) {
- ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
- log_msg.entry.len - sizeof(uint32_t));
- }
- ~android_log_event_context() { android_log_destroy(&ctx); }
-
- int close() {
- int retval = android_log_destroy(&ctx);
- if (retval < 0) ret = retval;
- return retval;
- }
-
- /* To allow above C calls to use this class as parameter */
- operator android_log_context() const { return ctx; }
-
- int status() const { return ret; }
-
- int begin() {
- int retval = android_log_write_list_begin(ctx);
- if (retval < 0) ret = retval;
- return ret;
- }
- int end() {
- int retval = android_log_write_list_end(ctx);
- if (retval < 0) ret = retval;
- return ret;
- }
-
- android_log_event_context& operator <<(int32_t value) {
- int retval = android_log_write_int32(ctx, value);
- if (retval < 0) ret = retval;
- return *this;
- }
- android_log_event_context& operator <<(uint32_t value) {
- int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
- if (retval < 0) ret = retval;
- return *this;
- }
- android_log_event_context& operator <<(int64_t value) {
- int retval = android_log_write_int64(ctx, value);
- if (retval < 0) ret = retval;
- return *this;
- }
- android_log_event_context& operator <<(uint64_t value) {
- int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
- if (retval < 0) ret = retval;
- return *this;
- }
- android_log_event_context& operator <<(const char* value) {
- int retval = android_log_write_string8(ctx, value);
- if (retval < 0) ret = retval;
- return *this;
- }
-#if defined(_USING_LIBCXX)
- android_log_event_context& operator <<(const std::string& value) {
- int retval = android_log_write_string8_len(ctx,
- value.data(),
- value.length());
- if (retval < 0) ret = retval;
- return *this;
- }
-#endif
- android_log_event_context& operator <<(float value) {
- int retval = android_log_write_float32(ctx, value);
- if (retval < 0) ret = retval;
- return *this;
- }
-
- int write(log_id_t id = LOG_ID_EVENTS) {
- int retval = android_log_write_list(ctx, id);
- if (retval < 0) ret = retval;
- return ret;
- }
-
- int operator <<(log_id_t id) {
- int retval = android_log_write_list(ctx, id);
- if (retval < 0) ret = retval;
- android_log_destroy(&ctx);
- return ret;
- }
-
- /*
- * Append should be a lesser-used interface, but adds
- * access to string with length. So we offer all types.
- */
- template <typename Tvalue>
- bool Append(Tvalue value) { *this << value; return ret >= 0; }
-
- bool Append(const char* value, size_t len) {
- int retval = android_log_write_string8_len(ctx, value, len);
- if (retval < 0) ret = retval;
- return ret >= 0;
- }
-
- android_log_list_element read() { return android_log_read_next(ctx); }
- android_log_list_element peek() { return android_log_peek_next(ctx); }
-
-};
-}
-#endif
-#endif
-
-#endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */
-
-/* --------------------------------------------------------------------- */
-
#ifndef _ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
#ifndef __ANDROID_API__
#define __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE 1
diff --git a/include/log/log_event_list.h b/include/log/log_event_list.h
new file mode 100644
index 0000000..31d49b2
--- /dev/null
+++ b/include/log/log_event_list.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2005-2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_LOG_EVENT_LIST_H
+#define _LIBS_LOG_EVENT_LIST_H
+
+#include <stdint.h>
+
+#if (defined(__cplusplus) && defined(_USING_LIBCXX))
+extern "C++" {
+#include <string>
+}
+#endif
+
+#include <log/log.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE
+#ifndef __ANDROID_API__
+#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
+#elif __ANDROID_API__ > 23 /* > Marshmallow */
+#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
+#else
+#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0
+#endif
+#endif
+
+#if __ANDROID_USE_LIBLOG_EVENT_INTERFACE
+
+/* For manipulating lists of events. */
+
+#define ANDROID_MAX_LIST_NEST_DEPTH 8
+
+/*
+ * The opaque context used to manipulate lists of events.
+ */
+#ifndef __android_log_context_defined
+#define __android_log_context_defined
+typedef struct android_log_context_internal* android_log_context;
+#endif
+
+/*
+ * Elements returned when reading a list of events.
+ */
+#ifndef __android_log_list_element_defined
+#define __android_log_list_element_defined
+typedef struct {
+ AndroidEventLogType type;
+ uint16_t complete;
+ uint16_t len;
+ union {
+ int32_t int32;
+ int64_t int64;
+ char* string;
+ float float32;
+ } data;
+} android_log_list_element;
+#endif
+
+/*
+ * Creates a context associated with an event tag to write elements to
+ * the list of events.
+ */
+android_log_context create_android_logger(uint32_t tag);
+
+/* All lists must be braced by a begin and end call */
+/*
+ * NB: If the first level braces are missing when specifying multiple
+ * elements, we will manufacturer a list to embrace it for your API
+ * convenience. For a single element, it will remain solitary.
+ */
+int android_log_write_list_begin(android_log_context ctx);
+int android_log_write_list_end(android_log_context ctx);
+
+int android_log_write_int32(android_log_context ctx, int32_t value);
+int android_log_write_int64(android_log_context ctx, int64_t value);
+int android_log_write_string8(android_log_context ctx, const char* value);
+int android_log_write_string8_len(android_log_context ctx,
+ const char* value, size_t maxlen);
+int android_log_write_float32(android_log_context ctx, float value);
+
+/* Submit the composed list context to the specified logger id */
+/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
+int android_log_write_list(android_log_context ctx, log_id_t id);
+
+/*
+ * Creates a context from a raw buffer representing a list of events to be read.
+ */
+android_log_context create_android_log_parser(const char* msg, size_t len);
+
+android_log_list_element android_log_read_next(android_log_context ctx);
+android_log_list_element android_log_peek_next(android_log_context ctx);
+
+/* Finished with reader or writer context */
+int android_log_destroy(android_log_context* ctx);
+
+#ifdef __cplusplus
+#ifndef __class_android_log_event_list_defined
+#define __class_android_log_event_list_defined
+/* android_log_list C++ helpers */
+extern "C++" {
+class android_log_event_list {
+friend class __android_log_event_list;
+
+private:
+ android_log_context ctx;
+ int ret;
+
+ android_log_event_list(const android_log_event_list&) = delete;
+ void operator =(const android_log_event_list&) = delete;
+
+public:
+ explicit android_log_event_list(int tag) : ret(0) {
+ ctx = create_android_logger(static_cast<uint32_t>(tag));
+ }
+ explicit android_log_event_list(log_msg& log_msg) : ret(0) {
+ ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
+ log_msg.entry.len - sizeof(uint32_t));
+ }
+ ~android_log_event_list() { android_log_destroy(&ctx); }
+
+ int close() {
+ int retval = android_log_destroy(&ctx);
+ if (retval < 0) ret = retval;
+ return retval;
+ }
+
+ /* To allow above C calls to use this class as parameter */
+ operator android_log_context() const { return ctx; }
+
+ int status() const { return ret; }
+
+ int begin() {
+ int retval = android_log_write_list_begin(ctx);
+ if (retval < 0) ret = retval;
+ return ret;
+ }
+ int end() {
+ int retval = android_log_write_list_end(ctx);
+ if (retval < 0) ret = retval;
+ return ret;
+ }
+
+ android_log_event_list& operator <<(int32_t value) {
+ int retval = android_log_write_int32(ctx, value);
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+ android_log_event_list& operator <<(uint32_t value) {
+ int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+ android_log_event_list& operator <<(int64_t value) {
+ int retval = android_log_write_int64(ctx, value);
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+ android_log_event_list& operator <<(uint64_t value) {
+ int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+ android_log_event_list& operator <<(const char* value) {
+ int retval = android_log_write_string8(ctx, value);
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+#if defined(_USING_LIBCXX)
+ android_log_event_list& operator <<(const std::string& value) {
+ int retval = android_log_write_string8_len(ctx,
+ value.data(),
+ value.length());
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+#endif
+
+ android_log_event_list& operator <<(float value) {
+ int retval = android_log_write_float32(ctx, value);
+ if (retval < 0) ret = retval;
+ return *this;
+ }
+
+ int write(log_id_t id = LOG_ID_EVENTS) {
+ int retval = android_log_write_list(ctx, id);
+ if (retval < 0) ret = retval;
+ return ret;
+ }
+
+ int operator <<(log_id_t id) {
+ int retval = android_log_write_list(ctx, id);
+ if (retval < 0) ret = retval;
+ android_log_destroy(&ctx);
+ return ret;
+ }
+
+ /*
+ * Append<Type> methods removes any integer promotion
+ * confusion, and adds access to string with length.
+ * Append methods are also added for all types for
+ * convenience.
+ */
+
+ bool AppendInt(int32_t value) {
+ int retval = android_log_write_int32(ctx, value);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+ bool AppendLong(int64_t value) {
+ int retval = android_log_write_int64(ctx, value);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+ bool AppendString(const char* value) {
+ int retval = android_log_write_string8(ctx, value);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+ bool AppendString(const char* value, size_t len) {
+ int retval = android_log_write_string8_len(ctx, value, len);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+#if defined(_USING_LIBCXX)
+ bool AppendString(const std::string& value) {
+ int retval = android_log_write_string8_len(ctx,
+ value.data(),
+ value.length());
+ if (retval < 0) ret = retval;
+ return ret;
+ }
+
+ bool Append(const std::string& value) {
+ int retval = android_log_write_string8_len(ctx,
+ value.data(),
+ value.length());
+ if (retval < 0) ret = retval;
+ return ret;
+ }
+#endif
+
+ bool AppendFloat(float value) {
+ int retval = android_log_write_float32(ctx, value);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+ template <typename Tvalue>
+ bool Append(Tvalue value) { *this << value; return ret >= 0; }
+
+ bool Append(const char* value, size_t len) {
+ int retval = android_log_write_string8_len(ctx, value, len);
+ if (retval < 0) ret = retval;
+ return ret >= 0;
+ }
+
+ android_log_list_element read() { return android_log_read_next(ctx); }
+ android_log_list_element peek() { return android_log_peek_next(ctx); }
+
+};
+}
+#endif
+#endif
+
+#endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBS_LOG_EVENT_LIST_H */
diff --git a/include/private/android_logger.h b/include/private/android_logger.h
index f3c6cf7..9f81b1f 100644
--- a/include/private/android_logger.h
+++ b/include/private/android_logger.h
@@ -25,6 +25,13 @@
#include <stdint.h>
#include <sys/types.h>
+#if (defined(__cplusplus) && defined(_USING_LIBCXX))
+extern "C++" {
+#include <string>
+}
+#endif
+
+#include <log/log_event_list.h>
#include <log/log.h>
#define LOGGER_MAGIC 'l'
@@ -146,6 +153,40 @@
unsigned long __android_logger_get_buffer_size(log_id_t logId);
bool __android_logger_valid_buffer_size(unsigned long value);
+/* Retrieve the composed event buffer */
+int android_log_write_list_buffer(android_log_context ctx, const char** msg);
+
+#ifdef __cplusplus
+#ifdef __class_android_log_event_list_defined
+#ifndef __class_android_log_event_list_private_defined
+#define __class_android_log_event_list_private_defined
+/* android_log_context C++ helpers */
+extern "C++" {
+class __android_log_event_list : public android_log_event_list {
+ __android_log_event_list(const android_log_event_list&) = delete;
+ void operator =(const __android_log_event_list&) = delete;
+
+public:
+ explicit __android_log_event_list(int tag) : android_log_event_list(tag) { }
+ explicit __android_log_event_list(log_msg& log_msg) : android_log_event_list(log_msg) { }
+
+#if defined(_USING_LIBCXX)
+ operator std::string() {
+ if (ret) return std::string("");
+ const char* cp = NULL;
+ ssize_t len = android_log_write_list_buffer(ctx, &cp);
+ if (len < 0) ret = len;
+ if (!cp || (len <= 0)) return std::string("");
+ return std::string(cp, len);
+ }
+#endif
+
+};
+}
+#endif
+#endif
+#endif
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/system/graphics-base.h b/include/system/graphics-base.h
index cebd2f9..b86d031 100644
--- a/include/system/graphics-base.h
+++ b/include/system/graphics-base.h
@@ -13,6 +13,8 @@
HAL_PIXEL_FORMAT_RGB_888 = 3,
HAL_PIXEL_FORMAT_RGB_565 = 4,
HAL_PIXEL_FORMAT_BGRA_8888 = 5,
+ HAL_PIXEL_FORMAT_RGBA_FP16 = 16, // 0x10
+ HAL_PIXEL_FORMAT_RGBX_FP16 = 17, // 0x11
HAL_PIXEL_FORMAT_YV12 = 842094169, // 0x32315659
HAL_PIXEL_FORMAT_Y8 = 538982489, // 0x20203859
HAL_PIXEL_FORMAT_Y16 = 540422489, // 0x20363159
@@ -55,6 +57,8 @@
HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE = 458752, // (7 << STANDARD_SHIFT)
HAL_DATASPACE_STANDARD_BT470M = 524288, // (8 << STANDARD_SHIFT)
HAL_DATASPACE_STANDARD_FILM = 589824, // (9 << STANDARD_SHIFT)
+ HAL_DATASPACE_STANDARD_DCI_P3 = 655360, // (10 << STANDARD_SHIFT)
+ HAL_DATASPACE_STANDARD_ADOBE_RGB = 720896, // (11 << STANDARD_SHIFT)
HAL_DATASPACE_TRANSFER_SHIFT = 22,
HAL_DATASPACE_TRANSFER_MASK = 130023424, // (31 << TRANSFER_SHIFT)
HAL_DATASPACE_TRANSFER_UNSPECIFIED = 0, // (0 << TRANSFER_SHIFT)
@@ -62,18 +66,22 @@
HAL_DATASPACE_TRANSFER_SRGB = 8388608, // (2 << TRANSFER_SHIFT)
HAL_DATASPACE_TRANSFER_SMPTE_170M = 12582912, // (3 << TRANSFER_SHIFT)
HAL_DATASPACE_TRANSFER_GAMMA2_2 = 16777216, // (4 << TRANSFER_SHIFT)
- HAL_DATASPACE_TRANSFER_GAMMA2_8 = 20971520, // (5 << TRANSFER_SHIFT)
- HAL_DATASPACE_TRANSFER_ST2084 = 25165824, // (6 << TRANSFER_SHIFT)
- HAL_DATASPACE_TRANSFER_HLG = 29360128, // (7 << TRANSFER_SHIFT)
+ HAL_DATASPACE_TRANSFER_GAMMA2_6 = 20971520, // (5 << TRANSFER_SHIFT)
+ HAL_DATASPACE_TRANSFER_GAMMA2_8 = 25165824, // (6 << TRANSFER_SHIFT)
+ HAL_DATASPACE_TRANSFER_ST2084 = 29360128, // (7 << TRANSFER_SHIFT)
+ HAL_DATASPACE_TRANSFER_HLG = 33554432, // (8 << TRANSFER_SHIFT)
HAL_DATASPACE_RANGE_SHIFT = 27,
HAL_DATASPACE_RANGE_MASK = 939524096, // (7 << RANGE_SHIFT)
HAL_DATASPACE_RANGE_UNSPECIFIED = 0, // (0 << RANGE_SHIFT)
HAL_DATASPACE_RANGE_FULL = 134217728, // (1 << RANGE_SHIFT)
HAL_DATASPACE_RANGE_LIMITED = 268435456, // (2 << RANGE_SHIFT)
+ HAL_DATASPACE_RANGE_EXTENDED = 402653184, // (3 << RANGE_SHIFT)
HAL_DATASPACE_SRGB_LINEAR = 512, // 0x200
HAL_DATASPACE_V0_SRGB_LINEAR = 138477568, // ((STANDARD_BT709 | TRANSFER_LINEAR) | RANGE_FULL)
+ HAL_DATASPACE_V0_SCRGB_LINEAR = 406913024, // ((STANDARD_BT709 | TRANSFER_LINEAR) | RANGE_EXTENDED)
HAL_DATASPACE_SRGB = 513, // 0x201
HAL_DATASPACE_V0_SRGB = 142671872, // ((STANDARD_BT709 | TRANSFER_SRGB) | RANGE_FULL)
+ HAL_DATASPACE_V0_SCRGB = 411107328, // ((STANDARD_BT709 | TRANSFER_SRGB) | RANGE_EXTENDED)
HAL_DATASPACE_JFIF = 257, // 0x101
HAL_DATASPACE_V0_JFIF = 146931712, // ((STANDARD_BT601_625 | TRANSFER_SMPTE_170M) | RANGE_FULL)
HAL_DATASPACE_BT601_625 = 258, // 0x102
@@ -82,6 +90,11 @@
HAL_DATASPACE_V0_BT601_525 = 281280512, // ((STANDARD_BT601_525 | TRANSFER_SMPTE_170M) | RANGE_LIMITED)
HAL_DATASPACE_BT709 = 260, // 0x104
HAL_DATASPACE_V0_BT709 = 281083904, // ((STANDARD_BT709 | TRANSFER_SMPTE_170M) | RANGE_LIMITED)
+ HAL_DATASPACE_DCI_P3_LINEAR = 139067392, // ((STANDARD_DCI_P3 | TRANSFER_LINEAR) | RANGE_FULL)
+ HAL_DATASPACE_DCI_P3 = 155844608, // ((STANDARD_DCI_P3 | TRANSFER_GAMMA2_6) | RANGE_FULL)
+ HAL_DATASPACE_ADOBE_RGB = 151715840, // ((STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2) | RANGE_FULL)
+ HAL_DATASPACE_BT2020_LINEAR = 138805248, // ((STANDARD_BT2020 | TRANSFER_LINEAR) | RANGE_FULL)
+ HAL_DATASPACE_BT2020 = 147193856, // ((STANDARD_BT2020 | TRANSFER_SMPTE_170M) | RANGE_FULL)
HAL_DATASPACE_DEPTH = 4096, // 0x1000
} android_dataspace_t;
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index fc845a4..54946fc 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -195,7 +195,8 @@
* Uncompress and write an entry to an open file identified by |fd|.
* |entry->uncompressed_length| bytes will be written to the file at
* its current offset, and the file will be truncated at the end of
- * the uncompressed data.
+ * the uncompressed data (no truncation if |fd| references a block
+ * device).
*
* Returns 0 on success and negative values on failure.
*/
diff --git a/init/action.cpp b/init/action.cpp
index ccc18cf..0ea7e14 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -105,7 +105,10 @@
}
void Action::ExecuteOneCommand(std::size_t command) const {
- ExecuteCommand(commands_[command]);
+ // We need a copy here since some Command execution may result in
+ // changing commands_ vector by importing .rc files through parser
+ Command cmd = commands_[command];
+ ExecuteCommand(cmd);
}
void Action::ExecuteAllCommands() const {
@@ -118,14 +121,16 @@
Timer t;
int result = command.InvokeFunc();
- // TODO: this should probably be changed to "if (failed || took a long time)"...
- if (android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
+ double duration_ms = t.duration() * 1000;
+ // Any action longer than 50ms will be warned to user as slow operation
+ if (duration_ms > 50.0 ||
+ android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
std::string trigger_name = BuildTriggersString();
std::string cmd_str = command.BuildCommandString();
std::string source = command.BuildSourceString();
LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << source
- << " returned " << result << " took " << t.duration() << "s";
+ << " returned " << result << " took " << duration_ms << "ms.";
}
}
@@ -152,6 +157,11 @@
bool Action::InitTriggers(const std::vector<std::string>& args, std::string* err) {
const static std::string prop_str("property:");
for (std::size_t i = 0; i < args.size(); ++i) {
+ if (args[i].empty()) {
+ *err = "empty trigger is not valid";
+ return false;
+ }
+
if (i % 2) {
if (args[i] != "&&") {
*err = "&& is the only symbol allowed to concatenate actions";
@@ -181,7 +191,11 @@
bool Action::InitSingleTrigger(const std::string& trigger) {
std::vector<std::string> name_vector{trigger};
std::string err;
- return InitTriggers(name_vector, &err);
+ bool ret = InitTriggers(name_vector, &err);
+ if (!ret) {
+ LOG(ERROR) << "InitSingleTrigger failed due to: " << err;
+ }
+ return ret;
}
// This function checks that all property triggers are satisfied, that is
@@ -247,9 +261,7 @@
result += event_trigger_;
result += ' ';
}
- if (!result.empty()) {
- result.pop_back();
- }
+ result.pop_back();
return result;
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 8524234..42ae5e6 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -38,6 +38,9 @@
#include <linux/loop.h>
#include <linux/module.h>
+#include <thread>
+
+#include <selinux/android.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -65,7 +68,6 @@
#include "util.h"
#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
-#define UNMOUNT_CHECK_MS 5000
#define UNMOUNT_CHECK_TIMES 10
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
@@ -192,11 +194,9 @@
close(fd);
break;
} else if (errno == EBUSY) {
- /* Some processes using |entry->mnt_dir| are still alive. Wait for a
- * while then retry.
- */
- TEMP_FAILURE_RETRY(
- usleep(UNMOUNT_CHECK_MS * 1000 / UNMOUNT_CHECK_TIMES));
+ // Some processes using |entry->mnt_dir| are still alive. Wait for a
+ // while then retry.
+ std::this_thread::sleep_for(5000ms / UNMOUNT_CHECK_TIMES);
continue;
} else {
/* Cannot open the device. Give up. */
@@ -595,9 +595,9 @@
for (na = args.size() - 1; na > 1; --na) {
if (args[na] == "--early") {
- path_arg_end = na;
- queue_event = false;
- mount_mode = MOUNT_MODE_EARLY;
+ path_arg_end = na;
+ queue_event = false;
+ mount_mode = MOUNT_MODE_EARLY;
} else if (args[na] == "--late") {
path_arg_end = na;
import_rc = false;
@@ -754,7 +754,7 @@
}
// Wait a bit before recounting the number or running services.
- usleep(50000 /*us*/);
+ std::this_thread::sleep_for(50ms);
}
LOG(VERBOSE) << "Terminating running services took " << t.duration() << " seconds";
}
@@ -910,25 +910,49 @@
static int do_restorecon(const std::vector<std::string>& args) {
int ret = 0;
- for (auto it = std::next(args.begin()); it != args.end(); ++it) {
- if (restorecon(it->c_str()) < 0)
- ret = -errno;
+ struct flag_type {const char* name; int value;};
+ static const flag_type flags[] = {
+ {"--recursive", SELINUX_ANDROID_RESTORECON_RECURSE},
+ {"--skip-ce", SELINUX_ANDROID_RESTORECON_SKIPCE},
+ {"--cross-filesystems", SELINUX_ANDROID_RESTORECON_CROSS_FILESYSTEMS},
+ {0, 0}
+ };
+
+ int flag = 0;
+
+ bool in_flags = true;
+ for (size_t i = 1; i < args.size(); ++i) {
+ if (android::base::StartsWith(args[i], "--")) {
+ if (!in_flags) {
+ LOG(ERROR) << "restorecon - flags must precede paths";
+ return -1;
+ }
+ bool found = false;
+ for (size_t j = 0; flags[j].name; ++j) {
+ if (args[i] == flags[j].name) {
+ flag |= flags[j].value;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ LOG(ERROR) << "restorecon - bad flag " << args[i];
+ return -1;
+ }
+ } else {
+ in_flags = false;
+ if (restorecon(args[i].c_str(), flag) < 0) {
+ ret = -errno;
+ }
+ }
}
return ret;
}
static int do_restorecon_recursive(const std::vector<std::string>& args) {
- int ret = 0;
-
- for (auto it = std::next(args.begin()); it != args.end(); ++it) {
- /* The contents of CE paths are encrypted on FBE devices until user
- * credentials are presented (filenames inside are mangled), so we need
- * to delay restorecon of those until vold explicitly requests it. */
- if (restorecon_recursive_skipce(it->c_str()) < 0) {
- ret = -errno;
- }
- }
- return ret;
+ std::vector<std::string> non_const_args(args);
+ non_const_args.insert(std::next(non_const_args.begin()), "--recursive");
+ return do_restorecon(non_const_args);
}
static int do_loglevel(const std::vector<std::string>& args) {
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index 10aae88..429a76e 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -23,7 +23,7 @@
#include <unistd.h>
#include <android-base/stringprintf.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
#include "init.h"
diff --git a/init/devices.cpp b/init/devices.cpp
index d422ba7..2db24b7 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -35,6 +35,7 @@
#include <linux/netlink.h>
#include <memory>
+#include <thread>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -110,13 +111,18 @@
return -ENOMEM;
node->dp.name = strdup(name);
- if (!node->dp.name)
+ if (!node->dp.name) {
+ free(node);
return -ENOMEM;
+ }
if (attr) {
node->dp.attr = strdup(attr);
- if (!node->dp.attr)
+ if (!node->dp.attr) {
+ free(node->dp.name);
+ free(node);
return -ENOMEM;
+ }
}
node->dp.perm = perm;
@@ -184,7 +190,7 @@
if (access(path.c_str(), F_OK) == 0) {
LOG(VERBOSE) << "restorecon_recursive: " << path;
- restorecon_recursive(path.c_str());
+ restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
}
}
@@ -841,7 +847,7 @@
if (booting) {
// If we're not fully booted, we may be missing
// filesystems needed for firmware, wait and retry.
- usleep(100000);
+ std::this_thread::sleep_for(100ms);
booting = is_booting();
goto try_loading_again;
}
diff --git a/init/init.cpp b/init/init.cpp
index 9573718..7bdeec2 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -459,11 +459,17 @@
if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
}
+static int property_enable_triggers_action(const std::vector<std::string>& args)
+{
+ /* Enable property triggers. */
+ property_triggers_enabled = 1;
+ return 0;
+}
+
static int queue_property_triggers_action(const std::vector<std::string>& args)
{
+ ActionManager::GetInstance().QueueBuiltinAction(property_enable_triggers_action, "enable_property_trigger");
ActionManager::GetInstance().QueueAllPropertyTriggers();
- /* enable property triggers */
- property_triggers_enabled = 1;
return 0;
}
@@ -695,6 +701,8 @@
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
+ mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
+ mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
}
// Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
@@ -757,10 +765,12 @@
restorecon("/dev");
restorecon("/dev/kmsg");
restorecon("/dev/socket");
+ restorecon("/dev/random");
+ restorecon("/dev/urandom");
restorecon("/dev/__properties__");
restorecon("/property_contexts");
- restorecon_recursive("/sys");
- restorecon_recursive("/dev/block");
+ restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
+ restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE);
restorecon("/dev/device-mapper");
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
@@ -824,15 +834,15 @@
// By default, sleep until something happens.
int epoll_timeout_ms = -1;
- // If there's more work to do, wake up again immediately.
- if (am.HasMoreCommands()) epoll_timeout_ms = 0;
-
// If there's a process that needs restarting, wake up in time for that.
if (process_needs_restart_at != 0) {
epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
}
+ // If there's more work to do, wake up again immediately.
+ if (am.HasMoreCommands()) epoll_timeout_ms = 0;
+
bootchart_sample(&epoll_timeout_ms);
epoll_event ev;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index e7176c6..e198297 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -42,6 +42,7 @@
#include <netinet/in.h>
#include <sys/mman.h>
+#include <selinux/android.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -175,7 +176,7 @@
if (valuelen >= PROP_VALUE_MAX) return -1;
if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
- if (restorecon_recursive(value) != 0) {
+ if (restorecon(value, SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
LOG(ERROR) << "Failed to restorecon_recursive " << value;
}
}
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index e7794ec..361b925 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -95,7 +95,6 @@
int prefix = 0;
int wildcard = 0;
char *endptr;
- char *tmp = 0;
if (nargs == 0)
return;
@@ -129,14 +128,12 @@
perm = strtol(args[1], &endptr, 8);
if (!endptr || *endptr != '\0') {
LOG(ERROR) << "invalid mode '" << args[1] << "'";
- free(tmp);
return;
}
struct passwd* pwd = getpwnam(args[2]);
if (!pwd) {
LOG(ERROR) << "invalid uid '" << args[2] << "'";
- free(tmp);
return;
}
uid = pwd->pw_uid;
@@ -144,11 +141,17 @@
struct group* grp = getgrnam(args[3]);
if (!grp) {
LOG(ERROR) << "invalid gid '" << args[3] << "'";
- free(tmp);
return;
}
gid = grp->gr_gid;
- add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard);
- free(tmp);
+ if (add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard) != 0) {
+ PLOG(ERROR) << "add_dev_perms(name=" << name <<
+ ", attr=" << attr <<
+ ", perm=" << std::oct << perm << std::dec <<
+ ", uid=" << uid << ", gid=" << gid <<
+ ", prefix=" << prefix << ", wildcard=" << wildcard <<
+ ")";
+ return;
+ }
}
diff --git a/init/util.cpp b/init/util.cpp
index 5288a05..5205ea0 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -34,6 +34,8 @@
#include <sys/types.h>
#include <sys/un.h>
+#include <thread>
+
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -326,7 +328,7 @@
struct stat sb;
if (stat(filename, &sb) != -1) return 0;
- usleep(10000);
+ std::this_thread::sleep_for(10ms);
}
return -1;
}
@@ -367,20 +369,9 @@
return rc;
}
-int restorecon(const char* pathname)
+int restorecon(const char* pathname, int flags)
{
- return selinux_android_restorecon(pathname, 0);
-}
-
-int restorecon_recursive(const char* pathname)
-{
- return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE);
-}
-
-int restorecon_recursive_skipce(const char* pathname)
-{
- return selinux_android_restorecon(pathname,
- SELINUX_ANDROID_RESTORECON_RECURSE | SELINUX_ANDROID_RESTORECON_SKIPCE);
+ return selinux_android_restorecon(pathname, flags);
}
/*
diff --git a/init/util.h b/init/util.h
index ef40748..d56da39 100644
--- a/init/util.h
+++ b/init/util.h
@@ -68,9 +68,7 @@
void import_kernel_cmdline(bool in_qemu,
const std::function<void(const std::string&, const std::string&, bool)>&);
int make_dir(const char *path, mode_t mode);
-int restorecon(const char *pathname);
-int restorecon_recursive(const char *pathname);
-int restorecon_recursive_skipce(const char *pathname);
+int restorecon(const char *pathname, int flags = 0);
std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
bool is_dir(const char* pathname);
bool expand_props(const std::string& src, std::string* dst);
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 6ecbf90..e9f164d 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -16,6 +16,7 @@
#include "util.h"
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -23,7 +24,9 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <cutils/android_get_control_file.h>
#include <gtest/gtest.h>
#include <selinux/android.h>
@@ -55,45 +58,48 @@
TEST(util, create_file) {
if (!sehandle) sehandle = selinux_android_file_context_handle();
- static const char path[] = "/data/local/tmp/util.create_file.test";
- static const char key[] = ANDROID_FILE_ENV_PREFIX "_data_local_tmp_util_create_file_test";
- EXPECT_EQ(unsetenv(key), 0);
- unlink(path);
+ TemporaryFile tf;
+ close(tf.fd);
+ EXPECT_GE(unlink(tf.path), 0);
- int fd;
+ std::string key(ANDROID_FILE_ENV_PREFIX);
+ key += tf.path;
+
+ std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; });
+
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+
uid_t uid = decode_uid("logd");
gid_t gid = decode_uid("system");
mode_t perms = S_IRWXU | S_IWGRP | S_IRGRP | S_IROTH;
static const char context[] = "u:object_r:misc_logd_file:s0";
- EXPECT_GE(fd = create_file(path, O_RDWR | O_CREAT, perms, uid, gid, context), 0);
- if (fd < 0) return;
+ EXPECT_GE(tf.fd = create_file(tf.path, O_RDWR | O_CREAT, perms, uid, gid, context), 0);
+ if (tf.fd < 0) return;
static const char hello[] = "hello world\n";
static const ssize_t len = strlen(hello);
- EXPECT_EQ(write(fd, hello, len), len);
- char buffer[sizeof(hello)];
+ EXPECT_EQ(write(tf.fd, hello, len), len);
+ char buffer[sizeof(hello) + 1];
memset(buffer, 0, sizeof(buffer));
- EXPECT_GE(lseek(fd, 0, SEEK_SET), 0);
- EXPECT_EQ(read(fd, buffer, sizeof(buffer)), len);
- EXPECT_EQ(strcmp(hello, buffer), 0);
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(android_get_control_file(path), -1);
- setenv(key, val, true);
- EXPECT_EQ(android_get_control_file(path), fd);
- close(fd);
- EXPECT_EQ(android_get_control_file(path), -1);
- EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_GE(lseek(tf.fd, 0, SEEK_SET), 0);
+ EXPECT_EQ(read(tf.fd, buffer, sizeof(buffer)), len);
+ EXPECT_EQ(std::string(hello), buffer);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), tf.fd);
+ close(tf.fd);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
struct stat st;
- EXPECT_EQ(stat(path, &st), 0);
+ EXPECT_EQ(stat(tf.path, &st), 0);
EXPECT_EQ(st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), perms);
EXPECT_EQ(st.st_uid, uid);
EXPECT_EQ(st.st_gid, gid);
security_context_t con;
- EXPECT_GE(getfilecon(path, &con), 0);
+ EXPECT_GE(getfilecon(tf.path, &con), 0);
EXPECT_NE(con, static_cast<security_context_t>(NULL));
if (con) {
EXPECT_EQ(context, std::string(con));
}
freecon(con);
- EXPECT_EQ(unlink(path), 0);
+ EXPECT_EQ(unlink(tf.path), 0);
}
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index acb963c..2386bf8 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -20,12 +20,14 @@
#include <android-base/unique_fd.h>
namespace android {
+namespace fuse {
-bool FuseBridgeLoop::Start(
- int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoop::Callback* callback) {
+bool StartFuseBridgeLoop(
+ int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoopCallback* callback) {
base::unique_fd dev_fd(raw_dev_fd);
base::unique_fd proxy_fd(raw_proxy_fd);
- fuse::FuseBuffer buffer;
+ FuseBuffer buffer;
+ size_t open_count = 0;
LOG(DEBUG) << "Start fuse loop.";
while (true) {
@@ -71,18 +73,29 @@
return false;
}
- if (opcode == FUSE_INIT) {
- callback->OnMount();
+ switch (opcode) {
+ case FUSE_INIT:
+ callback->OnMount();
+ break;
+ case FUSE_OPEN:
+ if (buffer.response.header.error == fuse::kFuseSuccess) {
+ open_count++;
+ }
+ break;
+ case FUSE_RELEASE:
+ if (open_count != 0) {
+ open_count--;
+ } else {
+ LOG(WARNING) << "Unexpected FUSE_RELEASE before opening a file.";
+ break;
+ }
+ if (open_count == 0) {
+ return true;
+ }
+ break;
}
}
}
-namespace fuse {
-
-bool StartFuseBridgeLoop(
- int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoopCallback* callback) {
- return FuseBridgeLoop().Start(raw_dev_fd, raw_proxy_fd, callback);
-}
-
} // namespace fuse
} // namespace android
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 74fe756..3ade31c 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -118,23 +118,18 @@
return;
}
- // We limit ourselves to 15 because we don't handle BATCH_FORGET yet
- size_t response_size = sizeof(fuse_init_out);
+ // We limit ourselves to minor=15 because we don't handle BATCH_FORGET yet.
+ // Thus we need to use FUSE_COMPAT_22_INIT_OUT_SIZE.
#if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
// FUSE_KERNEL_VERSION >= 23.
-
- // If the kernel only works on minor revs older than or equal to 22,
- // then use the older structure size since this code only uses the 7.22
- // version of the structure.
- if (minor <= 22) {
- response_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
- }
+ const size_t response_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
+#else
+ const size_t response_size = sizeof(fuse_init_out);
#endif
response.Reset(response_size, kFuseSuccess, unique);
fuse_init_out* const out = &response.init_out;
out->major = FUSE_KERNEL_VERSION;
- // We limit ourselves to 15 because we don't handle BATCH_FORGET yet.
out->minor = std::min(minor, 15u);
out->max_readahead = max_readahead;
out->flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
diff --git a/libappfuse/include/libappfuse/FuseBridgeLoop.h b/libappfuse/include/libappfuse/FuseBridgeLoop.h
index 38043bc..1f71cf2 100644
--- a/libappfuse/include/libappfuse/FuseBridgeLoop.h
+++ b/libappfuse/include/libappfuse/FuseBridgeLoop.h
@@ -20,23 +20,14 @@
#include "libappfuse/FuseBuffer.h"
namespace android {
-
-// TODO: Remove the class after switching to StartFuseBridgeLoop in the
-// framework code.
-class FuseBridgeLoop final {
- public:
- class Callback {
- public:
- virtual void OnMount() = 0;
- virtual ~Callback() = default;
- };
-
- bool Start(int dev_fd, int proxy_fd, Callback* callback);
-};
-
namespace fuse {
-class FuseBridgeLoopCallback : public FuseBridgeLoop::Callback {};
+class FuseBridgeLoopCallback {
+ public:
+ virtual void OnMount() = 0;
+ virtual ~FuseBridgeLoopCallback() = default;
+};
+
bool StartFuseBridgeLoop(
int dev_fd, int proxy_fd, FuseBridgeLoopCallback* callback);
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index bd503eb..e74d9e7 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -200,11 +200,16 @@
TEST_F(FuseBridgeLoopTest, Proxy) {
CheckProxy(FUSE_LOOKUP);
CheckProxy(FUSE_GETATTR);
- CheckProxy(FUSE_OPEN);
CheckProxy(FUSE_READ);
CheckProxy(FUSE_WRITE);
- CheckProxy(FUSE_RELEASE);
CheckProxy(FUSE_FSYNC);
+
+ // Invoke FUSE_OPEN and FUSE_RELEASE at last as the loop will exit when all files are closed.
+ CheckProxy(FUSE_OPEN);
+ CheckProxy(FUSE_RELEASE);
+
+ // Ensure the loop exits.
+ Close();
}
} // namespace fuse
diff --git a/libappfuse/tests/FuseBufferTest.cc b/libappfuse/tests/FuseBufferTest.cc
index 17f1306..c822135 100644
--- a/libappfuse/tests/FuseBufferTest.cc
+++ b/libappfuse/tests/FuseBufferTest.cc
@@ -164,7 +164,7 @@
buffer.HandleInit();
- ASSERT_EQ(sizeof(fuse_out_header) + sizeof(fuse_init_out),
+ ASSERT_EQ(sizeof(fuse_out_header) + FUSE_COMPAT_22_INIT_OUT_SIZE,
buffer.response.header.len);
EXPECT_EQ(kFuseSuccess, buffer.response.header.error);
EXPECT_EQ(static_cast<unsigned int>(FUSE_KERNEL_VERSION),
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index bb17325..0f01872 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -38,40 +38,15 @@
include $(LLVM_ROOT_PATH)/llvm.mk
#-------------------------------------------------------------------------
-# The libbacktrace_offline shared library.
+# The libbacktrace_offline static library.
#-------------------------------------------------------------------------
libbacktrace_offline_src_files := \
BacktraceOffline.cpp \
-# Use shared llvm library on device to save space.
-libbacktrace_offline_shared_libraries_target := \
- libbacktrace \
+# Use shared libraries so their headers get included during build.
+libbacktrace_offline_shared_libraries := \
libbase \
- liblog \
libunwind \
- libutils \
- libLLVM \
-
-libbacktrace_offline_static_libraries_target := \
- libziparchive \
- libz \
-
-# Use static llvm libraries on host to remove dependency on 32-bit llvm shared library
-# which is not included in the prebuilt.
-libbacktrace_offline_static_libraries_host := \
- libbacktrace \
- libunwind \
- libziparchive \
- libz \
- libbase \
- liblog \
- libutils \
- libLLVMObject \
- libLLVMBitReader \
- libLLVMMC \
- libLLVMMCParser \
- libLLVMCore \
- libLLVMSupport \
module := libbacktrace_offline
build_type := target
@@ -113,10 +88,16 @@
backtrace_test_shared_libraries_target += \
libdl \
libutils \
- libLLVM \
+# Statically link LLVMlibraries to remove dependency on llvm shared library.
backtrace_test_static_libraries := \
libbacktrace_offline \
+ libLLVMObject \
+ libLLVMBitReader \
+ libLLVMMC \
+ libLLVMMCParser \
+ libLLVMCore \
+ libLLVMSupport \
backtrace_test_static_libraries_target := \
libziparchive \
@@ -126,12 +107,6 @@
libziparchive \
libz \
libutils \
- libLLVMObject \
- libLLVMBitReader \
- libLLVMMC \
- libLLVMMCParser \
- libLLVMCore \
- libLLVMSupport \
backtrace_test_ldlibs_host += \
-ldl \
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index f7b497d..39f8aba 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -18,6 +18,7 @@
// they correspond to features not used by our host development tools
// which are also hard or even impossible to port to native Win32
libcutils_nonwindows_sources = [
+ "android_get_control_file.cpp",
"fs.c",
"multiuser.c",
"socket_inaddr_any_server_unix.c",
@@ -34,7 +35,6 @@
host_supported: true,
srcs: [
"config_utils.c",
- "files.cpp",
"fs_config.c",
"canned_fs_config.c",
"hashmap.c",
diff --git a/include/cutils/files.h b/libcutils/android_get_control_env.h
similarity index 63%
copy from include/cutils/files.h
copy to libcutils/android_get_control_env.h
index 0210e30..638c831 100644
--- a/include/cutils/files.h
+++ b/libcutils/android_get_control_env.h
@@ -14,24 +14,20 @@
* limitations under the License.
*/
-#ifndef __CUTILS_FILES_H
-#define __CUTILS_FILES_H
+#ifndef __CUTILS_ANDROID_GET_CONTROL_ENV_H
+#define __CUTILS_ANDROID_GET_CONTROL_ENV_H
-#define ANDROID_FILE_ENV_PREFIX "ANDROID_FILE_"
+/* To declare library function hidden and internal */
+#define LIBCUTILS_HIDDEN __attribute__((visibility("hidden")))
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * android_get_control_file - simple helper function to get the file
- * descriptor of our init-managed file. `path' is the filename path as
- * given in init.rc. Returns -1 on error.
- */
-int android_get_control_file(const char* path);
-
+LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
+ const char* name);
#ifdef __cplusplus
}
#endif
-#endif /* __CUTILS_FILES_H */
+#endif /* __CUTILS_ANDROID_GET_CONTROL_ENV_H */
diff --git a/libcutils/files.cpp b/libcutils/android_get_control_file.cpp
similarity index 74%
rename from libcutils/files.cpp
rename to libcutils/android_get_control_file.cpp
index bf15b42..780d9f1 100644
--- a/libcutils/files.cpp
+++ b/libcutils/android_get_control_file.cpp
@@ -25,11 +25,6 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-// This file contains files implementation that can be shared between
-// platforms as long as the correct headers are included.
-#define _GNU_SOURCE 1 // for asprintf
-
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -41,17 +36,20 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
-#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define
-#define TEMP_FAILURE_RETRY(exp) (exp)
+#include "android_get_control_env.h"
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation
#endif
-int android_get_control_file(const char* path) {
- if (!path) return -1;
+LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
+ const char* name) {
+ if (!prefix || !name) return -1;
char *key = NULL;
- if (asprintf(&key, ANDROID_FILE_ENV_PREFIX "%s", path) < 0) return -1;
+ if (asprintf(&key, "%s%s", prefix, name) < 0) return -1;
if (!key) return -1;
char *cp = key;
@@ -70,29 +68,33 @@
// validity checking
if ((fd < 0) || (fd > INT_MAX)) return -1;
-#if defined(_SC_OPEN_MAX)
- if (fd >= sysconf(_SC_OPEN_MAX)) return -1;
-#elif defined(OPEN_MAX)
- if (fd >= OPEN_MAX) return -1;
-#elif defined(_POSIX_OPEN_MAX)
- if (fd >= _POSIX_OPEN_MAX) return -1;
-#endif
-#if defined(F_GETFD)
+ // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX
+
+ // Still open?
+#if defined(F_GETFD) // Lowest overhead
if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
-#elif defined(F_GETFL)
+#elif defined(F_GETFL) // Alternate lowest overhead
if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
-#else
+#else // Hail Mary pass
struct stat s;
if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
#endif
+ return static_cast<int>(fd);
+}
+
+int android_get_control_file(const char* path) {
+ int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
+
#if defined(__linux__)
+ // Find file path from /proc and make sure it is correct
char *proc = NULL;
- if (asprintf(&proc, "/proc/self/fd/%ld", fd) < 0) return -1;
+ if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1;
if (!proc) return -1;
size_t len = strlen(path);
+ // readlink() does not guarantee a nul byte, len+2 so we catch truncation.
char *buf = static_cast<char *>(calloc(1, len + 2));
if (!buf) {
free(proc);
@@ -104,8 +106,8 @@
free(buf);
if (ret < 0) return -1;
if (cmp != 0) return -1;
+ // It is what we think it is
#endif
- // It is what we think it is
- return static_cast<int>(fd);
+ return fd;
}
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index af7e189..159a9d4 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -42,24 +42,6 @@
struct mntent entry;
} mntent_list;
-static bool has_mount_option(const char* opts, const char* opt_to_find)
-{
- bool ret = false;
- char* copy = NULL;
- char* opt;
- char* rem;
-
- while ((opt = strtok_r(copy ? NULL : (copy = strdup(opts)), ",", &rem))) {
- if (!strcmp(opt, opt_to_find)) {
- ret = true;
- break;
- }
- }
-
- free(copy);
- return ret;
-}
-
static bool is_block_device(const char* fsname)
{
return !strncmp(fsname, "/dev/block", 10);
@@ -78,8 +60,7 @@
return;
}
while ((mentry = getmntent(fp)) != NULL) {
- if (is_block_device(mentry->mnt_fsname) &&
- has_mount_option(mentry->mnt_opts, "rw")) {
+ if (is_block_device(mentry->mnt_fsname) && hasmntopt(mentry, "rw")) {
mntent_list* item = (mntent_list*)calloc(1, sizeof(mntent_list));
item->entry = *mentry;
item->entry.mnt_fsname = strdup(mentry->mnt_fsname);
@@ -170,8 +151,7 @@
goto out;
}
while ((mentry = getmntent(fp)) != NULL) {
- if (!is_block_device(mentry->mnt_fsname) ||
- !has_mount_option(mentry->mnt_opts, "ro")) {
+ if (!is_block_device(mentry->mnt_fsname) || !hasmntopt(mentry, "ro")) {
continue;
}
mntent_list* item = find_item(&rw_entries, mentry->mnt_fsname);
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index 9d823cf..4bad28a 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -24,7 +24,7 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/klog.h>
static int klog_level = KLOG_DEFAULT_LEVEL;
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
index 63761a2..23a447b 100644
--- a/libcutils/sockets.cpp
+++ b/libcutils/sockets.cpp
@@ -28,33 +28,9 @@
// This file contains socket implementation that can be shared between
// platforms as long as the correct headers are included.
-#define _GNU_SOURCE 1 // For asprintf
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#if !defined(_WIN32)
-#include <netinet/in.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#if !defined(_WIN32)
-#include <sys/un.h>
-#endif
-#include <unistd.h>
-
-#include <string>
#include <cutils/sockets.h>
-#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define
-#define TEMP_FAILURE_RETRY(exp) (exp)
-#endif
-
int socket_get_local_port(cutils_socket_t sock) {
sockaddr_storage addr;
socklen_t addr_size = sizeof(addr);
@@ -65,58 +41,3 @@
}
return -1;
}
-
-int android_get_control_socket(const char* name) {
- char *key = NULL;
- if (asprintf(&key, ANDROID_SOCKET_ENV_PREFIX "%s", name) < 0) return -1;
- if (!key) return -1;
-
- char *cp = key;
- while (*cp) {
- if (!isalnum(*cp)) *cp = '_';
- ++cp;
- }
-
- const char* val = getenv(key);
- free(key);
- if (!val) return -1;
-
- errno = 0;
- long fd = strtol(val, NULL, 10);
- if (errno) return -1;
-
- // validity checking
- if ((fd < 0) || (fd > INT_MAX)) return -1;
-#if defined(_SC_OPEN_MAX)
- if (fd >= sysconf(_SC_OPEN_MAX)) return -1;
-#elif defined(OPEN_MAX)
- if (fd >= OPEN_MAX) return -1;
-#elif defined(_POSIX_OPEN_MAX)
- if (fd >= _POSIX_OPEN_MAX) return -1;
-#endif
-
-#if defined(F_GETFD)
- if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
-#elif defined(F_GETFL)
- if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
-#else
- struct stat s;
- if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
-#endif
-
-#if !defined(_WIN32)
- struct sockaddr_un addr;
- socklen_t addrlen = sizeof(addr);
- int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen));
- if (ret < 0) return -1;
- char *path = NULL;
- if (asprintf(&path, ANDROID_SOCKET_DIR"/%s", name) < 0) return -1;
- if (!path) return -1;
- int cmp = strcmp(addr.sun_path, path);
- free(path);
- if (cmp != 0) return -1;
-#endif
-
- // It is what we think it is
- return static_cast<int>(fd);
-}
diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp
index 3545403..5a14a5c 100644
--- a/libcutils/sockets_unix.cpp
+++ b/libcutils/sockets_unix.cpp
@@ -16,13 +16,25 @@
#define LOG_TAG "socket-unix"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <time.h>
#include <unistd.h>
#include <android/log.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
+#include "android_get_control_env.h"
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation
+#endif
+
#if defined(__ANDROID__)
/* For the socket trust (credentials) check */
#include <private/android_filesystem_config.h>
@@ -80,3 +92,24 @@
return writev(sock, iovec_buffers, num_buffers);
}
+
+int android_get_control_socket(const char* name) {
+ int fd = __android_get_control_from_env(ANDROID_SOCKET_ENV_PREFIX, name);
+
+ if (fd < 0) return fd;
+
+ // Compare to UNIX domain socket name, must match!
+ struct sockaddr_un addr;
+ socklen_t addrlen = sizeof(addr);
+ int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen));
+ if (ret < 0) return -1;
+ char *path = NULL;
+ if (asprintf(&path, ANDROID_SOCKET_DIR "/%s", name) < 0) return -1;
+ if (!path) return -1;
+ int cmp = strcmp(addr.sun_path, path);
+ free(path);
+ if (cmp != 0) return -1;
+
+ // It is what we think it is
+ return fd;
+}
diff --git a/libcutils/sockets_windows.cpp b/libcutils/sockets_windows.cpp
index ed6b1a7..3064c70 100644
--- a/libcutils/sockets_windows.cpp
+++ b/libcutils/sockets_windows.cpp
@@ -84,3 +84,7 @@
return -1;
}
+
+int android_get_control_socket(const char* name) {
+ return -1;
+}
diff --git a/libcutils/tests/Android.bp b/libcutils/tests/Android.bp
index bd35412..abe3c21 100644
--- a/libcutils/tests/Android.bp
+++ b/libcutils/tests/Android.bp
@@ -14,7 +14,7 @@
cc_defaults {
name: "libcutils_test_default",
- srcs: ["sockets_test.cpp", "files_test.cpp"],
+ srcs: ["sockets_test.cpp"],
target: {
android: {
@@ -24,11 +24,16 @@
"PropertiesTest.cpp",
"sched_policy_test.cpp",
"trace-dev_test.cpp",
+ "test_str_parms.cpp",
+ "android_get_control_socket_test.cpp",
+ "android_get_control_file_test.cpp"
],
},
not_windows: {
- srcs: ["test_str_parms.cpp"],
+ srcs: [
+ "test_str_parms.cpp",
+ ],
},
},
diff --git a/libcutils/tests/android_get_control_file_test.cpp b/libcutils/tests/android_get_control_file_test.cpp
new file mode 100644
index 0000000..6c6fd2a
--- /dev/null
+++ b/libcutils/tests/android_get_control_file_test.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <string>
+
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <cutils/android_get_control_file.h>
+#include <gtest/gtest.h>
+
+TEST(FilesTest, android_get_control_file) {
+ TemporaryFile tf;
+ ASSERT_GE(tf.fd, 0);
+
+ std::string key(ANDROID_FILE_ENV_PREFIX);
+ key += tf.path;
+
+ std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; });
+
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+
+ EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0);
+
+ EXPECT_EQ(android_get_control_file(tf.path), tf.fd);
+ close(tf.fd);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+}
diff --git a/libcutils/tests/android_get_control_socket_test.cpp b/libcutils/tests/android_get_control_socket_test.cpp
new file mode 100644
index 0000000..e586748
--- /dev/null
+++ b/libcutils/tests/android_get_control_socket_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <time.h>
+
+#include <cutils/sockets.h>
+#include <gtest/gtest.h>
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 0
+#endif
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+
+TEST(SocketsTest, android_get_control_socket) {
+ static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
+ static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
+
+ EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ int fd;
+ ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
+#ifdef F_GETFL
+ int flags;
+ ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
+ ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
+#endif
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
+ unlink(addr.sun_path);
+
+ EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ char val[32];
+ snprintf(val, sizeof(val), "%d", fd);
+ EXPECT_EQ(setenv(key, val, true), 0);
+
+ EXPECT_EQ(android_get_control_socket(name), fd);
+ socket_close(fd);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+ EXPECT_EQ(unlink(addr.sun_path), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+ EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+}
diff --git a/libcutils/tests/files_test.cpp b/libcutils/tests/files_test.cpp
deleted file mode 100644
index 1a7d673..0000000
--- a/libcutils/tests/files_test.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include <cutils/files.h>
-#include <gtest/gtest.h>
-
-TEST(FilesTest, android_get_control_file) {
- static const char key[] = ANDROID_FILE_ENV_PREFIX "_dev_kmsg";
- static const char name[] = "/dev/kmsg";
-
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-
- int fd;
- ASSERT_GE(fd = open(name, O_RDONLY | O_CLOEXEC), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(setenv(key, val, true), 0);
-
- EXPECT_EQ(android_get_control_file(name), fd);
- close(fd);
- EXPECT_EQ(android_get_control_file(name), -1);
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-}
diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp
index adfbf4a..0441fb6 100644
--- a/libcutils/tests/sockets_test.cpp
+++ b/libcutils/tests/sockets_test.cpp
@@ -18,11 +18,9 @@
// IPv6 capabilities. These tests assume that no UDP packets are lost, which
// should be the case for loopback communication, but is not guaranteed.
-#include <stdio.h>
-#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <time.h>
#include <cutils/sockets.h>
@@ -189,49 +187,3 @@
TEST(SocketsTest, TestSocketSendBuffersFailure) {
EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
}
-
-#ifndef SOCK_NONBLOCK
-#define SOCK_NONBLOCK 0
-#endif
-
-#ifndef SOCK_CLOEXEC
-#define SOCK_CLOEXEC 0
-#endif
-
-TEST(SocketsTest, android_get_control_socket) {
- static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
- static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
-
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- int fd;
- ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
-#ifdef F_GETFL
- int flags;
- ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
- ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
-#endif
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
- unlink(addr.sun_path);
-
- EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(setenv(key, val, true), 0);
-
- EXPECT_EQ(android_get_control_socket(name), fd);
- socket_close(fd);
- EXPECT_EQ(android_get_control_socket(name), -1);
- EXPECT_EQ(unlink(addr.sun_path), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-}
diff --git a/libion/ion.c b/libion/ion.c
index 2db8845..a7b22b8 100644
--- a/libion/ion.c
+++ b/libion/ion.c
@@ -34,7 +34,7 @@
int ion_open()
{
- int fd = open("/dev/ion", O_RDONLY);
+ int fd = open("/dev/ion", O_RDONLY | O_CLOEXEC);
if (fd < 0)
ALOGE("open /dev/ion failed!\n");
return fd;
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 16aa4fa..c498153 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -73,6 +73,9 @@
linux: {
host_ldlibs: ["-lrt"],
},
+ linux_bionic: {
+ enabled: true,
+ },
},
cflags: [
diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c
index f9cad99..e8e0335 100644
--- a/liblog/event_tag_map.c
+++ b/liblog/event_tag_map.c
@@ -73,12 +73,13 @@
EventTagMap* newTagMap;
off_t end;
int save_errno;
+ const char* tagfile = fileName ? fileName : EVENT_TAG_MAP_FILE;
- int fd = open(fileName, O_RDONLY | O_CLOEXEC);
+ int fd = open(tagfile, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
save_errno = errno;
fprintf(stderr, "%s: unable to open map '%s': %s\n",
- OUT_TAG, fileName, strerror(save_errno));
+ OUT_TAG, tagfile, strerror(save_errno));
goto fail_errno;
}
@@ -87,7 +88,7 @@
(void) lseek(fd, 0L, SEEK_SET);
if (end < 0) {
fprintf(stderr, "%s: unable to seek map '%s' %s\n",
- OUT_TAG, fileName, strerror(save_errno));
+ OUT_TAG, tagfile, strerror(save_errno));
goto fail_close;
}
@@ -103,7 +104,7 @@
fd = -1;
if ((newTagMap->mapAddr == MAP_FAILED) || (newTagMap->mapAddr == NULL)) {
fprintf(stderr, "%s: mmap(%s) failed: %s\n",
- OUT_TAG, fileName, strerror(save_errno));
+ OUT_TAG, tagfile, strerror(save_errno));
goto fail_free;
}
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index 11d8afb..9ac1d30 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
+#include <log/log_event_list.h>
#include <private/android_logger.h>
#include "log_portability.h"
@@ -319,7 +320,7 @@
context->storage[1] = context->count[0];
len = context->len = context->pos;
msg = (const char *)context->storage;
- /* it'snot a list */
+ /* it's not a list */
if (context->count[0] <= 1) {
len -= sizeof(uint8_t) + sizeof(uint8_t);
if (len < 0) {
@@ -332,6 +333,38 @@
__android_log_security_bwrite(context->tag, msg, len);
}
+LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
+ const char **buffer) {
+ android_log_context_internal *context;
+ const char *msg;
+ ssize_t len;
+
+ context = (android_log_context_internal *)ctx;
+ if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
+ return -EBADF;
+ }
+ if (context->list_nest_depth) {
+ return -EIO;
+ }
+ if (buffer == NULL) {
+ return -EFAULT;
+ }
+ /* NB: if there was overflow, then log is truncated. Nothing reported */
+ context->storage[1] = context->count[0];
+ len = context->len = context->pos;
+ msg = (const char *)context->storage;
+ /* it's not a list */
+ if (context->count[0] <= 1) {
+ len -= sizeof(uint8_t) + sizeof(uint8_t);
+ if (len < 0) {
+ len = 0;
+ }
+ msg += sizeof(uint8_t) + sizeof(uint8_t);
+ }
+ *buffer = msg;
+ return len;
+}
+
/*
* Extract a 4-byte value from a byte stream.
*/
diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c
index 7262fc5..14d6482 100644
--- a/liblog/log_event_write.c
+++ b/liblog/log_event_write.c
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <log/log.h>
+#include <log/log_event_list.h>
#include "log_portability.h"
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index 157bd88..f19c3ab 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -48,7 +48,7 @@
static int check_log_uid_permissions()
{
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
uid_t uid = __android_log_uid();
/* Matches clientHasLogCredentials() in logd */
@@ -130,7 +130,7 @@
return kLogNotAvailable;
}
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
static atomic_uintptr_t tagMap;
#endif
@@ -140,7 +140,7 @@
LIBLOG_ABI_PUBLIC void __android_log_close()
{
struct android_log_transport_write *transport;
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
EventTagMap *m;
#endif
@@ -170,7 +170,7 @@
}
}
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
/*
* Additional risk here somewhat mitigated by immediately unlock flushing
* the processor cache. The multi-threaded race that we choose to accept,
@@ -188,7 +188,7 @@
__android_log_unlock();
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
if (m != (EventTagMap *)(uintptr_t)-1LL) android_closeEventTagMap(m);
#endif
@@ -261,7 +261,7 @@
return -EINVAL;
}
-#if defined(__BIONIC__)
+#if defined(__ANDROID__)
if (log_id == LOG_ID_SECURITY) {
if (vec[0].iov_len < 4) {
return -EINVAL;
@@ -293,7 +293,7 @@
ret = __android_log_trylock();
m = (EventTagMap *)atomic_load(&tagMap); /* trylock flush cache */
if (!m) {
- m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ m = android_openEventTagMap(NULL);
if (ret) { /* trylock failed, use local copy, mark for close */
f = m;
} else {
diff --git a/liblog/logprint.c b/liblog/logprint.c
index fb942a1..da80e36 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -632,8 +632,8 @@
size_t len;
int64_t lval;
- if (eventDataLen < 1)
- return -1;
+ if (eventDataLen < 1) return -1;
+
type = *eventData++;
eventDataLen--;
@@ -729,8 +729,7 @@
{
int32_t ival;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
@@ -740,8 +739,7 @@
goto pr_lval;
case EVENT_TYPE_LONG:
/* 64-bit signed long */
- if (eventDataLen < 8)
- return -1;
+ if (eventDataLen < 8) return -1;
lval = get8LE(eventData);
eventData += 8;
eventDataLen -= 8;
@@ -761,8 +759,7 @@
uint32_t ival;
float fval;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
fval = *(float*)&ival;
eventData += 4;
@@ -783,14 +780,12 @@
{
unsigned int strLen;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
strLen = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
- if (eventDataLen < strLen)
- return -1;
+ if (eventDataLen < strLen) return -1;
if (cp && (strLen == 0)) {
/* reset the format if no content */
@@ -818,41 +813,32 @@
unsigned char count;
int i;
- if (eventDataLen < 1)
- return -1;
+ if (eventDataLen < 1) return -1;
count = *eventData++;
eventDataLen--;
- if (outBufLen > 0) {
- *outBuf++ = '[';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (outBufLen <= 0) goto no_room;
+
+ *outBuf++ = '[';
+ outBufLen--;
for (i = 0; i < count; i++) {
result = android_log_printBinaryEvent(&eventData, &eventDataLen,
&outBuf, &outBufLen, fmtStr, fmtLen);
- if (result != 0)
- goto bail;
+ if (result != 0) goto bail;
- if (i < count-1) {
- if (outBufLen > 0) {
- *outBuf++ = ',';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (i < (count - 1)) {
+ if (outBufLen <= 0) goto no_room;
+ *outBuf++ = ',';
+ outBufLen--;
}
}
- if (outBufLen > 0) {
- *outBuf++ = ']';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (outBufLen <= 0) goto no_room;
+
+ *outBuf++ = ']';
+ outBufLen--;
}
break;
default:
@@ -997,8 +983,7 @@
}
}
inCount = buf->len;
- if (inCount < 4)
- return -1;
+ if (inCount < 4) return -1;
tagIndex = get4LE(eventData);
eventData += 4;
inCount -= 4;
@@ -1031,16 +1016,20 @@
/*
* Format the event log data into the buffer.
*/
- char* outBuf = messageBuf;
- size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
- int result;
const char* fmtStr = NULL;
size_t fmtLen = 0;
if (descriptive_output && map) {
fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex);
}
- result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
- &outRemaining, &fmtStr, &fmtLen);
+
+ char* outBuf = messageBuf;
+ size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
+ int result = 0;
+
+ if ((inCount > 0) || fmtLen) {
+ result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
+ &outRemaining, &fmtStr, &fmtLen);
+ }
if ((result == 1) && fmtStr) {
/* We overflowed :-(, let's repaint the line w/o format dressings */
eventData = (const unsigned char*)buf->msg;
@@ -1055,18 +1044,18 @@
}
if (result < 0) {
fprintf(stderr, "Binary log entry conversion failed\n");
- return -1;
- } else if (result == 1) {
- if (outBuf > messageBuf) {
- /* leave an indicator */
- *(outBuf-1) = '!';
- } else {
- /* no room to output anything at all */
- *outBuf++ = '!';
- outRemaining--;
+ }
+ if (result) {
+ if (!outRemaining) {
+ /* make space to leave an indicator */
+ --outBuf;
+ ++outRemaining;
}
- /* pretend we ate all the data */
+ *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */
+ outRemaining--;
+ /* pretend we ate all the data to prevent log stutter */
inCount = 0;
+ if (result > 0) result = 0;
}
/* eat the silly terminating '\n' */
@@ -1090,7 +1079,7 @@
entry->message = messageBuf;
- return 0;
+ return result;
}
/*
@@ -1802,8 +1791,7 @@
outBuffer = android_log_formatLogLine(p_format, defaultBuffer,
sizeof(defaultBuffer), entry, &totalLen);
- if (!outBuffer)
- return -1;
+ if (!outBuffer) return -1;
do {
ret = write(fd, outBuffer, totalLen);
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index 158987a..ec5a99b 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -74,3 +74,38 @@
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
LOCAL_SRC_FILES := $(test_src_files)
include $(BUILD_NATIVE_TEST)
+
+cts_executable := CtsLiblogTestCases
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(cts_executable)
+LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS += $(test_c_flags)
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
+LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
+LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_CTS_TEST_PACKAGE := android.core.liblog
+include $(BUILD_CTS_EXECUTABLE)
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(cts_executable)_list
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(test_c_flags) -DHOST
+LOCAL_C_INCLUDES := external/gtest/include
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_CXX_STL := libc++
+LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_NATIVE_TEST)
+
+endif # ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
diff --git a/liblog/tests/AndroidTest.xml b/liblog/tests/AndroidTest.xml
new file mode 100644
index 0000000..b8d87e6
--- /dev/null
+++ b/liblog/tests/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for CTS Logging Library test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="CtsLiblogTestCases->/data/local/tmp/CtsLiblogTestCases" />
+ <option name="append-bitness" value="true" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="CtsLiblogTestCases" />
+ <option name="runtime-hint" value="65s" />
+ </test>
+</configuration>
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
index f05a955..8cea7dc 100644
--- a/liblog/tests/libc_test.cpp
+++ b/liblog/tests/libc_test.cpp
@@ -20,6 +20,7 @@
#include <stdio.h>
TEST(libc, __pstore_append) {
+#ifdef __ANDROID__
FILE *fp;
ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a")));
static const char message[] = "libc.__pstore_append\n";
@@ -42,4 +43,7 @@
"Reboot, ensure string libc.__pstore_append is in /sys/fs/pstore/pmsg-ramoops-0\n"
);
}
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 44045c3..5420f68 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -20,7 +20,10 @@
#include <sys/types.h>
#include <unistd.h>
+#include <unordered_set>
+
#include <cutils/sockets.h>
+#include <log/event_tag_map.h>
#include <private/android_logger.h>
#include "benchmark.h"
@@ -689,3 +692,96 @@
StopBenchmarkTiming();
}
BENCHMARK(BM_security);
+
+// Keep maps around for multiple iterations
+static std::unordered_set<uint32_t> set;
+static const EventTagMap* map;
+
+static bool prechargeEventMap() {
+ if (map) return true;
+
+ fprintf(stderr, "Precharge: start\n");
+
+ map = android_openEventTagMap(NULL);
+ for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) {
+ size_t len;
+ if (android_lookupEventTag_len(map, &len, tag) == NULL) continue;
+ set.insert(tag);
+ }
+
+ fprintf(stderr, "Precharge: stop %zu\n", set.size());
+
+ return true;
+}
+
+/*
+ * Measure the time it takes for android_lookupEventTag_len
+ */
+static void BM_lookupEventTag(int iters) {
+
+ prechargeEventMap();
+
+ std::unordered_set<uint32_t>::const_iterator it = set.begin();
+
+ StartBenchmarkTiming();
+
+ for (int i = 0; i < iters; ++i) {
+ size_t len;
+ android_lookupEventTag_len(map, &len, (*it));
+ ++it;
+ if (it == set.end()) it = set.begin();
+ }
+
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_lookupEventTag);
+
+/*
+ * Measure the time it takes for android_lookupEventTag_len
+ */
+static uint32_t notTag = 1;
+
+static void BM_lookupEventTag_NOT(int iters) {
+
+ prechargeEventMap();
+
+ while (set.find(notTag) != set.end()) {
+ ++notTag;
+ if (notTag >= USHRT_MAX) notTag = 1;
+ }
+
+ StartBenchmarkTiming();
+
+ for (int i = 0; i < iters; ++i) {
+ size_t len;
+ android_lookupEventTag_len(map, &len, notTag);
+ }
+
+ StopBenchmarkTiming();
+
+ ++notTag;
+ if (notTag >= USHRT_MAX) notTag = 1;
+}
+BENCHMARK(BM_lookupEventTag_NOT);
+
+/*
+ * Measure the time it takes for android_lookupEventFormat_len
+ */
+static void BM_lookupEventFormat(int iters) {
+
+ prechargeEventMap();
+
+ std::unordered_set<uint32_t>::const_iterator it = set.begin();
+
+ StartBenchmarkTiming();
+
+ for (int i = 0; i < iters; ++i) {
+ size_t len;
+ android_lookupEventFormat_len(map, &len, (*it));
+ ++it;
+ if (it == set.end()) it = set.begin();
+ }
+
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_lookupEventFormat);
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 9c09523..29c0fe6 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -30,9 +30,12 @@
#include <android-base/file.h>
#include <android-base/stringprintf.h>
+#ifdef __ANDROID__ // includes sys/properties.h which does not exist outside
#include <cutils/properties.h>
+#endif
#include <gtest/gtest.h>
#include <log/logprint.h>
+#include <log/log_event_list.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
@@ -52,6 +55,7 @@
_rc; })
TEST(liblog, __android_log_buf_print) {
+#ifdef __ANDROID__
EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_print",
"radio"));
@@ -64,9 +68,13 @@
"TEST__android_log_buf_print",
"main"));
usleep(1000);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_buf_write) {
+#ifdef __ANDROID__
EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_write",
"radio"));
@@ -79,9 +87,13 @@
"TEST__android_log_buf_write",
"main"));
usleep(1000);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_btwrite) {
+#ifdef __ANDROID__
int intBuf = 0xDEADBEEF;
EXPECT_LT(0, __android_log_btwrite(0,
EVENT_TYPE_INT,
@@ -96,20 +108,26 @@
EVENT_TYPE_STRING,
Buf, sizeof(Buf) - 1));
usleep(1000);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static void* ConcurrentPrintFn(void *arg) {
int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_print", "Concurrent %" PRIuPTR,
reinterpret_cast<uintptr_t>(arg));
return reinterpret_cast<void*>(ret);
}
+#endif
#define NUM_CONCURRENT 64
#define _concurrent_name(a,n) a##__concurrent##n
#define concurrent_name(a,n) _concurrent_name(a,n)
TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
+#ifdef __ANDROID__
pthread_t t[NUM_CONCURRENT];
int i;
for (i=0; i < NUM_CONCURRENT; i++) {
@@ -127,8 +145,12 @@
}
}
ASSERT_LT(0, ret);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
std::string popenToString(std::string command) {
std::string ret;
@@ -192,8 +214,10 @@
}
return false;
}
+#endif
TEST(liblog, __android_log_btwrite__android_logger_list_read) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -256,14 +280,20 @@
EXPECT_EQ(1, second_count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static inline int32_t get4LE(const char* src)
{
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
+#endif
static void bswrite_test(const char *message) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -328,6 +358,9 @@
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
char msgBuf[1024];
+ if (length != total) {
+ fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n");
+ }
int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
&log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
@@ -343,6 +376,10 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ message = NULL;
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_bswrite_and_print) {
@@ -366,6 +403,7 @@
}
static void buf_write_test(const char *message) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -432,6 +470,10 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ message = NULL;
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_buf_write_and_print__empty) {
@@ -447,6 +489,7 @@
}
TEST(liblog, __security) {
+#ifdef __ANDROID__
static const char persist_key[] = "persist.logd.security";
static const char readonly_key[] = "ro.device_owner";
static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
@@ -481,9 +524,13 @@
property_set(persist_key, "");
EXPECT_FALSE(__android_log_security());
property_set(persist_key, persist);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __security_buffer) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
android_event_long_t buffer;
@@ -617,9 +664,12 @@
"not system, content submitted but can not check end-to-end\n");
}
EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count);
-
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static unsigned signaled;
static log_time signal_time;
@@ -678,8 +728,10 @@
*uticks = *sticks = 0;
}
}
+#endif
TEST(liblog, android_logger_list_read__cpu_signal) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
unsigned long long v = 0xDEADBEEFA55A0000ULL;
@@ -764,8 +816,12 @@
EXPECT_GT(one_percent_ticks, user_ticks);
EXPECT_GT(one_percent_ticks, system_ticks);
EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
/*
* Strictly, we are not allowed to log messages in a signal context, the
* correct way to handle this is to ensure the messages are constructed in
@@ -828,8 +884,10 @@
pthread_attr_destroy(&attr);
return 0;
}
+#endif
TEST(liblog, android_logger_list_read__cpu_thread) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
unsigned long long v = 0xDEADBEAFA55A0000ULL;
@@ -915,11 +973,16 @@
EXPECT_GT(one_percent_ticks, user_ticks);
EXPECT_GT(one_percent_ticks, system_ticks);
EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
sizeof(max_payload_tag) - 1)
+#endif
static const char max_payload_buf[] = "LEONATO\n\
I learn in this letter that Don Peter of Arragon\n\
comes this night to Messina\n\
@@ -1052,6 +1115,7 @@
takes his leave.";
TEST(liblog, max_payload) {
+#ifdef __ANDROID__
pid_t pid = getpid();
char tag[sizeof(max_payload_tag)];
memcpy(tag, max_payload_tag, sizeof(tag));
@@ -1109,9 +1173,13 @@
EXPECT_EQ(true, matches);
EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_buf_print__maxtag) {
+#ifdef __ANDROID__
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -1165,9 +1233,13 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, too_big_payload) {
+#ifdef __ANDROID__
pid_t pid = getpid();
static const char big_payload_tag[] = "TEST_big_payload_XXXX";
char tag[sizeof(big_payload_tag)];
@@ -1222,9 +1294,13 @@
static_cast<size_t>(max_len));
EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, dual_reader) {
+#ifdef __ANDROID__
struct logger_list *logger_list1;
// >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
@@ -1269,9 +1345,13 @@
EXPECT_EQ(25, count1);
EXPECT_EQ(15, count2);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_logger_get_) {
+#ifdef __ANDROID__
struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
@@ -1303,14 +1383,20 @@
}
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
return android_log_shouldPrintLine(p_format, tag, pri)
&& !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
}
+#endif
TEST(liblog, filterRule) {
+#ifdef __ANDROID__
static const char tag[] = "random";
AndroidLogFormat *p_format = android_log_format_new();
@@ -1372,9 +1458,13 @@
#endif
android_log_format_free(p_format);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, is_loggable) {
+#ifdef __ANDROID__
static const char tag[] = "is_loggable";
static const char log_namespace[] = "persist.log.tag.";
static const size_t base_offset = 8; /* skip "persist." */
@@ -1667,9 +1757,13 @@
key[sizeof(log_namespace) - 2] = '\0';
property_set(key, hold[2]);
property_set(key + base_offset, hold[3]);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
+#ifdef __ANDROID__
const int TAG = 123456781;
const char SUBTAG[] = "test-subtag";
const int UID = -1;
@@ -1751,9 +1845,13 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
+#ifdef __ANDROID__
const int TAG = 123456782;
const char SUBTAG[] = "test-subtag";
const int UID = -1;
@@ -1842,9 +1940,13 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
+#ifdef __ANDROID__
const int TAG = 123456783;
const char SUBTAG[] = "test-subtag";
const int UID = -1;
@@ -1888,9 +1990,13 @@
EXPECT_EQ(0, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
+#ifdef __ANDROID__
const int TAG = 123456784;
const char SUBTAG[] = "abcdefghijklmnopqrstuvwxyz now i know my abc";
const int UID = -1;
@@ -1973,6 +2079,9 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, __android_log_bswrite_and_print___max) {
@@ -1984,6 +2093,7 @@
}
TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
+#ifdef __ANDROID__
const int TAG = 123456785;
const char SUBTAG[] = "test-subtag";
struct logger_list *logger_list;
@@ -2042,9 +2152,13 @@
EXPECT_EQ(1, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
+#ifdef __ANDROID__
const int TAG = 123456786;
struct logger_list *logger_list;
@@ -2084,8 +2198,12 @@
EXPECT_EQ(0, count);
android_logger_list_close(logger_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
static int is_real_element(int type) {
return ((type == EVENT_TYPE_INT) ||
(type == EVENT_TYPE_LONG) ||
@@ -2579,48 +2697,90 @@
android_logger_list_close(logger_list);
}
+#endif
TEST(liblog, create_android_logger_int32) {
+#ifdef __ANDROID__
create_android_logger(event_test_int32);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_int64) {
+#ifdef __ANDROID__
create_android_logger(event_test_int64);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_list_int64) {
+#ifdef __ANDROID__
create_android_logger(event_test_list_int64);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_simple_automagic_list) {
+#ifdef __ANDROID__
create_android_logger(event_test_simple_automagic_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_list_empty) {
+#ifdef __ANDROID__
create_android_logger(event_test_list_empty);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_complex_nested_list) {
+#ifdef __ANDROID__
create_android_logger(event_test_complex_nested_list);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_7_level_prefix) {
+#ifdef __ANDROID__
create_android_logger(event_test_7_level_prefix);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_7_level_suffix) {
+#ifdef __ANDROID__
create_android_logger(event_test_7_level_suffix);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_android_log_error_write) {
+#ifdef __ANDROID__
create_android_logger(event_test_android_log_error_write);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_android_log_error_write_null) {
+#ifdef __ANDROID__
create_android_logger(event_test_android_log_error_write_null);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
TEST(liblog, create_android_logger_overflow) {
+#ifdef __ANDROID__
android_log_context ctx;
EXPECT_TRUE(NULL != (ctx = create_android_logger(1005)));
@@ -2645,12 +2805,35 @@
EXPECT_GT(0, android_log_write_list_begin(ctx));
EXPECT_LE(0, android_log_destroy(&ctx));
ASSERT_TRUE(NULL == ctx);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+TEST(liblog, android_log_write_list_buffer) {
+#ifdef __ANDROID__
+ __android_log_event_list ctx(1005);
+ ctx << 1005 << "tag_def" << "(tag|1),(name|3),(format|3)";
+ std::string buffer(ctx);
+ ctx.close();
+
+ char msgBuf[1024];
+ memset(msgBuf, 0, sizeof(msgBuf));
+ EXPECT_EQ(android_log_buffer_to_string(buffer.data(), buffer.length(),
+ msgBuf, sizeof(msgBuf)), 0);
+ EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]");
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
+
+#ifdef __ANDROID__
static const char __pmsg_file[] =
"/data/william-shakespeare/MuchAdoAboutNothing.txt";
+#endif
TEST(liblog, __android_log_pmsg_file_write) {
+#ifdef __ANDROID__
__android_log_close();
bool pmsgActiveAfter__android_log_close = isPmsgActive();
bool logdwActiveAfter__android_log_close = isLogdwActive();
@@ -2687,8 +2870,12 @@
logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
const char *buf, size_t len, void *arg) {
EXPECT_TRUE(NULL == arg);
@@ -2710,8 +2897,10 @@
(len != sizeof(max_payload_buf)) ||
!!strcmp(max_payload_buf, buf) ? -ENOEXEC : 1;
}
+#endif
TEST(liblog, __android_log_pmsg_file_read) {
+#ifdef __ANDROID__
signaled = 0;
__android_log_close();
@@ -2739,8 +2928,12 @@
EXPECT_LT(0, ret);
EXPECT_EQ(1U, signaled);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
+#ifdef __ANDROID__
// meant to be handed to ASSERT_TRUE / EXPECT_TRUE only to expand the message
static testing::AssertionResult IsOk(bool ok, std::string &message) {
return ok ?
@@ -2804,8 +2997,10 @@
EXPECT_TRUE(IsOk(shared_ok, content));
EXPECT_TRUE(IsOk(anonymous_ok, content));
}
+#endif
TEST(liblog, event_log_tags) {
+#ifdef __ANDROID__
std::unique_ptr<DIR, int(*)(DIR*)> proc_dir(opendir("/proc"), closedir);
ASSERT_FALSE(!proc_dir);
@@ -2819,4 +3014,7 @@
if (id != pid) continue;
event_log_tags_test_smap(pid);
}
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
}
diff --git a/libmemtrack/Android.bp b/libmemtrack/Android.bp
index 9310b24..68c580a 100644
--- a/libmemtrack/Android.bp
+++ b/libmemtrack/Android.bp
@@ -10,7 +10,8 @@
"libhardware",
"liblog",
"libbase",
- "libhidl",
+ "libhidlbase",
+ "libhidltransport",
"libhwbinder",
"libutils",
"android.hardware.memtrack@1.0",
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 7c15429..eb66727 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -31,12 +31,15 @@
#include <chrono>
#include <memory>
#include <mutex>
+#include <thread>
#include <android-base/logging.h>
#include <private/android_filesystem_config.h>
#include <processgroup/processgroup.h>
+using namespace std::chrono_literals;
+
// Uncomment line below use memory cgroups for keeping track of (forked) PIDs
// #define USE_MEMCG 1
@@ -288,7 +291,7 @@
while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
LOG(VERBOSE) << "killed " << processes << " processes for processgroup " << initialPid;
if (retry > 0) {
- usleep(5 * 1000); // 5ms
+ std::this_thread::sleep_for(5ms);
--retry;
} else {
LOG(ERROR) << "failed to kill " << processes << " processes for processgroup "
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 25c779e..217b8c3 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -86,6 +86,13 @@
"ProcessCallStack.cpp",
],
},
+ linux_bionic: {
+ enabled: true,
+ srcs: [
+ "Looper.cpp",
+ "ProcessCallStack.cpp",
+ ],
+ },
darwin: {
cflags: ["-Wno-unused-parameter"],
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 5ed0fe8..fce1378 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -62,7 +62,17 @@
android: {
static_libs: ["libz"],
},
- host: {
+ linux_bionic: {
+ static_libs: ["libz"],
+ enabled: true,
+ },
+ linux: {
+ shared_libs: ["libz-host"],
+ },
+ darwin: {
+ shared_libs: ["libz-host"],
+ },
+ windows: {
shared_libs: ["libz-host"],
},
},
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 23cbff3..c2055b7 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -796,7 +796,8 @@
// Creates a FileWriter for |fd| and prepare to write |entry| to it,
// guaranteeing that the file descriptor is valid and that there's enough
// space on the volume to write out the entry completely and that the file
- // is truncated to the correct length.
+ // is truncated to the correct length (no truncation if |fd| references a
+ // block device).
//
// Returns a valid FileWriter on success, |nullptr| if an error occurred.
static std::unique_ptr<FileWriter> Create(int fd, const ZipEntry* entry) {
@@ -829,13 +830,22 @@
}
#endif // __linux__
- result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
- if (result == -1) {
- ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
- static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ struct stat sb;
+ if (fstat(fd, &sb) == -1) {
+ ALOGW("Zip: unable to fstat file: %s", strerror(errno));
return std::unique_ptr<FileWriter>(nullptr);
}
+ // Block device doesn't support ftruncate(2).
+ if (!S_ISBLK(sb.st_mode)) {
+ result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+ if (result == -1) {
+ ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ return std::unique_ptr<FileWriter>(nullptr);
+ }
+ }
+
return std::unique_ptr<FileWriter>(new FileWriter(fd, declared_length));
}
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index d0c693d..c204a16 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -81,6 +81,7 @@
static size_t g_maxCount;
static size_t g_printCount;
static bool g_printItAnyways;
+static bool g_debug;
enum helpType {
HELP_FALSE,
@@ -176,7 +177,7 @@
static EventTagMap *eventTagMap = NULL;
if (!eventTagMap && !hasOpenedEventTagMap) {
- eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ eventTagMap = android_openEventTagMap(NULL);
hasOpenedEventTagMap = true;
}
err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
@@ -188,7 +189,7 @@
} else {
err = android_log_processLogBuffer(&buf->entry_v1, &entry);
}
- if (err < 0) {
+ if ((err < 0) && !g_debug) {
goto error;
}
@@ -320,7 +321,7 @@
" -g, --buffer-size Get the size of the ring buffer.\n"
" -G <size>, --buffer-size=<size>\n"
" Set size of log ring buffer, may suffix with K or M.\n"
- " -L, -last Dump logs from prior to last reboot\n"
+ " -L, --last Dump logs from prior to last reboot\n"
// Leave security (Device Owner only installations) and
// kernel (userdebug and eng) buffers undocumented.
" -b <buffer>, --buffer=<buffer> Request alternate ring buffer, 'main',\n"
@@ -619,6 +620,7 @@
int option_index = 0;
// list of long-argument only strings for later comparison
static const char pid_str[] = "pid";
+ static const char debug_str[] = "debug";
static const char id_str[] = "id";
static const char wrap_str[] = "wrap";
static const char print_str[] = "print";
@@ -627,6 +629,7 @@
{ "buffer", required_argument, NULL, 'b' },
{ "buffer-size", optional_argument, NULL, 'g' },
{ "clear", no_argument, NULL, 'c' },
+ { debug_str, no_argument, NULL, 0 },
{ "dividers", no_argument, NULL, 'D' },
{ "file", required_argument, NULL, 'f' },
{ "format", required_argument, NULL, 'v' },
@@ -691,6 +694,10 @@
g_printItAnyways = true;
break;
}
+ if (long_options[option_index].name == debug_str) {
+ g_debug = true;
+ break;
+ }
if (long_options[option_index].name == id_str) {
setId = optarg && optarg[0] ? optarg : NULL;
break;
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 18067dc..11cffe6 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -29,6 +29,7 @@
#include <gtest/gtest.h>
#include <log/log.h>
+#include <log/log_event_list.h>
#define BIG_BUFFER (5 * 1024)
@@ -1091,7 +1092,7 @@
while (fgets(buffer, sizeof(buffer), fp)) {
char *hold = *list;
char *buf = buffer;
- while (isspace(*buf)) {
+ while (isspace(*buf)) {
++buf;
}
char *end = buf + strlen(buf);
@@ -1126,7 +1127,7 @@
while (fgets(buffer, sizeof(buffer), fp)) {
char *buf = buffer;
- while (isspace(*buf)) {
+ while (isspace(*buf)) {
++buf;
}
char *end = buf + strlen(buf);
@@ -1255,19 +1256,25 @@
va_end(ap);
char *str = NULL;
- asprintf(&str, "I/%s ( %%d): %s%%c", tag, buffer);
+ asprintf(&str, "I/%s ( %%d):%%c%s%%c", tag, buffer);
std::string expect(str);
free(str);
int count = 0;
pid_t pid = getpid();
std::string lastMatch;
+ int maxMatch = 1;
while (fgets(buffer, sizeof(buffer), fp)) {
+ char space;
char newline;
int p;
- int ret = sscanf(buffer, expect.c_str(), &p, &newline);
- if ((2 == ret) && (p == pid) && (newline == '\n')) ++count;
- else if ((1 == ret) && (p == pid) && (count == 0)) lastMatch = buffer;
+ int ret = sscanf(buffer, expect.c_str(), &p, &space, &newline);
+ if ((ret == 3) && (p == pid) && (space == ' ') && (newline == '\n')) {
+ ++count;
+ } else if ((ret >= maxMatch) && (p == pid) && (count == 0)) {
+ lastMatch = buffer;
+ maxMatch = ret;
+ }
}
pclose(fp);
@@ -1289,7 +1296,7 @@
{
static const struct tag hhgtg = { 42, "answer" };
- android_log_event_context ctx(hhgtg.tagNo);
+ android_log_event_list ctx(hhgtg.tagNo);
static const char theAnswer[] = "what is five by seven";
ctx << theAnswer;
ctx.write();
@@ -1301,7 +1308,7 @@
static const struct tag sync = { 2720, "sync" };
static const char id[] = "logcat.decriptive";
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << id << (int32_t)42 << (int32_t)-1 << (int32_t)0;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1311,7 +1318,7 @@
// Partial match to description
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << id << (int32_t)43 << (int64_t)-1 << (int32_t)0;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1321,7 +1328,7 @@
// Negative Test of End_to_End, ensure it is working
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << id << (int32_t)44 << (int32_t)-1 << (int64_t)0;
ctx.write();
fprintf(stderr, "Expect a \"Closest match\" message\n");
@@ -1334,7 +1341,7 @@
{
static const struct tag sync = { 2747, "contacts_aggregation" };
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint64_t)30 << (int32_t)2;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1342,7 +1349,7 @@
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint64_t)31570 << (int32_t)911;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1353,46 +1360,52 @@
{
static const struct tag sync = { 75000, "sqlite_mem_alarm_current" };
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)512;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=512B"));
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)3072;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=3KB"));
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)2097152;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=2MB"));
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)2097153;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=2097153B"));
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)1073741824;
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=1GB"));
}
{
- android_log_event_context ctx(sync.tagNo);
+ android_log_event_list ctx(sync.tagNo);
ctx << (uint32_t)3221225472; // 3MB, but on purpose overflowed
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, "current=-1GB"));
}
}
+ {
+ static const struct tag sync = { 27501, "notification_panel_hidden" };
+ android_log_event_list ctx(sync.tagNo);
+ ctx.write();
+ EXPECT_TRUE(End_to_End(sync.tagStr, ""));
+ }
}
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 7394f11..52c6742 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -48,6 +48,7 @@
registerCmd(new SetPruneListCmd(buf));
registerCmd(new GetPruneListCmd(buf));
registerCmd(new ReinitCmd());
+ registerCmd(new ExitCmd(this));
}
CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader,
@@ -297,6 +298,21 @@
return 0;
}
+CommandListener::ExitCmd::ExitCmd(CommandListener *parent) :
+ LogCommand("EXIT"),
+ mParent(*parent) {
+}
+
+int CommandListener::ExitCmd::runCommand(SocketClient * cli,
+ int /*argc*/, char ** /*argv*/) {
+ setname();
+
+ cli->sendMsg("success");
+ release(cli);
+
+ return 0;
+}
+
int CommandListener::getLogSocket() {
static const char socketName[] = "logd";
int sock = android_get_control_socket(socketName);
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
index cbcd601..5d50177 100644
--- a/logd/CommandListener.h
+++ b/logd/CommandListener.h
@@ -52,22 +52,38 @@
explicit name##Cmd(LogBuffer *buf); \
virtual ~name##Cmd() {} \
int runCommand(SocketClient *c, int argc, char ** argv); \
- };
+ }
- LogBufferCmd(Clear)
- LogBufferCmd(GetBufSize)
- LogBufferCmd(SetBufSize)
- LogBufferCmd(GetBufSizeUsed)
- LogBufferCmd(GetStatistics)
- LogBufferCmd(GetPruneList)
- LogBufferCmd(SetPruneList)
+ LogBufferCmd(Clear);
+ LogBufferCmd(GetBufSize);
+ LogBufferCmd(SetBufSize);
+ LogBufferCmd(GetBufSizeUsed);
+ LogBufferCmd(GetStatistics);
+ LogBufferCmd(GetPruneList);
+ LogBufferCmd(SetPruneList);
- class ReinitCmd : public LogCommand {
- public:
- ReinitCmd();
- virtual ~ReinitCmd() {}
- int runCommand(SocketClient *c, int argc, char ** argv);
- };
+#define LogCmd(name) \
+ class name##Cmd : public LogCommand { \
+ public: \
+ name##Cmd(); \
+ virtual ~name##Cmd() {} \
+ int runCommand(SocketClient *c, int argc, char ** argv); \
+ }
+
+ LogCmd(Reinit);
+
+#define LogParentCmd(name) \
+ class name##Cmd : public LogCommand { \
+ CommandListener &mParent; \
+ public: \
+ name##Cmd(); \
+ explicit name##Cmd(CommandListener *parent); \
+ virtual ~name##Cmd() {} \
+ int runCommand(SocketClient *c, int argc, char ** argv); \
+ void release(SocketClient *c) { mParent.release(c); } \
+ }
+
+ LogParentCmd(Exit);
};
diff --git a/logd/main.cpp b/logd/main.cpp
index d698976..c3343d7 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -37,9 +37,9 @@
#include <memory>
#include <android-base/macros.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
-#include <cutils/files.h>
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
#include <packagelistparser/packagelistparser.h>
@@ -311,7 +311,7 @@
if (!map) {
sem_wait(&sem_name);
if (!map) {
- map = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ map = android_openEventTagMap(NULL);
}
sem_post(&sem_name);
if (!map) {
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index aa5a520..7d0c87d 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -123,6 +123,7 @@
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
sbin dev proc sys system data oem acct config storage mnt root $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
+ ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
ln -sf /sys/kernel/debug $(TARGET_ROOT_OUT)/d; \
ln -sf /storage/self/primary $(TARGET_ROOT_OUT)/sdcard
ifdef BOARD_USES_VENDORIMAGE
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2f69b42..11f91ce 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -294,7 +294,6 @@
trigger early-boot
trigger boot
-
on post-fs
start logd
# once everything is setup, no need to modify /
@@ -306,11 +305,8 @@
mount none none /storage slave rec
# Make sure /sys/kernel/debug (if present) is labeled properly
- restorecon_recursive /sys/kernel/debug
-
- # On systems with tracefs, tracing is a separate mount, so make sure
- # it too is correctly labeled
- restorecon_recursive /sys/kernel/debug/tracing
+ # Note that tracefs may be mounted under debug, so we need to cross filesystems
+ restorecon --recursive --cross-filesystems /sys/kernel/debug
# We chown/chmod /cache again so because mount is run as root + defaults
chown system cache /cache
@@ -450,10 +446,6 @@
mkdir /data/anr 0775 system system
- # symlink to bugreport storage location
- rm /data/bugreports
- symlink /data/user_de/0/com.android.shell/files/bugreports /data/bugreports
-
# Create all remaining /data root dirs so that they are made through init
# and get proper encryption policy installed
mkdir /data/backup 0700 system system
@@ -484,7 +476,7 @@
init_user0
# Set SELinux security contexts on upgrade or policy update.
- restorecon_recursive /data
+ restorecon --recursive --skip-ce /data
# Check any timezone data in /data is newer than the copy in /system, delete if not.
exec - system system -- /system/bin/tzdatacheck /system/usr/share/zoneinfo /data/misc/zoneinfo
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index 28b191a..95559d7 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -1260,12 +1260,9 @@
#if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
/* FUSE_KERNEL_VERSION >= 23. */
- /* If the kernel only works on minor revs older than or equal to 22,
- * then use the older structure size since this code only uses the 7.22
- * version of the structure. */
- if (req->minor <= 22) {
- fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
- }
+ /* Since we return minor version 15, the kernel does not accept the latest
+ * fuse_init_out size. We need to use FUSE_COMPAT_22_INIT_OUT_SIZE always.*/
+ fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
#endif
out.major = FUSE_KERNEL_VERSION;
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index bc502a0..df3ce85 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -331,6 +331,27 @@
return true;
}
+static bool sdcardfs_setup_bind_remount(const std::string& source_path, const std::string& dest_path,
+ gid_t gid, mode_t mask) {
+ std::string opts = android::base::StringPrintf("mask=%d,gid=%d", mask, gid);
+
+ if (mount(source_path.c_str(), dest_path.c_str(), nullptr,
+ MS_BIND, nullptr) != 0) {
+ PLOG(ERROR) << "failed to bind mount sdcardfs filesystem";
+ return false;
+ }
+
+ if (mount(source_path.c_str(), dest_path.c_str(), "none",
+ MS_REMOUNT | MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) != 0) {
+ PLOG(ERROR) << "failed to mount sdcardfs filesystem";
+ if (umount2(dest_path.c_str(), MNT_DETACH))
+ PLOG(WARNING) << "Failed to unmount bind";
+ return false;
+ }
+
+ return true;
+}
+
static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid,
gid_t gid, userid_t userid, bool multi_user, bool full_write) {
std::string dest_path_default = "/mnt/runtime/default/" + label;
@@ -343,9 +364,8 @@
// permissions are completely masked off.
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
AID_SDCARD_RW, 0006)
- || !sdcardfs_setup(source_path, dest_path_read, uid, gid, multi_user, userid,
- AID_EVERYBODY, 0027)
- || !sdcardfs_setup(source_path, dest_path_write, uid, gid, multi_user, userid,
+ || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027)
+ || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
AID_EVERYBODY, full_write ? 0007 : 0027)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
@@ -355,9 +375,9 @@
// deep inside attr_from_stat().
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
AID_SDCARD_RW, 0006)
- || !sdcardfs_setup(source_path, dest_path_read, uid, gid, multi_user, userid,
+ || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read,
AID_EVERYBODY, full_write ? 0027 : 0022)
- || !sdcardfs_setup(source_path, dest_path_write, uid, gid, multi_user, userid,
+ || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
AID_EVERYBODY, full_write ? 0007 : 0022)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 5319ff4..d6ead1a 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -81,15 +81,6 @@
$(INPUT_H_LABELS_H):
$(transform-generated-source)
-# We only want 'r' on userdebug and eng builds.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := r.c
-LOCAL_CFLAGS += $(common_cflags)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/upstream-netbsd/include/
-LOCAL_MODULE := r
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_EXECUTABLE)
-
# We build BSD grep separately, so it can provide egrep and fgrep too.
include $(CLEAR_VARS)
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index 30053af..e6def6b 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -9,6 +9,7 @@
#include <sys/limits.h>
#include <sys/poll.h>
#include <linux/input.h>
+#include <err.h>
#include <errno.h>
#include <unistd.h>
@@ -110,10 +111,8 @@
break;
bits_size = res + 16;
bits = realloc(bits, bits_size * 2);
- if(bits == NULL) {
- fprintf(stderr, "failed to allocate buffer of size %d\n", (int)bits_size);
- return 1;
- }
+ if(bits == NULL)
+ err(1, "failed to allocate buffer of size %d\n", (int)bits_size);
}
res2 = 0;
switch(i) {
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 27ea9e8..d7047e2 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -741,6 +741,7 @@
exit(1);
}
}
+ free(img);
}
return 0;
}
diff --git a/toolbox/r.c b/toolbox/r.c
deleted file mode 100644
index b96cdb2..0000000
--- a/toolbox/r.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#if __LP64__
-#define strtoptr strtoull
-#else
-#define strtoptr strtoul
-#endif
-
-static int usage()
-{
- fprintf(stderr,"r [-b|-s] <address> [<value>]\n");
- return -1;
-}
-
-int main(int argc, char *argv[])
-{
- if(argc < 2) return usage();
-
- int width = 4;
- if(!strcmp(argv[1], "-b")) {
- width = 1;
- argc--;
- argv++;
- } else if(!strcmp(argv[1], "-s")) {
- width = 2;
- argc--;
- argv++;
- }
-
- if(argc < 2) return usage();
- uintptr_t addr = strtoptr(argv[1], 0, 16);
-
- uintptr_t endaddr = 0;
- char* end = strchr(argv[1], '-');
- if (end)
- endaddr = strtoptr(end + 1, 0, 16);
-
- if (!endaddr)
- endaddr = addr + width - 1;
-
- if (endaddr <= addr) {
- fprintf(stderr, "end address <= start address\n");
- return -1;
- }
-
- bool set = false;
- uint32_t value = 0;
- if(argc > 2) {
- set = true;
- value = strtoul(argv[2], 0, 16);
- }
-
- int fd = open("/dev/mem", O_RDWR | O_SYNC);
- if(fd < 0) {
- fprintf(stderr,"cannot open /dev/mem\n");
- return -1;
- }
-
- off64_t mmap_start = addr & ~(PAGE_SIZE - 1);
- size_t mmap_size = endaddr - mmap_start + 1;
- mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
-
- void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, mmap_start);
-
- if(page == MAP_FAILED){
- fprintf(stderr,"cannot mmap region\n");
- return -1;
- }
-
- while (addr <= endaddr) {
- switch(width){
- case 4: {
- uint32_t* x = (uint32_t*) (((uintptr_t) page) + (addr & 4095));
- if(set) *x = value;
- fprintf(stderr,"%08"PRIxPTR": %08x\n", addr, *x);
- break;
- }
- case 2: {
- uint16_t* x = (uint16_t*) (((uintptr_t) page) + (addr & 4095));
- if(set) *x = value;
- fprintf(stderr,"%08"PRIxPTR": %04x\n", addr, *x);
- break;
- }
- case 1: {
- uint8_t* x = (uint8_t*) (((uintptr_t) page) + (addr & 4095));
- if(set) *x = value;
- fprintf(stderr,"%08"PRIxPTR": %02x\n", addr, *x);
- break;
- }
- }
- addr += width;
- }
- return 0;
-}