Merge "Set HOME, LOGNAME, SHELL, and USER from adbd."
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index ddd15a2..4458c85 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -72,6 +72,19 @@
// That's why we don't need a lock for fdevent.
static std::unordered_map<int, PollNode> g_poll_node_map;
static std::list<fdevent*> g_pending_list;
+static bool main_thread_valid;
+static pthread_t main_thread;
+
+static void check_main_thread() {
+ if (main_thread_valid) {
+ CHECK_NE(0, pthread_equal(main_thread, pthread_self()));
+ }
+}
+
+static void set_main_thread() {
+ main_thread_valid = true;
+ main_thread = pthread_self();
+}
static std::string dump_fde(const fdevent* fde) {
std::string state;
@@ -101,6 +114,7 @@
fdevent *fdevent_create(int fd, fd_func func, void *arg)
{
+ check_main_thread();
fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
if(fde == 0) return 0;
fdevent_install(fde, fd, func, arg);
@@ -110,6 +124,7 @@
void fdevent_destroy(fdevent *fde)
{
+ check_main_thread();
if(fde == 0) return;
if(!(fde->state & FDE_CREATED)) {
LOG(FATAL) << "destroying fde not created by fdevent_create(): " << dump_fde(fde);
@@ -119,6 +134,7 @@
}
void fdevent_install(fdevent* fde, int fd, fd_func func, void* arg) {
+ check_main_thread();
CHECK_GE(fd, 0);
memset(fde, 0, sizeof(fdevent));
fde->state = FDE_ACTIVE;
@@ -137,6 +153,7 @@
}
void fdevent_remove(fdevent* fde) {
+ check_main_thread();
D("fdevent_remove %s", dump_fde(fde).c_str());
if (fde->state & FDE_ACTIVE) {
g_poll_node_map.erase(fde->fd);
@@ -171,6 +188,7 @@
}
void fdevent_set(fdevent* fde, unsigned events) {
+ check_main_thread();
events &= FDE_EVENTMASK;
if ((fde->state & FDE_EVENTMASK) == events) {
return;
@@ -190,10 +208,12 @@
}
void fdevent_add(fdevent* fde, unsigned events) {
+ check_main_thread();
fdevent_set(fde, (fde->state & FDE_EVENTMASK) | events);
}
void fdevent_del(fdevent* fde, unsigned events) {
+ check_main_thread();
fdevent_set(fde, (fde->state & FDE_EVENTMASK) & ~events);
}
@@ -335,6 +355,7 @@
void fdevent_loop()
{
+ set_main_thread();
#if !ADB_HOST
fdevent_subproc_setup();
#endif // !ADB_HOST
@@ -359,4 +380,5 @@
void fdevent_reset() {
g_poll_node_map.clear();
g_pending_list.clear();
+ main_thread_valid = false;
}
diff --git a/adb/services.cpp b/adb/services.cpp
index e24b470..19a6726 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -184,15 +184,18 @@
adb_close(fd);
}
-void reverse_service(int fd, void* arg)
-{
- const char* command = reinterpret_cast<const char*>(arg);
-
- if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
- SendFail(fd, "not a reverse forwarding command");
+int reverse_service(const char* command) {
+ int s[2];
+ if (adb_socketpair(s)) {
+ PLOG(ERROR) << "cannot create service socket pair.";
+ return -1;
}
- free(arg);
- adb_close(fd);
+ VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
+ if (handle_forward_request(command, kTransportAny, nullptr, s[1]) < 0) {
+ SendFail(s[1], "not a reverse forwarding command");
+ }
+ adb_close(s[1]);
+ return s[0];
}
// Shell service string can look like:
@@ -335,15 +338,7 @@
} else if(!strncmp(name, "usb:", 4)) {
ret = create_service_thread(restart_usb_service, NULL);
} else if (!strncmp(name, "reverse:", 8)) {
- char* cookie = strdup(name + 8);
- if (cookie == NULL) {
- ret = -1;
- } else {
- ret = create_service_thread(reverse_service, cookie);
- if (ret < 0) {
- free(cookie);
- }
- }
+ ret = reverse_service(name + 8);
} else if(!strncmp(name, "disable-verity:", 15)) {
ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
} else if(!strncmp(name, "enable-verity:", 15)) {
diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h
index aba9577..50fde35 100644
--- a/include/utils/StrongPointer.h
+++ b/include/utils/StrongPointer.h
@@ -62,8 +62,10 @@
sp(T* other);
sp(const sp<T>& other);
+ sp(sp<T>&& other);
template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);
+ template<typename U> sp(sp<U>&& other);
~sp();
@@ -71,8 +73,10 @@
sp& operator = (T* other);
sp& operator = (const sp<T>& other);
+ sp& operator = (sp<T>&& other);
template<typename U> sp& operator = (const sp<U>& other);
+ template<typename U> sp& operator = (sp<U>&& other);
template<typename U> sp& operator = (U* other);
//! Special optimization for use by ProcessState (and nobody else).
@@ -123,6 +127,12 @@
m_ptr->incStrong(this);
}
+template<typename T>
+sp<T>::sp(sp<T>&& other)
+ : m_ptr(other.m_ptr) {
+ other.m_ptr = nullptr;
+}
+
template<typename T> template<typename U>
sp<T>::sp(U* other)
: m_ptr(other) {
@@ -137,6 +147,12 @@
m_ptr->incStrong(this);
}
+template<typename T> template<typename U>
+sp<T>::sp(sp<U>&& other)
+ : m_ptr(other.m_ptr) {
+ other.m_ptr = nullptr;
+}
+
template<typename T>
sp<T>::~sp() {
if (m_ptr)
@@ -155,6 +171,15 @@
}
template<typename T>
+sp<T>& sp<T>::operator =(sp<T>&& other) {
+ if (m_ptr)
+ m_ptr->decStrong(this);
+ m_ptr = other.m_ptr;
+ other.m_ptr = nullptr;
+ return *this;
+}
+
+template<typename T>
sp<T>& sp<T>::operator =(T* other) {
if (other)
other->incStrong(this);
@@ -176,6 +201,15 @@
}
template<typename T> template<typename U>
+sp<T>& sp<T>::operator =(sp<U>&& other) {
+ if (m_ptr)
+ m_ptr->decStrong(this);
+ m_ptr = other.m_ptr;
+ other.m_ptr = nullptr;
+ return *this;
+}
+
+template<typename T> template<typename U>
sp<T>& sp<T>::operator =(U* other) {
if (other)
((T*) other)->incStrong(this);
diff --git a/libutils/tests/Android.mk b/libutils/tests/Android.mk
index 514f8c1..cb9e8a2 100644
--- a/libutils/tests/Android.mk
+++ b/libutils/tests/Android.mk
@@ -27,6 +27,7 @@
Looper_test.cpp \
LruCache_test.cpp \
String8_test.cpp \
+ StrongPointer_test.cpp \
Unicode_test.cpp \
Vector_test.cpp \
diff --git a/libutils/tests/StrongPointer_test.cpp b/libutils/tests/StrongPointer_test.cpp
new file mode 100644
index 0000000..f46d6d1
--- /dev/null
+++ b/libutils/tests/StrongPointer_test.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <utils/StrongPointer.h>
+#include <utils/RefBase.h>
+
+using namespace android;
+
+class Foo : public LightRefBase<Foo> {
+public:
+ Foo(bool* deleted_check) : mDeleted(deleted_check) {
+ *mDeleted = false;
+ }
+
+ ~Foo() {
+ *mDeleted = true;
+ }
+private:
+ bool* mDeleted;
+};
+
+TEST(StrongPointer, move) {
+ bool isDeleted;
+ Foo* foo = new Foo(&isDeleted);
+ ASSERT_EQ(0, foo->getStrongCount());
+ ASSERT_FALSE(isDeleted) << "Already deleted...?";
+ sp<Foo> sp1(foo);
+ ASSERT_EQ(1, foo->getStrongCount());
+ {
+ sp<Foo> sp2 = std::move(sp1);
+ ASSERT_EQ(1, foo->getStrongCount()) << "std::move failed, incremented refcnt";
+ ASSERT_EQ(nullptr, sp1.get()) << "std::move failed, sp1 is still valid";
+ // The strong count isn't increasing, let's double check the old object
+ // is properly reset and doesn't early delete
+ sp1 = std::move(sp2);
+ }
+ ASSERT_FALSE(isDeleted) << "deleted too early! still has a reference!";
+ {
+ // Now let's double check it deletes on time
+ sp<Foo> sp2 = std::move(sp1);
+ }
+ ASSERT_TRUE(isDeleted) << "foo was leaked!";
+}
diff --git a/metricsd/constants.h b/metricsd/constants.h
index 7e1e116..3a7569b 100644
--- a/metricsd/constants.h
+++ b/metricsd/constants.h
@@ -30,6 +30,10 @@
// Build time properties name.
static const char kProductId[] = "product_id";
static const char kProductVersion[] = "product_version";
+
+// Weave configuration.
+static const char kWeaveConfigurationFile[] = "/system/etc/weaved/weaved.conf";
+static const char kModelManifestId[] = "model_id";
} // namespace metrics
#endif // METRICS_CONSTANTS_H_
diff --git a/metricsd/uploader/system_profile_cache.cc b/metricsd/uploader/system_profile_cache.cc
index 1995510..f7060a2 100644
--- a/metricsd/uploader/system_profile_cache.cc
+++ b/metricsd/uploader/system_profile_cache.cc
@@ -108,7 +108,18 @@
profile_.client_id = testing_ ?
"client_id_test" :
GetPersistentGUID(guid_path);
- profile_.hardware_class = "unknown";
+ profile_.model_manifest_id = "unknown";
+ if (!testing_) {
+ brillo::KeyValueStore weave_config;
+ if (!weave_config.Load(base::FilePath(metrics::kWeaveConfigurationFile))) {
+ LOG(ERROR) << "Failed to load the weave configuration file.";
+ } else if (!weave_config.GetString(metrics::kModelManifestId,
+ &profile_.model_manifest_id)) {
+ LOG(ERROR) << "The model manifest id (model_id) is undefined in "
+ << metrics::kWeaveConfigurationFile;
+ }
+ }
+
profile_.channel = ProtoChannelFromString(channel);
// Increment the session_id everytime we initialize this. If metrics_daemon
@@ -143,7 +154,7 @@
metrics::SystemProfileProto* profile_proto =
metrics_proto->mutable_system_profile();
profile_proto->mutable_hardware()->set_hardware_class(
- profile_.hardware_class);
+ profile_.model_manifest_id);
profile_proto->set_app_version(profile_.version);
profile_proto->set_channel(profile_.channel);
metrics::SystemProfileProto_BrilloDeviceData* device_data =
diff --git a/metricsd/uploader/system_profile_cache.h b/metricsd/uploader/system_profile_cache.h
index 97fb33a..ae54a2a 100644
--- a/metricsd/uploader/system_profile_cache.h
+++ b/metricsd/uploader/system_profile_cache.h
@@ -35,7 +35,7 @@
struct SystemProfile {
std::string version;
- std::string hardware_class;
+ std::string model_manifest_id;
std::string client_id;
int session_id;
metrics::SystemProfileProto::Channel channel;
diff --git a/metricsd/uploader/upload_service.h b/metricsd/uploader/upload_service.h
index a4d0a1e..77df74b 100644
--- a/metricsd/uploader/upload_service.h
+++ b/metricsd/uploader/upload_service.h
@@ -46,8 +46,8 @@
//
// The two states are the presence or not of a staged log.
// A staged log is a compressed protobuffer containing both the aggregated
-// metrics and event and information about the client. (product, hardware id,
-// etc...).
+// metrics and event and information about the client. (product,
+// model_manifest_id, etc...).
//
// At regular intervals, the upload event will be triggered and the following
// will happen:
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 8b16996..b134f93 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -41,17 +41,21 @@
# because init.rc is conditionally included.
#
# create some directories (some are mount points) and symlinks
-local_post_install_cmd_base := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data oem acct cache config storage mnt root); \
+LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
+ sbin dev proc sys system data oem acct cache config storage mnt root $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /sys/kernel/debug $(TARGET_ROOT_OUT)/d; \
ln -sf /storage/self/primary $(TARGET_ROOT_OUT)/sdcard
ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
- LOCAL_POST_INSTALL_CMD := $(local_post_install_cmd_base); mkdir -p $(TARGET_ROOT_OUT)/vendor
-else
- LOCAL_POST_INSTALL_CMD := $(local_post_install_cmd_base)
+ LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/vendor
endif
-local_post_install_cmd_base :=
+ifdef BOARD_ROOT_EXTRA_SYMLINKS
+# BOARD_ROOT_EXTRA_SYMLINKS is a list of <target>:<link_name>.
+ LOCAL_POST_INSTALL_CMD += $(foreach s, $(BOARD_ROOT_EXTRA_SYMLINKS),\
+ $(eval p := $(subst :,$(space),$(s)))\
+ ; mkdir -p $(dir $(TARGET_ROOT_OUT)/$(word 2,$(p))) \
+ ; ln -sf $(word 1,$(p)) $(TARGET_ROOT_OUT)/$(word 2,$(p)))
+endif
include $(BUILD_SYSTEM)/base_rules.mk