Merge "Limit btsnoop file size (1/9)" into oc-dev
diff --git a/include/hardware/ble_advertiser.h b/include/hardware/ble_advertiser.h
index 8abca00..02d553f 100644
--- a/include/hardware/ble_advertiser.h
+++ b/include/hardware/ble_advertiser.h
@@ -57,6 +57,9 @@
   /** Registers an advertiser with the stack */
   virtual void RegisterAdvertiser(IdStatusCallback) = 0;
 
+  using GetAddressCallback = base::Callback<void(uint8_t /* address_type*/, bt_bdaddr_t /*address*/)>;
+  virtual void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) = 0;
+
   /* Set the parameters as per spec, user manual specified values */
   virtual void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
                              ParametersCallback cb) = 0;
diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h
index ec8dd16..33a6825 100644
--- a/include/hardware/bt_gatt_client.h
+++ b/include/hardware/bt_gatt_client.h
@@ -224,8 +224,13 @@
     bt_status_t (*search_service)(int conn_id, bt_uuid_t *filter_uuid );
 
     /** Read a characteristic on a remote device */
-    bt_status_t (*read_characteristic)( int conn_id, uint16_t handle,
-                    int auth_req );
+    bt_status_t (*read_characteristic)(int conn_id, uint16_t handle,
+                                       int auth_req);
+
+    /** Read a characteristic on a remote device */
+    bt_status_t (*read_using_characteristic_uuid)(
+        int conn_id, bt_uuid_t *uuid, uint16_t s_handle,
+        uint16_t e_handle, int auth_req);
 
     /** Write a remote characteristic */
     bt_status_t (*write_characteristic)(int conn_id, uint16_t handle,
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
index 67a6f27..c51e912 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -105,30 +105,35 @@
 // FileConnectionDetector functions
 FileConnectionDetector::FileConnectionDetector (
         BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex)
-            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex) {
+            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex),
+              mLooper(new Looper(true /*allowNonCallback*/)), mInotifyFd(-1) {
+    if (mLooper == nullptr) {
+        return;
+    }
+
     mInotifyFd = ::inotify_init1(IN_NONBLOCK);
     if (mInotifyFd < 0) {
         ALOGE("Cannot init inotify");
         return;
     }
 
-    int wd = ::inotify_add_watch(mInotifyFd, path.c_str(), IN_CREATE | IN_DELETE | IN_MOVED_FROM);
-    if (wd < 0) {
+    int wd = ::inotify_add_watch(mInotifyFd, path.c_str(), IN_CREATE | IN_DELETE);
+    if (wd < 0 || !mLooper->addFd(mInotifyFd, POLL_IDENT, Looper::EVENT_INPUT, nullptr, nullptr)) {
         ::close(mInotifyFd);
         mInotifyFd = -1;
         ALOGE("Cannot setup watch on dir %s", path.c_str());
         return;
     }
 
-    mPollFd.fd = wd;
-    mPollFd.events = POLLIN;
-
+    // mLooper != null && mInotifyFd added to looper
     run("ddad_file");
 }
 
 FileConnectionDetector::~FileConnectionDetector() {
-    if (mInotifyFd) {
-        requestExitAndWait();
+    if (mInotifyFd > 0) {
+        requestExit();
+        mLooper->wake();
+        join();
         ::close(mInotifyFd);
     }
 }
@@ -153,63 +158,81 @@
     ::closedir(dirp);
 }
 
-bool FileConnectionDetector::threadLoop() {
-    struct {
-        struct inotify_event e;
-        uint8_t padding[NAME_MAX + 1];
-    } ev;
+void FileConnectionDetector::handleInotifyData(ssize_t len, const char *data) {
+    const char *dataEnd = data + len;
+    const struct inotify_event *ev;
 
-    processExistingFiles();
-
-    while (!Thread::exitPending()) {
-        int pollNum = ::poll(&mPollFd, 1, -1);
-        if (pollNum == -1) {
-           if (errno == EINTR)
-               continue;
-           ALOGE("inotify poll error: %s", ::strerror(errno));
+    // inotify adds paddings to guarantee the next read is aligned
+    for (; data < dataEnd; data += sizeof(struct inotify_event) + ev->len) {
+        ev = reinterpret_cast<const struct inotify_event*>(data);
+        if (ev->mask & IN_ISDIR) {
+            continue;
         }
 
-        if (pollNum > 0) {
-            if (! (mPollFd.revents & POLLIN)) {
-                continue;
+        const std::string name(ev->name);
+        if (matches(name)) {
+            if (ev->mask & IN_CREATE) {
+                mDaemon->onConnectionChange(getFullName(name), true /*connected*/);
             }
+            if (ev->mask & IN_DELETE) {
+                mDaemon->onConnectionChange(getFullName(name), false /*connected*/);
+            }
+        }
+    }
+}
 
-            /* Inotify events are available */
-            while (true) {
-                /* Read some events. */
-                ssize_t len = ::read(mInotifyFd, &ev, sizeof ev);
-                if (len == -1 && errno != EAGAIN) {
-                    ALOGE("read error: %s", ::strerror(errno));
-                    requestExit();
-                    break;
-                }
+bool FileConnectionDetector::readInotifyData() {
+    struct {
+        struct inotify_event ev;
+        char padding[NAME_MAX + 1];
+    } buffer;
 
-                /* If the nonblocking read() found no events to read, then
-                   it returns -1 with errno set to EAGAIN. In that case,
-                   we exit the loop. */
-                if (len <= 0) {
-                    break;
-                }
+    bool ret = true;
+    while (true) {
+        ssize_t len = ::read(mInotifyFd, &buffer, sizeof(buffer));
+        if (len == -1 && errno == EAGAIN) {
+            // no more data
+            break;
+        } else if (len > static_cast<ssize_t>(sizeof(struct inotify_event))) {
+            handleInotifyData(len, reinterpret_cast<char*>(&buffer));
+        } else if (len < 0) {
+            ALOGE("read error: %s", ::strerror(errno));
+            ret = false;
+            break;
+        } else {
+            // 0 <= len <= sizeof(struct inotify_event)
+            ALOGE("read return %zd, shorter than inotify_event size %zu",
+                  len, sizeof(struct inotify_event));
+            ret = false;
+            break;
+        }
+    }
+    return ret;
+}
 
-                if (ev.e.len && !(ev.e.mask & IN_ISDIR)) {
-                    const std::string name(ev.e.name);
-                    ALOGV("device %s state changed", name.c_str());
-                    if (matches(name)) {
-                        if (ev.e.mask & IN_CREATE) {
-                            mDaemon->onConnectionChange(getFullName(name), true /* connected*/);
-                        }
+bool FileConnectionDetector::threadLoop() {
+    Looper::setForThread(mLooper);
+    processExistingFiles();
+    while(!Thread::exitPending()) {
+        int ret = mLooper->pollOnce(-1);
 
-                        if (ev.e.mask & IN_DELETE || ev.e.mask & IN_MOVED_FROM) {
-                            mDaemon->onConnectionChange(getFullName(name), false /* connected*/);
-                        }
-                    }
-                }
+        if (ret != Looper::POLL_WAKE && ret != POLL_IDENT) {
+            ALOGE("Unexpected value %d from pollOnce, quit", ret);
+            requestExit();
+            break;
+        }
+
+        if (ret == POLL_IDENT) {
+            if (!readInotifyData()) {
+                requestExit();
             }
         }
     }
 
+    mLooper->removeFd(mInotifyFd);
     ALOGD("FileConnectionDetection thread exited");
     return false;
 }
+
 } // namespace SensorHalExt
 } // namespace android
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.h b/modules/sensors/dynamic_sensor/ConnectionDetector.h
index 712d832..0ee1df2 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.h
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.h
@@ -19,6 +19,7 @@
 
 #include "BaseDynamicSensorDaemon.h"
 #include <utils/Thread.h>
+#include <utils/Looper.h>
 
 #include <regex>
 
@@ -62,17 +63,20 @@
             BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex);
     virtual ~FileConnectionDetector();
 private:
+    static constexpr int POLL_IDENT = 1;
     // implement virtual of Thread
     virtual bool threadLoop();
 
     bool matches(const std::string &name) const;
     void processExistingFiles() const;
+    void handleInotifyData(ssize_t len, const char *data);
+    bool readInotifyData();
     std::string getFullName(const std::string name) const;
 
     std::string mPath;
     std::regex mRegex;
+    sp<Looper> mLooper;
     int mInotifyFd;
-    struct pollfd mPollFd;
 };
 
 } // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
index 16e9060..8aa4cf9 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
@@ -37,7 +37,7 @@
 
 sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) {
     sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName));
