Merge "A couple recoverymap fixes."
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d741c99..a2ed8aa 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -982,14 +982,16 @@
 
 class SyncCallback {
 public:
-    static void function(void* callbackContext, nsecs_t /* latchTime */,
-                         const sp<Fence>& /* presentFence */,
-                         const std::vector<SurfaceControlStats>& /* stats */) {
-        if (!callbackContext) {
-            ALOGE("failed to get callback context for SyncCallback");
-        }
-        SyncCallback* helper = static_cast<SyncCallback*>(callbackContext);
-        LOG_ALWAYS_FATAL_IF(sem_post(&helper->mSemaphore), "sem_post failed");
+    static auto getCallback(std::shared_ptr<SyncCallback>& callbackContext) {
+        return [callbackContext](void* /* unused context */, nsecs_t /* latchTime */,
+                                 const sp<Fence>& /* presentFence */,
+                                 const std::vector<SurfaceControlStats>& /* stats */) {
+            if (!callbackContext) {
+                ALOGE("failed to get callback context for SyncCallback");
+                return;
+            }
+            LOG_ALWAYS_FATAL_IF(sem_post(&callbackContext->mSemaphore), "sem_post failed");
+        };
     }
     ~SyncCallback() {
         if (mInitialized) {
@@ -1024,10 +1026,11 @@
         return mStatus;
     }
 
-    SyncCallback syncCallback;
+    std::shared_ptr<SyncCallback> syncCallback = std::make_shared<SyncCallback>();
     if (synchronous) {
-        syncCallback.init();
-        addTransactionCommittedCallback(syncCallback.function, syncCallback.getContext());
+        syncCallback->init();
+        addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback),
+                                        /*callbackContext=*/nullptr);
     }
 
     bool hasListenerCallbacks = !mListenerCallbacks.empty();
@@ -1103,7 +1106,7 @@
     clear();
 
     if (synchronous) {
-        syncCallback.wait();
+        syncCallback->wait();
     }
 
     mStatus = NO_ERROR;
@@ -2155,6 +2158,12 @@
     mStatus = NO_INIT;
 }
 
+status_t SurfaceComposerClient::bootFinished() {
+    sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
+    binder::Status status = sf->bootFinished();
+    return statusTFromBinderStatus(status);
+}
+
 sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                         PixelFormat format, int32_t flags,
                                                         const sp<IBinder>& parentHandle,
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 488a148..a0b613c 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -62,8 +62,6 @@
      * Signal that we're done booting.
      * Requires ACCESS_SURFACE_FLINGER permission
      */
-    // Note this must be the 1st method, so IBinder::FIRST_CALL_TRANSACTION
-    // is assigned, as it is called from Java by ActivityManagerService.
     void bootFinished();
 
     /**
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 96d3a23..cc459c5 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -158,6 +158,9 @@
     status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
             void* cookie = nullptr, uint32_t flags = 0);
 
+    // Notify the SurfaceComposerClient that the boot procedure has completed
+    static status_t bootFinished();
+
     // Get transactional state of given display.
     static status_t getDisplayState(const sp<IBinder>& display, ui::DisplayState*);
 
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
index 74f9776..fca78a0 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
@@ -30,8 +30,9 @@
 
 // Transfer functions as defined for XMP metadata
 typedef enum {
-  JPEGR_TF_HLG = 0,
-  JPEGR_TF_PQ = 1,
+  JPEGR_TF_LINEAR = 0,
+  JPEGR_TF_HLG = 1,
+  JPEGR_TF_PQ = 2,
 } jpegr_transfer_function;
 
 struct jpegr_info_struct {
@@ -344,47 +345,6 @@
                                jr_compressed_ptr dest);
 
     /*
-     * This method generates XMP metadata.
-     *
-     * below is an example of the XMP metadata that this function generates where
-     * secondary_image_length = 1000
-     * range_scaling_factor = 1.25
-     *
-     * <x:xmpmeta
-     *   xmlns:x="adobe:ns:meta/"
-     *   x:xmptk="Adobe XMP Core 5.1.2">
-     *   <rdf:RDF
-     *     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-     *     <rdf:Description
-     *       xmlns:GContainer="http://ns.google.com/photos/1.0/container/">
-     *       <GContainer:Version>1</GContainer:Version>
-     *       <GContainer:RangeScalingFactor>1.25</GContainer:RangeScalingFactor>
-     *       <GContainer:Directory>
-     *         <rdf:Seq>
-     *           <rdf:li>
-     *             <GContainer:Item
-     *               Item:Semantic="Primary"
-     *               Item:Mime="image/jpeg"/>
-     *           </rdf:li>
-     *           <rdf:li>
-     *             <GContainer:Item
-     *               Item:Semantic="RecoveryMap"
-     *               Item:Mime="image/jpeg"
-     *               Item:Length="1000"/>
-     *           </rdf:li>
-     *         </rdf:Seq>
-     *       </GContainer:Directory>
-     *     </rdf:Description>
-     *   </rdf:RDF>
-     * </x:xmpmeta>
-     *
-     * @param secondary_image_length length of secondary image
-     * @param metadata JPEG/R metadata to encode as XMP
-     * @return XMP metadata in type of string
-     */
-    std::string generateXmp(int secondary_image_length, jpegr_metadata& metadata);
-
-    /*
      * This method will tone map a HDR image to an SDR image.
      *
      * @param uncompressed_p010_image (input) uncompressed P010 image
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
index e35f2d7..e61d0c4 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
@@ -17,10 +17,11 @@
 #ifndef ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
 #define ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
 
+#include <sstream>
 #include <stdint.h>
+#include <string>
 #include <cstdio>
 
-
 namespace android::recoverymap {
 
 struct jpegr_metadata;
@@ -35,6 +36,53 @@
 */
 bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata* metadata);
 
