Merge "Unicode: specify destination length in utf8_to_utf16 methods"
diff --git a/adb/Android.mk b/adb/Android.mk
index 0babf1d..6a2a6b1 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -63,6 +63,7 @@
fdevent_test.cpp \
socket_test.cpp \
sysdeps_test.cpp \
+ sysdeps/stat_test.cpp \
transport_test.cpp \
LIBADB_CFLAGS := \
@@ -90,6 +91,7 @@
LIBADB_windows_SRC_FILES := \
sysdeps_win32.cpp \
+ sysdeps/win32/stat.cpp \
usb_windows.cpp \
LIBADB_TEST_windows_SRCS := \
@@ -181,6 +183,10 @@
LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS)
LOCAL_SRC_FILES := \
$(LIBADB_TEST_SRCS) \
+ adb_client.cpp \
+ bugreport.cpp \
+ bugreport_test.cpp \
+ line_printer.cpp \
services.cpp \
shell_service_protocol.cpp \
shell_service_protocol_test.cpp \
@@ -196,6 +202,7 @@
libcrypto_static \
libcutils \
libdiagnose_usb \
+ libgmock_host \
# Set entrypoint to wmain from sysdeps_win32.cpp instead of main
LOCAL_LDFLAGS_windows := -municode
@@ -224,6 +231,7 @@
LOCAL_SRC_FILES := \
adb_client.cpp \
+ bugreport.cpp \
client/main.cpp \
console.cpp \
commandline.cpp \
diff --git a/adb/adb.h b/adb/adb.h
index 9227eb1..cd6b7bd 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -203,8 +203,6 @@
int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
#endif
-int adb_commandline(int argc, const char **argv);
-
ConnectionState connection_state(atransport *t);
extern const char* adb_device_banner;
diff --git a/adb/adb_client.h b/adb/adb_client.h
index d5cd922..9f9eb1f 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -18,6 +18,7 @@
#define _ADB_CLIENT_H_
#include "adb.h"
+#include "sysdeps.h"
#include "transport.h"
#include <string>
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index aabc5d7..4cac485 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -52,18 +52,6 @@
ASSERT_TRUE(directory_exists(profiles_dir));
- // On modern (English?) Windows, this is a directory symbolic link to
- // C:\ProgramData. Symbolic links are rare on Windows and the user requires
- // a special permission (by default granted to Administrative users) to
- // create symbolic links.
- ASSERT_FALSE(directory_exists(subdir(profiles_dir, "All Users")));
-
- // On modern (English?) Windows, this is a directory junction to
- // C:\Users\Default. Junctions are used throughout user profile directories
- // for backwards compatibility and they don't require any special permissions
- // to create.
- ASSERT_FALSE(directory_exists(subdir(profiles_dir, "Default User")));
-
ASSERT_FALSE(directory_exists(subdir(profiles_dir, "does-not-exist")));
#else
ASSERT_TRUE(directory_exists("/proc"));
@@ -72,6 +60,28 @@
#endif
}
+#if defined(_WIN32)
+TEST(adb_utils, directory_exists_win32_symlink_junction) {
+ char profiles_dir[MAX_PATH];
+ DWORD cch = arraysize(profiles_dir);
+
+ // On typical Windows 7, returns C:\Users
+ ASSERT_TRUE(GetProfilesDirectoryA(profiles_dir, &cch));
+
+ // On modern (English?) Windows, this is a directory symbolic link to
+ // C:\ProgramData. Symbolic links are rare on Windows and the user requires
+ // a special permission (by default granted to Administrative users) to
+ // create symbolic links.
+ EXPECT_FALSE(directory_exists(subdir(profiles_dir, "All Users")));
+
+ // On modern (English?) Windows, this is a directory junction to
+ // C:\Users\Default. Junctions are used throughout user profile directories
+ // for backwards compatibility and they don't require any special permissions
+ // to create.
+ EXPECT_FALSE(directory_exists(subdir(profiles_dir, "Default User")));
+}
+#endif
+
TEST(adb_utils, escape_arg) {
ASSERT_EQ(R"('')", escape_arg(""));
@@ -111,16 +121,22 @@
EXPECT_EQ("/system/bin", adb_dirname("/system/bin/sh/"));
}
-void test_mkdirs(const std::string basepath) {
+void test_mkdirs(const std::string& basepath) {
// Test creating a directory hierarchy.
- EXPECT_TRUE(mkdirs(basepath));
+ ASSERT_TRUE(mkdirs(basepath));
// Test finding an existing directory hierarchy.
- EXPECT_TRUE(mkdirs(basepath));
+ ASSERT_TRUE(mkdirs(basepath));
+ // Test mkdirs on an existing hierarchy with a trailing slash.
+ ASSERT_TRUE(mkdirs(basepath + '/'));
+#if defined(_WIN32)
+ ASSERT_TRUE(mkdirs(basepath + '\\'));
+#endif
+
const std::string filepath = basepath + "/file";
// Verify that the hierarchy was created by trying to create a file in it.
- EXPECT_NE(-1, adb_creat(filepath.c_str(), 0600));
+ ASSERT_NE(-1, adb_creat(filepath.c_str(), 0600));
// If a file exists where we want a directory, the operation should fail.
- EXPECT_FALSE(mkdirs(filepath));
+ ASSERT_FALSE(mkdirs(filepath));
}
TEST(adb_utils, mkdirs) {
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
new file mode 100644
index 0000000..64f01bd
--- /dev/null
+++ b/adb/bugreport.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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 <string>
+
+#include <android-base/strings.h>
+
+#include "bugreport.h"
+#include "file_sync_service.h"
+
+static constexpr char BUGZ_OK_PREFIX[] = "OK:";
+static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
+static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
+static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
+
+// Custom callback used to handle the output of zipped bugreports.
+class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
+ public:
+ BugreportStandardStreamsCallback(const std::string& dest_file, bool show_progress, Bugreport* br)
+ : br_(br),
+ dest_file_(dest_file),
+ line_message_(android::base::StringPrintf("generating %s", dest_file_.c_str())),
+ show_progress_(show_progress),
+ status_(-1),
+ line_() {
+ }
+
+ void OnStdout(const char* buffer, int length) {
+ for (int i = 0; i < length; i++) {
+ char c = buffer[i];
+ if (c == '\n') {
+ ProcessLine(line_);
+ line_.clear();
+ } else {
+ line_.append(1, c);
+ }
+ }
+ }
+
+ void OnStderr(const char* buffer, int length) {
+ OnStream(nullptr, stderr, buffer, length);
+ }
+ int Done(int unused_) {
+ // Process remaining line, if any...
+ ProcessLine(line_);
+ // ..then return.
+ return status_;
+ }
+
+ private:
+ void ProcessLine(const std::string& line) {
+ if (line.empty()) return;
+
+ if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
+ if (show_progress_) {
+ // Make sure pull message doesn't conflict with generation message.
+ br_->UpdateProgress(line_message_, 100, 100);
+ }
+
+ const char* zip_file = &line[strlen(BUGZ_OK_PREFIX)];
+ std::vector<const char*> srcs{zip_file};
+ status_ = br_->DoSyncPull(srcs, dest_file_.c_str(), true, line_message_.c_str()) ? 0 : 1;
+ if (status_ != 0) {
+ fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file_.c_str());
+ }
+ } else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
+ const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
+ fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
+ status_ = -1;
+ } else if (show_progress_ && android::base::StartsWith(line, BUGZ_PROGRESS_PREFIX)) {
+ // progress_line should have the following format:
+ //
+ // BUGZ_PROGRESS_PREFIX:PROGRESS/TOTAL
+ //
+ size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
+ size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
+ int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
+ int total = std::stoi(line.substr(idx2 + 1));
+ br_->UpdateProgress(dest_file_, progress, total);
+ } else {
+ fprintf(stderr,
+ "WARNING: unexpected line (%s) returned by bugreportz, "
+ "device probably does not support zipped bugreports.\n"
+ "Try 'adb bugreport' instead.",
+ line.c_str());
+ }
+ }
+
+ Bugreport* br_;
+ const std::string dest_file_;
+ const std::string line_message_;
+ bool show_progress_;
+ int status_;
+
+ // Temporary buffer containing the characters read since the last newline
+ // (\n).
+ std::string line_;
+
+ DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
+};
+
+// Implemented in commandline.cpp
+int usage();
+
+int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
+ if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
+ if (argc != 2) return usage();
+
+ // Zipped bugreport option - will call 'bugreportz', which prints the location
+ // of the generated
+ // file, then pull it to the destination file provided by the user.
+ std::string dest_file = argv[1];
+ if (!android::base::EndsWith(argv[1], ".zip")) {
+ // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
+ dest_file += ".zip";
+ }
+
+ // Gets bugreportz version.
+ std::string bugz_stderr;
+ DefaultStandardStreamsCallback version_callback(nullptr, &bugz_stderr);
+ int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback);
+
+ if (status != 0) {
+ fprintf(stderr,
+ "Failed to get bugreportz version: 'bugreport -v' returned '%s' "
+ "(code %d)."
+ "\nIf the device does not support it, try running 'adb bugreport' "
+ "to get a "
+ "flat-file bugreport.",
+ bugz_stderr.c_str(), status);
+ return status;
+ }
+ std::string bugz_version = android::base::Trim(bugz_stderr);
+
+ bool show_progress = true;
+ std::string bugz_command = "bugreportz -p";
+ if (bugz_version == "1.0") {
+ // 1.0 does not support progress notifications, so print a disclaimer
+ // message instead.
+ fprintf(stderr,
+ "Bugreport is in progress and it could take minutes to complete.\n"
+ "Please be patient and do not cancel or disconnect your device "
+ "until it completes."
+ "\n");
+ show_progress = false;
+ bugz_command = "bugreportz";
+ }
+ BugreportStandardStreamsCallback bugz_callback(dest_file, show_progress, this);
+ return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
+}
+
+void Bugreport::UpdateProgress(const std::string& message, int progress, int total) {
+ int progress_percentage = (progress * 100 / total);
+ line_printer_.Print(
+ android::base::StringPrintf("[%3d%%] %s", progress_percentage, message.c_str()),
+ LinePrinter::INFO);
+}
+
+int Bugreport::SendShellCommand(TransportType transport_type, const char* serial,
+ const std::string& command, bool disable_shell_protocol,
+ StandardStreamsCallbackInterface* callback) {
+ return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback);
+}
+
+bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
+ const char* name) {
+ return do_sync_pull(srcs, dst, copy_attrs, name);
+}
diff --git a/adb/bugreport.h b/adb/bugreport.h
new file mode 100644
index 0000000..ee99cbc
--- /dev/null
+++ b/adb/bugreport.h
@@ -0,0 +1,51 @@
+/*
+ * 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 BUGREPORT_H
+#define BUGREPORT_H
+
+#include <vector>
+
+#include "adb.h"
+#include "commandline.h"
+#include "line_printer.h"
+
+class Bugreport {
+ friend class BugreportStandardStreamsCallback;
+
+ public:
+ Bugreport() : line_printer_() {
+ }
+ int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv);
+
+ protected:
+ // Functions below are abstractions of external functions so they can be
+ // mocked on tests.
+ virtual int SendShellCommand(
+ TransportType transport_type, const char* serial, const std::string& command,
+ bool disable_shell_protocol,
+ StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
+
+ virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
+ const char* name);
+
+ private:
+ virtual void UpdateProgress(const std::string& file_name, int progress, int total);
+ LinePrinter line_printer_;
+ DISALLOW_COPY_AND_ASSIGN(Bugreport);
+};
+
+#endif // BUGREPORT_H
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
new file mode 100644
index 0000000..a89d8dc
--- /dev/null
+++ b/adb/bugreport_test.cpp
@@ -0,0 +1,307 @@
+/*
+ * 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 "bugreport.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::testing::_;
+using ::testing::Action;
+using ::testing::ActionInterface;
+using ::testing::DoAll;
+using ::testing::ElementsAre;
+using ::testing::HasSubstr;
+using ::testing::MakeAction;
+using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::WithArg;
+using ::testing::internal::CaptureStderr;
+using ::testing::internal::GetCapturedStderr;
+
+// Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
+// SELinux and its transitive dependencies...
+bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
+ const char* name) {
+ ADD_FAILURE() << "do_sync_pull() should have been mocked";
+ return false;
+}
+
+// Empty functions so tests don't need to be linked against commandline.cpp
+DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
+int usage() {
+ return -42;
+}
+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
+ bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
+ ADD_FAILURE() << "send_shell_command() should have been mocked";
+ return -42;
+}
+
+enum StreamType {
+ kStreamStdout,
+ kStreamStderr,
+};
+
+// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher
+typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
+
+class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
+ public:
+ explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
+ : type_(type), output_(output) {
+ }
+ virtual Result Perform(const ArgumentTuple& args) {
+ if (type_ == kStreamStdout) {
+ ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
+ }
+ if (type_ == kStreamStderr) {
+ ::std::tr1::get<0>(args)->OnStderr(output_.c_str(), output_.size());
+ }
+ }
+
+ private:
+ StreamType type_;
+ std::string output_;
+};
+
+// Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
+// length)
+Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
+ return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
+}
+
+// Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
+// length)
+Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
+ return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
+}
+
+typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
+
+class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
+ public:
+ explicit CallbackDoneAction(int status) : status_(status) {
+ }
+ virtual Result Perform(const ArgumentTuple& args) {
+ int status = ::std::tr1::get<0>(args)->Done(status_);
+ return status;
+ }
+
+ private:
+ int status_;
+};
+
+// Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
+Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
+ return MakeAction(new CallbackDoneAction(status));
+}
+
+class BugreportMock : public Bugreport {
+ public:
+ MOCK_METHOD5(SendShellCommand,
+ int(TransportType transport_type, const char* serial, const std::string& command,
+ bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
+ MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
+ bool copy_attrs, const char* name));
+ MOCK_METHOD3(UpdateProgress, void(const std::string&, int, int));
+};
+
+class BugreportTest : public ::testing::Test {
+ public:
+ void SetBugreportzVersion(const std::string& version) {
+ EXPECT_CALL(br_,
+ SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
+ WithArg<4>(ReturnCallbackDone(0))));
+ }
+
+ void ExpectProgress(int progress, int total) {
+ EXPECT_CALL(br_, UpdateProgress(HasSubstr("file.zip"), progress, total));
+ }
+
+ BugreportMock br_;
+};
+
+// Tests when called with invalid number of argumnts
+TEST_F(BugreportTest, InvalidNumberArgs) {
+ const char* args[1024] = {"bugreport", "to", "principal"};
+ ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
+}
+
+// Tests the legacy 'adb bugreport' option
+TEST_F(BugreportTest, FlatFileFormat) {
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
+ .WillOnce(Return(0));
+
+ const char* args[1024] = {"bugreport"};
+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
+}
+
+// Tests 'adb bugreport file.zip' when it succeeds and device does not support
+// progress.
+TEST_F(BugreportTest, OkLegacy) {
+ SetBugreportzVersion("1.0");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
+ WithArg<4>(ReturnCallbackDone())));
+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
+ true, HasSubstr("file.zip")))
+ .WillOnce(Return(true));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
+// multiple buffer writers and without progress updates.
+TEST_F(BugreportTest, OkLegacySplitBuffer) {
+ SetBugreportzVersion("1.0");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
+ WithArg<4>(WriteOnStdout("/bugreport.zip")),
+ WithArg<4>(ReturnCallbackDone())));
+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
+ true, HasSubstr("file.zip")))
+ .WillOnce(Return(true));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
+TEST_F(BugreportTest, Ok) {
+ SetBugreportzVersion("1.1");
+ ExpectProgress(1, 100);
+ ExpectProgress(10, 100);
+ ExpectProgress(50, 100);
+ ExpectProgress(99, 100);
+ ExpectProgress(100, 100);
+ // clang-format off
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(DoAll(
+ // Progress line in one write
+ WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
+ // Add some bogus lines
+ WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\n")),
+ // Multiple progress lines in one write
+ WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
+ // Progress line in multiple writes
+ WithArg<4>(WriteOnStdout("PROG")),
+ WithArg<4>(WriteOnStdout("RESS:99")),
+ WithArg<4>(WriteOnStdout("/100\n")),
+ // Split last message as well, just in case
+ WithArg<4>(WriteOnStdout("OK:/device/bugreport")),
+ WithArg<4>(WriteOnStdout(".zip")),
+ WithArg<4>(ReturnCallbackDone())));
+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
+ true, HasSubstr("file.zip")))
+ .WillOnce(Return(true));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file' when it succeeds
+TEST_F(BugreportTest, OkNoExtension) {
+ SetBugreportzVersion("1.1");
+ ExpectProgress(100, 100);
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
+ WithArg<4>(ReturnCallbackDone())));
+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
+ true, HasSubstr("file.zip")))
+ .WillOnce(Return(true));
+
+ const char* args[1024] = {"bugreport", "file"};
+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file.zip' when the bugreport itself failed
+TEST_F(BugreportTest, BugreportzReturnedFail) {
+ SetBugreportzVersion("1.1");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(
+ DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
+
+ CaptureStderr();
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+ ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
+}
+
+// Tests 'adb bugreport file.zip' when the bugreport itself failed but response
+// was sent in
+// multiple buffer writes
+TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
+ SetBugreportzVersion("1.1");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
+ WithArg<4>(ReturnCallbackDone())));
+
+ CaptureStderr();
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+ ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
+}
+
+// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
+// response.
+TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
+ SetBugreportzVersion("1.1");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
+ WithArg<4>(ReturnCallbackDone())));
+
+ CaptureStderr();
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+ ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
+}
+
+// Tests 'adb bugreport file.zip' when the bugreportz -v command failed
+TEST_F(BugreportTest, BugreportzVersionFailed) {
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
+ .WillOnce(Return(666));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file.zip' when the main bugreportz command failed
+TEST_F(BugreportTest, BugreportzFailed) {
+ SetBugreportzVersion("1.1");
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(Return(666));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
+
+// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
+TEST_F(BugreportTest, PullFails) {
+ SetBugreportzVersion("1.1");
+ ExpectProgress(100, 100);
+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
+ WithArg<4>(ReturnCallbackDone())));
+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
+ true, HasSubstr("file.zip")))
+ .WillOnce(Return(false));
+
+ const char* args[1024] = {"bugreport", "file.zip"};
+ ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
+}
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index d2ca44e..894ebd1 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -32,6 +32,7 @@
#include "adb_auth.h"
#include "adb_listeners.h"
#include "adb_utils.h"
+#include "commandline.h"
#include "transport.h"
static std::string GetLogFilePath() {
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 64d4b9b..74a3451 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -52,10 +52,11 @@
#include "adb_client.h"
#include "adb_io.h"
#include "adb_utils.h"
+#include "bugreport.h"
+#include "commandline.h"
#include "file_sync_service.h"
#include "services.h"
#include "shell_service.h"
-#include "transport.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);
@@ -66,8 +67,7 @@
static auto& gProductOutPath = *new std::string();
extern int gListenAll;
-static constexpr char BUGZ_OK_PREFIX[] = "OK:";
-static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
+DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
static std::string product_file(const char *extra) {
if (gProductOutPath.empty()) {
@@ -254,7 +254,7 @@
);
}
-static int usage() {
+int usage() {
help();
return 1;
}
@@ -292,17 +292,14 @@
// this expects that incoming data will use the shell protocol, in which case
// stdout/stderr are routed independently and the remote exit code will be
// returned.
-// if |output| is non-null, stdout will be appended to it instead.
-// if |err| is non-null, stderr will be appended to it instead.
-static int read_and_dump(int fd, bool use_shell_protocol=false, std::string* output=nullptr,
- std::string* err=nullptr) {
+// if |callback| is non-null, stdout/stderr output will be handled by it.
+int read_and_dump(int fd, bool use_shell_protocol = false,
+ StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK) {
int exit_code = 0;
if (fd < 0) return exit_code;
std::unique_ptr<ShellProtocol> protocol;
int length = 0;
- FILE* outfile = stdout;
- std::string* outstring = output;
char raw_buffer[BUFSIZ];
char* buffer_ptr = raw_buffer;
@@ -320,14 +317,13 @@
if (!protocol->Read()) {
break;
}
+ length = protocol->data_length();
switch (protocol->id()) {
case ShellProtocol::kIdStdout:
- outfile = stdout;
- outstring = output;
+ callback->OnStdout(buffer_ptr, length);
break;
case ShellProtocol::kIdStderr:
- outfile = stderr;
- outstring = err;
+ callback->OnStderr(buffer_ptr, length);
break;
case ShellProtocol::kIdExit:
exit_code = protocol->data()[0];
@@ -343,17 +339,11 @@
if (length <= 0) {
break;
}
- }
-
- if (outstring == nullptr) {
- fwrite(buffer_ptr, 1, length, outfile);
- fflush(outfile);
- } else {
- outstring->append(buffer_ptr, length);
+ callback->OnStdout(buffer_ptr, length);
}
}
- return exit_code;
+ return callback->Done(exit_code);
}
static void read_status_line(int fd, char* buf, size_t count)
@@ -1119,20 +1109,16 @@
return true;
}
-// Connects to the device "shell" service with |command| and prints the
-// resulting output.
-static int send_shell_command(TransportType transport_type, const char* serial,
- const std::string& command,
- bool disable_shell_protocol,
- std::string* output=nullptr,
- std::string* err=nullptr) {
+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
+ bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
int fd;
bool use_shell_protocol = false;
while (true) {
bool attempt_connection = true;
- // Use shell protocol if it's supported and the caller doesn't explicitly disable it.
+ // Use shell protocol if it's supported and the caller doesn't explicitly
+ // disable it.
if (!disable_shell_protocol) {
FeatureSet features;
std::string error;
@@ -1154,13 +1140,13 @@
}
}
- fprintf(stderr,"- waiting for device -\n");
+ fprintf(stderr, "- waiting for device -\n");
if (!wait_for_device("wait-for-device", transport_type, serial)) {
return 1;
}
}
- int exit_code = read_and_dump(fd, use_shell_protocol, output, err);
+ int exit_code = read_and_dump(fd, use_shell_protocol, callback);
if (adb_close(fd) < 0) {
PLOG(ERROR) << "failure closing FD " << fd;
@@ -1169,45 +1155,6 @@
return exit_code;
}
-static int bugreport(TransportType transport_type, const char* serial, int argc,
- const char** argv) {
- if (argc == 1) return send_shell_command(transport_type, serial, "bugreport", false);
- if (argc != 2) return usage();
-
- // Zipped bugreport option - will call 'bugreportz', which prints the location of the generated
- // file, then pull it to the destination file provided by the user.
- std::string dest_file = argv[1];
- if (!android::base::EndsWith(argv[1], ".zip")) {
- // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
- dest_file += ".zip";
- }
- std::string output;
-
- fprintf(stderr, "Bugreport is in progress and it could take minutes to complete.\n"
- "Please be patient and do not cancel or disconnect your device until it completes.\n");
- int status = send_shell_command(transport_type, serial, "bugreportz", false, &output, nullptr);
- if (status != 0 || output.empty()) return status;
- output = android::base::Trim(output);
-
- if (android::base::StartsWith(output, BUGZ_OK_PREFIX)) {
- const char* zip_file = &output[strlen(BUGZ_OK_PREFIX)];
- std::vector<const char*> srcs{zip_file};
- status = do_sync_pull(srcs, dest_file.c_str(), true, dest_file.c_str()) ? 0 : 1;
- if (status != 0) {
- fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file.c_str());
- }
- return status;
- }
- if (android::base::StartsWith(output, BUGZ_FAIL_PREFIX)) {
- const char* error_message = &output[strlen(BUGZ_FAIL_PREFIX)];
- fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
- return -1;
- }
- fprintf(stderr, "Unexpected string (%s) returned by bugreportz, "
- "device probably does not support -z option\n", output.c_str());
- return -1;
-}
-
static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
char* log_tags = getenv("ANDROID_LOG_TAGS");
std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
@@ -1363,9 +1310,10 @@
return hint;
}
- // If there are any slashes in it, assume it's a relative path;
+ // If any of the OS_PATH_SEPARATORS is found, assume it's a relative path;
// make it absolute.
- if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
+ // NOLINT: Do not complain if OS_PATH_SEPARATORS has only one character.
+ if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) { // NOLINT
std::string cwd;
if (!getcwd(&cwd)) {
fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
@@ -1468,6 +1416,16 @@
#endif
}
+static bool _use_legacy_install() {
+ FeatureSet features;
+ std::string error;
+ if (!adb_get_feature_set(&features, &error)) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return true;
+ }
+ return !CanUseFeature(features, kFeatureCmd);
+}
+
int adb_commandline(int argc, const char **argv) {
int no_daemon = 0;
int is_daemon = 0;
@@ -1768,7 +1726,8 @@
} else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
return adb_root(argv[0]) ? 0 : 1;
} else if (!strcmp(argv[0], "bugreport")) {
- return bugreport(transport_type, serial, argc, argv);
+ Bugreport bugreport;
+ return bugreport.DoIt(transport_type, serial, argc, argv);
} else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
bool reverse = !strcmp(argv[0], "reverse");
++argv;
@@ -1862,17 +1821,10 @@
}
else if (!strcmp(argv[0], "install")) {
if (argc < 2) return usage();
- FeatureSet features;
- std::string error;
- if (!adb_get_feature_set(&features, &error)) {
- fprintf(stderr, "error: %s\n", error.c_str());
- return 1;
+ if (_use_legacy_install()) {
+ return install_app_legacy(transport_type, serial, argc, argv);
}
-
- if (CanUseFeature(features, kFeatureCmd)) {
- return install_app(transport_type, serial, argc, argv);
- }
- return install_app_legacy(transport_type, serial, argc, argv);
+ return install_app(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "install-multiple")) {
if (argc < 2) return usage();
@@ -1880,17 +1832,10 @@
}
else if (!strcmp(argv[0], "uninstall")) {
if (argc < 2) return usage();
- FeatureSet features;
- std::string error;
- if (!adb_get_feature_set(&features, &error)) {
- fprintf(stderr, "error: %s\n", error.c_str());
- return 1;
+ if (_use_legacy_install()) {
+ return uninstall_app_legacy(transport_type, serial, argc, argv);
}
-
- if (CanUseFeature(features, kFeatureCmd)) {
- return uninstall_app(transport_type, serial, argc, argv);
- }
- return uninstall_app_legacy(transport_type, serial, argc, argv);
+ return uninstall_app(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "sync")) {
std::string src;
@@ -2104,7 +2049,6 @@
int i;
struct stat sb;
uint64_t total_size = 0;
-
// Find all APK arguments starting at end.
// All other arguments passed through verbatim.
int first_apk = -1;
@@ -2129,7 +2073,14 @@
return 1;
}
- std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+ std::string install_cmd;
+ if (_use_legacy_install()) {
+ install_cmd = "exec:pm";
+ } else {
+ install_cmd = "exec:cmd package";
+ }
+
+ std::string cmd = android::base::StringPrintf("%s install-create -S %" PRIu64, install_cmd.c_str(), total_size);
for (i = 1; i < first_apk; i++) {
cmd += " " + escape_arg(argv[i]);
}
@@ -2171,8 +2122,8 @@
}
std::string cmd = android::base::StringPrintf(
- "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
- static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
+ "%s install-write -S %" PRIu64 " %d %d_%s -",
+ install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
int localFd = adb_open(file, O_RDONLY);
if (localFd < 0) {
@@ -2207,8 +2158,8 @@
finalize_session:
// Commit session if we streamed everything okay; otherwise abandon
std::string service =
- android::base::StringPrintf("exec:pm install-%s %d",
- success ? "commit" : "abandon", session_id);
+ android::base::StringPrintf("%s install-%s %d",
+ install_cmd.c_str(), success ? "commit" : "abandon", session_id);
fd = adb_connect(service, &error);
if (fd < 0) {
fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
diff --git a/adb/commandline.h b/adb/commandline.h
new file mode 100644
index 0000000..0cf655c
--- /dev/null
+++ b/adb/commandline.h
@@ -0,0 +1,99 @@
+/*
+ * 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 COMMANDLINE_H
+#define COMMANDLINE_H
+
+#include "adb.h"
+
+// Callback used to handle the standard streams (stdout and stderr) sent by the
+// device's upon receiving a command.
+//
+class StandardStreamsCallbackInterface {
+ public:
+ StandardStreamsCallbackInterface() {
+ }
+ // Handles the stdout output from devices supporting the Shell protocol.
+ virtual void OnStdout(const char* buffer, int length) = 0;
+
+ // Handles the stderr output from devices supporting the Shell protocol.
+ virtual void OnStderr(const char* buffer, int length) = 0;
+
+ // Indicates the communication is finished and returns the appropriate error
+ // code.
+ //
+ // |status| has the status code returning by the underlying communication
+ // channels
+ virtual int Done(int status) = 0;
+
+ protected:
+ static void OnStream(std::string* string, FILE* stream, const char* buffer, int length) {
+ if (string != nullptr) {
+ string->append(buffer, length);
+ } else {
+ fwrite(buffer, 1, length, stream);
+ fflush(stream);
+ }
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface);
+};
+
+// Default implementation that redirects the streams to the equilavent host
+// stream or to a string
+// passed to the constructor.
+class DefaultStandardStreamsCallback : public StandardStreamsCallbackInterface {
+ public:
+ // If |stdout_str| is non-null, OnStdout will append to it.
+ // If |stderr_str| is non-null, OnStderr will append to it.
+ DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
+ : stdout_str_(stdout_str), stderr_str_(stderr_str) {
+ }
+
+ void OnStdout(const char* buffer, int length) {
+ OnStream(stdout_str_, stdout, buffer, length);
+ }
+
+ void OnStderr(const char* buffer, int length) {
+ OnStream(stderr_str_, stderr, buffer, length);
+ }
+
+ int Done(int status) {
+ return status;
+ }
+
+ private:
+ std::string* stdout_str_;
+ std::string* stderr_str_;
+
+ DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
+};
+
+// Singleton.
+extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
+
+int adb_commandline(int argc, const char** argv);
+int usage();
+
+// Connects to the device "shell" service with |command| and prints the
+// resulting output.
+// if |callback| is non-null, stdout/stderr output will be handled by it.
+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
+ bool disable_shell_protocol, StandardStreamsCallbackInterface* callback =
+ &DEFAULT_STANDARD_STREAMS_CALLBACK);
+
+#endif // COMMANDLINE_H
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 651e8ca..6302eb7 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -433,7 +433,7 @@
typedef void (sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char* name);
static bool sync_ls(SyncConnection& sc, const char* path,
- std::function<sync_ls_cb> func) {
+ const std::function<sync_ls_cb>& func) {
if (!sc.SendRequest(ID_LIST, path)) return false;
while (true) {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 212c1c3..04df16f 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -34,6 +34,8 @@
#include <android-base/unique_fd.h>
#include <android-base/utf8.h>
+#include "sysdeps/stat.h"
+
/*
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
@@ -199,8 +201,6 @@
/* nothing really */
}
-#define lstat stat /* no symlinks on Win32 */
-
#define S_ISLNK(m) 0 /* no symlinks on Win32 */
extern int adb_unlink(const char* path);
@@ -307,27 +307,6 @@
return isalpha(path[0]) && path[1] == ':' && path[2] == '\\';
}
-// We later define a macro mapping 'stat' to 'adb_stat'. This causes:
-// struct stat s;
-// stat(filename, &s);
-// To turn into the following:
-// struct adb_stat s;
-// adb_stat(filename, &s);
-// To get this to work, we need to make 'struct adb_stat' the same as
-// 'struct stat'. Note that this definition of 'struct adb_stat' uses the
-// *current* macro definition of stat, so it may actually be inheriting from
-// struct _stat32i64 (or some other remapping).
-struct adb_stat : public stat {};
-
-static_assert(sizeof(struct adb_stat) == sizeof(struct stat),
- "structures should be the same");
-
-extern int adb_stat(const char* f, struct adb_stat* s);
-
-// stat is already a macro, undefine it so we can redefine it.
-#undef stat
-#define stat adb_stat
-
// UTF-8 versions of POSIX APIs.
extern DIR* adb_opendir(const char* dirname);
extern struct dirent* adb_readdir(DIR* dir);
diff --git a/adb/sysdeps/stat.h b/adb/sysdeps/stat.h
new file mode 100644
index 0000000..5953595
--- /dev/null
+++ b/adb/sysdeps/stat.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 <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if defined(_WIN32)
+// stat is broken on Win32: stat on a path with a trailing slash or backslash will always fail with
+// ENOENT.
+int adb_stat(const char* path, struct adb_stat* buf);
+
+// We later define a macro mapping 'stat' to 'adb_stat'. This causes:
+// struct stat s;
+// stat(filename, &s);
+// To turn into the following:
+// struct adb_stat s;
+// adb_stat(filename, &s);
+// To get this to work, we need to make 'struct adb_stat' the same as
+// 'struct stat'. Note that this definition of 'struct adb_stat' uses the
+// *current* macro definition of stat, so it may actually be inheriting from
+// struct _stat32i64 (or some other remapping).
+struct adb_stat : public stat {};
+
+#undef stat
+#define stat adb_stat
+
+// Windows doesn't have lstat.
+#define lstat adb_stat
+
+#endif
diff --git a/adb/sysdeps/stat_test.cpp b/adb/sysdeps/stat_test.cpp
new file mode 100644
index 0000000..2c2e0ee
--- /dev/null
+++ b/adb/sysdeps/stat_test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+
+#include "adb_utils.h"
+#include "sysdeps.h"
+
+TEST(sysdeps, stat) {
+ TemporaryDir td;
+ TemporaryFile tf;
+
+ struct stat st;
+ ASSERT_EQ(0, stat(td.path, &st));
+ ASSERT_FALSE(S_ISREG(st.st_mode));
+ ASSERT_TRUE(S_ISDIR(st.st_mode));
+
+ ASSERT_EQ(0, stat((std::string(td.path) + '/').c_str(), &st));
+ ASSERT_TRUE(S_ISDIR(st.st_mode));
+
+#if defined(_WIN32)
+ ASSERT_EQ(0, stat((std::string(td.path) + '\\').c_str(), &st));
+ ASSERT_TRUE(S_ISDIR(st.st_mode));
+#endif
+
+ std::string nonexistent_path = std::string(td.path) + "/nonexistent";
+ ASSERT_EQ(-1, stat(nonexistent_path.c_str(), &st));
+ ASSERT_EQ(ENOENT, errno);
+
+ ASSERT_EQ(-1, stat((nonexistent_path + "/").c_str(), &st));
+ ASSERT_EQ(ENOENT, errno);
+
+#if defined(_WIN32)
+ ASSERT_EQ(-1, stat((nonexistent_path + "\\").c_str(), &st));
+ ASSERT_EQ(ENOENT, errno);
+#endif
+
+ ASSERT_EQ(0, stat(tf.path, &st));
+ ASSERT_TRUE(S_ISREG(st.st_mode));
+ ASSERT_FALSE(S_ISDIR(st.st_mode));
+
+ ASSERT_EQ(-1, stat((std::string(tf.path) + '/').c_str(), &st));
+ ASSERT_EQ(ENOTDIR, errno);
+
+#if defined(_WIN32)
+ ASSERT_EQ(-1, stat((std::string(tf.path) + '\\').c_str(), &st));
+ ASSERT_EQ(ENOTDIR, errno);
+#endif
+}
diff --git a/adb/sysdeps/win32/stat.cpp b/adb/sysdeps/win32/stat.cpp
new file mode 100644
index 0000000..844c1ce
--- /dev/null
+++ b/adb/sysdeps/win32/stat.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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 "sysdeps/stat.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+#include <android-base/utf8.h>
+
+// Version of stat() that takes a UTF-8 path.
+int adb_stat(const char* path, struct adb_stat* s) {
+// This definition of wstat seems to be missing from <sys/stat.h>.
+#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
+#ifdef _USE_32BIT_TIME_T
+#define wstat _wstat32i64
+#else
+#define wstat _wstat64
+#endif
+#else
+// <sys/stat.h> has a function prototype for wstat() that should be available.
+#endif
+
+ std::wstring path_wide;
+ if (!android::base::UTF8ToWide(path, &path_wide)) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ // If the path has a trailing slash, stat will fail with ENOENT regardless of whether the path
+ // is a directory or not.
+ bool expected_directory = false;
+ while (*path_wide.rbegin() == u'/' || *path_wide.rbegin() == u'\\') {
+ path_wide.pop_back();
+ expected_directory = true;
+ }
+
+ struct adb_stat st;
+ int result = wstat(path_wide.c_str(), &st);
+ if (result == 0 && expected_directory) {
+ if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+
+ memcpy(s, &st, sizeof(st));
+ return result;
+}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index f94d6fc..ee27406 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -2252,30 +2252,6 @@
}
}
-// Version of stat() that takes a UTF-8 path.
-int adb_stat(const char* path, struct adb_stat* s) {
-#pragma push_macro("wstat")
-// This definition of wstat seems to be missing from <sys/stat.h>.
-#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
-#ifdef _USE_32BIT_TIME_T
-#define wstat _wstat32i64
-#else
-#define wstat _wstat64
-#endif
-#else
-// <sys/stat.h> has a function prototype for wstat() that should be available.
-#endif
-
- std::wstring path_wide;
- if (!android::base::UTF8ToWide(path, &path_wide)) {
- return -1;
- }
-
- return wstat(path_wide.c_str(), s);
-
-#pragma pop_macro("wstat")
-}
-
// Version of opendir() that takes a UTF-8 path.
DIR* adb_opendir(const char* path) {
std::wstring path_wide;
diff --git a/base/file.cpp b/base/file.cpp
index da1adba..4e7ac82 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -24,9 +24,8 @@
#include <string>
#include "android-base/macros.h" // For TEMP_FAILURE_RETRY on Darwin.
+#include "android-base/logging.h"
#include "android-base/utf8.h"
-#define LOG_TAG "base.file"
-#include "cutils/log.h"
#include "utils/Compat.h"
namespace android {
@@ -86,22 +85,22 @@
int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
if (fd == -1) {
- ALOGE("android::WriteStringToFile open failed: %s", strerror(errno));
+ PLOG(ERROR) << "android::WriteStringToFile open failed";
return false;
}
// We do an explicit fchmod here because we assume that the caller really
// meant what they said and doesn't want the umask-influenced mode.
if (fchmod(fd, mode) == -1) {
- ALOGE("android::WriteStringToFile fchmod failed: %s", strerror(errno));
+ PLOG(ERROR) << "android::WriteStringToFile fchmod failed";
return CleanUpAfterFailedWrite(path);
}
if (fchown(fd, owner, group) == -1) {
- ALOGE("android::WriteStringToFile fchown failed: %s", strerror(errno));
+ PLOG(ERROR) << "android::WriteStringToFile fchown failed";
return CleanUpAfterFailedWrite(path);
}
if (!WriteStringToFd(content, fd)) {
- ALOGE("android::WriteStringToFile write failed: %s", strerror(errno));
+ PLOG(ERROR) << "android::WriteStringToFile write failed";
return CleanUpAfterFailedWrite(path);
}
close(fd);
diff --git a/base/logging.cpp b/base/logging.cpp
index 769c266..959bb8b 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -43,12 +43,11 @@
#include "android-base/macros.h"
#include "android-base/strings.h"
-#include "cutils/threads.h"
// Headers for LogMessage::LogLine.
#ifdef __ANDROID__
#include <android/set_abort_message.h>
-#include "cutils/log.h"
+#include "log/log.h"
#else
#include <sys/types.h>
#include <unistd.h>
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index ef4f68e..346eada 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -25,6 +25,7 @@
#include <utility>
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include "histogram_logger.h"
#include "uptime_parser.h"
@@ -57,8 +58,10 @@
// Ignore existing bootstat records (which do not contain file content).
if (!content.empty()) {
- int32_t value = std::stoi(content);
- bootstat::LogHistogram("bootstat_mtime_matches_content", value == *uptime);
+ int32_t value;
+ if (android::base::ParseInt(content.c_str(), &value)) {
+ bootstat::LogHistogram("bootstat_mtime_matches_content", value == *uptime);
+ }
}
return true;
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 7c1b7f3..71a5a39 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -28,6 +28,7 @@
#include <memory>
#include <string>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <cutils/properties.h>
#include <log/log.h>
#include "boot_event_record_store.h"
@@ -56,8 +57,9 @@
BootEventRecordStore boot_event_store;
if (!value_str.empty()) {
int32_t value = 0;
- value = std::stoi(value_str);
- boot_event_store.AddBootEventWithValue(event, value);
+ if (android::base::ParseInt(value_str.c_str(), &value)) {
+ boot_event_store.AddBootEventWithValue(event, value);
+ }
} else {
boot_event_store.AddBootEvent(event);
}
@@ -187,7 +189,10 @@
std::string boot_complete_prefix = "boot_complete";
std::string build_date_str = GetProperty("ro.build.date.utc");
- int32_t build_date = std::stoi(build_date_str);
+ int32_t build_date;
+ if (!android::base::ParseInt(build_date_str.c_str(), &build_date)) {
+ return std::string();
+ }
BootEventRecordStore boot_event_store;
BootEventRecordStore::BootEventRecord record;
@@ -223,6 +228,10 @@
// ota_boot_complete. The latter signifies that the device is booting after
// a system update.
std::string boot_complete_prefix = CalculateBootCompletePrefix();
+ if (boot_complete_prefix.empty()) {
+ // The system is hosed because the build date property could not be read.
+ return;
+ }
// post_decrypt_time_elapsed is only logged on encrypted devices.
if (boot_event_store.GetBootEvent("post_decrypt_time_elapsed", &record)) {
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index d993576..6e81c51 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -317,7 +317,7 @@
continue;
std::string filename(ent->d_name);
- size_t last_dot = filename.rfind(".");
+ size_t last_dot = filename.rfind('.');
std::string basename;
// If there is a valid looking extension, use the base part of the
// name. If the only dot is the first byte (aka a dot file), treat
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index 60fd832..0f6b930 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -283,7 +283,7 @@
pos += strlen(kNamePrefix);
std::string filename = log.substr(pos, std::string::npos);
// Take the name up until \n
- size_t end_pos = filename.find_first_of("\n");
+ size_t end_pos = filename.find_first_of('\n');
ASSERT_NE(std::string::npos, end_pos);
filename = filename.substr(0, end_pos);
ASSERT_EQ(0U, filename.find(test_crash_directory().value()));
diff --git a/debuggerd/test/BacktraceMock.h b/debuggerd/test/BacktraceMock.h
index f75534e..6104f7e 100644
--- a/debuggerd/test/BacktraceMock.h
+++ b/debuggerd/test/BacktraceMock.h
@@ -41,7 +41,7 @@
class BacktraceMock : public Backtrace {
public:
- BacktraceMock(BacktraceMapMock* map) : Backtrace(0, 0, map) {
+ explicit BacktraceMock(BacktraceMapMock* map) : Backtrace(0, 0, map) {
if (map_ == nullptr) {
abort();
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 5dde490..314ed42 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -969,7 +969,7 @@
}
static void do_for_partition(Transport* transport, const std::string& part, const std::string& slot,
- std::function<void(const std::string&)> func, bool force_slot) {
+ const std::function<void(const std::string&)>& func, bool force_slot) {
std::string has_slot;
std::string current_slot;
@@ -1002,7 +1002,7 @@
* partition does not support slots.
*/
static void do_for_partitions(Transport* transport, const std::string& part, const std::string& slot,
- std::function<void(const std::string&)> func, bool force_slot) {
+ const std::function<void(const std::string&)>& func, bool force_slot) {
std::string has_slot;
if (slot == "all") {
diff --git a/fastboot/socket.h b/fastboot/socket.h
index de543db..7eaa0ab 100644
--- a/fastboot/socket.h
+++ b/fastboot/socket.h
@@ -104,7 +104,7 @@
protected:
// Protected constructor to force factory function use.
- Socket(cutils_socket_t sock);
+ explicit Socket(cutils_socket_t sock);
// Blocks up to |timeout_ms| until a read is possible on |sock_|, and sets |receive_timed_out_|
// as appropriate to help distinguish between normal timeouts and fatal errors. Returns true if
diff --git a/fastboot/socket_test.cpp b/fastboot/socket_test.cpp
index affbdfd..373abc3 100644
--- a/fastboot/socket_test.cpp
+++ b/fastboot/socket_test.cpp
@@ -34,7 +34,7 @@
// Creates connected sockets |server| and |client|. Returns true on success.
bool MakeConnectedSockets(Socket::Protocol protocol, std::unique_ptr<Socket>* server,
std::unique_ptr<Socket>* client,
- const std::string hostname = "localhost") {
+ const std::string& hostname = "localhost") {
*server = Socket::NewServer(protocol, 0);
if (*server == nullptr) {
ADD_FAILURE() << "Failed to create server.";
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 759c5e8..031b042 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -869,7 +869,7 @@
std::string result, word;
auto tokens = android::base::Split(*table, " ");
- for (const auto token : tokens) {
+ for (const auto& token : tokens) {
if (android::base::StartsWith(token, "/dev/block/") &&
android::base::StartsWith(blk_device, token.c_str())) {
word = blk_device;
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp
index 5d1fa52..d28ba41 100644
--- a/healthd/BatteryPropertiesRegistrar.cpp
+++ b/healthd/BatteryPropertiesRegistrar.cpp
@@ -35,7 +35,7 @@
defaultServiceManager()->addService(String16("batteryproperties"), service);
}
-void BatteryPropertiesRegistrar::notifyListeners(struct BatteryProperties props) {
+void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) {
Mutex::Autolock _l(mRegistrationLock);
for (size_t i = 0; i < mListeners.size(); i++) {
mListeners[i]->batteryPropertiesChanged(props);
diff --git a/healthd/BatteryPropertiesRegistrar.h b/healthd/BatteryPropertiesRegistrar.h
index d17e4a3..095f3d3 100644
--- a/healthd/BatteryPropertiesRegistrar.h
+++ b/healthd/BatteryPropertiesRegistrar.h
@@ -31,7 +31,7 @@
public IBinder::DeathRecipient {
public:
void publish(const sp<BatteryPropertiesRegistrar>& service);
- void notifyListeners(struct BatteryProperties props);
+ void notifyListeners(const struct BatteryProperties& props);
private:
Mutex mRegistrationLock;
diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
index 2d3e82a..85bd263 100644
--- a/include/utils/SortedVector.h
+++ b/include/utils/SortedVector.h
@@ -38,18 +38,18 @@
public:
typedef TYPE value_type;
-
- /*!
+
+ /*!
* Constructors and destructors
*/
-
+
SortedVector();
SortedVector(const SortedVector<TYPE>& rhs);
virtual ~SortedVector();
/*! copy operator */
- const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
- SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
+ const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
+ SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
/*
* empty the vector
@@ -57,7 +57,7 @@
inline void clear() { VectorImpl::clear(); }
- /*!
+ /*!
* vector stats
*/
@@ -70,11 +70,11 @@
//! sets the capacity. capacity can never be reduced less than size()
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
- /*!
+ /*!
* C-style array access
*/
-
- //! read-only C-style access
+
+ //! read-only C-style access
inline const TYPE* array() const;
//! read-write C-style access. BE VERY CAREFUL when modifying the array
@@ -83,12 +83,12 @@
//! finds the index of an item
ssize_t indexOf(const TYPE& item) const;
-
+
//! finds where this item should be inserted
size_t orderOf(const TYPE& item) const;
-
-
- /*!
+
+
+ /*!
* accessors
*/
@@ -105,7 +105,7 @@
//! add an item in the right place (and replace the one that is there)
ssize_t add(const TYPE& item);
-
+
//! editItemAt() MUST NOT change the order of this item
TYPE& editItemAt(size_t index) {
return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
@@ -114,7 +114,7 @@
//! merges a vector into this one
ssize_t merge(const Vector<TYPE>& vector);
ssize_t merge(const SortedVector<TYPE>& vector);
-
+
//! removes an item
ssize_t remove(const TYPE&);
@@ -122,7 +122,24 @@
inline ssize_t removeItemsAt(size_t index, size_t count = 1);
//! remove one item
inline ssize_t removeAt(size_t index) { return removeItemsAt(index); }
-
+
+ /*
+ * these inlines add some level of compatibility with STL.
+ */
+ typedef TYPE* iterator;
+ typedef TYPE const* const_iterator;
+
+ inline iterator begin() { return editArray(); }
+ inline iterator end() { return editArray() + size(); }
+ inline const_iterator begin() const { return array(); }
+ inline const_iterator end() const { return array() + size(); }
+ inline void reserve(size_t n) { setCapacity(n); }
+ inline bool empty() const{ return isEmpty(); }
+ inline iterator erase(iterator pos) {
+ ssize_t index = removeItemsAt(pos-array());
+ return begin() + index;
+ }
+
protected:
virtual void do_construct(void* storage, size_t num) const;
virtual void do_destroy(void* storage, size_t num) const;
@@ -164,13 +181,13 @@
template<class TYPE> inline
SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
SortedVectorImpl::operator = (rhs);
- return *this;
+ return *this;
}
template<class TYPE> inline
const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
SortedVectorImpl::operator = (rhs);
- return *this;
+ return *this;
}
template<class TYPE> inline
diff --git a/init/action.cpp b/init/action.cpp
index eeed744..f3e362e 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -118,7 +118,7 @@
Timer t;
int result = command.InvokeFunc();
- if (klog_get_level() >= KLOG_INFO_LEVEL) {
+ if (klog_get_level() >= KLOG_DEBUG_LEVEL) {
std::string trigger_name = BuildTriggersString();
std::string cmd_str = command.BuildCommandString();
std::string source = command.BuildSourceString();
diff --git a/init/action.h b/init/action.h
index 6dee2d0..0bae9f0 100644
--- a/init/action.h
+++ b/init/action.h
@@ -44,7 +44,7 @@
class Action {
public:
- Action(bool oneshot = false);
+ explicit Action(bool oneshot = false);
bool AddCommand(const std::vector<std::string>& args,
const std::string& filename, int line, std::string* err);
diff --git a/init/devices.cpp b/init/devices.cpp
index 5e12f25..373177e 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -181,7 +181,7 @@
}
if (access(path.c_str(), F_OK) == 0) {
- LOG(INFO) << "restorecon_recursive: " << path;
+ LOG(VERBOSE) << "restorecon_recursive: " << path;
restorecon_recursive(path.c_str());
}
}
diff --git a/init/init.cpp b/init/init.cpp
index 4fcb0db..29e8cbb 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -30,6 +30,7 @@
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
@@ -589,12 +590,11 @@
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
+ mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
}
- // We must have some place other than / to create the device nodes for
- // kmsg and null, otherwise we won't be able to remount / read-only
- // later on. Now that tmpfs is mounted on /dev, we can actually talk
- // to the outside world.
+ // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
+ // talk to the outside world...
InitKernelLogging(argv);
LOG(INFO) << "init " << (is_first_stage ? "first stage" : "second stage") << " started!";
@@ -638,6 +638,7 @@
// This must happen before /dev is populated by ueventd.
LOG(INFO) << "Running restorecon...";
restorecon("/dev");
+ restorecon("/dev/kmsg");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon("/property_contexts");
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 1cfdd80..3dbb2f0 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -78,11 +78,13 @@
if (adb_enabled == "running") {
Service* svc = ServiceManager::GetInstance().FindServiceByKeychord(id);
if (svc) {
- LOG(INFO) << "Starting service " << svc->name() << " from keychord...";
+ LOG(INFO) << "Starting service " << svc->name() << " from keychord " << id;
svc->Start();
} else {
- LOG(ERROR) << "service for keychord " << id << " not found";
+ LOG(ERROR) << "Service for keychord " << id << " not found";
}
+ } else {
+ LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled";
}
}
diff --git a/init/log.cpp b/init/log.cpp
index 3934ca0..379141a 100644
--- a/init/log.cpp
+++ b/init/log.cpp
@@ -26,8 +26,12 @@
#include <selinux/selinux.h>
static const int kLogSeverityToKLogLevel[] = {
- KLOG_NOTICE_LEVEL, KLOG_DEBUG_LEVEL, KLOG_INFO_LEVEL,
- KLOG_WARNING_LEVEL, KLOG_ERROR_LEVEL, KLOG_ERROR_LEVEL,
+ [android::base::VERBOSE] = KLOG_DEBUG_LEVEL,
+ [android::base::DEBUG] = KLOG_DEBUG_LEVEL,
+ [android::base::INFO] = KLOG_INFO_LEVEL,
+ [android::base::WARNING] = KLOG_WARNING_LEVEL,
+ [android::base::ERROR] = KLOG_ERROR_LEVEL,
+ [android::base::FATAL] = KLOG_ERROR_LEVEL,
};
static_assert(arraysize(kLogSeverityToKLogLevel) == android::base::FATAL + 1,
"Mismatch in size of kLogSeverityToKLogLevel and values in LogSeverity");
@@ -68,7 +72,7 @@
if (fd > 2) close(fd);
android::base::InitLogging(argv, &KernelLogger);
- klog_set_level(KLOG_NOTICE_LEVEL);
+ klog_set_level(KLOG_INFO_LEVEL);
}
int selinux_klog_callback(int type, const char *fmt, ...) {
diff --git a/init/parser/tokenizer.h b/init/parser/tokenizer.h
index 8312a08..ade8f73 100644
--- a/init/parser/tokenizer.h
+++ b/init/parser/tokenizer.h
@@ -36,7 +36,7 @@
// a TOK_NEWLINE will not be generated for that line.
class Tokenizer {
public:
- Tokenizer(const std::string& data);
+ explicit Tokenizer(const std::string& data);
~Tokenizer();
enum TokenType { TOK_START, TOK_END, TOK_NEWLINE, TOK_TEXT };
diff --git a/init/service.cpp b/init/service.cpp
index c636677..44d9d8c 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -95,16 +95,16 @@
// It's OK to LOG(FATAL) in this function since it's running in the first
// child process.
if (mount("", "/proc", "proc", kSafeFlags | MS_REMOUNT, "") == -1) {
- PLOG(FATAL) << "couldn't remount(/proc)";
+ PLOG(FATAL) << "couldn't remount(/proc) for " << service_name;
}
if (prctl(PR_SET_NAME, service_name.c_str()) == -1) {
- PLOG(FATAL) << "couldn't set name";
+ PLOG(FATAL) << "couldn't set name for " << service_name;
}
pid_t child_pid = fork();
if (child_pid == -1) {
- PLOG(FATAL) << "couldn't fork init inside the PID namespace";
+ PLOG(FATAL) << "couldn't fork init inside the PID namespace for " << service_name;
}
if (child_pid > 0) {
@@ -219,31 +219,32 @@
}
void Service::SetProcessAttributes() {
- setpgid(0, getpid());
+ // TODO: work out why this fails for `console` then upgrade to FATAL.
+ if (setpgid(0, getpid()) == -1) PLOG(ERROR) << "setpgid failed for " << name_;
if (gid_) {
if (setgid(gid_) != 0) {
- PLOG(FATAL) << "setgid failed";
+ PLOG(FATAL) << "setgid failed for " << name_;
}
}
if (!supp_gids_.empty()) {
if (setgroups(supp_gids_.size(), &supp_gids_[0]) != 0) {
- PLOG(FATAL) << "setgroups failed";
+ PLOG(FATAL) << "setgroups failed for " << name_;
}
}
if (uid_) {
if (setuid(uid_) != 0) {
- PLOG(FATAL) << "setuid failed";
+ PLOG(FATAL) << "setuid failed for " << name_;
}
}
if (!seclabel_.empty()) {
if (setexeccon(seclabel_.c_str()) < 0) {
- PLOG(FATAL) << "cannot setexeccon('" << seclabel_ << "')";
+ PLOG(FATAL) << "cannot setexeccon('" << seclabel_ << "') for " << name_;
}
}
if (priority_ != 0) {
if (setpriority(PRIO_PROCESS, 0, priority_) != 0) {
- PLOG(FATAL) << "setpriority failed";
+ PLOG(FATAL) << "setpriority failed for " << name_;
}
}
}
@@ -849,7 +850,7 @@
return nullptr;
}
-void ServiceManager::ForEachService(std::function<void(Service*)> callback) const {
+void ServiceManager::ForEachService(const std::function<void(Service*)>& callback) const {
for (const auto& s : services_) {
callback(s.get());
}
diff --git a/init/service.h b/init/service.h
index aa73aaf..fb03a07 100644
--- a/init/service.h
+++ b/init/service.h
@@ -177,7 +177,7 @@
Service* FindServiceByName(const std::string& name) const;
Service* FindServiceByPid(pid_t pid) const;
Service* FindServiceByKeychord(int keychord_id) const;
- void ForEachService(std::function<void(Service*)> callback) const;
+ void ForEachService(const std::function<void(Service*)>& callback) const;
void ForEachServiceInClass(const std::string& classname,
void (*func)(Service* svc)) const;
void ForEachServiceWithFlags(unsigned matchflags,
diff --git a/init/util.cpp b/init/util.cpp
index 80b2325..c1750d2 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -317,7 +317,7 @@
}
void import_kernel_cmdline(bool in_qemu,
- std::function<void(const std::string&, const std::string&, bool)> fn) {
+ const std::function<void(const std::string&, const std::string&, bool)>& fn) {
std::string cmdline;
android::base::ReadFileToString("/proc/cmdline", &cmdline);
diff --git a/init/util.h b/init/util.h
index 651e609..29d0497 100644
--- a/init/util.h
+++ b/init/util.h
@@ -55,7 +55,7 @@
void remove_link(const char *oldpath, const char *newpath);
int wait_for_file(const char *filename, int timeout);
void import_kernel_cmdline(bool in_qemu,
- std::function<void(const std::string&, const std::string&, bool)>);
+ 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);
diff --git a/libbacktrace/UnwindMap.h b/libbacktrace/UnwindMap.h
index f85b54a..d5bec06 100644
--- a/libbacktrace/UnwindMap.h
+++ b/libbacktrace/UnwindMap.h
@@ -29,7 +29,7 @@
class UnwindMap : public BacktraceMap {
public:
- UnwindMap(pid_t pid);
+ explicit UnwindMap(pid_t pid);
unw_map_cursor_t* GetMapCursor() { return &map_cursor_; }
@@ -39,7 +39,7 @@
class UnwindMapRemote : public UnwindMap {
public:
- UnwindMapRemote(pid_t pid);
+ explicit UnwindMapRemote(pid_t pid);
virtual ~UnwindMapRemote();
bool Build() override;
diff --git a/libbacktrace/backtrace_offline_test.cpp b/libbacktrace/backtrace_offline_test.cpp
index 88a3533..d6dc2c9 100644
--- a/libbacktrace/backtrace_offline_test.cpp
+++ b/libbacktrace/backtrace_offline_test.cpp
@@ -73,7 +73,7 @@
return ucontext;
}
-static void OfflineBacktraceFunctionCall(std::function<int(void (*)(void*), void*)> function,
+static void OfflineBacktraceFunctionCall(const std::function<int(void (*)(void*), void*)>& function,
std::vector<uintptr_t>* pc_values) {
// Create a thread to generate the needed stack and registers information.
g_exit_flag = false;
diff --git a/libcrypto_utils/Android.mk b/libcrypto_utils/Android.mk
index 5e9763f..b6d2204 100644
--- a/libcrypto_utils/Android.mk
+++ b/libcrypto_utils/Android.mk
@@ -31,7 +31,7 @@
LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_SHARED_LIBRARIES := libcrypto-host
+LOCAL_SHARED_LIBRARIES := libcrypto
include $(BUILD_HOST_SHARED_LIBRARY)
include $(CLEAR_VARS)
@@ -40,7 +40,7 @@
LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := libcrypto_static
+LOCAL_STATIC_LIBRARIES := libcrypto
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
diff --git a/libcrypto_utils/tests/Android.mk b/libcrypto_utils/tests/Android.mk
index dad82f7..bdaef71 100644
--- a/libcrypto_utils/tests/Android.mk
+++ b/libcrypto_utils/tests/Android.mk
@@ -20,5 +20,5 @@
LOCAL_MODULE := libcrypto_utils_test
LOCAL_SRC_FILES := android_pubkey_test.cpp
LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c++11
-LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto-host
+LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto
include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index e681718..a6eaf11 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -91,6 +91,7 @@
{ 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" },
{ 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" },
+ { 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
{ 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" },
{ 00755, AID_ROOT, AID_ROOT, 0, "root" },
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index abf643f..061af1b 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -37,15 +37,7 @@
}
static int __open_klog(void) {
- int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);
- if (fd == -1) {
- static const char* name = "/dev/__kmsg__";
- if (mknod(name, S_IFCHR | 0600, (1 << 8) | 11) == 0) {
- fd = open(name, O_WRONLY | O_CLOEXEC);
- unlink(name);
- }
- }
- return fd;
+ return TEMP_FAILURE_RETRY(open("/dev/kmsg", O_WRONLY | O_CLOEXEC));
}
#define LOG_BUF_MAX 512
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 6e6a9eb..26f908f 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -171,7 +171,7 @@
FILE *fp;
snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid);
- if (!(fp = fopen(pathBuf, "r"))) {
+ if (!(fp = fopen(pathBuf, "re"))) {
return -1;
}
@@ -329,6 +329,27 @@
#endif
}
+static void set_timerslack_ns(int tid, unsigned long long slack) {
+ char buf[64];
+
+ /* v4.6+ kernels support the /proc/<tid>/timerslack_ns interface. */
+ snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid);
+ int fd = open(buf, O_WRONLY | O_CLOEXEC);
+ if (fd != -1) {
+ int len = snprintf(buf, sizeof(buf), "%llu", slack);
+ if (write(fd, buf, len) != len) {
+ SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno));
+ }
+ close(fd);
+ return;
+ }
+
+ /* If the above fails, try the old common.git PR_SET_TIMERSLACK_PID. */
+ if (prctl(PR_SET_TIMERSLACK_PID, slack, tid) == -1) {
+ SLOGE("set_timerslack_ns prctl failed: %s\n", strerror(errno));
+ }
+}
+
int set_sched_policy(int tid, SchedPolicy policy)
{
if (tid == 0) {
@@ -341,12 +362,11 @@
char statfile[64];
char statline[1024];
char thread_name[255];
- int fd;
snprintf(statfile, sizeof(statfile), "/proc/%d/stat", tid);
memset(thread_name, 0, sizeof(thread_name));
- fd = open(statfile, O_RDONLY);
+ int fd = open(statfile, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
int rc = read(fd, statline, 1023);
close(fd);
@@ -425,8 +445,8 @@
¶m);
}
- prctl(PR_SET_TIMERSLACK_PID,
- policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG, tid);
+ set_timerslack_ns(tid, policy == SP_BACKGROUND ?
+ TIMER_SLACK_BG : TIMER_SLACK_FG);
return 0;
}
diff --git a/liblog/tests/benchmark.h b/liblog/tests/benchmark.h
index 57b3748..e9280f6 100644
--- a/liblog/tests/benchmark.h
+++ b/liblog/tests/benchmark.h
@@ -38,7 +38,7 @@
Benchmark(const char* name, void (*fn)(int)) : name_(strdup(name)), fn_(fn) {
BenchmarkRegister(this);
}
- Benchmark(const char* name) : name_(strdup(name)), fn_(NULL) {}
+ explicit Benchmark(const char* name) : name_(strdup(name)), fn_(NULL) {}
virtual ~Benchmark() {
free(name_);
diff --git a/libmemunreachable/Allocator.h b/libmemunreachable/Allocator.h
index a8f579e..5390739 100644
--- a/libmemunreachable/Allocator.h
+++ b/libmemunreachable/Allocator.h
@@ -109,13 +109,13 @@
}
// Construct an STLAllocator on top of a Heap
- STLAllocator(const Heap& heap) :
+ STLAllocator(const Heap& heap) : // NOLINT, implicit
heap_(heap) {
}
// Rebind an STLAllocator from an another STLAllocator
template<typename U>
- STLAllocator(const STLAllocator<U>& other) :
+ STLAllocator(const STLAllocator<U>& other) : // NOLINT, implicit
heap_(other.heap_) {
}
@@ -155,12 +155,12 @@
public:
~Allocator() {}
- Allocator(const Heap& other) :
+ Allocator(const Heap& other) : // NOLINT, implicit
STLAllocator<T>(other) {
}
template<typename U>
- Allocator(const STLAllocator<U>& other) :
+ Allocator(const STLAllocator<U>& other) : // NOLINT, implicit
STLAllocator<T>(other) {
}
diff --git a/libmemunreachable/HeapWalker.h b/libmemunreachable/HeapWalker.h
index 3c1b513..b25696f 100644
--- a/libmemunreachable/HeapWalker.h
+++ b/libmemunreachable/HeapWalker.h
@@ -48,7 +48,7 @@
class HeapWalker {
public:
- HeapWalker(Allocator<HeapWalker> allocator) : allocator_(allocator),
+ explicit HeapWalker(Allocator<HeapWalker> allocator) : allocator_(allocator),
allocations_(allocator), allocation_bytes_(0),
roots_(allocator), root_vals_(allocator),
segv_handler_(allocator), walking_ptr_(0) {
diff --git a/libmemunreachable/LeakFolding.h b/libmemunreachable/LeakFolding.h
index 732d3f2..9c6a525 100644
--- a/libmemunreachable/LeakFolding.h
+++ b/libmemunreachable/LeakFolding.h
@@ -54,7 +54,7 @@
bool dominator;
SCCInfo* accumulator;
- SCCInfo(Allocator<SCCInfo> allocator) : node(this, allocator),
+ explicit SCCInfo(Allocator<SCCInfo> allocator) : node(this, allocator),
count(0), size(0), cuumulative_count(0), cuumulative_size(0),
dominator(false), accumulator(nullptr) {}
private:
diff --git a/libmemunreachable/LinkedList.h b/libmemunreachable/LinkedList.h
index 3e44035..132842d 100644
--- a/libmemunreachable/LinkedList.h
+++ b/libmemunreachable/LinkedList.h
@@ -21,7 +21,7 @@
class LinkedList {
public:
LinkedList() : next_(this), prev_(this), data_() {}
- LinkedList(T data) : LinkedList() {
+ explicit LinkedList(T data) : LinkedList() {
data_ = data;
}
~LinkedList() {}
diff --git a/libmemunreachable/PtracerThread.h b/libmemunreachable/PtracerThread.h
index 4d6ca9a..f88b599 100644
--- a/libmemunreachable/PtracerThread.h
+++ b/libmemunreachable/PtracerThread.h
@@ -32,7 +32,7 @@
// the parent.
class PtracerThread {
public:
- PtracerThread(const std::function<int()>& func);
+ explicit PtracerThread(const std::function<int()>& func);
~PtracerThread();
bool Start();
int Join();
diff --git a/libmemunreachable/ScopedDisableMalloc.h b/libmemunreachable/ScopedDisableMalloc.h
index 4f96376..758d317 100644
--- a/libmemunreachable/ScopedDisableMalloc.h
+++ b/libmemunreachable/ScopedDisableMalloc.h
@@ -74,7 +74,7 @@
class ScopedDisableMallocTimeout {
public:
- ScopedDisableMallocTimeout(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000)) :
+ explicit ScopedDisableMallocTimeout(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000)) :
timeout_(timeout), timed_out_(false), disable_malloc_() {
Disable();
}
diff --git a/libmemunreachable/ScopedSignalHandler.h b/libmemunreachable/ScopedSignalHandler.h
index e006d43..1fd9d4d 100644
--- a/libmemunreachable/ScopedSignalHandler.h
+++ b/libmemunreachable/ScopedSignalHandler.h
@@ -30,7 +30,7 @@
public:
using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>;
- ScopedSignalHandler(Allocator<Fn> allocator) : allocator_(allocator), signal_(-1) {}
+ explicit ScopedSignalHandler(Allocator<Fn> allocator) : allocator_(allocator), signal_(-1) {}
~ScopedSignalHandler() {
reset();
}
diff --git a/libmemunreachable/Semaphore.h b/libmemunreachable/Semaphore.h
index 45e8c81..6bcf4ea 100644
--- a/libmemunreachable/Semaphore.h
+++ b/libmemunreachable/Semaphore.h
@@ -24,7 +24,7 @@
class Semaphore {
public:
- Semaphore(int count = 0) : count_(count) {}
+ explicit Semaphore(int count = 0) : count_(count) {}
~Semaphore() = default;
void Wait(std::chrono::milliseconds ms) {
diff --git a/libmemunreachable/Tarjan.h b/libmemunreachable/Tarjan.h
index d7ecdb9..dcd139a 100644
--- a/libmemunreachable/Tarjan.h
+++ b/libmemunreachable/Tarjan.h
@@ -62,7 +62,7 @@
template<class T>
class TarjanAlgorithm {
public:
- TarjanAlgorithm(Allocator<void> allocator) : index_(0),
+ explicit TarjanAlgorithm(Allocator<void> allocator) : index_(0),
stack_(allocator), components_(allocator) {}
void Execute(Graph<T>& graph, SCCList<T>& out);
diff --git a/libmemunreachable/tests/Allocator_test.cpp b/libmemunreachable/tests/Allocator_test.cpp
index fa76ae0..21c8218 100644
--- a/libmemunreachable/tests/Allocator_test.cpp
+++ b/libmemunreachable/tests/Allocator_test.cpp
@@ -160,7 +160,7 @@
Allocator<int>::shared_ptr ptr = allocator.make_shared(0);
{
- auto ptr2 = ptr;
+ auto ptr2 = ptr; // NOLINT, test copy of ptr
}
ASSERT_NE(ptr, nullptr);
}
diff --git a/libmemunreachable/tests/MemUnreachable_test.cpp b/libmemunreachable/tests/MemUnreachable_test.cpp
index 0747b12..2ae3db8 100644
--- a/libmemunreachable/tests/MemUnreachable_test.cpp
+++ b/libmemunreachable/tests/MemUnreachable_test.cpp
@@ -27,7 +27,7 @@
class HiddenPointer {
public:
- HiddenPointer(size_t size = 256) {
+ explicit HiddenPointer(size_t size = 256) {
Set(malloc(size));
}
~HiddenPointer() {
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
new file mode 100644
index 0000000..b4a69bc
--- /dev/null
+++ b/libnativeloader/Android.bp
@@ -0,0 +1,32 @@
+// Shared library for target
+// ========================================================
+cc_library {
+ name: "libnativeloader",
+ host_supported: true,
+ srcs: ["native_loader.cpp"],
+ shared_libs: [
+ "libnativehelper",
+ "liblog",
+ "libcutils",
+ ],
+ static_libs: ["libbase"],
+ target: {
+ android: {
+ shared_libs: ["libdl"],
+ },
+ host: {
+ host_ldlibs: ["-ldl"],
+ },
+ },
+ clang: true,
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ cppflags: [
+ "-std=gnu++14",
+ "-fvisibility=hidden",
+ ],
+ export_include_dirs: ["include"],
+ local_include_dirs: ["include"],
+}
diff --git a/libnativeloader/Android.mk b/libnativeloader/Android.mk
deleted file mode 100644
index c81c671..0000000
--- a/libnativeloader/Android.mk
+++ /dev/null
@@ -1,58 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-native_loader_common_src_files := \
- native_loader.cpp
-
-native_loader_common_cflags := -Werror -Wall
-
-# Shared library for target
-# ========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libnativeloader
-
-LOCAL_SRC_FILES:= $(native_loader_common_src_files)
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libcutils libdl
-LOCAL_STATIC_LIBRARIES := libbase
-LOCAL_CLANG := true
-LOCAL_CFLAGS := $(native_loader_common_cflags)
-LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
-LOCAL_MULTILIB := both
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-include $(BUILD_SHARED_LIBRARY)
-
-# Shared library for host
-# ========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libnativeloader
-
-LOCAL_SRC_FILES:= $(native_loader_common_src_files)
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libcutils
-LOCAL_STATIC_LIBRARIES := libbase
-LOCAL_CLANG := true
-LOCAL_CFLAGS := $(native_loader_common_cflags)
-LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
-LOCAL_LDFLAGS := -ldl
-LOCAL_MULTILIB := both
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-include $(BUILD_HOST_SHARED_LIBRARY)
-
-# Static library for host
-# ========================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libnativeloader
-
-LOCAL_SRC_FILES:= $(native_loader_common_src_files)
-LOCAL_STATIC_LIBRARIES := libnativehelper libcutils liblog libbase
-LOCAL_CLANG := true
-LOCAL_CFLAGS := $(native_loader_common_cflags)
-LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
-LOCAL_LDFLAGS := -ldl
-LOCAL_MULTILIB := both
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h
index 7178c65..76acf7e 100644
--- a/libpixelflinger/codeflinger/ARMAssembler.h
+++ b/libpixelflinger/codeflinger/ARMAssembler.h
@@ -35,7 +35,7 @@
class ARMAssembler : public ARMAssemblerInterface
{
public:
- ARMAssembler(const sp<Assembly>& assembly);
+ explicit ARMAssembler(const sp<Assembly>& assembly);
virtual ~ARMAssembler();
uint32_t* base() const;
diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.h b/libpixelflinger/codeflinger/ARMAssemblerProxy.h
index b852794..10d0390 100644
--- a/libpixelflinger/codeflinger/ARMAssemblerProxy.h
+++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.h
@@ -34,7 +34,7 @@
// ARMAssemblerProxy take ownership of the target
ARMAssemblerProxy();
- ARMAssemblerProxy(ARMAssemblerInterface* target);
+ explicit ARMAssemblerProxy(ARMAssemblerInterface* target);
virtual ~ARMAssemblerProxy();
void setTarget(ARMAssemblerInterface* target);
diff --git a/libpixelflinger/codeflinger/Arm64Assembler.h b/libpixelflinger/codeflinger/Arm64Assembler.h
index c9be116..527c757 100644
--- a/libpixelflinger/codeflinger/Arm64Assembler.h
+++ b/libpixelflinger/codeflinger/Arm64Assembler.h
@@ -47,8 +47,8 @@
class ArmToArm64Assembler : public ARMAssemblerInterface
{
public:
- ArmToArm64Assembler(const sp<Assembly>& assembly);
- ArmToArm64Assembler(void *base);
+ explicit ArmToArm64Assembler(const sp<Assembly>& assembly);
+ explicit ArmToArm64Assembler(void *base);
virtual ~ArmToArm64Assembler();
uint32_t* base() const;
diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h
index 0fb6fd5..c0e0684 100644
--- a/libpixelflinger/codeflinger/CodeCache.h
+++ b/libpixelflinger/codeflinger/CodeCache.h
@@ -42,7 +42,7 @@
class AssemblyKey : public AssemblyKeyBase
{
public:
- AssemblyKey(const T& rhs) : mKey(rhs) { }
+ explicit AssemblyKey(const T& rhs) : mKey(rhs) { }
virtual int compare_type(const AssemblyKeyBase& key) const {
const T& rhs = static_cast<const AssemblyKey&>(key).mKey;
return android::compare_type(mKey, rhs);
@@ -56,7 +56,7 @@
class Assembly
{
public:
- Assembly(size_t size);
+ explicit Assembly(size_t size);
virtual ~Assembly();
ssize_t size() const;
@@ -80,13 +80,13 @@
{
public:
// pretty simple cache API...
- CodeCache(size_t size);
- ~CodeCache();
-
- sp<Assembly> lookup(const AssemblyKeyBase& key) const;
+ explicit CodeCache(size_t size);
+ ~CodeCache();
- int cache( const AssemblyKeyBase& key,
- const sp<Assembly>& assembly);
+ sp<Assembly> lookup(const AssemblyKeyBase& key) const;
+
+ int cache(const AssemblyKeyBase& key,
+ const sp<Assembly>& assembly);
private:
// nothing to see here...
@@ -105,7 +105,7 @@
const AssemblyKeyBase* mKey;
public:
key_t() { };
- key_t(const AssemblyKeyBase& k) : mKey(&k) { }
+ explicit key_t(const AssemblyKeyBase& k) : mKey(&k) { }
};
mutable pthread_mutex_t mLock;
diff --git a/libpixelflinger/codeflinger/GGLAssembler.h b/libpixelflinger/codeflinger/GGLAssembler.h
index ecc242a..47dbf3a 100644
--- a/libpixelflinger/codeflinger/GGLAssembler.h
+++ b/libpixelflinger/codeflinger/GGLAssembler.h
@@ -49,7 +49,7 @@
public:
class RegisterFile;
- RegisterAllocator(int arch);
+ RegisterAllocator(int arch); // NOLINT, implicit
RegisterFile& registerFile();
int reserveReg(int reg);
int obtainReg();
@@ -59,7 +59,7 @@
class RegisterFile
{
public:
- RegisterFile(int arch);
+ RegisterFile(int arch); // NOLINT, implicit
RegisterFile(const RegisterFile& rhs, int arch);
~RegisterFile();
@@ -101,7 +101,7 @@
class Scratch
{
public:
- Scratch(RegisterFile& regFile)
+ explicit Scratch(RegisterFile& regFile)
: mRegFile(regFile), mScratch(0) {
}
~Scratch() {
@@ -177,8 +177,8 @@
{
public:
- GGLAssembler(ARMAssemblerInterface* target);
- virtual ~GGLAssembler();
+ explicit GGLAssembler(ARMAssemblerInterface* target);
+ virtual ~GGLAssembler();
uint32_t* base() const { return 0; } // XXX
uint32_t* pc() const { return 0; } // XXX
@@ -206,7 +206,7 @@
struct reg_t {
reg_t() : reg(-1), flags(0) {
}
- reg_t(int r, int f=0)
+ reg_t(int r, int f=0) // NOLINT, implicit
: reg(r), flags(f) {
}
void setTo(int r, int f=0) {
@@ -219,7 +219,7 @@
struct integer_t : public reg_t {
integer_t() : reg_t(), s(0) {
}
- integer_t(int r, int sz=32, int f=0)
+ integer_t(int r, int sz=32, int f=0) // NOLINT, implicit
: reg_t(r, f), s(sz) {
}
void setTo(int r, int sz=32, int f=0) {
@@ -251,7 +251,7 @@
struct component_t : public reg_t {
component_t() : reg_t(), h(0), l(0) {
}
- component_t(int r, int f=0)
+ component_t(int r, int f=0) // NOLINT, implicit
: reg_t(r, f), h(0), l(0) {
}
component_t(int r, int lo, int hi, int f=0)
diff --git a/libpixelflinger/codeflinger/tinyutils/smartpointer.h b/libpixelflinger/codeflinger/tinyutils/smartpointer.h
index 9d0a16e..23a5f7e 100644
--- a/libpixelflinger/codeflinger/tinyutils/smartpointer.h
+++ b/libpixelflinger/codeflinger/tinyutils/smartpointer.h
@@ -51,10 +51,10 @@
public:
inline sp() : m_ptr(0) { }
- sp(T* other);
+ sp(T* other); // NOLINT, implicit
sp(const sp<T>& other);
- template<typename U> sp(U* other);
- template<typename U> sp(const sp<U>& other);
+ template<typename U> sp(U* other); // NOLINT, implicit
+ template<typename U> sp(const sp<U>& other); // NOLINT, implicit
~sp();
diff --git a/libutils/tests/Looper_test.cpp b/libutils/tests/Looper_test.cpp
index 17319e0..8ebcfaf 100644
--- a/libutils/tests/Looper_test.cpp
+++ b/libutils/tests/Looper_test.cpp
@@ -76,7 +76,7 @@
int fd;
int events;
- StubCallbackHandler(int nextResult) : nextResult(nextResult),
+ explicit StubCallbackHandler(int nextResult) : nextResult(nextResult),
callbackCount(0), fd(-1), events(-1) {
}
diff --git a/libutils/tests/StrongPointer_test.cpp b/libutils/tests/StrongPointer_test.cpp
index f46d6d1..323a6f2 100644
--- a/libutils/tests/StrongPointer_test.cpp
+++ b/libutils/tests/StrongPointer_test.cpp
@@ -23,7 +23,7 @@
class Foo : public LightRefBase<Foo> {
public:
- Foo(bool* deleted_check) : mDeleted(deleted_check) {
+ explicit Foo(bool* deleted_check) : mDeleted(deleted_check) {
*mDeleted = false;
}
diff --git a/libutils/tests/TestHelpers.h b/libutils/tests/TestHelpers.h
index d8e985e..6801cd7 100644
--- a/libutils/tests/TestHelpers.h
+++ b/libutils/tests/TestHelpers.h
@@ -60,7 +60,7 @@
int mDelayMillis;
public:
- DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
+ explicit DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
protected:
virtual ~DelayedTask() { }
diff --git a/logcat/logpersist b/logcat/logpersist
index e9982e2..f0e7d42 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -17,6 +17,7 @@
;;
esac
+log_tag_property=persist.log.tag
data=/data/misc/logd
service=logcatd
size_default=256
@@ -65,6 +66,9 @@
exit 1
fi
+log_tag="`getprop ${log_tag_property}`"
+logd_logpersistd="`getprop ${property}`"
+
case ${progname} in
*.cat)
if [ -n "${size}${buffer}" -o "true" = "${clear}" ]; then
@@ -123,6 +127,12 @@
while [ "clear" = "`getprop ${property#persist.}`" ]; do
continue
done
+ # Tell Settings that we are back on again if we turned logging off
+ tag="${log_tag#Settings}"
+ if [ X"${log_tag}" != X"${tag}" ]; then
+ echo "WARNING: enabling logd service" >&2
+ setprop ${log_tag_property} "${tag#,}"
+ fi
# ${service}.rc does the heavy lifting with the following trigger
setprop ${property} ${service}
# 20ms done, to permit process feedback check
@@ -158,3 +168,9 @@
echo "ERROR: Unexpected command ${0##*/} ${args}" >&2
exit 1
esac
+
+if [ X"${log_tag}" != X"`getprop ${log_tag_property}`" ] ||
+ [ X"${logd_logpersistd}" != X"`getprop ${property}`" ]; then
+ echo "WARNING: killing Settings" >&2
+ am force-stop com.android.settings
+fi
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h
index 9224773..7172d5f 100644
--- a/logd/FlushCommand.h
+++ b/logd/FlushCommand.h
@@ -35,7 +35,7 @@
uint64_t mTimeout;
public:
- FlushCommand(LogReader &mReader,
+ explicit FlushCommand(LogReader &mReader,
bool nonBlock = false,
unsigned long tail = -1,
unsigned int logMask = -1,
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index b390a0c..162c189 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -103,7 +103,7 @@
public:
LastLogTimes &mTimes;
- LogBuffer(LastLogTimes *times);
+ explicit LogBuffer(LastLogTimes *times);
void init();
bool isMonotonic() { return monotonic; }
diff --git a/logd/LogCommand.h b/logd/LogCommand.h
index c944478..0adc2a1 100644
--- a/logd/LogCommand.h
+++ b/logd/LogCommand.h
@@ -22,7 +22,7 @@
class LogCommand : public FrameworkCommand {
public:
- LogCommand(const char *cmd);
+ explicit LogCommand(const char *cmd);
virtual ~LogCommand() {}
};
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index ac2b128..a0b7499 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -401,7 +401,32 @@
}
}
-pid_t LogKlog::sniffPid(const char *cp, size_t len) {
+pid_t LogKlog::sniffPid(const char **buf, size_t len) {
+ const char *cp = *buf;
+ // HTC kernels with modified printk "c0 1648 "
+ if ((len > 9) &&
+ (cp[0] == 'c') &&
+ isdigit(cp[1]) &&
+ (isdigit(cp[2]) || (cp[2] == ' ')) &&
+ (cp[3] == ' ')) {
+ bool gotDigit = false;
+ int i;
+ for (i = 4; i < 9; ++i) {
+ if (isdigit(cp[i])) {
+ gotDigit = true;
+ } else if (gotDigit || (cp[i] != ' ')) {
+ break;
+ }
+ }
+ if ((i == 9) && (cp[i] == ' ')) {
+ int pid = 0;
+ char dummy;
+ if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) {
+ *buf = cp + 10; // skip-it-all
+ return pid;
+ }
+ }
+ }
while (len) {
// Mediatek kernels with modified printk
if (*cp == '[') {
@@ -587,7 +612,7 @@
}
// Parse pid, tid and uid
- const pid_t pid = sniffPid(p, len - (p - buf));
+ const pid_t pid = sniffPid(&p, len - (p - buf));
const pid_t tid = pid;
const uid_t uid = pid ? logbuf->pidToUid(pid) : 0;
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index ee73b71..a4f871e 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -51,7 +51,7 @@
protected:
void sniffTime(log_time &now, const char **buf, size_t len, bool reverse);
- pid_t sniffPid(const char *buf, size_t len);
+ pid_t sniffPid(const char **buf, size_t len);
void calculateCorrection(const log_time &monotonic,
const char *real_string, size_t len);
virtual bool onDataAvailable(SocketClient *cli);
diff --git a/logd/LogReader.h b/logd/LogReader.h
index 98674b8..fdcedf1 100644
--- a/logd/LogReader.h
+++ b/logd/LogReader.h
@@ -27,7 +27,7 @@
LogBuffer &mLogbuf;
public:
- LogReader(LogBuffer *logbuf);
+ explicit LogReader(LogBuffer *logbuf);
void notifyNewLog();
LogBuffer &logbuf(void) const { return mLogbuf; }
diff --git a/metricsd/collectors/cpu_usage_collector.h b/metricsd/collectors/cpu_usage_collector.h
index f81dfcb..9f92cf3 100644
--- a/metricsd/collectors/cpu_usage_collector.h
+++ b/metricsd/collectors/cpu_usage_collector.h
@@ -23,7 +23,7 @@
class CpuUsageCollector {
public:
- CpuUsageCollector(MetricsLibraryInterface* metrics_library);
+ explicit CpuUsageCollector(MetricsLibraryInterface* metrics_library);
// Initialize this collector's state.
void Init();
diff --git a/metricsd/collectors/disk_usage_collector.h b/metricsd/collectors/disk_usage_collector.h
index c1d4546..288b34b 100644
--- a/metricsd/collectors/disk_usage_collector.h
+++ b/metricsd/collectors/disk_usage_collector.h
@@ -23,7 +23,7 @@
class DiskUsageCollector {
public:
- DiskUsageCollector(MetricsLibraryInterface* metrics_library);
+ explicit DiskUsageCollector(MetricsLibraryInterface* metrics_library);
// Schedule the next collection.
void Schedule();
diff --git a/metricsd/uploader/metricsd_service_runner.h b/metricsd/uploader/metricsd_service_runner.h
index f5dad21..b36d4a5 100644
--- a/metricsd/uploader/metricsd_service_runner.h
+++ b/metricsd/uploader/metricsd_service_runner.h
@@ -27,7 +27,7 @@
class MetricsdServiceRunner {
public:
- MetricsdServiceRunner(std::shared_ptr<CrashCounters> counters);
+ explicit MetricsdServiceRunner(std::shared_ptr<CrashCounters> counters);
// Start the Metricsd Binder service in a new thread.
void Start();
diff --git a/metricsd/uploader/sender_http.cc b/metricsd/uploader/sender_http.cc
index 4b572a6..1f775df 100644
--- a/metricsd/uploader/sender_http.cc
+++ b/metricsd/uploader/sender_http.cc
@@ -23,7 +23,7 @@
#include <brillo/http/http_utils.h>
#include <brillo/mime_utils.h>
-HttpSender::HttpSender(const std::string server_url)
+HttpSender::HttpSender(const std::string& server_url)
: server_url_(server_url) {}
bool HttpSender::Send(const std::string& content,
diff --git a/metricsd/uploader/sender_http.h b/metricsd/uploader/sender_http.h
index 4f1c08f..0d64c74 100644
--- a/metricsd/uploader/sender_http.h
+++ b/metricsd/uploader/sender_http.h
@@ -26,7 +26,7 @@
// Sender implemented using http_utils from libbrillo
class HttpSender : public Sender {
public:
- explicit HttpSender(std::string server_url);
+ explicit HttpSender(const std::string& server_url);
~HttpSender() override = default;
// Sends |content| whose SHA1 hash is |hash| to server_url with a synchronous
// POST request to server_url.
diff --git a/rootdir/init.usb.configfs.rc b/rootdir/init.usb.configfs.rc
index e19b058..dc875b4 100644
--- a/rootdir/init.usb.configfs.rc
+++ b/rootdir/init.usb.configfs.rc
@@ -5,6 +5,10 @@
write /config/usb_gadget/g1/bDeviceClass 0
write /config/usb_gadget/g1/bDeviceSubClass 0
write /config/usb_gadget/g1/bDeviceProtocol 0
+ rm /config/usb_gadget/g1/configs/b.1/f1
+ rm /config/usb_gadget/g1/configs/b.1/f2
+ rm /config/usb_gadget/g1/configs/b.1/f3
+ rmdir /config/usb_gadget/g1/functions/rndis.gs4
setprop sys.usb.state ${sys.usb.config}
on property:sys.usb.config=adb && property:sys.usb.configfs=1
@@ -12,18 +16,12 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
on property:sys.usb.config=mtp && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -33,9 +31,6 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -43,9 +38,6 @@
on property:sys.usb.config=ptp && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -55,9 +47,6 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -65,9 +54,6 @@
on property:sys.usb.config=accessory && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -77,9 +63,6 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -87,9 +70,6 @@
on property:sys.usb.config=audio_source && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "audiosource"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -99,9 +79,6 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=audio_source,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "audiosource_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -109,9 +86,6 @@
on property:sys.usb.config=accessory,audio_source && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_audiosource"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -122,9 +96,6 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_audiosource_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f3
@@ -133,9 +104,6 @@
on property:sys.usb.config=midi && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "midi"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -145,19 +113,14 @@
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=midi,adb && property:sys.usb.configfs=1
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "midi_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
on property:sys.usb.config=rndis && property:sys.usb.configfs=1
+ mkdir /config/usb_gadget/g1/functions/rndis.gs4
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "rndis"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -166,10 +129,8 @@
start adbd
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=rndis,adb && property:sys.usb.configfs=1
+ mkdir /config/usb_gadget/g1/functions/rndis.gs4
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "rndis_adb"
- rm /config/usb_gadget/g1/configs/b.1/f1
- rm /config/usb_gadget/g1/configs/b.1/f2
- rm /config/usb_gadget/g1/configs/b.1/f3
symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 6ef491c..bf87b43 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -19,6 +19,7 @@
/dev/hw_random 0440 root system
/dev/ashmem 0666 root root
/dev/binder 0666 root root
+/dev/hwbinder 0666 root root
# Anyone can read the logs, but if they're not in the "logs"
# group, then they'll only see log entries for their UID.
diff --git a/sdcard/Android.mk b/sdcard/Android.mk
index 992b51c..0c58574 100644
--- a/sdcard/Android.mk
+++ b/sdcard/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := sdcard.cpp fuse.cpp
LOCAL_MODULE := sdcard
LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
-LOCAL_SHARED_LIBRARIES := libbase liblog libcutils libminijail libpackagelistparser
+LOCAL_SHARED_LIBRARIES := libbase libcutils libminijail libpackagelistparser
LOCAL_SANITIZE := integer
LOCAL_CLANG := true
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index f371901..6a972ea 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -18,6 +18,8 @@
#include "fuse.h"
+#include <android-base/logging.h>
+
/* FUSE_CANONICAL_PATH is not currently upstreamed */
#define FUSE_CANONICAL_PATH 2016
@@ -43,18 +45,20 @@
static void acquire_node_locked(struct node* node)
{
node->refcount++;
- TRACE("ACQUIRE %p (%s) rc=%d\n", node, node->name, node->refcount);
+ DLOG(INFO) << "ACQUIRE " << std::hex << node << std::dec
+ << " (" << node->name << ") rc=" << node->refcount;
}
static void remove_node_from_parent_locked(struct node* node);
static void release_node_locked(struct node* node)
{
- TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount);
+ DLOG(INFO) << "RELEASE " << std::hex << node << std::dec
+ << " (" << node->name << ") rc=" << node->refcount;
if (node->refcount > 0) {
node->refcount--;
if (!node->refcount) {
- TRACE("DESTROY %p (%s)\n", node, node->name);
+ DLOG(INFO) << "DESTROY " << std::hex << node << std::dec << " (" << node->name << ")";
remove_node_from_parent_locked(node);
/* TODO: remove debugging - poison memory */
@@ -65,7 +69,7 @@
free(node);
}
} else {
- ERROR("Zero refcnt %p\n", node);
+ LOG(ERROR) << std::hex << node << std::dec << " refcount=0";
}
}
@@ -159,7 +163,7 @@
struct dirent* entry;
DIR* dir = opendir(path);
if (!dir) {
- ERROR("opendir %s failed: %s\n", path, strerror(errno));
+ PLOG(ERROR) << "opendir(" << path << ") failed";
return actual;
}
while ((entry = readdir(dir))) {
@@ -227,7 +231,7 @@
if (errno == EEXIST) {
return 0;
} else {
- ERROR("Failed to open(%s): %s\n", path, strerror(errno));
+ PLOG(ERROR) << "open(" << path << ") failed";
return -1;
}
}
@@ -339,7 +343,7 @@
// Detect overflows in the inode counter. "4 billion nodes should be enough
// for everybody".
if (fuse->global->inode_ctr == 0) {
- ERROR("No more inode numbers available");
+ LOG(ERROR) << "No more inode numbers available";
return NULL;
}
@@ -488,7 +492,7 @@
res = writev(fuse->fd, vec, 2);
if (res < 0) {
- ERROR("*** REPLY FAILED *** %d\n", errno);
+ PLOG(ERROR) << "*** REPLY FAILED ***";
}
}
@@ -564,7 +568,7 @@
res = writev(fuse->fd, vec, 3);
/* Ignore ENOENT, since other views may not have seen the entry */
if (res < 0 && errno != ENOENT) {
- ERROR("*** NOTIFY FAILED *** %d\n", errno);
+ PLOG(ERROR) << "*** NOTIFY FAILED ***";
}
}
@@ -579,8 +583,8 @@
pthread_mutex_lock(&fuse->global->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
- TRACE("[%d] LOOKUP %s @ %" PRIx64 " (%s)\n", handler->token, name, hdr->nodeid,
- parent_node ? parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] LOOKUP " << name << " @ " << hdr->nodeid
+ << " (" << (parent_node ? parent_node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -601,8 +605,9 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_by_id_locked(fuse, hdr->nodeid);
- TRACE("[%d] FORGET #%" PRIu64 " @ %" PRIx64 " (%s)\n", handler->token, req->nlookup,
- hdr->nodeid, node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] FORGET #" << req->nlookup
+ << " @ " << std::hex << hdr->nodeid
+ << " (" << (node ? node->name : "?") << ")";
if (node) {
__u64 n = req->nlookup;
while (n) {
@@ -622,8 +627,9 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
- TRACE("[%d] GETATTR flags=%x fh=%" PRIx64 " @ %" PRIx64 " (%s)\n", handler->token,
- req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] GETATTR flags=" << req->getattr_flags
+ << " fh=" << std::hex << req->fh << " @ " << hdr->nodeid << std::dec
+ << " (" << (node ? node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!node) {
@@ -645,8 +651,9 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
- TRACE("[%d] SETATTR fh=%" PRIx64 " valid=%x @ %" PRIx64 " (%s)\n", handler->token,
- req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] SETATTR fh=" << std::hex << req->fh
+ << " valid=" << std::hex << req->valid << " @ " << hdr->nodeid << std::dec
+ << " (" << (node ? node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!node) {
@@ -690,8 +697,8 @@
times[1].tv_nsec = req->mtimensec;
}
}
- TRACE("[%d] Calling utimensat on %s with atime %ld, mtime=%ld\n",
- handler->token, path, times[0].tv_sec, times[1].tv_sec);
+ DLOG(INFO) << "[" << handler->token << "] Calling utimensat on " << path
+ << " with atime " << times[0].tv_sec << ", mtime=" << times[1].tv_sec;
if (utimensat(-1, path, times, 0) < 0) {
return -errno;
}
@@ -710,8 +717,9 @@
pthread_mutex_lock(&fuse->global->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
- TRACE("[%d] MKNOD %s 0%o @ %" PRIx64 " (%s)\n", handler->token,
- name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] MKNOD " << name << " 0" << std::oct << req->mode
+ << " @ " << std::hex << hdr->nodeid
+ << " (" << (parent_node ? parent_node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -739,8 +747,9 @@
pthread_mutex_lock(&fuse->global->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
- TRACE("[%d] MKDIR %s 0%o @ %" PRIx64 " (%s)\n", handler->token,
- name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] MKDIR " << name << " 0" << std::oct << req->mode
+ << " @ " << std::hex << hdr->nodeid
+ << " (" << (parent_node ? parent_node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!parent_node || !(actual_name = find_file_within(parent_path, name,
@@ -760,7 +769,7 @@
char nomedia[PATH_MAX];
snprintf(nomedia, PATH_MAX, "%s/.nomedia", child_path);
if (touch(nomedia, 0664) != 0) {
- ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
+ PLOG(ERROR) << "touch(" << nomedia << ") failed";
return -ENOENT;
}
}
@@ -768,7 +777,7 @@
char nomedia[PATH_MAX];
snprintf(nomedia, PATH_MAX, "%s/.nomedia", fuse->global->obb_path);
if (touch(nomedia, 0664) != 0) {
- ERROR("Failed to touch(%s): %s\n", nomedia, strerror(errno));
+ PLOG(ERROR) << "touch(" << nomedia << ") failed";
return -ENOENT;
}
}
@@ -787,8 +796,8 @@
pthread_mutex_lock(&fuse->global->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
- TRACE("[%d] UNLINK %s @ %" PRIx64 " (%s)\n", handler->token,
- name, hdr->nodeid, parent_node ? parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
+ << " (" << (parent_node ? parent_node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!parent_node || !find_file_within(parent_path, name,
@@ -809,8 +818,10 @@
pthread_mutex_unlock(&fuse->global->lock);
if (parent_node && child_node) {
/* Tell all other views that node is gone */
- TRACE("[%d] fuse_notify_delete parent=%" PRIx64 ", child=%" PRIx64 ", name=%s\n",
- handler->token, (uint64_t) parent_node->nid, (uint64_t) child_node->nid, name);
+ DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
+ << " parent=" << std::hex << parent_node->nid
+ << ", child=" << std::hex << child_node->nid << std::dec
+ << ", name=" << name;
if (fuse != fuse->global->fuse_default) {
fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
}
@@ -835,8 +846,8 @@
pthread_mutex_lock(&fuse->global->lock);
parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
parent_path, sizeof(parent_path));
- TRACE("[%d] RMDIR %s @ %" PRIx64 " (%s)\n", handler->token,
- name, hdr->nodeid, parent_node ? parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
+ << " (" << (parent_node ? parent_node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!parent_node || !find_file_within(parent_path, name,
@@ -857,8 +868,10 @@
pthread_mutex_unlock(&fuse->global->lock);
if (parent_node && child_node) {
/* Tell all other views that node is gone */
- TRACE("[%d] fuse_notify_delete parent=%" PRIx64 ", child=%" PRIx64 ", name=%s\n",
- handler->token, (uint64_t) parent_node->nid, (uint64_t) child_node->nid, name);
+ DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
+ << " parent=" << std::hex << parent_node->nid
+ << ", child=" << std::hex << child_node->nid << std::dec
+ << ", name=" << name;
if (fuse != fuse->global->fuse_default) {
fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
}
@@ -892,10 +905,11 @@
old_parent_path, sizeof(old_parent_path));
new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
new_parent_path, sizeof(new_parent_path));
- TRACE("[%d] RENAME %s->%s @ %" PRIx64 " (%s) -> %" PRIx64 " (%s)\n", handler->token,
- old_name, new_name,
- hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
- req->newdir, new_parent_node ? new_parent_node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] RENAME " << old_name << "->" << new_name
+ << " @ " << std::hex << hdr->nodeid
+ << " (" << (old_parent_node ? old_parent_node->name : "?") << ") -> "
+ << std::hex << req->newdir
+ << " (" << (new_parent_node ? new_parent_node->name : "?") << ")";
if (!old_parent_node || !new_parent_node) {
res = -ENOENT;
goto lookup_error;
@@ -929,7 +943,7 @@
goto io_error;
}
- TRACE("[%d] RENAME %s->%s\n", handler->token, old_child_path, new_child_path);
+ DLOG(INFO) << "[" << handler->token << "] RENAME " << old_child_path << "->" << new_child_path;
res = rename(old_child_path, new_child_path);
if (res < 0) {
res = -errno;
@@ -976,8 +990,9 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
- TRACE("[%d] OPEN 0%o @ %" PRIx64 " (%s)\n", handler->token,
- req->flags, hdr->nodeid, node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] OPEN 0" << std::oct << req->flags
+ << " @ " << std::hex << hdr->nodeid << std::dec
+ << " (" << (node ? node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!node) {
@@ -991,7 +1006,7 @@
if (!h) {
return -ENOMEM;
}
- TRACE("[%d] OPEN %s\n", handler->token, path);
+ DLOG(INFO) << "[" << handler->token << "] OPEN " << path;
h->fd = open(path, req->flags);
if (h->fd < 0) {
free(h);
@@ -1018,8 +1033,8 @@
* overlaps the request buffer and will clobber data in the request. This
* saves us 128KB per request handler thread at the cost of this scary comment. */
- TRACE("[%d] READ %p(%d) %u@%" PRIu64 "\n", handler->token,
- h, h->fd, size, (uint64_t) offset);
+ DLOG(INFO) << "[" << handler->token << "] READ " << std::hex << h << std::dec
+ << "(" << h->fd << ") " << size << "@" << offset;
if (size > MAX_READ) {
return -EINVAL;
}
@@ -1045,8 +1060,8 @@
buffer = (const __u8*) aligned_buffer;
}
- TRACE("[%d] WRITE %p(%d) %u@%" PRIu64 "\n", handler->token,
- h, h->fd, req->size, req->offset);
+ DLOG(INFO) << "[" << handler->token << "] WRITE " << std::hex << h << std::dec
+ << "(" << h->fd << ") " << req->size << "@" << req->offset;
res = pwrite64(h->fd, buffer, req->size, req->offset);
if (res < 0) {
return -errno;
@@ -1066,7 +1081,7 @@
int res;
pthread_mutex_lock(&fuse->global->lock);
- TRACE("[%d] STATFS\n", handler->token);
+ DLOG(INFO) << "[" << handler->token << "] STATFS";
res = get_node_path_locked(&fuse->global->root, path, sizeof(path));
pthread_mutex_unlock(&fuse->global->lock);
if (res < 0) {
@@ -1093,7 +1108,8 @@
{
struct handle *h = static_cast<struct handle*>(id_to_ptr(req->fh));
- TRACE("[%d] RELEASE %p(%d)\n", handler->token, h, h->fd);
+ DLOG(INFO) << "[" << handler->token << "] RELEASE " << std::hex << h << std::dec
+ << "(" << h->fd << ")";
close(h->fd);
free(h);
return 0;
@@ -1114,9 +1130,8 @@
fd = h->fd;
}
- TRACE("[%d] %s %p(%d) is_data_sync=%d\n", handler->token,
- is_dir ? "FSYNCDIR" : "FSYNC",
- static_cast<struct node*>(id_to_ptr(req->fh)), fd, is_data_sync);
+ DLOG(INFO) << "[" << handler->token << "] " << (is_dir ? "FSYNCDIR" : "FSYNC") << " "
+ << std::hex << req->fh << std::dec << "(" << fd << ") is_data_sync=" << is_data_sync;
int res = is_data_sync ? fdatasync(fd) : fsync(fd);
if (res == -1) {
return -errno;
@@ -1127,7 +1142,7 @@
static int handle_flush(struct fuse* fuse, struct fuse_handler* handler,
const struct fuse_in_header* hdr)
{
- TRACE("[%d] FLUSH\n", handler->token);
+ DLOG(INFO) << "[" << handler->token << "] FLUSH";
return 0;
}
@@ -1141,8 +1156,8 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
- TRACE("[%d] OPENDIR @ %" PRIx64 " (%s)\n", handler->token,
- hdr->nodeid, node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] OPENDIR @ " << std::hex << hdr->nodeid
+ << " (" << (node ? node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!node) {
@@ -1155,7 +1170,7 @@
if (!h) {
return -ENOMEM;
}
- TRACE("[%d] OPENDIR %s\n", handler->token, path);
+ DLOG(INFO) << "[" << handler->token << "] OPENDIR " << path;
h->d = opendir(path);
if (!h->d) {
free(h);
@@ -1176,10 +1191,10 @@
struct dirent *de;
struct dirhandle *h = static_cast<struct dirhandle*>(id_to_ptr(req->fh));
- TRACE("[%d] READDIR %p\n", handler->token, h);
+ DLOG(INFO) << "[" << handler->token << "] READDIR " << h;
if (req->offset == 0) {
/* rewinddir() might have been called above us, so rewind here too */
- TRACE("[%d] calling rewinddir()\n", handler->token);
+ DLOG(INFO) << "[" << handler->token << "] calling rewinddir()";
rewinddir(h->d);
}
de = readdir(h->d);
@@ -1202,7 +1217,7 @@
{
struct dirhandle *h = static_cast<struct dirhandle*>(id_to_ptr(req->fh));
- TRACE("[%d] RELEASEDIR %p\n", handler->token, h);
+ DLOG(INFO) << "[" << handler->token << "] RELEASEDIR " << h;
closedir(h->d);
free(h);
return 0;
@@ -1214,8 +1229,8 @@
struct fuse_init_out out;
size_t fuse_struct_size;
- TRACE("[%d] INIT ver=%d.%d maxread=%d flags=%x\n",
- handler->token, req->major, req->minor, req->max_readahead, req->flags);
+ DLOG(INFO) << "[" << handler->token << "] INIT ver=" << req->major << "." << req->minor
+ << " maxread=" << req->max_readahead << " flags=" << std::hex << req->flags;
/* Kernel 2.6.16 is the first stable kernel with struct fuse_init_out
* defined (fuse version 7.6). The structure is the same from 7.6 through
@@ -1223,8 +1238,9 @@
* new parameters.
*/
if (req->major != FUSE_KERNEL_VERSION || req->minor < 6) {
- ERROR("Fuse kernel version mismatch: Kernel version %d.%d, Expected at least %d.6",
- req->major, req->minor, FUSE_KERNEL_VERSION);
+ LOG(ERROR) << "Fuse kernel version mismatch: Kernel version "
+ << req->major << "." << req->minor
+ << ", Expected at least " << FUSE_KERNEL_VERSION << ".6";
return -1;
}
@@ -1262,8 +1278,8 @@
pthread_mutex_lock(&fuse->global->lock);
node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
path, sizeof(path));
- TRACE("[%d] CANONICAL_PATH @ %" PRIx64 " (%s)\n", handler->token, hdr->nodeid,
- node ? node->name : "?");
+ DLOG(INFO) << "[" << handler->token << "] CANONICAL_PATH @ " << std::hex << hdr->nodeid
+ << std::dec << " (" << (node ? node->name : "?") << ")";
pthread_mutex_unlock(&fuse->global->lock);
if (!node) {
@@ -1401,8 +1417,8 @@
}
default: {
- TRACE("[%d] NOTIMPL op=%d uniq=%" PRIx64 " nid=%" PRIx64 "\n",
- handler->token, hdr->opcode, hdr->unique, hdr->nodeid);
+ DLOG(INFO) << "[" << handler->token << "] NOTIMPL op=" << hdr->opcode
+ << "uniq=" << std::hex << hdr->unique << "nid=" << hdr->nodeid << std::dec;
return -ENOSYS;
}
}
@@ -1416,23 +1432,23 @@
handler->request_buffer, sizeof(handler->request_buffer)));
if (len < 0) {
if (errno == ENODEV) {
- ERROR("[%d] someone stole our marbles!\n", handler->token);
+ LOG(ERROR) << "[" << handler->token << "] someone stole our marbles!";
exit(2);
}
- ERROR("[%d] handle_fuse_requests: errno=%d\n", handler->token, errno);
+ PLOG(ERROR) << "[" << handler->token << "] handle_fuse_requests";
continue;
}
if ((size_t)len < sizeof(struct fuse_in_header)) {
- ERROR("[%d] request too short: len=%zu\n", handler->token, (size_t)len);
+ LOG(ERROR) << "[" << handler->token << "] request too short: len=" << len;
continue;
}
const struct fuse_in_header* hdr =
reinterpret_cast<const struct fuse_in_header*>(handler->request_buffer);
if (hdr->len != (size_t)len) {
- ERROR("[%d] malformed header: len=%zu, hdr->len=%u\n",
- handler->token, (size_t)len, hdr->len);
+ LOG(ERROR) << "[" << handler->token << "] malformed header: len=" << len
+ << ", hdr->len=" << hdr->len;
continue;
}
@@ -1446,7 +1462,7 @@
if (res != NO_STATUS) {
if (res) {
- TRACE("[%d] ERROR %d\n", handler->token, res);
+ DLOG(INFO) << "[" << handler->token << "] ERROR " << res;
}
fuse_status(fuse, unique, res);
}
diff --git a/sdcard/fuse.h b/sdcard/fuse.h
index 634fbf1..9ccd21d 100644
--- a/sdcard/fuse.h
+++ b/sdcard/fuse.h
@@ -33,23 +33,24 @@
#include <map>
#include <string>
+#include <android-base/logging.h>
#include <cutils/fs.h>
-#include <cutils/log.h>
#include <cutils/multiuser.h>
#include <packagelistparser/packagelistparser.h>
#include <private/android_filesystem_config.h>
-// TODO(b/30222003): Fix compilation with FUSE_TRACE == 1.
#define FUSE_TRACE 0
#if FUSE_TRACE
-#define TRACE(x...) ALOGD(x)
-#else
-#define TRACE(x...) do {} while (0)
+static constexpr bool kEnableDLog = true;
+#else // FUSE_TRACE == 0
+static constexpr bool kEnableDLog = false;
#endif
-#define ERROR(x...) ALOGE(x)
+// Use same strategy as DCHECK().
+#define DLOG(x) \
+ if (kEnableDLog) LOG(x)
/* Maximum number of bytes to write in one request. */
#define MAX_WRITE (256 * 1024)
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index 3d7bdc9..3481ec3 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -32,7 +32,6 @@
#include <android-base/macros.h>
#include <cutils/fs.h>
-#include <cutils/log.h>
#include <cutils/multiuser.h>
#include <packagelistparser/packagelistparser.h>
@@ -89,8 +88,7 @@
global->package_to_appid->clear();
bool rc = packagelist_parse(package_parse_callback, global);
- TRACE("read_package_list: found %zu packages\n",
- global->package_to_appid->size());
+ DLOG(INFO) << "read_package_list: found " << global->package_to_appid->size() << " packages";
// Regenerate ownership details using newly loaded mapping.
derive_permissions_recursive_locked(global->fuse_default, &global->root);
@@ -148,7 +146,7 @@
int event_size;
event = (struct inotify_event *) (event_buf + event_pos);
- TRACE("inotify event: %08x\n", event->mask);
+ DLOG(INFO) << "inotify event: " << std::hex << event->mask << std::dec;
if ((event->mask & IN_IGNORED) == IN_IGNORED) {
/* Previously watched file was deleted, probably due to move
* that swapped in new data; re-arm the watch and read. */
diff --git a/trusty/gatekeeper/trusty_gatekeeper.h b/trusty/gatekeeper/trusty_gatekeeper.h
index 82108dc..2becc49 100644
--- a/trusty/gatekeeper/trusty_gatekeeper.h
+++ b/trusty/gatekeeper/trusty_gatekeeper.h
@@ -27,7 +27,7 @@
class TrustyGateKeeperDevice {
public:
- TrustyGateKeeperDevice(const hw_module_t* module);
+ explicit TrustyGateKeeperDevice(const hw_module_t* module);
~TrustyGateKeeperDevice();
hw_device_t* hw_device();
diff --git a/trusty/keymaster/trusty_keymaster_device.h b/trusty/keymaster/trusty_keymaster_device.h
index cb74386..68cf40c 100644
--- a/trusty/keymaster/trusty_keymaster_device.h
+++ b/trusty/keymaster/trusty_keymaster_device.h
@@ -39,7 +39,7 @@
* These are the only symbols that will be exported by libtrustykeymaster. All functionality
* can be reached via the function pointers in device_.
*/
- __attribute__((visibility("default"))) TrustyKeymasterDevice(const hw_module_t* module);
+ __attribute__((visibility("default"))) explicit TrustyKeymasterDevice(const hw_module_t* module);
__attribute__((visibility("default"))) hw_device_t* hw_device();
~TrustyKeymasterDevice();
diff --git a/trusty/nvram/Android.mk b/trusty/nvram/Android.mk
index 18c54d5..44e2212 100644
--- a/trusty/nvram/Android.mk
+++ b/trusty/nvram/Android.mk
@@ -22,9 +22,22 @@
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
module.c \
+ trusty_nvram_device.cpp \
trusty_nvram_implementation.cpp
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror -Wextra -fvisibility=hidden
LOCAL_STATIC_LIBRARIES := libnvram-hal
LOCAL_SHARED_LIBRARIES := libtrusty libnvram-messages liblog
include $(BUILD_SHARED_LIBRARY)
+
+# nvram-wipe is a helper tool for clearing NVRAM state.
+include $(CLEAR_VARS)
+LOCAL_MODULE := nvram-wipe
+LOCAL_SRC_FILES := \
+ nvram_wipe.cpp \
+ trusty_nvram_implementation.cpp
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Wall -Werror -Wextra -fvisibility=hidden
+LOCAL_STATIC_LIBRARIES := libnvram-hal
+LOCAL_SHARED_LIBRARIES := libtrusty libnvram-messages liblog
+include $(BUILD_EXECUTABLE)
diff --git a/trusty/nvram/module.c b/trusty/nvram/module.c
index 06819c0..a2e64d3 100644
--- a/trusty/nvram/module.c
+++ b/trusty/nvram/module.c
@@ -16,7 +16,7 @@
#include <hardware/nvram.h>
-// This function is defined in trusty_nvram_implementation.cpp.
+// This function is defined in trusty_nvram_device.cpp.
int trusty_nvram_open(const hw_module_t* module,
const char* device_id,
hw_device_t** device_ptr);
diff --git a/trusty/nvram/nvram_wipe.cpp b/trusty/nvram/nvram_wipe.cpp
new file mode 100644
index 0000000..d0f4fad
--- /dev/null
+++ b/trusty/nvram/nvram_wipe.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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 <string.h>
+
+#include <nvram/messages/nvram_messages.h>
+
+#include "trusty_nvram_implementation.h"
+
+void usage(const char* program_name) {
+ fprintf(stderr, "Usage: %s [status|disable|wipe]\n", program_name);
+ exit(-1);
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ usage(argv[0]);
+ }
+
+ nvram::TrustyNvramImplementation nvram_proxy;
+ nvram::Request request;
+ nvram::Response response;
+
+ if (!strcmp(argv[1], "status")) {
+ request.payload.Activate<nvram::COMMAND_GET_INFO>();
+ nvram_proxy.Execute(request, &response);
+ const nvram::GetInfoResponse* get_info_response =
+ response.payload.get<nvram::COMMAND_GET_INFO>();
+ if (response.result == NV_RESULT_SUCCESS) {
+ int status = get_info_response && get_info_response->wipe_disabled;
+ printf("Wiping disabled: %d\n", status);
+ return status;
+ }
+ } else if (!strcmp(argv[1], "disable")) {
+ request.payload.Activate<nvram::COMMAND_DISABLE_WIPE>();
+ nvram_proxy.Execute(request, &response);
+ } else if (!strcmp(argv[1], "wipe")) {
+ request.payload.Activate<nvram::COMMAND_WIPE_STORAGE>();
+ nvram_proxy.Execute(request, &response);
+ } else {
+ usage(argv[0]);
+ }
+
+ if (response.result != NV_RESULT_SUCCESS) {
+ fprintf(stderr, "Command execution failure: %u\n", response.result);
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/trusty/nvram/trusty_nvram_device.cpp b/trusty/nvram/trusty_nvram_device.cpp
new file mode 100644
index 0000000..2c50915
--- /dev/null
+++ b/trusty/nvram/trusty_nvram_device.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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 <nvram/hal/nvram_device_adapter.h>
+
+#include "trusty_nvram_implementation.h"
+
+extern "C" int trusty_nvram_open(const hw_module_t* module,
+ const char* device_id,
+ hw_device_t** device_ptr) {
+ if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) {
+ return -EINVAL;
+ }
+
+ nvram::NvramDeviceAdapter* adapter = new nvram::NvramDeviceAdapter(
+ module, new nvram::TrustyNvramImplementation);
+ *device_ptr = adapter->as_device();
+ return 0;
+}
diff --git a/trusty/nvram/trusty_nvram_implementation.cpp b/trusty/nvram/trusty_nvram_implementation.cpp
index 39496b4..041c1bd 100644
--- a/trusty/nvram/trusty_nvram_implementation.cpp
+++ b/trusty/nvram/trusty_nvram_implementation.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "trusty_nvram_implementation.h"
+
#include <errno.h>
#include <string.h>
@@ -23,10 +25,9 @@
#define LOG_TAG "TrustyNVRAM"
#include <log/log.h>
-#include <nvram/hal/nvram_device_adapter.h>
#include <nvram/messages/blob.h>
-#include <nvram/messages/nvram_messages.h>
+namespace nvram {
namespace {
// Character device to open for Trusty IPC connections.
@@ -35,35 +36,7 @@
// App identifier of the NVRAM app.
const char kTrustyNvramAppId[] = "com.android.trusty.nvram";
-// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It
-// serializes the request objects, sends it to the Trusty app and finally reads
-// back the result and decodes it.
-class TrustyNvramImplementation : public nvram::NvramImplementation {
- public:
- ~TrustyNvramImplementation() override;
-
- void Execute(const nvram::Request& request,
- nvram::Response* response) override;
-
- private:
- // Connects the IPC channel to the Trusty app if it is not already open.
- // Returns true if the channel is open, false on errors.
- bool Connect();
-
- // Dispatches a command to the trust app. Returns true if successful (note
- // that the response may still indicate an error on the Trusty side), false if
- // there are any I/O or encoding/decoding errors.
- bool SendRequest(const nvram::Request& request,
- nvram::Response* response);
-
- // The file descriptor for the IPC connection to the Trusty app.
- int tipc_nvram_fd_ = -1;
-
- // Response buffer. This puts a hard size limit on the responses from the
- // Trusty app. 4096 matches the maximum IPC message size currently supported
- // by Trusty.
- uint8_t response_buffer_[4096];
-};
+} // namespace
TrustyNvramImplementation::~TrustyNvramImplementation() {
if (tipc_nvram_fd_ != -1) {
@@ -136,17 +109,4 @@
return true;
}
-} // namespace
-
-extern "C" int trusty_nvram_open(const hw_module_t* module,
- const char* device_id,
- hw_device_t** device_ptr) {
- if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) {
- return -EINVAL;
- }
-
- nvram::NvramDeviceAdapter* adapter =
- new nvram::NvramDeviceAdapter(module, new TrustyNvramImplementation);
- *device_ptr = adapter->as_device();
- return 0;
-}
+} // namespace nvram
diff --git a/trusty/nvram/trusty_nvram_implementation.h b/trusty/nvram/trusty_nvram_implementation.h
new file mode 100644
index 0000000..60758f7
--- /dev/null
+++ b/trusty/nvram/trusty_nvram_implementation.h
@@ -0,0 +1,59 @@
+/*
+ * 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 TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
+#define TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
+
+#include <stdint.h>
+
+#include <nvram/hal/nvram_device_adapter.h>
+#include <nvram/messages/nvram_messages.h>
+
+namespace nvram {
+
+// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It
+// serializes the request objects, sends it to the Trusty app and finally reads
+// back the result and decodes it.
+class TrustyNvramImplementation : public nvram::NvramImplementation {
+ public:
+ ~TrustyNvramImplementation() override;
+
+ void Execute(const nvram::Request& request,
+ nvram::Response* response) override;
+
+ private:
+ // Connects the IPC channel to the Trusty app if it is not already open.
+ // Returns true if the channel is open, false on errors.
+ bool Connect();
+
+ // Dispatches a command to the trust app. Returns true if successful (note
+ // that the response may still indicate an error on the Trusty side), false if
+ // there are any I/O or encoding/decoding errors.
+ bool SendRequest(const nvram::Request& request,
+ nvram::Response* response);
+
+ // The file descriptor for the IPC connection to the Trusty app.
+ int tipc_nvram_fd_ = -1;
+
+ // Response buffer. This puts a hard size limit on the responses from the
+ // Trusty app. 4096 matches the maximum IPC message size currently supported
+ // by Trusty.
+ uint8_t response_buffer_[4096];
+};
+
+} // namespace nvram
+
+#endif // TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_