Merge "Revert^2 "Prepare to fail in RefBase destructor if count is untouched""
diff --git a/adb/Android.bp b/adb/Android.bp
index 906c5e3..dabc5ce 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -449,7 +449,7 @@
test_suites: ["device-tests"],
}
-python_binary_host {
+python_test_host {
name: "adb_integration_test_adb",
main: "test_adb.py",
srcs: [
@@ -458,6 +458,8 @@
libs: [
"adb_py",
],
+ test_config: "adb_integration_test_adb.xml",
+ test_suites: ["general-tests"],
version: {
py2: {
enabled: true,
diff --git a/adb/adb.cpp b/adb/adb.cpp
index a8fe736..8e028f4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1044,7 +1044,7 @@
return 0;
}
-int handle_host_request(const char* service, TransportType type, const char* serial,
+bool handle_host_request(const char* service, TransportType type, const char* serial,
TransportId transport_id, int reply_fd, asocket* s) {
if (strcmp(service, "kill") == 0) {
fprintf(stderr, "adb server killed by remote request\n");
@@ -1070,7 +1070,7 @@
transport_id = strtoll(service, const_cast<char**>(&service), 10);
if (*service != '\0') {
SendFail(reply_fd, "invalid transport id");
- return 1;
+ return true;
}
} else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
type = kTransportUsb;
@@ -1088,10 +1088,13 @@
if (t != nullptr) {
s->transport = t;
SendOkay(reply_fd);
+
+ // We succesfully handled the device selection, but there's another request coming.
+ return false;
} else {
SendFail(reply_fd, error);
+ return true;
}
- return 1;
}
// return a list of all connected devices
@@ -1101,9 +1104,9 @@
D("Getting device list...");
std::string device_list = list_transports(long_listing);
D("Sending device list...");
- return SendOkay(reply_fd, device_list);
+ SendOkay(reply_fd, device_list);
}
- return 1;
+ return true;
}
if (!strcmp(service, "reconnect-offline")) {
@@ -1119,7 +1122,7 @@
response.resize(response.size() - 1);
}
SendOkay(reply_fd, response);
- return 0;
+ return true;
}
if (!strcmp(service, "features")) {
@@ -1130,7 +1133,7 @@
} else {
SendFail(reply_fd, error);
}
- return 0;
+ return true;
}
if (!strcmp(service, "host-features")) {
@@ -1141,7 +1144,7 @@
}
features.insert(kFeaturePushSync);
SendOkay(reply_fd, FeatureSetToString(features));
- return 0;
+ return true;
}
// remove TCP transport
@@ -1149,7 +1152,8 @@
const std::string address(service + 11);
if (address.empty()) {
kick_all_tcp_devices();
- return SendOkay(reply_fd, "disconnected everything");
+ SendOkay(reply_fd, "disconnected everything");
+ return true;
}
std::string serial;
@@ -1157,21 +1161,24 @@
int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
std::string error;
if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
- return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
- address.c_str(), error.c_str()));
+ SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
+ address.c_str(), error.c_str()));
+ return true;
}
atransport* t = find_transport(serial.c_str());
if (t == nullptr) {
- return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
- serial.c_str()));
+ SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", serial.c_str()));
+ return true;
}
kick_transport(t);
- return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
+ SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
+ return true;
}
// Returns our value for ADB_SERVER_VERSION.
if (!strcmp(service, "version")) {
- return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
+ SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
+ return true;
}
// These always report "unknown" rather than the actual error, for scripts.
@@ -1179,28 +1186,31 @@
std::string error;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
if (t) {
- return SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
+ SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
} else {
- return SendFail(reply_fd, error);
+ SendFail(reply_fd, error);
}
+ return true;
}
if (!strcmp(service, "get-devpath")) {
std::string error;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
if (t) {
- return SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
+ SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
} else {
- return SendFail(reply_fd, error);
+ SendFail(reply_fd, error);
}
+ return true;
}
if (!strcmp(service, "get-state")) {
std::string error;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
if (t) {
- return SendOkay(reply_fd, t->connection_state_name());
+ SendOkay(reply_fd, t->connection_state_name());
} else {
- return SendFail(reply_fd, error);
+ SendFail(reply_fd, error);
}
+ return true;
}
// Indicates a new emulator instance has started.
@@ -1208,7 +1218,7 @@
int port = atoi(service+9);
local_connect(port);
/* we don't even need to send a reply */
- return 0;
+ return true;
}
if (!strcmp(service, "reconnect")) {
@@ -1219,7 +1229,8 @@
response =
"reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
}
- return SendOkay(reply_fd, response);
+ SendOkay(reply_fd, response);
+ return true;
}
if (handle_forward_request(service,
@@ -1228,10 +1239,10 @@
error);
},
reply_fd)) {
- return 0;
+ return true;
}
- return -1;
+ return false;
}
static auto& init_mutex = *new std::mutex();
diff --git a/adb/adb.h b/adb/adb.h
index e6af780..f434e2d 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -210,8 +210,8 @@
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
#endif
-int handle_host_request(const char* service, TransportType type, const char* serial,
- TransportId transport_id, int reply_fd, asocket* s);
+bool handle_host_request(const char* service, TransportType type, const char* serial,
+ TransportId transport_id, int reply_fd, asocket* s);
void handle_online(atransport* t);
void handle_offline(atransport* t);
diff --git a/adb/adb_integration_test_adb.xml b/adb/adb_integration_test_adb.xml
new file mode 100644
index 0000000..e722956
--- /dev/null
+++ b/adb/adb_integration_test_adb.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config to run adb integration tests">
+ <option name="test-suite-tag" value="adb_tests" />
+ <option name="test-suite-tag" value="adb_integration" />
+ <target_preparer class="com.android.tradefed.targetprep.SemaphoreTokenTargetPreparer">
+ <option name="disable" value="false" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.adb.AdbStopServerPreparer" />
+ <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" >
+ <option name="par-file-name" value="adb_integration_test_adb" />
+ <option name="inject-android-serial" value="true" />
+ <option name="test-timeout" value="2m" />
+ </test>
+</configuration>
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 69b5180..1534792 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -685,13 +685,9 @@
if (service) {
asocket* s2;
- /* some requests are handled immediately -- in that
- ** case the handle_host_request() routine has sent
- ** the OKAY or FAIL message and all we have to do
- ** is clean up.
- */
- if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s) == 0) {
- /* XXX fail message? */
+ // Some requests are handled immediately -- in that case the handle_host_request() routine
+ // has sent the OKAY or FAIL message and all we have to do is clean up.
+ if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s)) {
D("SS(%d): handled host service '%s'", s->id, service);
goto fail;
}
diff --git a/base/Android.bp b/base/Android.bp
index 46a0233..3d80d97 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -135,7 +135,6 @@
"strings_test.cpp",
"test_main.cpp",
"test_utils_test.cpp",
- "unique_fd_test.cpp",
],
target: {
android: {
diff --git a/base/include/android-base/parsedouble.h b/base/include/android-base/parsedouble.h
index c273c61..9a20eb1 100644
--- a/base/include/android-base/parsedouble.h
+++ b/base/include/android-base/parsedouble.h
@@ -24,7 +24,7 @@
namespace android {
namespace base {
-// Parse double value in the string 's' and sets 'out' to that value.
+// Parse double value in the string 's' and sets 'out' to that value if it exists.
// Optionally allows the caller to define a 'min' and 'max' beyond which
// otherwise valid values will be rejected. Returns boolean success.
static inline bool ParseDouble(const char* s, double* out,
@@ -39,7 +39,9 @@
if (result < min || max < result) {
return false;
}
- *out = result;
+ if (out != nullptr) {
+ *out = result;
+ }
return true;
}
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index bb54c99..55f1ed3 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -27,9 +27,9 @@
namespace base {
// Parses the unsigned decimal or hexadecimal integer in the string 's' and sets
-// 'out' to that value. Optionally allows the caller to define a 'max' beyond
-// which otherwise valid values will be rejected. Returns boolean success; 'out'
-// is untouched if parsing fails.
+// 'out' to that value if it is specified. Optionally allows the caller to define
+// a 'max' beyond which otherwise valid values will be rejected. Returns boolean
+// success; 'out' is untouched if parsing fails.
template <typename T>
bool ParseUint(const char* s, T* out, T max = std::numeric_limits<T>::max(),
bool allow_suffixes = false) {
@@ -72,9 +72,9 @@
}
// Parses the signed decimal or hexadecimal integer in the string 's' and sets
-// 'out' to that value. Optionally allows the caller to define a 'min' and 'max'
-// beyond which otherwise valid values will be rejected. Returns boolean
-// success; 'out' is untouched if parsing fails.
+// 'out' to that value if it is specified. Optionally allows the caller to define
+// a 'min' and 'max' beyond which otherwise valid values will be rejected. Returns
+// boolean success; 'out' is untouched if parsing fails.
template <typename T>
bool ParseInt(const char* s, T* out,
T min = std::numeric_limits<T>::min(),
diff --git a/base/parsedouble_test.cpp b/base/parsedouble_test.cpp
index 8734c42..797a370 100644
--- a/base/parsedouble_test.cpp
+++ b/base/parsedouble_test.cpp
@@ -35,4 +35,9 @@
ASSERT_FALSE(android::base::ParseDouble("3.0", &d, -1.0, 2.0));
ASSERT_TRUE(android::base::ParseDouble("1.0", &d, 0.0, 2.0));
ASSERT_DOUBLE_EQ(1.0, d);
+
+ ASSERT_FALSE(android::base::ParseDouble("123.4x", nullptr));
+ ASSERT_TRUE(android::base::ParseDouble("-123.4", nullptr));
+ ASSERT_FALSE(android::base::ParseDouble("3.0", nullptr, -1.0, 2.0));
+ ASSERT_TRUE(android::base::ParseDouble("1.0", nullptr, 0.0, 2.0));
}
diff --git a/base/unique_fd_test.cpp b/base/unique_fd_test.cpp
deleted file mode 100644
index 3fdf12a..0000000
--- a/base/unique_fd_test.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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 "android-base/unique_fd.h"
-
-#include <gtest/gtest.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-using android::base::unique_fd;
-
-TEST(unique_fd, unowned_close) {
-#if defined(__BIONIC__)
- unique_fd fd(open("/dev/null", O_RDONLY));
- EXPECT_DEATH(close(fd.get()), "incorrect tag");
-#endif
-}
-
-TEST(unique_fd, untag_on_release) {
- unique_fd fd(open("/dev/null", O_RDONLY));
- close(fd.release());
-}
-
-TEST(unique_fd, move) {
- unique_fd fd(open("/dev/null", O_RDONLY));
- unique_fd fd_moved = std::move(fd);
- ASSERT_EQ(-1, fd.get());
- ASSERT_GT(fd_moved.get(), -1);
-}
-
-TEST(unique_fd, unowned_close_after_move) {
-#if defined(__BIONIC__)
- unique_fd fd(open("/dev/null", O_RDONLY));
- unique_fd fd_moved = std::move(fd);
- ASSERT_EQ(-1, fd.get());
- ASSERT_GT(fd_moved.get(), -1);
- EXPECT_DEATH(close(fd_moved.get()), "incorrect tag");
-#endif
-}
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 51cc62a..aa88a8a 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -96,6 +96,8 @@
"device/fastboot_device.cpp",
"device/main.cpp",
"device/usb_client.cpp",
+ "device/utility.cpp",
+ "device/variables.cpp",
],
shared_libs: [
@@ -103,6 +105,7 @@
"libext4_utils",
"libsparse",
"liblog",
+ "android.hardware.boot@1.0",
"libbootloader_message",
"libhidltransport",
"libhidlbase",
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 7caca3d..fa17070 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -51,3 +51,5 @@
#define FB_VAR_HAS_SLOT "has-slot"
#define FB_VAR_SLOT_COUNT "slot-count"
#define FB_VAR_PARTITION_SIZE "partition-size"
+#define FB_VAR_SLOT_SUCCESSFUL "slot-successful"
+#define FB_VAR_SLOT_UNBOOTABLE "slot-unbootable"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index a3cbf96..ac381fb 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -27,7 +27,43 @@
#include <android-base/unique_fd.h>
#include <cutils/android_reboot.h>
+#include "constants.h"
#include "fastboot_device.h"
+#include "utility.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::boot::V1_0::BoolResult;
+using ::android::hardware::boot::V1_0::CommandResult;
+using ::android::hardware::boot::V1_0::Slot;
+
+bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+ using VariableHandler =
+ std::function<std::string(FastbootDevice*, const std::vector<std::string>&)>;
+ const std::unordered_map<std::string, VariableHandler> kVariableMap = {
+ {FB_VAR_VERSION, GetVersion},
+ {FB_VAR_VERSION_BOOTLOADER, GetBootloaderVersion},
+ {FB_VAR_VERSION_BASEBAND, GetBasebandVersion},
+ {FB_VAR_PRODUCT, GetProduct},
+ {FB_VAR_SERIALNO, GetSerial},
+ {FB_VAR_SECURE, GetSecure},
+ {FB_VAR_UNLOCKED, GetUnlocked},
+ {FB_VAR_MAX_DOWNLOAD_SIZE, GetMaxDownloadSize},
+ {FB_VAR_CURRENT_SLOT, ::GetCurrentSlot},
+ {FB_VAR_SLOT_COUNT, GetSlotCount},
+ {FB_VAR_HAS_SLOT, GetHasSlot},
+ {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful},
+ {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable}};
+
+ // args[0] is command name, args[1] is variable.
+ auto found_variable = kVariableMap.find(args[1]);
+ if (found_variable == kVariableMap.end()) {
+ return device->WriteStatus(FastbootResult::FAIL, "Unknown variable");
+ }
+
+ std::vector<std::string> getvar_args(args.begin() + 2, args.end());
+ auto result = found_variable->second(device, getvar_args);
+ return device->WriteStatus(FastbootResult::OKAY, result);
+}
bool DownloadHandler(FastbootDevice* device, const std::vector<std::string>& args) {
if (args.size() < 2) {
@@ -51,8 +87,31 @@
return device->WriteStatus(FastbootResult::FAIL, "Couldn't download data");
}
-bool SetActiveHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) {
- return device->WriteStatus(FastbootResult::OKAY, "");
+bool SetActiveHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (args.size() < 2) {
+ return device->WriteStatus(FastbootResult::FAIL, "Missing slot argument");
+ }
+
+ // Slot suffix needs to be between 'a' and 'z'.
+ Slot slot;
+ if (!GetSlotNumber(args[1], &slot)) {
+ return device->WriteStatus(FastbootResult::FAIL, "Bad slot suffix");
+ }
+
+ // Non-A/B devices will not have a boot control HAL.
+ auto boot_control_hal = device->boot_control_hal();
+ if (!boot_control_hal) {
+ return device->WriteStatus(FastbootResult::FAIL,
+ "Cannot set slot: boot control HAL absent");
+ }
+ if (slot >= boot_control_hal->getNumberSlots()) {
+ return device->WriteStatus(FastbootResult::FAIL, "Slot out of range");
+ }
+ CommandResult ret;
+ auto cb = [&ret](CommandResult result) { ret = result; };
+ auto result = boot_control_hal->setActiveBootSlot(slot, cb);
+ if (result.isOk() && ret.success) return device->WriteStatus(FastbootResult::OKAY, "");
+ return device->WriteStatus(FastbootResult::FAIL, "Unable to set slot");
}
bool ShutDownHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) {
diff --git a/fastboot/device/commands.h b/fastboot/device/commands.h
index cd984c8..8785b91 100644
--- a/fastboot/device/commands.h
+++ b/fastboot/device/commands.h
@@ -38,3 +38,4 @@
bool RebootBootloaderHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool RebootFastbootHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string>& args);
+bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args);
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 4c3d23f..f61e5c2 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -18,23 +18,31 @@
#include <android-base/logging.h>
#include <android-base/strings.h>
+#include <android/hardware/boot/1.0/IBootControl.h>
#include <algorithm>
#include "constants.h"
#include "usb_client.h"
+using ::android::hardware::hidl_string;
+using ::android::hardware::boot::V1_0::IBootControl;
+using ::android::hardware::boot::V1_0::Slot;
+namespace sph = std::placeholders;
+
FastbootDevice::FastbootDevice()
: kCommandMap({
{FB_CMD_SET_ACTIVE, SetActiveHandler},
{FB_CMD_DOWNLOAD, DownloadHandler},
+ {FB_CMD_GETVAR, GetVarHandler},
{FB_CMD_SHUTDOWN, ShutDownHandler},
{FB_CMD_REBOOT, RebootHandler},
{FB_CMD_REBOOT_BOOTLOADER, RebootBootloaderHandler},
{FB_CMD_REBOOT_FASTBOOT, RebootFastbootHandler},
{FB_CMD_REBOOT_RECOVERY, RebootRecoveryHandler},
}),
- transport_(std::make_unique<ClientUsbTransport>()) {}
+ transport_(std::make_unique<ClientUsbTransport>()),
+ boot_control_hal_(IBootControl::getService()) {}
FastbootDevice::~FastbootDevice() {
CloseDevice();
@@ -44,9 +52,21 @@
transport_->Close();
}
+std::string FastbootDevice::GetCurrentSlot() {
+ // Non-A/B devices must not have boot control HALs.
+ if (!boot_control_hal_) {
+ return "";
+ }
+ std::string suffix;
+ auto cb = [&suffix](hidl_string s) { suffix = s; };
+ boot_control_hal_->getSuffix(boot_control_hal_->getCurrentSlot(), cb);
+ return suffix;
+}
+
bool FastbootDevice::WriteStatus(FastbootResult result, const std::string& message) {
constexpr size_t kResponseReasonSize = 4;
constexpr size_t kNumResponseTypes = 4; // "FAIL", "OKAY", "INFO", "DATA"
+
char buf[FB_RESPONSE_SZ];
constexpr size_t kMaxMessageSize = sizeof(buf) - kResponseReasonSize;
size_t msg_len = std::min(kMaxMessageSize, message.size());
diff --git a/fastboot/device/fastboot_device.h b/fastboot/device/fastboot_device.h
index fec42a7..1092499 100644
--- a/fastboot/device/fastboot_device.h
+++ b/fastboot/device/fastboot_device.h
@@ -22,10 +22,11 @@
#include <utility>
#include <vector>
+#include <android/hardware/boot/1.0/IBootControl.h>
+
#include "commands.h"
#include "transport.h"
-
-class FastbootDevice;
+#include "variables.h"
class FastbootDevice {
public:
@@ -36,17 +37,21 @@
void ExecuteCommands();
bool WriteStatus(FastbootResult result, const std::string& message);
bool HandleData(bool read, std::vector<char>* data);
+ std::string GetCurrentSlot();
std::vector<char>& get_download_data() { return download_data_; }
void set_upload_data(const std::vector<char>& data) { upload_data_ = data; }
void set_upload_data(std::vector<char>&& data) { upload_data_ = std::move(data); }
Transport* get_transport() { return transport_.get(); }
+ android::sp<android::hardware::boot::V1_0::IBootControl> boot_control_hal() {
+ return boot_control_hal_;
+ }
private:
const std::unordered_map<std::string, CommandHandler> kCommandMap;
std::unique_ptr<Transport> transport_;
-
+ android::sp<android::hardware::boot::V1_0::IBootControl> boot_control_hal_;
std::vector<char> download_data_;
std::vector<char> upload_data_;
};
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
new file mode 100644
index 0000000..c8d2b3e
--- /dev/null
+++ b/fastboot/device/utility.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 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 "utility.h"
+
+using android::hardware::boot::V1_0::Slot;
+
+bool GetSlotNumber(const std::string& slot, Slot* number) {
+ if (slot.size() != 1) {
+ return false;
+ }
+ if (slot[0] < 'a' || slot[0] > 'z') {
+ return false;
+ }
+ *number = slot[0] - 'a';
+ return true;
+}
diff --git a/fastboot/device/utility.h b/fastboot/device/utility.h
new file mode 100644
index 0000000..867d693
--- /dev/null
+++ b/fastboot/device/utility.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 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 <string>
+
+#include <android/hardware/boot/1.0/IBootControl.h>
+
+bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number);
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
new file mode 100644
index 0000000..153ab92
--- /dev/null
+++ b/fastboot/device/variables.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 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 "variables.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <ext4_utils/ext4_utils.h>
+
+#include "fastboot_device.h"
+#include "utility.h"
+
+using ::android::hardware::boot::V1_0::BoolResult;
+using ::android::hardware::boot::V1_0::Slot;
+
+constexpr int kMaxDownloadSizeDefault = 0x20000000;
+constexpr char kFastbootProtocolVersion[] = "0.4";
+
+std::string GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */) {
+ return kFastbootProtocolVersion;
+}
+
+std::string GetBootloaderVersion(FastbootDevice* /* device */,
+ const std::vector<std::string>& /* args */) {
+ return android::base::GetProperty("ro.bootloader", "");
+}
+
+std::string GetBasebandVersion(FastbootDevice* /* device */,
+ const std::vector<std::string>& /* args */) {
+ return android::base::GetProperty("ro.build.expect.baseband", "");
+}
+
+std::string GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */) {
+ return android::base::GetProperty("ro.product.device", "");
+}
+
+std::string GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */) {
+ return android::base::GetProperty("ro.serialno", "");
+}
+
+std::string GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */) {
+ return android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
+}
+
+std::string GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */) {
+ std::string suffix = device->GetCurrentSlot();
+ return suffix.size() == 2 ? suffix.substr(1) : suffix;
+}
+
+std::string GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */) {
+ auto boot_control_hal = device->boot_control_hal();
+ if (!boot_control_hal) {
+ return "0";
+ }
+ return std::to_string(boot_control_hal->getNumberSlots());
+}
+
+std::string GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (args.empty()) {
+ return "no";
+ }
+ Slot slot;
+ if (!GetSlotNumber(args[0], &slot)) {
+ return "no";
+ }
+ auto boot_control_hal = device->boot_control_hal();
+ if (!boot_control_hal) {
+ return "no";
+ }
+ return boot_control_hal->isSlotMarkedSuccessful(slot) == BoolResult::TRUE ? "yes" : "no";
+}
+
+std::string GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (args.empty()) {
+ return "no";
+ }
+ Slot slot;
+ if (!GetSlotNumber(args[0], &slot)) {
+ return "no";
+ }
+ auto boot_control_hal = device->boot_control_hal();
+ if (!boot_control_hal) {
+ return "no";
+ }
+ return boot_control_hal->isSlotBootable(slot) == BoolResult::TRUE ? "no" : "yes";
+}
+
+std::string GetMaxDownloadSize(FastbootDevice* /* device */,
+ const std::vector<std::string>& /* args */) {
+ return std::to_string(kMaxDownloadSizeDefault);
+}
+
+std::string GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */) {
+ return "yes";
+}
+
+std::string GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (args.empty()) {
+ return "no";
+ }
+ std::string slot_suffix = device->GetCurrentSlot();
+ if (slot_suffix.empty()) {
+ return "no";
+ }
+ return args[0] == "userdata" ? "no" : "yes";
+}
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
new file mode 100644
index 0000000..09ef8ec
--- /dev/null
+++ b/fastboot/device/variables.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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 <functional>
+#include <string>
+#include <vector>
+
+class FastbootDevice;
+
+std::string GetVersion(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetBootloaderVersion(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetBasebandVersion(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetProduct(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetSerial(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetSecure(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetSlotCount(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetMaxDownloadSize(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetUnlocked(FastbootDevice* device, const std::vector<std::string>& args);
+std::string GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args);
diff --git a/libsync/Android.bp b/libsync/Android.bp
index dbee596..e56f8ba 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -20,8 +20,9 @@
cflags: ["-Werror"],
}
-cc_library_shared {
+cc_library {
name: "libsync",
+ recovery_available: true,
defaults: ["libsync_defaults"],
}
@@ -31,15 +32,6 @@
export_include_dirs: ["include"],
}
-// libsync_recovery is only intended for the recovery binary.
-// Future versions of the kernel WILL require an updated libsync, and will break
-// anything statically linked against the current libsync.
-cc_library_static {
- name: "libsync_recovery",
- recovery_available: true,
- defaults: ["libsync_defaults"],
-}
-
cc_test {
name: "sync-unit-tests",
shared_libs: ["libsync"],
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp
index 3d982f6..8ec560c 100644
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -24,6 +24,7 @@
#include <android-base/unique_fd.h>
+#include <dex/class_accessor-inl.h>
#include <dex/code_item_accessors-inl.h>
#include <dex/compact_dex_file.h>
#include <dex/dex_file-inl.h>
@@ -98,38 +99,20 @@
// Check the methods we haven't cached.
for (; class_def_index_ < dex_file_->NumClassDefs(); class_def_index_++) {
- const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(class_def_index_);
- const uint8_t* class_data = dex_file_->GetClassData(class_def);
- if (class_data == nullptr) {
- continue;
- }
+ art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(class_def_index_));
- if (class_it_.get() == nullptr || !class_it_->HasNext()) {
- class_it_.reset(new art::ClassDataItemIterator(*dex_file_.get(), class_data));
- }
-
- for (; class_it_->HasNext(); class_it_->Next()) {
- if (!class_it_->IsAtMethod()) {
- continue;
- }
- const art::DexFile::CodeItem* code_item = class_it_->GetMethodCodeItem();
- if (code_item == nullptr) {
- continue;
- }
- art::CodeItemInstructionAccessor code(*dex_file_.get(), code_item);
+ for (const art::ClassAccessor::Method& method : accessor.GetMethods()) {
+ art::CodeItemInstructionAccessor code = method.GetInstructions();
if (!code.HasCodeItem()) {
continue;
}
-
uint32_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
- uint32_t offset_end = offset + code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
- uint32_t member_index = class_it_->GetMemberIndex();
+ uint32_t offset_end = offset + code.InsnsSizeInBytes();
+ uint32_t member_index = method.GetIndex();
method_cache_[offset_end] = std::make_pair(offset, member_index);
if (offset <= dex_offset && dex_offset < offset_end) {
*method_name = dex_file_->PrettyMethod(member_index, false);
*method_offset = dex_offset - offset;
- // Move past this element.
- class_it_->Next();
return true;
}
}
diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h
index 508692d..c123158 100644
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -45,7 +45,6 @@
std::map<uint32_t, std::pair<uint64_t, uint32_t>> method_cache_; // dex offset to method index.
uint32_t class_def_index_ = 0;
- std::unique_ptr<art::ClassDataItemIterator> class_it_;
};
class DexFileFromFile : public DexFile {
diff --git a/libunwindstack/include/unwindstack/RegsGetLocal.h b/libunwindstack/include/unwindstack/RegsGetLocal.h
index 81c0af3..f0b5e3a 100644
--- a/libunwindstack/include/unwindstack/RegsGetLocal.h
+++ b/libunwindstack/include/unwindstack/RegsGetLocal.h
@@ -33,8 +33,7 @@
#if defined(__arm__)
-inline __always_inline void RegsGetLocal(Regs* regs) {
- void* reg_data = regs->RawData();
+inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
asm volatile(
".align 2\n"
"bx pc\n"
@@ -55,8 +54,7 @@
#elif defined(__aarch64__)
-inline __always_inline void RegsGetLocal(Regs* regs) {
- void* reg_data = regs->RawData();
+inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
asm volatile(
"1:\n"
"stp x0, x1, [%[base], #0]\n"
@@ -87,11 +85,12 @@
extern "C" void AsmGetRegs(void* regs);
-inline void RegsGetLocal(Regs* regs) {
+#endif
+
+inline __attribute__((__always_inline__)) void RegsGetLocal(Regs* regs) {
AsmGetRegs(regs->RawData());
}
-#endif
} // namespace unwindstack
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 8fda563..3b45db7 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -82,6 +82,9 @@
/* Defined as ProcessList.SYSTEM_ADJ in ProcessList.java */
#define SYSTEM_ADJ (-900)
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define STRINGIFY_INTERNAL(x) #x
+
/* default to old in-kernel interface if no memory pressure events */
static bool use_inkernel_interface = true;
static bool has_inkernel_module;
@@ -730,10 +733,10 @@
#ifdef LMKD_LOG_STATS
static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
- char key[LINE_MAX];
+ char key[LINE_MAX + 1];
int64_t value;
- sscanf(line,"%s %" SCNd64 "", key, &value);
+ sscanf(line, "%" STRINGIFY(LINE_MAX) "s %" SCNd64 "", key, &value);
if (strcmp(key, "total_") < 0) {
return;
@@ -752,24 +755,31 @@
}
static int memory_stat_parse(struct memory_stat *mem_st, int pid, uid_t uid) {
- FILE *fp;
- char buf[PATH_MAX];
+ FILE *fp;
+ char buf[PATH_MAX];
- snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
+ /*
+ * Per-application memory.stat files are available only when
+ * per-application memcgs are enabled.
+ */
+ if (!per_app_memcg)
+ return -1;
- fp = fopen(buf, "r");
+ snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
- if (fp == NULL) {
- ALOGE("%s open failed: %s", buf, strerror(errno));
- return -1;
- }
+ fp = fopen(buf, "r");
- while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
- memory_stat_parse_line(buf, mem_st);
- }
- fclose(fp);
+ if (fp == NULL) {
+ ALOGE("%s open failed: %s", buf, strerror(errno));
+ return -1;
+ }
- return 0;
+ while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
+ memory_stat_parse_line(buf, mem_st);
+ }
+ fclose(fp);
+
+ return 0;
}
#endif