+/*
+ * This method generates XMP metadata.
+ *
+ * below is an example of the XMP metadata that this function generates where
+ * secondary_image_length = 1000
+ * range_scaling_factor = 1.25
+ *
+ * <x:xmpmeta
+ *   xmlns:x="adobe:ns:meta/"
+ *   x:xmptk="Adobe XMP Core 5.1.2">
+ *   <rdf:RDF
+ *     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ *     <rdf:Description
+ *       xmlns:GContainer="http://ns.google.com/photos/1.0/container/"
+ *       xmlns:RecoveryMap="http://ns.google.com/photos/1.0/recoverymap/">
+ *       <GContainer:Version>1</GContainer:Version>
+ *       <GContainer:Directory>
+ *         <rdf:Seq>
+ *           <rdf:li>
+ *             <GContainer:Item
+ *               Item:Semantic="Primary"
+ *               Item:Mime="image/jpeg"
+ *               RecoveryMap:Version=”1”
+ *               RecoveryMap:RangeScalingFactor=”1.25”
+ *               RecoveryMap:TransferFunction=”2”/>
+ *               <RecoveryMap:HDR10Metadata
+ *                 // some attributes
+ *                 // some elements
+ *               </RecoveryMap:HDR10Metadata>
+ *           </rdf:li>
+ *           <rdf:li>
+ *             <GContainer:Item
+ *               Item:Semantic="RecoveryMap"
+ *               Item:Mime="image/jpeg"
+ *               Item:Length="1000"/>
+ *           </rdf:li>
+ *         </rdf:Seq>
+ *       </GContainer:Directory>
+ *     </rdf:Description>
+ *   </rdf:RDF>
+ * </x:xmpmeta>
+ *
+ * @param secondary_image_length length of secondary image
+ * @param metadata JPEG/R metadata to encode as XMP
+ * @return XMP metadata in type of string
+ */
+std::string generateXmp(int secondary_image_length, jpegr_metadata& metadata);
 }
 
 #endif //ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
\ No newline at end of file
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index 74bb512..200ec99 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -21,7 +21,6 @@
 #include <jpegrecoverymap/recoverymaputils.h>
 
 #include <image_io/jpeg/jpeg_marker.h>
-#include <image_io/xml/xml_writer.h>
 #include <image_io/jpeg/jpeg_info.h>
 #include <image_io/jpeg/jpeg_scanner.h>
 #include <image_io/jpeg/jpeg_info_builder.h>