-    // remove +1 strong count added by constructor
+    // offset +1 strong count added by constructor
     device->decStrong(device.get());
 
     if (device->mValid) {
@@ -50,13 +50,15 @@
 HidRawSensorDevice::HidRawSensorDevice(const std::string &devName)
         : RefBase(), HidRawDevice(devName, sInterested),
           Thread(false /*canCallJava*/), mValid(false) {
-    if (!HidRawDevice::isValid()) {
-        return;
-    }
     // create HidRawSensor objects from digest
     // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count
     // to prevent "this" being destructed.
     this->incStrong(this);
+
+    if (!HidRawDevice::isValid()) {
+        return;
+    }
+
     for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair
         uint32_t usage = static_cast<uint32_t>(digest.fullUsage);
         sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets));
diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp
index 2810118..887a4ba 100644
--- a/modules/sensors/multihal.cpp
+++ b/modules/sensors/multihal.cpp
@@ -500,15 +500,32 @@
  * The vector must not be null.
  */
 static void get_so_paths(std::vector<std::string> *so_paths) {
-    std::string line;
-    std::ifstream conf_file(MULTI_HAL_CONFIG_FILE_PATH);
+    const std::vector<const char *> config_path_list(
+            { MULTI_HAL_CONFIG_FILE_PATH, DEPRECATED_MULTI_HAL_CONFIG_FILE_PATH });
 
-    if(!conf_file) {
-        ALOGW("No multihal config file found at %s", MULTI_HAL_CONFIG_FILE_PATH);
+    std::ifstream stream;
+    const char *path = nullptr;
+    for (auto i : config_path_list) {
+        std::ifstream f(i);
+        if (f) {
+            stream = std::move(f);
+            path = i;
+            break;
+        }
+    }
+    if(!stream) {
+        ALOGW("No multihal config file found");
         return;
     }
-    ALOGV("Multihal config file found at %s", MULTI_HAL_CONFIG_FILE_PATH);
-    while (std::getline(conf_file, line)) {
+
+    ALOGE_IF(strcmp(path, DEPRECATED_MULTI_HAL_CONFIG_FILE_PATH) == 0,
+            "Multihal configuration file path %s is not compatible with Treble "
+            "requirements. Please move it to %s.",
+            path, MULTI_HAL_CONFIG_FILE_PATH);
+
+    ALOGV("Multihal config file found at %s", path);
+    std::string line;
+    while (std::getline(stream, line)) {
         ALOGV("config file line: '%s'", line.c_str());
         so_paths->push_back(line);
     }
diff --git a/modules/sensors/multihal.h b/modules/sensors/multihal.h
index 210c7cc..234f2f0 100644
--- a/modules/sensors/multihal.h
+++ b/modules/sensors/multihal.h
@@ -19,7 +19,10 @@
 #include <hardware/sensors.h>
 #include <hardware/hardware.h>
 
-static const char* MULTI_HAL_CONFIG_FILE_PATH = "/system/etc/sensors/hals.conf";
+static const char* MULTI_HAL_CONFIG_FILE_PATH = "/vendor/etc/sensors/hals.conf";
+
+// Depracated because system partition HAL config file does not satisfy treble requirements.
+static const char* DEPRECATED_MULTI_HAL_CONFIG_FILE_PATH = "/system/etc/sensors/hals.conf";
 
 struct sensors_module_t *get_multi_hal_module_info(void);
 
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index 6a3c5da..df4bc0f 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -933,7 +933,7 @@
                                   struct audio_config *config,
                                   struct audio_stream_in **stream_in,
                                   audio_input_flags_t flags __unused,
-                                  const char *address /*__unused*/,
+                                  const char *address,
                                   audio_source_t source __unused)
 {
     ALOGV("adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
@@ -989,7 +989,7 @@
         ret = config->sample_rate != in->adev->device_sample_rate ? -EINVAL : 0;
         proxy_config.rate = config->sample_rate = in->adev->device_sample_rate;
     } else if (profile_is_sample_rate_valid(in->profile, config->sample_rate)) {
-        in->adev->device_sample_rate = proxy_config.rate = config->sample_rate;
+        proxy_config.rate = config->sample_rate;
     } else {
         proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile);
         ret = -EINVAL;
@@ -1053,18 +1053,29 @@
         // and store THAT in proxy_config.channels
         proxy_config.channels =
                 profile_get_closest_channel_count(in->profile, in->hal_channel_count);
-        proxy_prepare(&in->proxy, in->profile, &proxy_config);
+        ret = proxy_prepare(&in->proxy, in->profile, &proxy_config);
+        if (ret == 0) {
+            in->standby = true;
 
-        in->standby = true;
+            in->conversion_buffer = NULL;
+            in->conversion_buffer_size = 0;
 
-        in->conversion_buffer = NULL;
-        in->conversion_buffer_size = 0;
+            *stream_in = &in->stream;
 
-        *stream_in = &in->stream;
+            /* Save this for adev_dump() */
+            adev_add_stream_to_list(in->adev, &in->adev->input_stream_list, &in->list_node);
+        } else {
+            ALOGW("proxy_prepare error %d", ret);
+            unsigned channel_count = proxy_get_channel_count(&in->proxy);
+            config->channel_mask = channel_count <= FCC_2
+                ? audio_channel_in_mask_from_count(channel_count)
+                : audio_channel_mask_for_index_assignment_from_count(channel_count);
+            config->format = audio_format_from_pcm_format(proxy_get_format(&in->proxy));
+            config->sample_rate = proxy_get_sample_rate(&in->proxy);
+        }
+    }
 
-        /* Save this for adev_dump() */
-        adev_add_stream_to_list(in->adev, &in->adev->input_stream_list, &in->list_node);
-    } else {
+    if (ret != 0) {
         // Deallocate this stream on error, because AudioFlinger won't call
         // adev_close_input_stream() in this case.
         *stream_in = NULL;