Merge changes If2510ab3,I811f3109

* changes:
  MediaMetrics: Add copy constructor to TransactionLog
  MediaMetrics: Add copy constructor to TimeMachine
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index 8682360..4d24ce4 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -60,7 +60,7 @@
  *
  * The TimeMachine is NOT thread safe.
  */
-class TimeMachine {
+class TimeMachine final { // made final as we have copy constructor instead of dup() override.
 public:
     using Elem = Item::Prop::Elem;  // use the Item property element.
     using PropertyHistory = std::multimap<int64_t /* time */, Elem>;
@@ -84,6 +84,8 @@
             putValue(BUNDLE_UID, (int32_t)uid, time);
         }
 
+        KeyHistory(const KeyHistory &other) = default;
+
         status_t checkPermission(uid_t uidCheck) const {
             return uidCheck != (uid_t)-1 && uidCheck != mUid ? PERMISSION_DENIED : NO_ERROR;
         }
@@ -189,6 +191,34 @@
                   __func__, keyHighWaterMark, keyLowWaterMark);
     }
 
+    // The TimeMachine copy constructor/assignment uses a deep copy,
+    // though the snapshot is not instantaneous nor isochronous.
+    //
+    // If there are concurrent operations ongoing in the other TimeMachine
+    // then there may be some history more recent than others (a time shear).
+    // This is expected to be a benign addition in history as small number of
+    // future elements are incorporated.
+    TimeMachine(const TimeMachine& other) {
+        *this = other;
+    }
+    TimeMachine& operator=(const TimeMachine& other) {
+        std::lock_guard lock(mLock);
+        mHistory.clear();
+
+        {
+            std::lock_guard lock2(other.mLock);
+            mHistory = other.mHistory;
+        }
+
+        // Now that we safely have our own shared pointers, let's dup them
+        // to ensure they are decoupled.  We do this by acquiring the other lock.
+        for (const auto &[lkey, lhist] : mHistory) {
+            std::lock_guard lock2(other.getLockForKey(lkey));
+            mHistory[lkey] = std::make_shared<KeyHistory>(*lhist);
+        }
+        return *this;
+    }
+
     /**
      * Put all the properties from an item into the Time Machine log.
      */
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 7a520d9..0c5d12b 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -36,7 +36,7 @@
  *
  * The TransactionLog is NOT thread safe.
  */
-class TransactionLog {
+class TransactionLog final { // made final as we have copy constructor instead of dup() override.
 public:
     // In long term run, the garbage collector aims to keep the
     // Transaction Log between the Low Water Mark and the High Water Mark.
@@ -58,6 +58,30 @@
                   __func__, highWaterMark, lowWaterMark);
     }
 
+    // The TransactionLog copy constructor/assignment is effectively an
+    // instantaneous, isochronous snapshot of the other TransactionLog.
+    //
+    // The contents of the Transaction Log are shared pointers to immutable instances -
+    // std::shared_ptr<const mediametrics::Item>, so we use a shallow copy,
+    // which is more efficient in space and execution time than a deep copy,
+    // and gives the same results.
+
+    TransactionLog(const TransactionLog &other) {
+        *this = other;
+    }
+
+    TransactionLog& operator=(const TransactionLog &other) {
+        std::lock_guard lock(mLock);
+        mLog.clear();
+        mItemMap.clear();
+
+        std::lock_guard lock2(other.mLock);
+        mLog = other.mLog;
+        mItemMap = other.mItemMap;
+
+        return *this;
+    }
+
     /**
      * Put an item in the TransactionLog.
      */