@@ -65,19 +64,6 @@
 };
 
 /*
- * Helper function used for generating XMP metadata.
- *
- * @param prefix The prefix part of the name.
- * @param suffix The suffix part of the name.
- * @return A name of the form "prefix:suffix".
- */
-string Name(const string &prefix, const string &suffix) {
-  std::stringstream ss;
-  ss << prefix << ":" << suffix;
-  return ss.str();
-}
-
-/*
  * Helper function used for writing data to destination.
  *
  * @param destination destination of the data to be written.
@@ -447,6 +433,9 @@
   ColorTransformFn hdrInvOetf = nullptr;
   float hdr_white_nits = 0.0f;
   switch (metadata->transferFunction) {
+    case JPEGR_TF_LINEAR:
+      hdrInvOetf = identityConversion;
+      break;
     case JPEGR_TF_HLG:
       hdrInvOetf = hlgInvOetf;
       hdr_white_nits = kHlgMaxNits;
@@ -544,6 +533,9 @@
 
   ColorTransformFn hdrOetf = nullptr;
   switch (metadata->transferFunction) {
+    case JPEGR_TF_LINEAR:
+      hdrOetf = identityConversion;
+      break;
     case JPEGR_TF_HLG:
       hdrOetf = hlgOetf;
       break;
@@ -680,57 +672,6 @@
   return NO_ERROR;
 }
 
-string RecoveryMap::generateXmp(int secondary_image_length, jpegr_metadata& metadata) {
-  const string kContainerPrefix = "GContainer";
-  const string kContainerUri    = "http://ns.google.com/photos/1.0/container/";
-  const string kItemPrefix      = "Item";
-  const string kRecoveryMap     = "RecoveryMap";
-  const string kDirectory       = "Directory";
-  const string kImageJpeg       = "image/jpeg";
-  const string kItem            = "Item";
-  const string kLength          = "Length";
-  const string kMime            = "Mime";
-  const string kPrimary         = "Primary";
-  const string kSemantic        = "Semantic";
-  const string kVersion         = "Version";
-
-  const string kConDir          = Name(kContainerPrefix, kDirectory);
-  const string kContainerItem   = Name(kContainerPrefix, kItem);
-  const string kItemLength      = Name(kItemPrefix, kLength);
-  const string kItemMime        = Name(kItemPrefix, kMime);
-  const string kItemSemantic    = Name(kItemPrefix, kSemantic);
-
-  const vector<string> kConDirSeq({kConDir, string("rdf:Seq")});
-  const vector<string> kLiItem({string("rdf:li"), kContainerItem});
-
-  std::stringstream ss;
-  photos_editing_formats::image_io::XmlWriter writer(ss);
-  writer.StartWritingElement("x:xmpmeta");
-  writer.WriteXmlns("x", "adobe:ns:meta/");
-  writer.WriteAttributeNameAndValue("x:xmptk", "Adobe XMP Core 5.1.2");
-  writer.StartWritingElement("rdf:RDF");
-  writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
-  writer.StartWritingElement("rdf:Description");
-  writer.WriteXmlns(kContainerPrefix, kContainerUri);
-  writer.WriteElementAndContent(Name(kContainerPrefix, kVersion), metadata.version);
-  writer.WriteElementAndContent(Name(kContainerPrefix, "rangeScalingFactor"),
-                                metadata.rangeScalingFactor);
-  // TODO: determine structure for hdr10 metadata
-  // TODO: write rest of metadata
-  writer.StartWritingElements(kConDirSeq);
-  size_t item_depth = writer.StartWritingElements(kLiItem);
-  writer.WriteAttributeNameAndValue(kItemSemantic, kPrimary);
-  writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
-  writer.FinishWritingElementsToDepth(item_depth);
-  writer.StartWritingElements(kLiItem);
-  writer.WriteAttributeNameAndValue(kItemSemantic, kRecoveryMap);
-  writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
-  writer.WriteAttributeNameAndValue(kItemLength, secondary_image_length);
-  writer.FinishWriting();
-
-  return ss.str();
-}
-
 status_t RecoveryMap::toneMap(jr_uncompressed_ptr uncompressed_p010_image,
                               jr_uncompressed_ptr dest) {
   if (uncompressed_p010_image == nullptr || dest == nullptr) {
diff --git a/libs/jpegrecoverymap/recoverymaputils.cpp b/libs/jpegrecoverymap/recoverymaputils.cpp
index fe46cba..63b25f7 100644
--- a/libs/jpegrecoverymap/recoverymaputils.cpp
+++ b/libs/jpegrecoverymap/recoverymaputils.cpp
@@ -17,26 +17,36 @@
 #include <jpegrecoverymap/recoverymaputils.h>
 #include <jpegrecoverymap/recoverymap.h>
 #include <image_io/xml/xml_reader.h>
+#include <image_io/xml/xml_writer.h>
 #include <image_io/base/message_handler.h>
 #include <image_io/xml/xml_element_rules.h>
 #include <image_io/xml/xml_handler.h>
 #include <image_io/xml/xml_rule.h>
 
-#include <string>
-#include <sstream>
-
 using namespace photos_editing_formats::image_io;
 using namespace std;
 
 namespace android::recoverymap {
 
+/*
+ * Helper function used for generating XMP metadata.
+ *
+ * @param prefix The prefix part of the name.
+ * @param suffix The suffix part of the name.
+ * @return A name of the form "prefix:suffix".
+ */
+string Name(const string &prefix, const string &suffix) {
+  std::stringstream ss;
+  ss << prefix << ":" << suffix;
+  return ss.str();
+}
 
 // Extremely simple XML Handler - just searches for interesting elements
 class XMPXmlHandler : public XmlHandler {
 public:
 
     XMPXmlHandler() : XmlHandler() {
-        rangeScalingFactorState = NotStrarted;
+        gContainerItemState = NotStrarted;
     }
 
     enum ParseState {
@@ -48,11 +58,11 @@
     virtual DataMatchResult StartElement(const XmlTokenContext& context) {
         string val;
         if (context.BuildTokenValue(&val)) {
-            if (!val.compare(rangeScalingFactorName)) {
-                rangeScalingFactorState = Started;
+            if (!val.compare(gContainerItemName)) {
+                gContainerItemState = Started;
             } else {
-                if (rangeScalingFactorState != Done) {
-                    rangeScalingFactorState = NotStrarted;
+                if (gContainerItemState != Done) {
+                    gContainerItemState = NotStrarted;
                 }
             }
         }
@@ -60,24 +70,45 @@
     }
 
     virtual DataMatchResult FinishElement(const XmlTokenContext& context) {
-        if (rangeScalingFactorState == Started) {
-            rangeScalingFactorState = Done;
+        if (gContainerItemState == Started) {
+            gContainerItemState = Done;
+            lastAttributeName = "";
         }
         return context.GetResult();
     }
 
-    virtual DataMatchResult ElementContent(const XmlTokenContext& context) {
+    virtual DataMatchResult AttributeName(const XmlTokenContext& context) {
         string val;
-        if (rangeScalingFactorState == Started) {
+        if (gContainerItemState == Started) {
             if (context.BuildTokenValue(&val)) {
-                rangeScalingFactorStr.assign(val);
+                if (!val.compare(rangeScalingFactorAttrName)) {
+                    lastAttributeName = rangeScalingFactorAttrName;
+                } else if (!val.compare(transferFunctionAttrName)) {
+                    lastAttributeName = transferFunctionAttrName;
+                } else {
+                    lastAttributeName = "";
+                }
+            }
+        }
+        return context.GetResult();
+    }
+
+    virtual DataMatchResult AttributeValue(const XmlTokenContext& context) {
+        string val;
+        if (gContainerItemState == Started) {
+            if (context.BuildTokenValue(&val, true)) {
+                if (!lastAttributeName.compare(rangeScalingFactorAttrName)) {
+                    rangeScalingFactorStr = val;
+                } else if (!lastAttributeName.compare(transferFunctionAttrName)) {
+                    transferFunctionStr = val;
+                }
             }
         }
         return context.GetResult();
     }
 
     bool getRangeScalingFactor(float* scaling_factor) {
-        if (rangeScalingFactorState == Done) {
+        if (gContainerItemState == Done) {
             stringstream ss(rangeScalingFactorStr);
             float val;
             if (ss >> val) {
@@ -92,19 +123,67 @@
     }
 
     bool getTransferFunction(jpegr_transfer_function* transfer_function) {
-        *transfer_function = JPEGR_TF_HLG;
+        if (gContainerItemState == Done) {
+            stringstream ss(transferFunctionStr);
+            int val;
+            if (ss >> val) {
+                *transfer_function = static_cast<jpegr_transfer_function>(val);
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
         return true;
     }
 
 private:
-    static const string rangeScalingFactorName;
+    static const string gContainerItemName;
+    static const string rangeScalingFactorAttrName;
+    static const string transferFunctionAttrName;
     string              rangeScalingFactorStr;
-    ParseState          rangeScalingFactorState;
+    string              transferFunctionStr;
+    string              lastAttributeName;
+    ParseState          gContainerItemState;
 };
 
-const string XMPXmlHandler::rangeScalingFactorName = "GContainer:rangeScalingFactor";
+const string XMPXmlHandler::gContainerItemName = "GContainer:Item";
+const string XMPXmlHandler::rangeScalingFactorAttrName = "RecoveryMap:RangeScalingFactor";
+const string XMPXmlHandler::transferFunctionAttrName = "RecoveryMap:TransferFunction";
 
 
+const string kContainerPrefix   = "GContainer";
+const string kContainerUri      = "http://ns.google.com/photos/1.0/container/";
+const string kRecoveryMapUri    = "http://ns.google.com/photos/1.0/recoverymap/";
+const string kItemPrefix        = "Item";
+const string kRecoveryMap       = "RecoveryMap";
+const string kDirectory         = "Directory";
+const string kImageJpeg         = "image/jpeg";
+const string kItem              = "Item";
+const string kLength            = "Length";
+const string kMime              = "Mime";
+const string kPrimary           = "Primary";
+const string kSemantic          = "Semantic";
+const string kVersion           = "Version";
+const string kHdr10Metadata     = "HDR10Metadata";
+const string kSt2086Metadata    = "ST2086Metadata";
+const string kSt2086Coordinate  = "ST2086Coordinate";
+const string kSt2086CoordinateX = "ST2086CoordinateX";
+const string kSt2086CoordinateY = "ST2086CoordinateY";
+const string kSt2086Primary     = "ST2086Primary";
+const int kSt2086PrimaryRed     = 0;
+const int kSt2086PrimaryGreen   = 1;
+const int kSt2086PrimaryBlue    = 2;
+const int kSt2086PrimaryWhite   = 3;
+const int kGContainerVersion    = 1;
+
+const string kConDir            = Name(kContainerPrefix, kDirectory);
+const string kContainerItem     = Name(kContainerPrefix, kItem);
+const string kItemLength        = Name(kItemPrefix, kLength);
+const string kItemMime          = Name(kItemPrefix, kMime);
+const string kItemSemantic      = Name(kItemPrefix, kSemantic);
+
 bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, jpegr_metadata* metadata) {
     string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
 
@@ -150,4 +229,96 @@
     return true;
 }
 
+string generateXmp(int secondary_image_length, jpegr_metadata& metadata) {
+  const vector<string> kConDirSeq({kConDir, string("rdf:Seq")});
+  const vector<string> kLiItem({string("rdf:li"), kContainerItem});
+
+  std::stringstream ss;
+  photos_editing_formats::image_io::XmlWriter writer(ss);
+  writer.StartWritingElement("x:xmpmeta");
+  writer.WriteXmlns("x", "adobe:ns:meta/");
+  writer.WriteAttributeNameAndValue("x:xmptk", "Adobe XMP Core 5.1.2");
+  writer.StartWritingElement("rdf:RDF");
+  writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+  writer.StartWritingElement("rdf:Description");
+  writer.WriteXmlns(kContainerPrefix, kContainerUri);
+  writer.WriteXmlns(kRecoveryMap, kRecoveryMapUri);
+  writer.WriteElementAndContent(Name(kContainerPrefix, kVersion), kGContainerVersion);
+  writer.StartWritingElements(kConDirSeq);
+  size_t item_depth = writer.StartWritingElements(kLiItem);
+  writer.WriteAttributeNameAndValue(kItemSemantic, kPrimary);
+  writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
+  writer.WriteAttributeNameAndValue(Name(kRecoveryMap, kVersion), metadata.version);
+  writer.WriteAttributeNameAndValue(
+      Name(kRecoveryMap, "RangeScalingFactor"), metadata.rangeScalingFactor);
+  writer.WriteAttributeNameAndValue(
+      Name(kRecoveryMap, "TransferFunction"), metadata.transferFunction);
+  if (metadata.transferFunction == JPEGR_TF_PQ) {
+    writer.StartWritingElement(Name(kRecoveryMap, kHdr10Metadata));
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, "HDR10MaxFALL"), metadata.hdr10Metadata.maxFALL);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, "HDR10MaxCLL"), metadata.hdr10Metadata.maxCLL);
+    writer.StartWritingElement(Name(kRecoveryMap, kSt2086Metadata));
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, "ST2086MaxLuminance"),
+        metadata.hdr10Metadata.st2086Metadata.maxLuminance);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, "ST2086MinLuminance"),
+        metadata.hdr10Metadata.st2086Metadata.minLuminance);
+
+    // red
+    writer.StartWritingElement(Name(kRecoveryMap, kSt2086Coordinate));
+    writer.WriteAttributeNameAndValue(Name(kRecoveryMap, kSt2086Primary), kSt2086PrimaryRed);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateX),
+        metadata.hdr10Metadata.st2086Metadata.redPrimary.x);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateY),
+        metadata.hdr10Metadata.st2086Metadata.redPrimary.y);
+    writer.FinishWritingElement();
+
+    // green
+    writer.StartWritingElement(Name(kRecoveryMap, kSt2086Coordinate));
+    writer.WriteAttributeNameAndValue(Name(kRecoveryMap, kSt2086Primary), kSt2086PrimaryGreen);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateX),
+        metadata.hdr10Metadata.st2086Metadata.greenPrimary.x);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateY),
+        metadata.hdr10Metadata.st2086Metadata.greenPrimary.y);
+    writer.FinishWritingElement();
+
+    // blue
+    writer.StartWritingElement(Name(kRecoveryMap, kSt2086Coordinate));
+    writer.WriteAttributeNameAndValue(Name(kRecoveryMap, kSt2086Primary), kSt2086PrimaryBlue);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateX),
+        metadata.hdr10Metadata.st2086Metadata.bluePrimary.x);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateY),
+        metadata.hdr10Metadata.st2086Metadata.bluePrimary.y);
+    writer.FinishWritingElement();
+
+    // white
+    writer.StartWritingElement(Name(kRecoveryMap, kSt2086Coordinate));
+    writer.WriteAttributeNameAndValue(Name(kRecoveryMap, kSt2086Primary), kSt2086PrimaryWhite);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateX),
+        metadata.hdr10Metadata.st2086Metadata.whitePoint.x);
+    writer.WriteAttributeNameAndValue(
+        Name(kRecoveryMap, kSt2086CoordinateY),
+        metadata.hdr10Metadata.st2086Metadata.whitePoint.y);
+    writer.FinishWritingElement();
+  }
+  writer.FinishWritingElementsToDepth(item_depth);
+  writer.StartWritingElements(kLiItem);
+  writer.WriteAttributeNameAndValue(kItemSemantic, kRecoveryMap);
+  writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
+  writer.WriteAttributeNameAndValue(kItemLength, secondary_image_length);
+  writer.FinishWriting();
+
+  return ss.str();
+}
+
 } // namespace android::recoverymap
