Make CFX_Observable copy constructable.

Fix some naming to make things clearer.

Review-Url: https://codereview.chromium.org/2587233002
diff --git a/core/fxcrt/cfx_observable.h b/core/fxcrt/cfx_observable.h
index dc869b1..8dc0907 100644
--- a/core/fxcrt/cfx_observable.h
+++ b/core/fxcrt/cfx_observable.h
@@ -15,39 +15,42 @@
  public:
   class ObservedPtr {
    public:
-    ObservedPtr() : m_pObservedPtr(nullptr) {}
-    explicit ObservedPtr(T* pObservedPtr) : m_pObservedPtr(pObservedPtr) {
-      if (m_pObservedPtr)
-        m_pObservedPtr->AddObservedPtr(this);
+    ObservedPtr() : m_pObservable(nullptr) {}
+    explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) {
+      if (m_pObservable)
+        m_pObservable->AddObservedPtr(this);
     }
-    ObservedPtr(const ObservedPtr& that) = delete;
+    ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {}
     ~ObservedPtr() {
-      if (m_pObservedPtr)
-        m_pObservedPtr->RemoveObservedPtr(this);
+      if (m_pObservable)
+        m_pObservable->RemoveObservedPtr(this);
     }
-    void Reset(T* pObservedPtr = nullptr) {
-      if (m_pObservedPtr)
-        m_pObservedPtr->RemoveObservedPtr(this);
-      m_pObservedPtr = pObservedPtr;
-      if (m_pObservedPtr)
-        m_pObservedPtr->AddObservedPtr(this);
+    void Reset(T* pObservable = nullptr) {
+      if (m_pObservable)
+        m_pObservable->RemoveObservedPtr(this);
+      m_pObservable = pObservable;
+      if (m_pObservable)
+        m_pObservable->AddObservedPtr(this);
     }
     void OnDestroy() {
-      ASSERT(m_pObservedPtr);
-      m_pObservedPtr = nullptr;
+      ASSERT(m_pObservable);
+      m_pObservable = nullptr;
     }
-    ObservedPtr& operator=(const ObservedPtr& that) = delete;
+    ObservedPtr& operator=(const ObservedPtr& that) {
+      Reset(that.Get());
+      return *this;
+    }
     bool operator==(const ObservedPtr& that) const {
-      return m_pObservedPtr == that.m_pObservedPtr;
+      return m_pObservable == that.m_pObservable;
     }
     bool operator!=(const ObservedPtr& that) const { return !(*this == that); }
-    explicit operator bool() const { return !!m_pObservedPtr; }
-    T* Get() const { return m_pObservedPtr; }
-    T& operator*() const { return *m_pObservedPtr; }
-    T* operator->() const { return m_pObservedPtr; }
+    explicit operator bool() const { return !!m_pObservable; }
+    T* Get() const { return m_pObservable; }
+    T& operator*() const { return *m_pObservable; }
+    T* operator->() const { return m_pObservable; }
 
    private:
-    T* m_pObservedPtr;
+    T* m_pObservable;
   };
 
   CFX_Observable() {}
diff --git a/core/fxcrt/cfx_observable_unittest.cpp b/core/fxcrt/cfx_observable_unittest.cpp
index 15c7649..3c0fabb 100644
--- a/core/fxcrt/cfx_observable_unittest.cpp
+++ b/core/fxcrt/cfx_observable_unittest.cpp
@@ -5,6 +5,7 @@
 #include "core/fxcrt/cfx_observable.h"
 
 #include <utility>
+#include <vector>
 
 #include "testing/fx_string_testhelpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -44,6 +45,77 @@
   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
 }
 
+TEST(fxcrt, ObserveCopyConstruct) {
+  PseudoObservable obs;
+  {
+    PseudoObservable::ObservedPtr ptr(&obs);
+    EXPECT_NE(nullptr, ptr.Get());
+    EXPECT_EQ(1u, obs.ActiveObservedPtrs());
+    {
+      PseudoObservable::ObservedPtr ptr2(ptr);
+      EXPECT_NE(nullptr, ptr2.Get());
+      EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+    }
+    EXPECT_EQ(1u, obs.ActiveObservedPtrs());
+  }
+  EXPECT_EQ(0u, obs.ActiveObservedPtrs());
+}
+
+TEST(fxcrt, ObserveCopyAssign) {
+  PseudoObservable obs;
+  {
+    PseudoObservable::ObservedPtr ptr(&obs);
+    EXPECT_NE(nullptr, ptr.Get());
+    EXPECT_EQ(1u, obs.ActiveObservedPtrs());
+    {
+      PseudoObservable::ObservedPtr ptr2;
+      ptr2 = ptr;
+      EXPECT_NE(nullptr, ptr2.Get());
+      EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+    }
+    EXPECT_EQ(1u, obs.ActiveObservedPtrs());
+  }
+  EXPECT_EQ(0u, obs.ActiveObservedPtrs());
+}
+
+TEST(fxcrt, ObserveVector) {
+  PseudoObservable obs;
+  {
+    std::vector<PseudoObservable::ObservedPtr> vec1;
+    std::vector<PseudoObservable::ObservedPtr> vec2;
+    vec1.emplace_back(&obs);
+    vec1.emplace_back(&obs);
+    EXPECT_NE(nullptr, vec1[0].Get());
+    EXPECT_NE(nullptr, vec1[1].Get());
+    EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+    vec2 = vec1;
+    EXPECT_NE(nullptr, vec2[0].Get());
+    EXPECT_NE(nullptr, vec2[1].Get());
+    EXPECT_EQ(4u, obs.ActiveObservedPtrs());
+    vec1.clear();
+    EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+    vec2.resize(10000);
+    EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+    vec2.resize(0);
+    EXPECT_EQ(0u, obs.ActiveObservedPtrs());
+  }
+  EXPECT_EQ(0u, obs.ActiveObservedPtrs());
+}
+
+TEST(fxcrt, ObserveVectorAutoClear) {
+  std::vector<PseudoObservable::ObservedPtr> vec1;
+  {
+    PseudoObservable obs;
+    vec1.emplace_back(&obs);
+    vec1.emplace_back(&obs);
+    EXPECT_NE(nullptr, vec1[0].Get());
+    EXPECT_NE(nullptr, vec1[1].Get());
+    EXPECT_EQ(2u, obs.ActiveObservedPtrs());
+  }
+  EXPECT_EQ(nullptr, vec1[0].Get());
+  EXPECT_EQ(nullptr, vec1[1].Get());
+}
+
 TEST(fxcrt, ObservePtrResetNull) {
   PseudoObservable obs;
   PseudoObservable::ObservedPtr ptr(&obs);