Merge "Move adb/fastboot bash completion into adb/fastboot."
diff --git a/adb/test_adb.py b/adb/test_adb.py
index e771106..3bb433d 100644
--- a/adb/test_adb.py
+++ b/adb/test_adb.py
@@ -162,15 +162,14 @@
 
         Bug: https://code.google.com/p/android/issues/detail?id=21021
         """
-        port = 12345
-
         with contextlib.closing(
                 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as listener:
             # Use SO_REUSEADDR so subsequent runs of the test can grab the port
             # even if it is in TIME_WAIT.
             listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-            listener.bind(('127.0.0.1', port))
+            listener.bind(('127.0.0.1', 0))
             listener.listen(4)
+            port = listener.getsockname()[1]
 
             # Now that listening has started, start adb emu kill, telling it to
             # connect to our mock emulator.
@@ -233,6 +232,24 @@
                 output.strip(), 'connected to localhost:{}'.format(port))
             s.close()
 
+    def test_already_connected(self):
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.bind(('127.0.0.1', 0))
+        s.listen(2)
+
+        port = s.getsockname()[1]
+        output = subprocess.check_output(
+            ['adb', 'connect', 'localhost:{}'.format(port)])
+
+        self.assertEqual(
+            output.strip(), 'connected to localhost:{}'.format(port))
+
+        # b/31250450: this always returns 0 but probably shouldn't.
+        output = subprocess.check_output(
+            ['adb', 'connect', 'localhost:{}'.format(port)])
+
+        self.assertEqual(
+            output.strip(), 'already connected to localhost:{}'.format(port))
 
 def main():
     random.seed(0)
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 37b56e2..2867d38 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -77,7 +77,15 @@
     Stop();
 }
 
+static void AssumeLocked(std::mutex& mutex) ASSERT_CAPABILITY(mutex) {}
+
 void BlockingConnectionAdapter::Start() {
+    std::lock_guard<std::mutex> lock(mutex_);
+    if (started_) {
+        LOG(FATAL) << "BlockingConnectionAdapter(" << this->transport_name_
+                   << "): started multiple times";
+    }
+
     read_thread_ = std::thread([this]() {
         LOG(INFO) << this->transport_name_ << ": read thread spawning";
         while (true) {
@@ -95,7 +103,11 @@
         LOG(INFO) << this->transport_name_ << ": write thread spawning";
         while (true) {
             std::unique_lock<std::mutex> lock(mutex_);
-            cv_.wait(lock, [this]() { return this->stopped_ || !this->write_queue_.empty(); });
+            cv_.wait(lock, [this]() REQUIRES(mutex_) {
+                return this->stopped_ || !this->write_queue_.empty();
+            });
+
+            AssumeLocked(mutex_);
 
             if (this->stopped_) {
                 return;
@@ -111,25 +123,44 @@
         }
         std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "write failed"); });
     });
+
+    started_ = true;
 }
 
 void BlockingConnectionAdapter::Stop() {
-    std::unique_lock<std::mutex> lock(mutex_);
-    if (stopped_) {
-        LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): already stopped";
-        return;
-    }
+    {
+        std::lock_guard<std::mutex> lock(mutex_);
+        if (!started_) {
+            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): not started";
+            return;
+        }
 
-    stopped_ = true;
-    lock.unlock();
+        if (stopped_) {
+            LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_
+                      << "): already stopped";
+            return;
+        }
+
+        stopped_ = true;
+    }
 
     LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopping";
 
     this->underlying_->Close();
-
     this->cv_.notify_one();
-    read_thread_.join();
-    write_thread_.join();
+
+    // Move the threads out into locals with the lock taken, and then unlock to let them exit.
+    std::thread read_thread;
+    std::thread write_thread;
+
+    {
+        std::lock_guard<std::mutex> lock(mutex_);
+        read_thread = std::move(read_thread_);
+        write_thread = std::move(write_thread_);
+    }
+
+    read_thread.join();
+    write_thread.join();
 
     LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopped";
     std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "requested stop"); });
@@ -137,7 +168,7 @@
 
 bool BlockingConnectionAdapter::Write(std::unique_ptr<apacket> packet) {
     {
-        std::unique_lock<std::mutex> lock(this->mutex_);
+        std::lock_guard<std::mutex> lock(this->mutex_);
         write_queue_.emplace_back(std::move(packet));
     }
 
diff --git a/adb/transport.h b/adb/transport.h
index 8b71e34..d18c362 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -30,6 +30,7 @@
 #include <thread>
 #include <unordered_set>
 
+#include <android-base/thread_annotations.h>
 #include <openssl/rsa.h>
 
 #include "adb.h"
@@ -121,13 +122,14 @@
     virtual void Start() override final;
     virtual void Stop() override final;
 
-    bool stopped_ = false;
+    bool started_ GUARDED_BY(mutex_) = false;
+    bool stopped_ GUARDED_BY(mutex_) = false;
 
     std::unique_ptr<BlockingConnection> underlying_;
-    std::thread read_thread_;
-    std::thread write_thread_;
+    std::thread read_thread_ GUARDED_BY(mutex_);
+    std::thread write_thread_ GUARDED_BY(mutex_);
 
-    std::deque<std::unique_ptr<apacket>> write_queue_;
+    std::deque<std::unique_ptr<apacket>> write_queue_ GUARDED_BY(mutex_);
     std::mutex mutex_;
     std::condition_variable cv_;
 
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 9c6fed4..d2d6ab8 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -149,13 +149,12 @@
   }
 
   // Create the process memory from the stack data.
-  uint64_t size = stack.end - stack.start;
-  unwindstack::MemoryBuffer* memory = new unwindstack::MemoryBuffer;
-  memory->Resize(size);
-  memcpy(memory->GetPtr(0), stack.data, size);
-  std::shared_ptr<unwindstack::Memory> shared_memory(memory);
-
-  process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
+  if (memory_ == nullptr) {
+    memory_ = new unwindstack::MemoryOfflineBuffer(stack.data, stack.start, stack.end);
+    process_memory_.reset(memory_);
+  } else {
+    memory_->Reset(stack.data, stack.start, stack.end);
+  }
   return true;
 }
 
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index ec0d9c1..039f4a2 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -79,6 +79,9 @@
   bool Build(const std::vector<backtrace_map_t>& maps);
 
   bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
+
+ private:
+  unwindstack::MemoryOfflineBuffer* memory_ = nullptr;
 };
 
 #endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 0d43f87..6868f18 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -155,6 +155,7 @@
         "tests/MemoryFake.cpp",
         "tests/MemoryFileTest.cpp",
         "tests/MemoryLocalTest.cpp",
+        "tests/MemoryOfflineBufferTest.cpp",
         "tests/MemoryOfflineTest.cpp",
         "tests/MemoryRangeTest.cpp",
         "tests/MemoryRemoteTest.cpp",
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index d4ba680..beb2aad 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -345,6 +345,25 @@
   return memory_->Read(addr, dst, size);
 }
 
+MemoryOfflineBuffer::MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end)
+    : data_(data), start_(start), end_(end) {}
+
+void MemoryOfflineBuffer::Reset(const uint8_t* data, uint64_t start, uint64_t end) {
+  data_ = data;
+  start_ = start;
+  end_ = end;
+}
+
+size_t MemoryOfflineBuffer::Read(uint64_t addr, void* dst, size_t size) {
+  if (addr < start_ || addr >= end_) {
+    return 0;
+  }
+
+  size_t read_length = std::min(size, static_cast<size_t>(end_ - addr));
+  memcpy(dst, &data_[addr - start_], read_length);
+  return read_length;
+}
+
 MemoryOfflineParts::~MemoryOfflineParts() {
   for (auto memory : memories_) {
     delete memory;
diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h
index 19bce04..c0c07f4 100644
--- a/libunwindstack/include/unwindstack/Memory.h
+++ b/libunwindstack/include/unwindstack/Memory.h
@@ -151,6 +151,21 @@
   std::unique_ptr<MemoryRange> memory_;
 };
 
+class MemoryOfflineBuffer : public Memory {
+ public:
+  MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end);
+  virtual ~MemoryOfflineBuffer() = default;
+
+  void Reset(const uint8_t* data, uint64_t start, uint64_t end);
+
+  size_t Read(uint64_t addr, void* dst, size_t size) override;
+
+ private:
+  const uint8_t* data_;
+  uint64_t start_;
+  uint64_t end_;
+};
+
 class MemoryOfflineParts : public Memory {
  public:
   MemoryOfflineParts() = default;
diff --git a/libunwindstack/tests/MemoryOfflineBufferTest.cpp b/libunwindstack/tests/MemoryOfflineBufferTest.cpp
new file mode 100644
index 0000000..f022884
--- /dev/null
+++ b/libunwindstack/tests/MemoryOfflineBufferTest.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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 <vector>
+
+#include <gtest/gtest.h>
+
+#include <unwindstack/Memory.h>
+
+#include "LogFake.h"
+
+namespace unwindstack {
+
+class MemoryOfflineBufferTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    ResetLogs();
+    memory_.reset(new MemoryOfflineBuffer(buffer_.data(), kStart, kEnd));
+  }
+
+  static void SetUpTestCase() {
+    buffer_.resize(kLength);
+    for (size_t i = 0; i < kLength; i++) {
+      buffer_[i] = i % 189;
+    }
+  }
+
+  std::unique_ptr<MemoryOfflineBuffer> memory_;
+
+  static constexpr size_t kLength = 0x2000;
+  static constexpr uint64_t kStart = 0x1000;
+  static constexpr uint64_t kEnd = kStart + kLength;
+  static std::vector<uint8_t> buffer_;
+};
+
+std::vector<uint8_t> MemoryOfflineBufferTest::buffer_;
+
+static void VerifyBuffer(uint8_t* buffer, size_t start_value, size_t length) {
+  for (size_t i = 0; i < length; i++) {
+    ASSERT_EQ((start_value + i) % 189, buffer[i]) << "Failed at byte " << i;
+  }
+}
+
+TEST_F(MemoryOfflineBufferTest, read_out_of_bounds) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_FALSE(memory_->ReadFully(0, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0xfff, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0xfff, buffer.data(), 2));
+  ASSERT_FALSE(memory_->ReadFully(0x3000, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0x3001, buffer.data(), 1));
+}
+
+TEST_F(MemoryOfflineBufferTest, read) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_TRUE(memory_->ReadFully(kStart, buffer.data(), 10));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0, 10));
+
+  ASSERT_TRUE(memory_->ReadFully(kStart + 555, buffer.data(), 40));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 555, 40));
+
+  ASSERT_TRUE(memory_->ReadFully(kStart + kLength - 105, buffer.data(), 105));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), kLength - 105, 105));
+}
+
+TEST_F(MemoryOfflineBufferTest, read_past_end) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_EQ(100U, memory_->Read(kStart + kLength - 100, buffer.data(), buffer.size()));
+  VerifyBuffer(buffer.data(), kLength - 100, 100);
+}
+
+TEST_F(MemoryOfflineBufferTest, read_after_reset) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_TRUE(memory_->ReadFully(kStart, buffer.data(), 100));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0, 100));
+
+  memory_->Reset(&buffer_[10], 0x12000, 0x13000);
+  ASSERT_TRUE(memory_->ReadFully(0x12000, buffer.data(), 100));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 10, 100));
+
+  ASSERT_EQ(50U, memory_->Read(0x13000 - 50, buffer.data(), buffer.size()));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0x1000 - 50 + 10, 50));
+}
+
+}  // namespace unwindstack