\ No newline at end of file
diff --git a/libs/jpegrecoverymap/tests/recoverymap_test.cpp b/libs/jpegrecoverymap/tests/recoverymap_test.cpp
index 0f96723..6dea27f 100644
--- a/libs/jpegrecoverymap/tests/recoverymap_test.cpp
+++ b/libs/jpegrecoverymap/tests/recoverymap_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <jpegrecoverymap/recoverymap.h>
+#include <jpegrecoverymap/recoverymaputils.h>
 #include <fcntl.h>
 #include <fstream>
 #include <gtest/gtest.h>
@@ -94,6 +95,19 @@
   recovery_map.decodeJPEGR(nullptr, nullptr, nullptr, false);
 }
 
+TEST_F(RecoveryMapTest, writeXmpThenRead) {
+  jpegr_metadata metadata_expected;
+  metadata_expected.transferFunction = JPEGR_TF_HLG;
+  metadata_expected.rangeScalingFactor = 1.25;
+  int length_expected = 1000;
+  std::string xmp = generateXmp(1000, metadata_expected);
+
+  jpegr_metadata metadata_read;
+  EXPECT_TRUE(getMetadataFromXMP(reinterpret_cast<uint8_t*>(xmp[0]), xmp.size(), &metadata_read));
+  ASSERT_EQ(metadata_expected.transferFunction, metadata_read.transferFunction);
+  ASSERT_EQ(metadata_expected.rangeScalingFactor, metadata_read.rangeScalingFactor);
+
+}
 TEST_F(RecoveryMapTest, encodeFromP010ThenDecode) {
   int ret;
 
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 0eeb820..11c56a8 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -76,7 +76,7 @@
         "libaidlcommonsupport",
         "android.hardware.sensors@1.0-convert",
         "android.hardware.sensors-V1-convert",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
 
     generated_headers: ["framework-cppstream-protos"],
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 291c770..4ac9651 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -151,7 +151,7 @@
         return PERMISSION_DENIED;
     }
 
-    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
     if (si == nullptr) {
         return NAME_NOT_FOUND;
     }
@@ -228,7 +228,7 @@
     for (auto &i : existingConnections) {
         int handle = i.first;
         int rateLevel = i.second;
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr) {
             const Sensor& s = si->getSensor();
             if (mService->isSensorInCappedSet(s.getType()) &&
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index f06f947..82d0295 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -160,7 +160,7 @@
 
 bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
     Mutex::Autolock _l(mConnectionLock);
-    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
     if (si == nullptr ||
         !mService->canAccessSensor(si->getSensor(), "Add to SensorEventConnection: ",
                                    mOpPackageName) ||
@@ -202,7 +202,7 @@
     Mutex::Autolock _l(mConnectionLock);
     for (auto &it : mSensorInfo) {
         const int handle = it.first;
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
             return true;
         }
@@ -245,7 +245,7 @@
     if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
     for (auto& it : mSensorInfo) {
         const int handle = it.first;
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().isWakeUpSensor()) {
             looper_flags |= ALOOPER_EVENT_INPUT;
         }
@@ -555,7 +555,7 @@
     // flush complete events to be sent.
     for (auto& it : mSensorInfo) {
         const int handle = it.first;
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si == nullptr) {
             continue;
         }
@@ -689,7 +689,7 @@
     if (enabled) {
         nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
         bool isSensorCapped = false;
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr) {
             const Sensor& s = si->getSensor();
             if (mService->isSensorInCappedSet(s.getType())) {
@@ -729,7 +729,7 @@
 
     nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
     bool isSensorCapped = false;
-    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
     if (si != nullptr) {
         const Sensor& s = si->getSensor();
         if (mService->isSensorInCappedSet(s.getType())) {
@@ -852,7 +852,7 @@
                 }
                 sensors_event_t sensor_event;
                 memcpy(&sensor_event, buf, sizeof(sensors_event_t));
-                sp<SensorInterface> si =
+                std::shared_ptr<SensorInterface> si =
                         mService->getSensorInterfaceFromHandle(sensor_event.sensor);
                 if (si == nullptr) {
                     return 1;
@@ -903,7 +903,7 @@
     size_t fifoWakeUpSensors = 0;
     size_t fifoNonWakeUpSensors = 0;
     for (auto& it : mSensorInfo) {
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(it.first);
+        std::shared_ptr<SensorInterface> si = mService->getSensorInterfaceFromHandle(it.first);
         if (si == nullptr) {
             continue;
         }
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index 6d36b47..daff4d0 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -28,13 +28,13 @@
 
 const Sensor SensorList::mNonSensor = Sensor("unknown");
 
-bool SensorList::add(
-        int handle, SensorInterface* si, bool isForDebug, bool isVirtual, int deviceId) {
+bool SensorList::add(int handle, std::shared_ptr<SensorInterface> si, bool isForDebug,
+                     bool isVirtual, int deviceId) {
     std::lock_guard<std::mutex> lk(mLock);
     if (handle == si->getSensor().getHandle() &&
         mUsedHandle.insert(handle).second) {
         // will succeed as the mUsedHandle does not have this handle
-        mHandleMap.emplace(handle, Entry(si, isForDebug, isVirtual, deviceId));
+        mHandleMap.emplace(handle, Entry(std::move(si), isForDebug, isVirtual, deviceId));
         return true;
     }
     // handle exist already or handle mismatch
@@ -63,12 +63,12 @@
             mNonSensor.getStringType());
 }
 
-sp<SensorInterface> SensorList::getInterface(int handle) const {
-    return getOne<sp<SensorInterface>>(
-            handle, [] (const Entry& e) -> sp<SensorInterface> {return e.si;}, nullptr);
+std::shared_ptr<SensorInterface> SensorList::getInterface(int handle) const {
+    return getOne<std::shared_ptr<SensorInterface>>(
+            handle, [] (const Entry& e) -> std::shared_ptr<SensorInterface> {return e.si;},
+            nullptr);
 }
 
-
 bool SensorList::isNewHandle(int handle) const {
     std::lock_guard<std::mutex> lk(mLock);
     return mUsedHandle.find(handle) == mUsedHandle.end();
diff --git a/services/sensorservice/SensorList.h b/services/sensorservice/SensorList.h
index 79f6701..ad5b21f 100644
--- a/services/sensorservice/SensorList.h
+++ b/services/sensorservice/SensorList.h
@@ -37,22 +37,18 @@
 class SensorList : public Dumpable {
 public:
     struct Entry {
-        sp<SensorInterface> si;
+        std::shared_ptr<SensorInterface> si;
         const bool isForDebug;
         const bool isVirtual;
         const int deviceId;
-        Entry(SensorInterface* si_, bool debug_, bool virtual_, int deviceId_) :
-            si(si_), isForDebug(debug_), isVirtual(virtual_), deviceId(deviceId_) {
+        Entry(std::shared_ptr<SensorInterface> si_, bool debug_, bool virtual_, int deviceId_) :
+            si(std::move(si_)), isForDebug(debug_), isVirtual(virtual_), deviceId(deviceId_) {
         }
     };
 
-    // After SensorInterface * is added into SensorList, it can be assumed that SensorList own the
-    // object it pointed to and the object should not be released elsewhere.
-    bool add(int handle, SensorInterface* si, bool isForDebug = false, bool isVirtual = false,
-             int deviceId = RuntimeSensor::DEFAULT_DEVICE_ID);
-
-    // After a handle is removed, the object that SensorInterface * pointing to may get deleted if
-    // no more sp<> of the same object exist.
+    // SensorList owns the SensorInterface pointer.
+    bool add(int handle, std::shared_ptr<SensorInterface> si, bool isForDebug = false,
+             bool isVirtual = false, int deviceId = RuntimeSensor::DEFAULT_DEVICE_ID);
     bool remove(int handle);
 
     inline bool hasAnySensor() const { return mHandleMap.size() > 0;}
@@ -67,7 +63,7 @@
     String8 getName(int handle) const;
     String8 getStringType(int handle) const;
 
-    sp<SensorInterface> getInterface(int handle) const;
+    std::shared_ptr<SensorInterface> getInterface(int handle) const;
     bool isNewHandle(int handle) const;
 
     // Iterate through Sensor in sensor list and perform operation f on each Sensor object.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 0c9fef5..6504b79 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <aidl/android/hardware/sensors/ISensors.h>
 #include <android-base/strings.h>
 #include <android/content/pm/IPackageManagerNative.h>
 #include <android/util/ProtoOutputStream.h>
@@ -104,12 +105,10 @@
 
 namespace {
 
-// TODO(b/259227294): Move the sensor ranges to the HAL.
 int32_t nextRuntimeSensorHandle() {
-    static constexpr int32_t kRuntimeHandleBase = 0x5F000000;
-    static constexpr int32_t kRuntimeHandleEnd = 0x5FFFFFFF;
-    static int32_t nextHandle = kRuntimeHandleBase;
-    if (nextHandle == kRuntimeHandleEnd) {
+    using ::aidl::android::hardware::sensors::ISensors;
+    static int32_t nextHandle = ISensors::RUNTIME_SENSORS_HANDLE_BASE;
+    if (nextHandle == ISensors::RUNTIME_SENSORS_HANDLE_END) {
         return -1;
     }
     return nextHandle++;
@@ -183,15 +182,14 @@
     sensor_t runtimeSensor = sensor;
     // force the handle to be consistent
     runtimeSensor.handle = handle;
-    SensorInterface *si = new RuntimeSensor(runtimeSensor, std::move(runtimeSensorCallback));
+    auto si = std::make_shared<RuntimeSensor>(runtimeSensor, std::move(runtimeSensorCallback));
 
     Mutex::Autolock _l(mLock);
-    const Sensor& s = registerSensor(si, /* isDebug= */ false, /* isVirtual= */ false, deviceId);
-
-    if (s.getHandle() != handle) {
+    if (!registerSensor(std::move(si), /* isDebug= */ false, /* isVirtual= */ false, deviceId)) {
         // The registration was unsuccessful.
-        return s.getHandle();
+        return mSensors.getNonSensor().getHandle();
     }
+
     return handle;
 }
 
@@ -319,11 +317,13 @@
                 }
                 if (useThisSensor) {
                     if (list[i].type == SENSOR_TYPE_PROXIMITY) {
-                        SensorInterface* s = new ProximitySensor(list[i], *this);
-                        registerSensor(s);
-                        mProxSensorHandles.push_back(s->getSensor().getHandle());
+                        auto s = std::make_shared<ProximitySensor>(list[i], *this);
+                        const int handle = s->getSensor().getHandle();
+                        if (registerSensor(std::move(s))) {
+                            mProxSensorHandles.push_back(handle);
+                        }
                     } else {
-                        registerSensor(new HardwareSensor(list[i]));
+                        registerSensor(std::make_shared<HardwareSensor>(list[i]));
                     }
                 }
             }
@@ -338,56 +338,63 @@
                 // available in the HAL
                 bool needRotationVector =
                         (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
-
-                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
-                registerSensor(new OrientationSensor(), !needRotationVector, true);
+                registerVirtualSensor(std::make_shared<RotationVectorSensor>(),
+                                      /* isDebug= */ !needRotationVector);
+                registerVirtualSensor(std::make_shared<OrientationSensor>(),
+                                      /* isDebug= */ !needRotationVector);
 
                 // virtual debugging sensors are not for user
-                registerSensor( new CorrectedGyroSensor(list, count), true, true);
-                registerSensor( new GyroDriftSensor(), true, true);
+                registerVirtualSensor(std::make_shared<CorrectedGyroSensor>(list, count),
+                                      /* isDebug= */ true);
+                registerVirtualSensor(std::make_shared<GyroDriftSensor>(), /* isDebug= */ true);
             }
 
             if (hasAccel && (hasGyro || hasGyroUncalibrated)) {
                 bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
-                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
+                registerVirtualSensor(std::make_shared<GravitySensor>(list, count),
+                                      /* isDebug= */ !needGravitySensor);
 
                 bool needLinearAcceleration =
                         (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
-                registerSensor(new LinearAccelerationSensor(list, count),
-                               !needLinearAcceleration, true);
+                registerVirtualSensor(std::make_shared<LinearAccelerationSensor>(list, count),
+                                      /* isDebug= */ !needLinearAcceleration);
 
                 bool needGameRotationVector =
                         (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
-                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
+                registerVirtualSensor(std::make_shared<GameRotationVectorSensor>(),
+                                      /* isDebug= */ !needGameRotationVector);
             }
 
             if (hasAccel && hasMag) {
                 bool needGeoMagRotationVector =
                         (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
-                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
+                registerVirtualSensor(std::make_shared<GeoMagRotationVectorSensor>(),
+                                      /* isDebug= */ !needGeoMagRotationVector);
             }
 
             if (isAutomotive()) {
                 if (hasAccel) {
-                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_ACCELEROMETER),
-                                  /*isDebug=*/false, /*isVirtual=*/true);
+                    registerVirtualSensor(
+                            std::make_shared<LimitedAxesImuSensor>(
+                                    list, count, SENSOR_TYPE_ACCELEROMETER));
                }
 
                if (hasGyro) {
-                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_GYROSCOPE),
-                                  /*isDebug=*/false, /*isVirtual=*/true);
+                    registerVirtualSensor(
+                            std::make_shared<LimitedAxesImuSensor>(
+                                    list, count, SENSOR_TYPE_GYROSCOPE));
                }
 
                if (hasAccelUncalibrated) {
-                   registerSensor(new LimitedAxesImuSensor(list, count,
-                                                           SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED),
-                                  /*isDebug=*/false, /*isVirtual=*/true);
+                    registerVirtualSensor(
+                            std::make_shared<LimitedAxesImuSensor>(
+                                    list, count, SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED));
                }
 
                if (hasGyroUncalibrated) {
-                   registerSensor(new LimitedAxesImuSensor(list, count,
-                                                           SENSOR_TYPE_GYROSCOPE_UNCALIBRATED),
-                                  /*isDebug=*/false, /*isVirtual=*/true);
+                    registerVirtualSensor(
+                            std::make_shared<LimitedAxesImuSensor>(
+                                    list, count, SENSOR_TYPE_GYROSCOPE_UNCALIBRATED));
                }
             }
 
@@ -488,20 +495,21 @@
         && isUidActive(uid) && !isOperationRestrictedLocked(opPackageName);
 }
 
-const Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual,
-                                            int deviceId) {
-    int handle = s->getSensor().getHandle();
-    int type = s->getSensor().getType();
-    if (mSensors.add(handle, s, isDebug, isVirtual, deviceId)) {
+bool SensorService::registerSensor(std::shared_ptr<SensorInterface> s, bool isDebug, bool isVirtual,
+                                   int deviceId) {
+    const int handle = s->getSensor().getHandle();
+    const int type = s->getSensor().getType();
+    if (mSensors.add(handle, std::move(s), isDebug, isVirtual, deviceId)) {
         mRecentEvent.emplace(handle, new SensorServiceUtil::RecentEventLogger(type));
-        return s->getSensor();
+        return true;
     } else {
-        return mSensors.getNonSensor();
+        LOG_FATAL("Failed to register sensor with handle %d", handle);
+        return false;
     }
 }
 
-const Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) {
-    return registerSensor(s, isDebug);
+bool SensorService::registerDynamicSensorLocked(std::shared_ptr<SensorInterface> s, bool isDebug) {
+    return registerSensor(std::move(s), isDebug);
 }
 
 bool SensorService::unregisterDynamicSensorLocked(int handle) {
@@ -515,8 +523,8 @@
     return ret;
 }
 
-const Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) {
-    return registerSensor(s, isDebug, true);
+bool SensorService::registerVirtualSensor(std::shared_ptr<SensorInterface> s, bool isDebug) {
+    return registerSensor(std::move(s), isDebug, true);
 }
 
 SensorService::~SensorService() {
@@ -611,8 +619,8 @@
 
             result.append("Recent Sensor events:\n");
             for (auto&& i : mRecentEvent) {
-                sp<SensorInterface> s = mSensors.getInterface(i.first);
-                if (!i.second->isEmpty()) {
+                std::shared_ptr<SensorInterface> s = getSensorInterfaceFromHandle(i.first);
+                if (!i.second->isEmpty() && s != nullptr) {
                     if (privileged || s->getSensor().getRequiredPermission().isEmpty()) {
                         i.second->setFormat("normal");
                     } else {
@@ -729,8 +737,8 @@
     // Write SensorEventsProto
     token = proto.start(SENSOR_EVENTS);
     for (auto&& i : mRecentEvent) {
-        sp<SensorInterface> s = mSensors.getInterface(i.first);
-        if (!i.second->isEmpty()) {
+        std::shared_ptr<SensorInterface> s = getSensorInterfaceFromHandle(i.first);
+        if (!i.second->isEmpty() && s != nullptr) {
             i.second->setFormat(privileged || s->getSensor().getRequiredPermission().isEmpty() ?
                     "normal" : "mask_data");
             const uint64_t mToken = proto.start(service::SensorEventsProto::RECENT_EVENTS_LOGS);
@@ -1020,7 +1028,7 @@
             handle = buffer[i].meta_data.sensor;
         }
         if (connection->hasSensor(handle)) {
-            sp<SensorInterface> si = getSensorInterfaceFromHandle(handle);
+            std::shared_ptr<SensorInterface> si = getSensorInterfaceFromHandle(handle);
             // If this buffer has an event from a one_shot sensor and this connection is registered
             // for this particular one_shot sensor, try cleaning up the connection.
             if (si != nullptr &&
@@ -1105,7 +1113,7 @@
                             break;
                         }
                         sensors_event_t out;
-                        sp<SensorInterface> si = mSensors.getInterface(handle);
+                        std::shared_ptr<SensorInterface> si = getSensorInterfaceFromHandle(handle);
                         if (si == nullptr) {
                             ALOGE("handle %d is not an valid virtual sensor", handle);
                             continue;
@@ -1200,12 +1208,12 @@
                         // force the handle to be consistent
                         s.handle = handle;
 
-                        SensorInterface *si = new HardwareSensor(s, uuid);
+                        auto si = std::make_shared<HardwareSensor>(s, uuid);
 
                         // This will release hold on dynamic sensor meta, so it should be called
                         // after Sensor object is created.
                         device.handleDynamicSensorConnection(handle, true /*connected*/);
-                        registerDynamicSensorLocked(si);
+                        registerDynamicSensorLocked(std::move(si));
                     } else {
                         ALOGE("Handle %d has been used, cannot use again before reboot.", handle);
                     }
@@ -1332,7 +1340,7 @@
 }
 
 bool SensorService::isVirtualSensor(int handle) const {
-    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
     return sensor != nullptr && sensor->isVirtual();
 }
 
@@ -1341,7 +1349,7 @@
     if (event.type == SENSOR_TYPE_META_DATA) {
         handle = event.meta_data.sensor;
     }
-    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
     return sensor != nullptr && sensor->getSensor().isWakeUpSensor();
 }
 
@@ -1741,7 +1749,7 @@
         int handle = mActiveSensors.keyAt(i);
         if (c->hasSensor(handle)) {
             ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
-            sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+            std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
             if (sensor != nullptr) {
                 sensor->activate(c, false);
             } else {
@@ -1855,7 +1863,7 @@
     return NAME_NOT_FOUND;
 }
 
-sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
+std::shared_ptr<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
     return mSensors.getInterface(handle);
 }
 
@@ -1865,7 +1873,7 @@
     if (mInitCheck != NO_ERROR)
         return mInitCheck;
 
-    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
     if (sensor == nullptr ||
         !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
         return BAD_VALUE;
@@ -2011,7 +2019,7 @@
     Mutex::Autolock _l(mLock);
     status_t err = cleanupWithoutDisableLocked(connection, handle);
     if (err == NO_ERROR) {
-        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
         err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
 
     }
@@ -2057,7 +2065,7 @@
     if (mInitCheck != NO_ERROR)
         return mInitCheck;
 
-    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+    std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
     if (sensor == nullptr ||
         !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
         return BAD_VALUE;
@@ -2083,7 +2091,7 @@
     Mutex::Autolock _l(mLock);
     // Loop through all sensors for this connection and call flush on each of them.
     for (int handle : connection->getActiveSensorHandles()) {
-        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
+        std::shared_ptr<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
         if (sensor == nullptr) {
             continue;
         }
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index e490398..78df501 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -375,15 +375,14 @@
     String8 getSensorName(int handle) const;
     String8 getSensorStringType(int handle) const;
     bool isVirtualSensor(int handle) const;
-    sp<SensorInterface> getSensorInterfaceFromHandle(int handle) const;
+    std::shared_ptr<SensorInterface> getSensorInterfaceFromHandle(int handle) const;
     bool isWakeUpSensor(int type) const;
     void recordLastValueLocked(sensors_event_t const* buffer, size_t count);
     static void sortEventBuffer(sensors_event_t* buffer, size_t count);
-    const Sensor& registerSensor(SensorInterface* sensor, bool isDebug = false,
-                                 bool isVirtual = false,
-                                 int deviceId = RuntimeSensor::DEFAULT_DEVICE_ID);
-    const Sensor& registerVirtualSensor(SensorInterface* sensor, bool isDebug = false);
-    const Sensor& registerDynamicSensorLocked(SensorInterface* sensor, bool isDebug = false);
+    bool registerSensor(std::shared_ptr<SensorInterface> sensor, bool isDebug = false,
+                        bool isVirtual = false, int deviceId = RuntimeSensor::DEFAULT_DEVICE_ID);
+    bool registerVirtualSensor(std::shared_ptr<SensorInterface> sensor, bool isDebug = false);
+    bool registerDynamicSensorLocked(std::shared_ptr<SensorInterface> sensor, bool isDebug = false);
     bool unregisterDynamicSensorLocked(int handle);
     status_t cleanupWithoutDisable(const sp<SensorEventConnection>& connection, int handle);
     status_t cleanupWithoutDisableLocked(const sp<SensorEventConnection>& connection, int handle);
diff --git a/services/sensorservice/aidl/Android.bp b/services/sensorservice/aidl/Android.bp
index 34d1de7..542fcae 100644
--- a/services/sensorservice/aidl/Android.bp
+++ b/services/sensorservice/aidl/Android.bp
@@ -28,7 +28,7 @@
         "libbinder_ndk",
         "libsensor",
         "android.frameworks.sensorservice-V1-ndk",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     export_include_dirs: [
         "include/",
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
index 0d6e476..5301fe9 100644
--- a/services/sensorservice/aidl/fuzzer/Android.bp
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -18,7 +18,7 @@
         "libpermission",
         "android.frameworks.sensorservice-V1-ndk",
         "android.hardware.sensors-V1-convert",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
         "android.hardware.common-V2-ndk",
         "libsensor",
         "libfakeservicemanager",
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b7abd95..1f159ae 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -216,6 +216,9 @@
 }
 
 Layer::~Layer() {
+    LOG_ALWAYS_FATAL_IF(std::this_thread::get_id() != mFlinger->mMainThreadId,
+                        "Layer destructor called off the main thread.");
+
     // The original layer and the clone layer share the same texture and buffer. Therefore, only
     // one of the layers, in this case the original layer, needs to handle the deletion. The
     // original layer and the clone should be removed at the same time so there shouldn't be any