Merge "CCodec: add more doc to PipelineWatcher"
diff --git a/apex/Android.bp b/apex/Android.bp
index c077a77..9455290 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -12,9 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-apex {
-    name: "com.android.media",
-    manifest: "manifest.json",
+apex_defaults {
+    name: "com.android.media-defaults",
     java_libs: ["updatable-media"],
     compile_multilib: "both",
     multilib: {
@@ -42,16 +41,29 @@
         },
     },
     key: "com.android.media.key",
+    certificate: ":com.android.media.certificate",
 }
 
 apex {
-    name: "com.android.media.swcodec",
-    manifest: "manifest_codec.json",
+    name: "com.android.media",
+    manifest: "manifest.json",
+    defaults: ["com.android.media-defaults"],
+}
+
+apex_defaults {
+    name: "com.android.media.swcodec-defaults",
     native_shared_libs: [
         "libmedia_codecserviceregistrant",
     ],
     use_vendor: true,
     key: "com.android.media.swcodec.key",
+    certificate: ":com.android.media.swcodec.certificate",
+}
+
+apex {
+    name: "com.android.media.swcodec",
+    manifest: "manifest_codec.json",
+    defaults: ["com.android.media.swcodec-defaults"],
 }
 
 apex_key {
@@ -65,3 +77,13 @@
     public_key: "com.android.media.swcodec.avbpubkey",
     private_key: "com.android.media.swcodec.pem",
 }
+
+android_app_certificate {
+    name: "com.android.media.certificate",
+    certificate: "com.android.media",
+}
+
+android_app_certificate {
+    name: "com.android.media.swcodec.certificate",
+    certificate: "com.android.media.swcodec",
+}
diff --git a/apex/com.android.media.pk8 b/apex/com.android.media.pk8
new file mode 100644
index 0000000..6df741e
--- /dev/null
+++ b/apex/com.android.media.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.pk8 b/apex/com.android.media.swcodec.pk8
new file mode 100644
index 0000000..05a4216
--- /dev/null
+++ b/apex/com.android.media.swcodec.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.x509.pem b/apex/com.android.media.swcodec.x509.pem
new file mode 100644
index 0000000..67b9b4f
--- /dev/null
+++ b/apex/com.android.media.swcodec.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIJAIM72JpD4v6XMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEiMCAGA1UE
+AwwZY29tLmFuZHJvaWQubWVkaWEuc3djb2RlYzAgFw0xOTAyMTEwMjExMTFaGA80
+NzU3MDEwNzAyMTExMVowgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
+bmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAw
+DgYDVQQLDAdBbmRyb2lkMSIwIAYDVQQDDBljb20uYW5kcm9pZC5tZWRpYS5zd2Nv
+ZGVjMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsqXE0AIWpLW9Tgq2
+nQGph7KZ6L2Q9oxviqCVHxIaPqfhM2SwTbycADIQeqrrlRxhddVkjLuMUkJa7mev
+fERmgpiOfnPIlGK6PTs2gljCkskZhF3bgfeyuHt0tsYO+UaN8MVoZD7/QdiE46w2
+OMDClG1UqgiqOBhLTEN/cHXObnUiiVXUYqN8aYZf6L6Fs3yQi2ZZgfbxTVFewqdv
+aLLOqCYnVYXZH+ZxbXESA0M+WXKgRKsYTj2GYs3eko1rFi4Y6uHVLx45yaoT5u/i
+SxPEkocyMCKvGJWu4XlSOd3EjSOMaqCOYVyGLxdlnQWQU7PZDqBSJ0SysWgpFHpB
+I15c2jhRdXOCfQ9ZtDfPZkE0a2A8kJDAoF1mzTp6IvBAWUsl5nHPw5CWkFpNad/h
+tqqGCScWbiKZuvrQ4/RQNm3f1K+mxX9TrjFigpqNO6d4pGAo1fa6sHR3xWPw/myq
+h5ZJjVnXU5Yq64S4xWOssfjpOg7RfNuvzuk3ok3MYs1mbx3vhZOj5km1f3qrgX9c
+mXjYnyXD0jJBm4uAJWXLdK9PlZvlXbztMCzYj832Io4pFLCtSxkzX75t1em36Nv0
+mNp6NtSSy6SFSq8l7IsXV2FNyUiyHWxS/UQm8pYg5Q5dWHvEEF78P6lV0wRa6FQl
+BBSgpqTAI092KIjDDtB7GQCgV5ECAwEAAaNTMFEwHQYDVR0OBBYEFAFIdFTDEDft
+ewSSAS7Fa3OZ5TXzMB8GA1UdIwQYMBaAFAFIdFTDEDftewSSAS7Fa3OZ5TXzMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAC5e3zXythJCGmz1FmAV
+8Y/UI+Glg6G0x/k04WaRG0DPLLjlJ1F0LM1/IReBSgXcYAL0CAgPycf/rGPOgMFm
+tQxYyjBUxKdjpIqU5DJoV1feanGveIRpto1YRKNgHuzG9rZGR4AgPnt6X4Yxlq04
+lI7QpWadXe1myARJhj3niSNY9+2wEInkx4ZuCO1LtIGqnbdc8jQ8YoVqIE5N4kuM
+ccyPYgsdABtopbjN92rueu8sfF8R6ROy+tNgb6OjpAAevtnBfZ2LXqfObKirHCK+
+k6w4WSB1UUoZ3Xgz8sJtXgokvYeInkN8tHuTagHYU2VQTcA0rdBGMN/1OljJpWlN
+0UUq4fAYU6cN4lHxr2LM9If4WvAzdLAWvaIZrDqaU4i/zYT9l6rR4lC2KW3EHWov
+nPXfgEJJ8AP1iRGibvew3i3SB6XTWFQYTUIBeJfDz/KDXQabP+yzXWISdZCUMUpx
+f+Raqsb5MoKaJdVgnSL0mBunjCyJDzzg34J7oGx6/BnwoiOrwLN4Qaz5U8jbrPSx
+p9LfleCcO7ZdeE8GKqx0X1T4d7tradtmxOS8Iwr4niskkHGRkzozvVvuyGKmoN2k
+162Vfjq+ddj7qEpSh3BS6hHU+vlMbC9L0trGxPxFEAHDrwu0KwGNduTkiu/3jvfB
+JTgH8P9mD1loYxRdo+vet8eQ
+-----END CERTIFICATE-----
diff --git a/apex/com.android.media.x509.pem b/apex/com.android.media.x509.pem
new file mode 100644
index 0000000..e7908fa
--- /dev/null
+++ b/apex/com.android.media.x509.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFzDCCA7SgAwIBAgIJAO05DBBusaaLMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRowGAYDVQQD
+DBFjb20uYW5kcm9pZC5tZWRpYTAgFw0xOTAxMjUxNzE3MTdaGA80NzU2MTIyMTE3
+MTcxN1owejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
+BAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsMB0Fu
+ZHJvaWQxGjAYBgNVBAMMEWNvbS5hbmRyb2lkLm1lZGlhMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAmNkVxUbp/bLbeGbvKqYXzwBycSDpmOhh///lNGYQ
+/AMUD0q6EaZzU2bd4aL0rOGqfoYlhKd0kMVmMUmfdE9ODAfKxleEeEaRl2GJS8a9
+ABi770l3GHbB2xMI2sEWeOD9xsPFF6+ByPZmoUuNhMr4pUbXsDpE3h8ljrgXHtIg
+bh7ofbvddruwBV0lS1k9OZ9jPVGhEKkJnhgQa67cwgdjizAMbI0Dcz9gtMMawsDj
+Z2aQd1r+vxgh1/XkI/NMmXCnG2ERytXcJeC5S4gEtHfTTPoP0FuVgSB6y6dalMuZ
+F0NBZw8Mvgdy3QJip0uNa36J63CMZKTJWbTdlFpPL2hk0PgaYvje8C5Xtk5282wT
+dMocc8n2zIXbzbnSXGvjcNZib3Pfu55YUnX6eTqZ1BxlJ0FHZAsC4quFFWXxYBYD
+LCRoNNFEtIDQpuvuHF2DuHNDULpAQjy2y6+7eot0KEsVoDmZ4H8BpuAVVu2SxYNb
+gYflR9SmM0tmYeAcRT48q3xrocGyEHMqvgQRUpPfvct/8l8xVcDzOI/sJVDqmYzM
+u0Cj3fkSypGDJOMF/esFSmVvoI01tS7kaNS5vvtKYib//xqKRC9f0dCsGfFLnuUK
+o4KYbYWYwMyJqEd/5/ZvXyKIPAEeJL174L9+wTkc3cQpoBwJN4t+2E5MnhOEq6do
+5L0CAwEAAaNTMFEwHQYDVR0OBBYEFHjNK/GZko1RdZp+8iavWXL5xz9wMB8GA1Ud
+IwQYMBaAFHjNK/GZko1RdZp+8iavWXL5xz9wMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggIBACmPQMksuLrNV1vbI44S1f70I0FHdBxchFGB39zuLbcn
+SsYom/LPtYJiD0Dl4bB4eb+ZnxkQP2XeP6pycmUH2j1EWexFwvdUvlfe8Qz+wAec
+ap4AxiX4Z2Ke2ivYotIZFUHdZOLkX20js8Wex1mzY43MLQn5APl9gK1VZTxDggeR
+EObH1S+JVjGwQqYZj2e6gNZH34Q25NQ698RL85GDkYtSISAifJtaJsU/B3vKm82I
+k9xMiCooCH6bRdGHG1jze4SRpidjxEm8cxkiaQagfcuXeCLziXJr3qAMKYiEY6bp
+0+bAqCt3S8OrrN3RQZfQrnlwitsM1jJJ/+C+WoDg4eY5AFrXDLvNeKh1qO/f8xv+
+fCXkQPcVVphLfRH9oxNrSgOWBP5/qIDH4s1YUL9luGT6H+08dlue3RkbzDbBqsQu
+7fQ/BbrIG/GuVKgyEM+a7C9gv7zc86YlueVYJEyxKidnn7RxOqyDBqyyfXA3zvme
+Rro7xIrMHPL7Nu3AWjwjXzbp/w0z+tEFPsfVB+OOHKsWPcUG0HUTJGkyeO/uHRjN
+qPEkkf7BHHUO4V2gjOIdCsELxKwHf7vsZTOk40EV751fZ7FDHMr1eddQkgH4eqAb
+DB79uP+SLfUo+42n4q6eMmoqw8d76bBXRoUhIo/Ms4sebhV0sRtAS67OQioc9UUg
+-----END CERTIFICATE-----
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
new file mode 100644
index 0000000..701ced7
--- /dev/null
+++ b/apex/testing/Android.bp
@@ -0,0 +1,29 @@
+// 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.
+
+apex {
+    name: "test_com.android.media",
+    manifest: "test_manifest.json",
+    file_contexts: "com.android.media",
+    defaults: ["com.android.media-defaults"],
+    installable: false,
+}
+
+apex {
+    name: "test_com.android.media.swcodec",
+    manifest: "test_manifest_codec.json",
+    file_contexts: "com.android.media.swcodec",
+    defaults: ["com.android.media.swcodec-defaults"],
+    installable: false,
+}
diff --git a/apex/testing/test_manifest.json b/apex/testing/test_manifest.json
new file mode 100644
index 0000000..9f81f9f
--- /dev/null
+++ b/apex/testing/test_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media",
+  "version": 2
+}
diff --git a/apex/testing/test_manifest_codec.json b/apex/testing/test_manifest_codec.json
new file mode 100644
index 0000000..c956454
--- /dev/null
+++ b/apex/testing/test_manifest_codec.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.media.swcodec",
+  "version": 2
+}
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index b8baec8..b158f8f 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -151,7 +151,7 @@
         c2_status_t status;
         do {
             status = mBase->fetchLinearBlock(capacity, usage, block);
-        } while (status == C2_TIMED_OUT);
+        } while (status == C2_BLOCKING);
         return status;
     }
 
@@ -162,7 +162,7 @@
         c2_status_t status;
         do {
             status = mBase->fetchCircularBlock(capacity, usage, block);
-        } while (status == C2_TIMED_OUT);
+        } while (status == C2_BLOCKING);
         return status;
     }
 
@@ -174,7 +174,7 @@
         do {
             status = mBase->fetchGraphicBlock(width, height, format, usage,
                                               block);
-        } while (status == C2_TIMED_OUT);
+        } while (status == C2_BLOCKING);
         return status;
     }
 
diff --git a/media/codec2/core/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
index 2997f6e..c428122 100644
--- a/media/codec2/core/include/C2Buffer.h
+++ b/media/codec2/core/include/C2Buffer.h
@@ -888,6 +888,7 @@
      * \retval C2_OK        the operation was successful
      * \retval C2_NO_MEMORY not enough memory to complete any required allocation
      * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
      * \retval C2_REFUSED   no permission to complete any required allocation
      * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
      * \retval C2_OMITTED   this pool does not support linear blocks
@@ -916,6 +917,7 @@
      * \retval C2_OK        the operation was successful
      * \retval C2_NO_MEMORY not enough memory to complete any required allocation
      * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
      * \retval C2_REFUSED   no permission to complete any required allocation
      * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
      * \retval C2_OMITTED   this pool does not support circular blocks
@@ -946,6 +948,7 @@
      * \retval C2_OK        the operation was successful
      * \retval C2_NO_MEMORY not enough memory to complete any required allocation
      * \retval C2_TIMED_OUT the operation timed out
+     * \retval C2_BLOCKING  the operation is blocked
      * \retval C2_REFUSED   no permission to complete any required allocation
      * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
      *                      error)
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 02cdc23..343bcb5 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -1803,7 +1803,8 @@
 }
 
 sp<HGraphicBufferProducer> getHgbp(const sp<IGraphicBufferProducer>& igbp) {
-    sp<HGraphicBufferProducer> hgbp = igbp->getHalInterface();
+    sp<HGraphicBufferProducer> hgbp =
+            igbp->getHalInterface<HGraphicBufferProducer>();
     return hgbp ? hgbp :
             new TWGraphicBufferProducer<HGraphicBufferProducer>(igbp);
 }
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 3808be5..7a2e549 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -1064,7 +1064,9 @@
         C2BlockPool::local_id_t blockPoolId,
         const sp<IGraphicBufferProducer>& surface,
         uint32_t generation) {
-    sp<HGraphicBufferProducer> igbp = surface->getHalInterface();
+    sp<HGraphicBufferProducer> igbp =
+            surface->getHalInterface<HGraphicBufferProducer>();
+
     if (!igbp) {
         igbp = new TWGraphicBufferProducer<HGraphicBufferProducer>(surface);
     }
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 7bf3d64..41a5b3f 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -207,12 +207,16 @@
         // dequeueBuffer returns flag.
         if (!transStatus.isOk() || status < android::OK) {
             ALOGD("cannot dequeue buffer %d", status);
-            if (transStatus.isOk() && status == android::INVALID_OPERATION) {
-              // Too many buffer dequeued. retrying after some time is required.
-              return C2_TIMED_OUT;
-            } else {
-              return C2_BAD_VALUE;
+            if (transStatus.isOk()) {
+                if (status == android::INVALID_OPERATION ||
+                    status == android::TIMED_OUT ||
+                    status == android::WOULD_BLOCK) {
+                    // Dequeue buffer is blocked temporarily. Retrying is
+                    // required.
+                    return C2_BLOCKING;
+                }
             }
+            return C2_BAD_VALUE;
         }
         ALOGV("dequeued a buffer successfully");
         native_handle_t* nh = nullptr;
@@ -227,7 +231,7 @@
             if (status == -ETIME) {
                 // fence is not signalled yet.
                 (void)mProducer->cancelBuffer(slot, fenceHandle).isOk();
-                return C2_TIMED_OUT;
+                return C2_BLOCKING;
             }
             if (status != android::NO_ERROR) {
                 ALOGD("buffer fence wait error %d", status);
@@ -353,14 +357,14 @@
                 return C2_OK;
             }
             c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block);
-            if (status == C2_TIMED_OUT) {
+            if (status == C2_BLOCKING) {
                 lock.unlock();
                 ::usleep(kMaxIgbpRetryDelayUs);
                 continue;
             }
             return status;
         }
-        return C2_TIMED_OUT;
+        return C2_BLOCKING;
     }
 
     void setRenderCallback(const OnRenderCallback &renderCallback) {
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index bd10d67..b111b78 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -74,6 +74,7 @@
         "libnblog",
         "libprocessgroup",
         "libutils",
+        "libvibrator",
     ],
     export_shared_lib_headers: ["libbinder"],
 
diff --git a/media/libaudioclient/include/media/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
index fbbbd11..41b425f 100644
--- a/media/libaudioclient/include/media/AudioMixer.h
+++ b/media/libaudioclient/include/media/AudioMixer.h
@@ -26,6 +26,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include <android/os/IExternalVibratorService.h>
 #include <media/AudioBufferProvider.h>
 #include <media/AudioResampler.h>
 #include <media/AudioResamplerPublic.h>
@@ -103,20 +104,21 @@
                                   // parameter 'value' is a pointer to the new playback rate.
     };
 
-    enum { // Haptic intensity, should keep consistent with VibratorService
-        HAPTIC_SCALE_VERY_LOW = -2,
-        HAPTIC_SCALE_LOW = -1,
-        HAPTIC_SCALE_NONE = 0,
-        HAPTIC_SCALE_HIGH = 1,
-        HAPTIC_SCALE_VERY_HIGH = 2,
-    };
-    typedef int32_t haptic_intensity_t;
-    static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2 / 3;
-    static constexpr float HAPTIC_SCALE_LOW_RATIO = 3 / 4;
-    static const CONSTEXPR float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
+    typedef enum { // Haptic intensity, should keep consistent with VibratorService
+        HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
+        HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
+        HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
+        HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
+        HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
+        HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
+    } haptic_intensity_t;
+    static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
+    static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
+    static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
 
     static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
         switch (hapticIntensity) {
+        case HAPTIC_SCALE_MUTE:
         case HAPTIC_SCALE_VERY_LOW:
         case HAPTIC_SCALE_LOW:
         case HAPTIC_SCALE_NONE:
@@ -428,8 +430,9 @@
         case HAPTIC_SCALE_NONE:
         case HAPTIC_SCALE_HIGH:
         case HAPTIC_SCALE_VERY_HIGH:
-        default:
             return 1.0f;
+        default:
+            return 0.0f;
         }
         }
 
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
index 817fb0b..cb78063 100644
--- a/media/libaudioprocessing/Android.bp
+++ b/media/libaudioprocessing/Android.bp
@@ -12,6 +12,11 @@
         "libnblog",
         "libsonic",
         "libutils",
+        "libvibrator",
+    ],
+
+    header_libs: [
+        "libbase_headers",
     ],
 
     cflags: [
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 86777d6..2c57db7 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -113,10 +113,10 @@
         // Integer volume.
         // Currently integer volume is kept for the legacy integer mixer.
         // Will be removed when the legacy mixer path is removed.
-        t->volume[0] = UNITY_GAIN_INT;
-        t->volume[1] = UNITY_GAIN_INT;
-        t->prevVolume[0] = UNITY_GAIN_INT << 16;
-        t->prevVolume[1] = UNITY_GAIN_INT << 16;
+        t->volume[0] = 0;
+        t->volume[1] = 0;
+        t->prevVolume[0] = 0 << 16;
+        t->prevVolume[1] = 0 << 16;
         t->volumeInc[0] = 0;
         t->volumeInc[1] = 0;
         t->auxLevel = 0;
@@ -124,10 +124,10 @@
         t->prevAuxLevel = 0;
 
         // Floating point volume.
-        t->mVolume[0] = UNITY_GAIN_FLOAT;
-        t->mVolume[1] = UNITY_GAIN_FLOAT;
-        t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
-        t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
+        t->mVolume[0] = 0.f;
+        t->mVolume[1] = 0.f;
+        t->mPrevVolume[0] = 0.f;
+        t->mPrevVolume[1] = 0.f;
         t->mVolumeInc[0] = 0.;
         t->mVolumeInc[1] = 0.;
         t->mAuxLevel = 0.;
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
index 811c16b..0c8e5bb 100644
--- a/media/libaudioprocessing/tests/Android.bp
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -10,6 +10,7 @@
         "libcutils",
         "liblog",
         "libutils",
+        "libvibrator",
     ],
 
     cflags: [
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index 1f9f659..3858450 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -132,8 +132,8 @@
     src += NrChannels * (NrFrames - 1);
     for (ii = NrFrames; ii != 0; ii--)
     {
-        dst[0] = src_st[0];
         dst[1] = src_st[1];
+        dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
         for (jj = 2; jj < NrChannels; jj++)
         {
             dst[jj] = src[jj];
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index 41a4f04..1a874a3 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -54,21 +54,13 @@
     192000
 )
 
-ch_arr=(
-    1
-    2
-    4
-    6
-    8
-)
-
 # run multichannel effects at different configs, saving only the stereo channel
 # pair.
 for flags in "${flags_arr[@]}"
 do
     for fs in ${fs_arr[*]}
     do
-        for ch in ${ch_arr[*]}
+        for ch in {1..8}
         do
             adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
                 -o:$testdir/sinesweep_$((ch))_$((fs)).raw -ch:$ch -fs:$fs $flags
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index a073081..747b88f 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -552,7 +552,7 @@
 };
 
 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
-IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
+IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
 
 ////////////////////////////////////////////////////////////////////////////////
 
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 08c6a50..98c5497 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -92,6 +92,19 @@
     {"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
     {"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
     {"highspeed2160p", CAMCORDER_QUALITY_HIGH_SPEED_2160P},
+
+    // Vendor-specific profiles
+    {"vga", CAMCORDER_QUALITY_VGA},
+    {"4kdci", CAMCORDER_QUALITY_4KDCI},
+    {"timelapsevga", CAMCORDER_QUALITY_TIME_LAPSE_VGA},
+    {"timelapse4kdci", CAMCORDER_QUALITY_TIME_LAPSE_4KDCI},
+    {"highspeedcif", CAMCORDER_QUALITY_HIGH_SPEED_CIF},
+    {"highspeedvga", CAMCORDER_QUALITY_HIGH_SPEED_VGA},
+    {"highspeed4kdci", CAMCORDER_QUALITY_HIGH_SPEED_4KDCI},
+    {"qhd", CAMCORDER_QUALITY_QHD},
+    {"2k", CAMCORDER_QUALITY_2k},
+    {"timelapseqhd", CAMCORDER_QUALITY_TIME_LAPSE_QHD},
+    {"timelapse2k", CAMCORDER_QUALITY_TIME_LAPSE_2k},
 };
 
 #if LOG_NDEBUG
diff --git a/media/libmedia/include/media/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
index 0feb4f3..3e8e7c8 100644
--- a/media/libmedia/include/media/MediaProfiles.h
+++ b/media/libmedia/include/media/MediaProfiles.h
@@ -34,7 +34,11 @@
     CAMCORDER_QUALITY_1080P = 6,
     CAMCORDER_QUALITY_QVGA = 7,
     CAMCORDER_QUALITY_2160P = 8,
-    CAMCORDER_QUALITY_LIST_END = 8,
+    CAMCORDER_QUALITY_VGA = 9,
+    CAMCORDER_QUALITY_4KDCI = 10,
+    CAMCORDER_QUALITY_QHD = 11,
+    CAMCORDER_QUALITY_2k = 12,
+    CAMCORDER_QUALITY_LIST_END = 12,
 
     CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
@@ -46,7 +50,11 @@
     CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
     CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
     CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
-    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
+    CAMCORDER_QUALITY_TIME_LAPSE_VGA = 1009,
+    CAMCORDER_QUALITY_TIME_LAPSE_4KDCI = 1010,
+    CAMCORDER_QUALITY_TIME_LAPSE_QHD = 1011,
+    CAMCORDER_QUALITY_TIME_LAPSE_2k = 1012,
+    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1012,
 
     CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
     CAMCORDER_QUALITY_HIGH_SPEED_LOW  = 2000,
@@ -55,7 +63,10 @@
     CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
     CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
     CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
-    CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
+    CAMCORDER_QUALITY_HIGH_SPEED_CIF = 2006,
+    CAMCORDER_QUALITY_HIGH_SPEED_VGA = 2007,
+    CAMCORDER_QUALITY_HIGH_SPEED_4KDCI = 2008,
+    CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2008,
 };
 
 enum video_decoder {
diff --git a/media/libmedia/include/media/omx/1.0/WOmxNode.h b/media/libmedia/include/media/omx/1.0/WOmxNode.h
index eebc8c6..1db4248 100644
--- a/media/libmedia/include/media/omx/1.0/WOmxNode.h
+++ b/media/libmedia/include/media/omx/1.0/WOmxNode.h
@@ -59,7 +59,7 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-struct LWOmxNode : public H2BConverter<IOmxNode, IOMXNode, BnOMXNode> {
+struct LWOmxNode : public H2BConverter<IOmxNode, BnOMXNode> {
     LWOmxNode(sp<IOmxNode> const& base) : CBase(base) {}
     status_t freeNode() override;
     status_t sendCommand(
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 31d1df9..1ed1d07 100644
--- a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -32,7 +32,7 @@
 
 BnStatus LWGraphicBufferSource::configure(
         const sp<IOMXNode>& omxNode, int32_t dataSpace) {
-    sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
+    sp<IOmxNode> hOmxNode = omxNode->getHalInterface<IOmxNode>();
     return toBinderStatus(mBase->configure(
             hOmxNode == nullptr ? new TWOmxNode(omxNode) : hOmxNode,
             toHardwareDataspace(dataSpace)));
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 52cb5fa..998f096 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4431,9 +4431,9 @@
         h264type.nRefFrames = 2;
         h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
 
-        // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
-        // h264type.nRefFrames = 1;
-        // h264type.nBFrames = 0;
+        // disable B-frames until we have explicit settings for enabling the feature.
+        h264type.nRefFrames = 1;
+        h264type.nBFrames = 0;
 
         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
         h264type.nAllowedPictureTypes =
@@ -6539,8 +6539,10 @@
 
     if (mDeathNotifier != NULL) {
         if (mCodec->mOMXNode != NULL) {
-            auto tOmxNode = mCodec->mOMXNode->getHalInterface();
-            tOmxNode->unlinkToDeath(mDeathNotifier);
+            auto tOmxNode = mCodec->mOMXNode->getHalInterface<IOmxNode>();
+            if (tOmxNode) {
+                tOmxNode->unlinkToDeath(mDeathNotifier);
+            }
         }
         mDeathNotifier.clear();
     }
@@ -6668,8 +6670,8 @@
     }
 
     mDeathNotifier = new DeathNotifier(notify);
-    auto tOmxNode = omxNode->getHalInterface();
-    if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+    auto tOmxNode = omxNode->getHalInterface<IOmxNode>();
+    if (tOmxNode && !tOmxNode->linkToDeath(mDeathNotifier, 0)) {
         mDeathNotifier.clear();
     }
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 74754ea..339f622 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -106,6 +106,10 @@
         symbol_file: "libmediandk.map.txt",
         versions: ["29"],
     },
+
+    // Bug: http://b/124522995 libmediandk has linker errors when built with
+    // coverage
+    native_coverage: false,
 }
 
 llndk_library {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2d80bd8..4033247 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -347,7 +347,7 @@
             return ret;
         }
     }
-    return AudioMixer::HAPTIC_SCALE_NONE;
+    return AudioMixer::HAPTIC_SCALE_MUTE;
 }
 
 /* static */
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index c27f2b7..396c797 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -49,7 +49,7 @@
     audio_format_t          mFormat;         // track format
     int                     mGeneration;     // increment when any field is assigned
     bool                    mHapticPlaybackEnabled = false; // haptic playback is enabled or not
-    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE; // intensity of
+    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE; // intensity of
                                                                                      // haptic data
 };
 
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 3381e4d..676a575 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -211,8 +211,8 @@
                 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
                  ((patch->sinks[0].ext.device.hw_module != srcModule) ||
                   !audioHwDevice->supportsAudioPatches()))) {
-                audio_devices_t outputDevice = AUDIO_DEVICE_NONE;
-                String8 outputDeviceAddress;
+                audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
+                String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
                 if (patch->num_sources == 2) {
                     if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
                             (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
@@ -234,8 +234,6 @@
                             reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
                 } else {
                     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
-                    audio_devices_t device = patch->sinks[0].ext.device.type;
-                    String8 address = String8(patch->sinks[0].ext.device.address);
                     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
@@ -254,8 +252,8 @@
                                                             patch->sinks[0].ext.device.hw_module,
                                                             &output,
                                                             &config,
-                                                            device,
-                                                            address,
+                                                            outputDevice,
+                                                            outputDeviceAddress,
                                                             flags);
                     ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
                     if (thread == 0) {
@@ -263,8 +261,6 @@
                         goto exit;
                     }
                     newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
-                    outputDevice = device;
-                    outputDeviceAddress = address;
                 }
                 audio_devices_t device = patch->sources[0].ext.device.type;
                 String8 address = String8(patch->sources[0].ext.device.address);
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 94ea042..357370e 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -124,6 +124,7 @@
             void    setHapticIntensity(AudioMixer::haptic_intensity_t hapticIntensity) {
                 if (AudioMixer::isValidHapticIntensity(hapticIntensity)) {
                     mHapticIntensity = hapticIntensity;
+                    setHapticPlaybackEnabled(mHapticIntensity != AudioMixer::HAPTIC_SCALE_MUTE);
                 }
             }
             sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
@@ -208,7 +209,7 @@
 
     bool                mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
     // intensity to play haptic data
-    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE;
+    AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE;
     class AudioVibrationController : public os::BnExternalVibrationController {
     public:
         explicit AudioVibrationController(Track* track) : mTrack(track) {}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6dd9cab..a8c4bd1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2372,6 +2372,7 @@
             const int intensity = AudioFlinger::onExternalVibrationStart(
                     track->getExternalVibration());
             mLock.lock();
+            track->setHapticIntensity(static_cast<AudioMixer::haptic_intensity_t>(intensity));
             // Haptic playback should be enabled by vibrator service.
             if (track->getHapticPlaybackEnabled()) {
                 // Disable haptic playback of all active track to ensure only
@@ -2380,7 +2381,6 @@
                     t->setHapticPlaybackEnabled(false);
                 }
             }
-            track->setHapticIntensity(intensity);
         }
 
         track->mResetDone = false;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 922547d..65f799e 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -698,6 +698,7 @@
 // TODO: compensate for time shift between HW modules.
 void AudioFlinger::PlaybackThread::Track::interceptBuffer(
         const AudioBufferProvider::Buffer& sourceBuffer) {
+    auto start = std::chrono::steady_clock::now();
     const size_t frameCount = sourceBuffer.frameCount;
     for (auto& sink : mTeePatches) {
         RecordThread::PatchRecord* patchRecord = sink.patchRecord.get();
@@ -715,6 +716,11 @@
                  "buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->mId,
                  framesWritten, frameCount, framesLeft);
     }
+    auto spent = ceil<std::chrono::microseconds>(std::chrono::steady_clock::now() - start);
+    using namespace std::chrono_literals;
+    // Average is ~20us per track, this should virtually never be logged (Logging takes >200us)
+    ALOGD_IF(spent > 200us, "%s: took %lldus to intercept %zu tracks", __func__,
+             spent.count(), mTeePatches.size());
 }
 
 size_t AudioFlinger::PlaybackThread::Track::writeFrames(AudioBufferProvider* dest,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5c22727..32cc380 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -560,6 +560,10 @@
         muteWaitMs = setOutputDevices(mPrimaryOutput, rxDevices, true, delayMs);
     } else { // create RX path audio patch
         mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevices.itemAt(0), delayMs);
+
+        // If the TX device is on the primary HW module but RX device is
+        // on other HW module, SinkMetaData of telephony input should handle it
+        // assuming the device uses audio HAL V5.0 and above
     }
     if (createTxPatch) { // create TX path audio patch
         mCallTxPatch = createTelephonyPatch(false /*isRx*/, txSourceDevice, delayMs);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index a39477d..76ac191 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -383,6 +383,8 @@
 //    OR The client is an accessibility service
 //        AND is on TOP OR latest started
 //        AND the source is VOICE_RECOGNITION or HOTWORD
+//    OR the source is one of: AUDIO_SOURCE_VOICE_DOWNLINK, AUDIO_SOURCE_VOICE_UPLINK,
+//       AUDIO_SOURCE_VOICE_CALL
 //    OR Any other client
 //        AND The assistant is not on TOP
 //        AND is on TOP OR latest started
@@ -463,6 +465,10 @@
                 (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD)) {
                 forceIdle = false;
             }
+        } else if (source == AUDIO_SOURCE_VOICE_DOWNLINK ||
+                   source == AUDIO_SOURCE_VOICE_CALL ||
+                   (source == AUDIO_SOURCE_VOICE_UPLINK)) {
+            forceIdle = false;
         } else {
             if (!isAssistantOnTop && (isOnTop || isLatest) &&
                 (!isSensitiveActive || isLatestSensitive)) {
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 8e9c39e..a61cdee 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -136,6 +136,8 @@
     mAppSegmentConsumer->setName(String8("Camera3-HeicComposite-AppSegmentStream"));
     mAppSegmentSurface = new Surface(producer);
 
+    mStaticInfo = device->info();
+
     res = device->createStream(mAppSegmentSurface, mAppSegmentMaxSize, 1, format,
             kAppSegmentDataSpace, rotation, &mAppSegmentStreamId, physicalCameraId, surfaceIds);
     if (res == OK) {
@@ -606,9 +608,42 @@
         mFrameNumberMap.erase(it);
     }
 
-    // Heic composition doesn't depend on capture result, so no need to check
-    // mErrorFrameNumbers. Just remove them.
-    mErrorFrameNumbers.clear();
+    while (!mCaptureResults.empty()) {
+        auto it = mCaptureResults.begin();
+        // Negative timestamp indicates that something went wrong during the capture result
+        // collection process.
+        if (it->first >= 0) {
+            if (mPendingInputFrames[it->first].frameNumber == std::get<0>(it->second)) {
+                mPendingInputFrames[it->first].result =
+                        std::make_unique<CameraMetadata>(std::get<1>(it->second));
+            } else {
+                ALOGE("%s: Capture result frameNumber/timestamp mapping changed between "
+                        "shutter and capture result!", __FUNCTION__);
+            }
+        }
+        mCaptureResults.erase(it);
+    }
+
+    // mErrorFrameNumbers stores frame number of dropped buffers.
+    auto it = mErrorFrameNumbers.begin();
+    while (it != mErrorFrameNumbers.end()) {
+        bool frameFound = false;
+        for (auto &inputFrame : mPendingInputFrames) {
+            if (inputFrame.second.frameNumber == *it) {
+                inputFrame.second.error = true;
+                frameFound = true;
+                break;
+            }
+        }
+
+        if (frameFound) {
+            it = mErrorFrameNumbers.erase(it);
+        } else {
+            ALOGW("%s: Not able to find failing input with frame number: %" PRId64, __FUNCTION__,
+                    *it);
+            it++;
+        }
+    }
 
     // Distribute codec input buffers to be filled out from YUV output
     for (auto it = mPendingInputFrames.begin();
@@ -639,14 +674,14 @@
 
     bool newInputAvailable = false;
     for (const auto& it : mPendingInputFrames) {
-        bool appSegmentBufferReady = (it.second.appSegmentBuffer.data != nullptr) &&
-                !it.second.appSegmentWritten;
+        bool appSegmentReady = (it.second.appSegmentBuffer.data != nullptr) &&
+                !it.second.appSegmentWritten && it.second.result != nullptr;
         bool codecOutputReady = !it.second.codecOutputBuffers.empty();
         bool codecInputReady = (it.second.yuvBuffer.data != nullptr) &&
                 (!it.second.codecInputBuffers.empty());
         if ((!it.second.error) &&
                 (it.first < *currentTs) &&
-                (appSegmentBufferReady || codecOutputReady || codecInputReady)) {
+                (appSegmentReady || codecOutputReady || codecInputReady)) {
             *currentTs = it.first;
             newInputAvailable = true;
             break;
@@ -678,13 +713,13 @@
     ATRACE_CALL();
     status_t res = OK;
 
-    bool appSegmentBufferReady = inputFrame.appSegmentBuffer.data != nullptr &&
-            !inputFrame.appSegmentWritten;
+    bool appSegmentReady = inputFrame.appSegmentBuffer.data != nullptr &&
+            !inputFrame.appSegmentWritten && inputFrame.result != nullptr;
     bool codecOutputReady = inputFrame.codecOutputBuffers.size() > 0;
     bool codecInputReady = inputFrame.yuvBuffer.data != nullptr &&
            !inputFrame.codecInputBuffers.empty();
 
-    if (!appSegmentBufferReady && !codecOutputReady && !codecInputReady) {
+    if (!appSegmentReady && !codecOutputReady && !codecInputReady) {
         ALOGW("%s: No valid appSegmentBuffer/codec input/outputBuffer available!", __FUNCTION__);
         return OK;
     }
@@ -710,7 +745,7 @@
     }
 
     // Write JPEG APP segments data to the muxer.
-    if (appSegmentBufferReady && inputFrame.muxer != nullptr) {
+    if (appSegmentReady && inputFrame.muxer != nullptr) {
         res = processAppSegment(timestamp, inputFrame);
         if (res != OK) {
             ALOGE("%s: Failed to process JPEG APP segments: %s (%d)", __FUNCTION__,
@@ -829,10 +864,8 @@
         ALOGE("%s: Failed to initialize ExifUtils object!", __FUNCTION__);
         return BAD_VALUE;
     }
-    //TODO: Use capture result metadata and static metadata to fill out the
-    //rest.
-    CameraMetadata dummyMeta;
-    exifRes = exifUtils->setFromMetadata(dummyMeta, mOutputWidth, mOutputHeight);
+    exifRes = exifUtils->setFromMetadata(*inputFrame.result, mStaticInfo,
+            mOutputWidth, mOutputHeight);
     if (!exifRes) {
         ALOGE("%s: Failed to set Exif tags using metadata and main image sizes", __FUNCTION__);
         return BAD_VALUE;
@@ -1012,6 +1045,7 @@
     }
     inputFrame.anb = nullptr;
 
+    ATRACE_ASYNC_END("HEIC capture", inputFrame.frameNumber);
     return OK;
 }
 
@@ -1497,6 +1531,36 @@
     return res;
 }
 
+void HeicCompositeStream::onResultError(const CaptureResultExtras& resultExtras) {
+    // For result error, since the APPS_SEGMENT buffer already contains EXIF,
+    // simply skip using the capture result metadata to override EXIF.
+    Mutex::Autolock l(mMutex);
+
+    int64_t timestamp = -1;
+    for (const auto& fn : mFrameNumberMap) {
+        if (fn.first == resultExtras.frameNumber) {
+            timestamp = fn.second;
+            break;
+        }
+    }
+    if (timestamp == -1) {
+        for (const auto& inputFrame : mPendingInputFrames) {
+            if (inputFrame.second.frameNumber == resultExtras.frameNumber) {
+                timestamp = inputFrame.first;
+                break;
+            }
+        }
+    }
+
+    if (timestamp == -1) {
+        ALOGE("%s: Failed to find shutter timestamp for result error!", __FUNCTION__);
+        return;
+    }
+
+    mCaptureResults.emplace(timestamp, std::make_tuple(resultExtras.frameNumber, CameraMetadata()));
+    mInputReadyCondition.signal();
+}
+
 void HeicCompositeStream::CodecCallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
     sp<HeicCompositeStream> parent = mParent.promote();
     if (parent == nullptr) return;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 0a76256..4cd9af0 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -77,7 +77,7 @@
 
     bool threadLoop() override;
     bool onStreamBufferError(const CaptureResultExtras& resultExtras) override;
-    void onResultError(const CaptureResultExtras& /*resultExtras*/) override {}
+    void onResultError(const CaptureResultExtras& resultExtras) override;
 
 private:
     //
@@ -145,12 +145,13 @@
         int32_t                   orientation;
         int32_t                   quality;
 
-        CpuConsumer::LockedBuffer     appSegmentBuffer;
+        CpuConsumer::LockedBuffer          appSegmentBuffer;
         std::vector<CodecOutputBufferInfo> codecOutputBuffers;
+        std::unique_ptr<CameraMetadata>    result;
 
         // Fields that are only applicable to HEVC tiling.
-        CpuConsumer::LockedBuffer     yuvBuffer;
-        std::vector<CodecInputBufferInfo> codecInputBuffers;
+        CpuConsumer::LockedBuffer          yuvBuffer;
+        std::vector<CodecInputBufferInfo>  codecInputBuffers;
 
         bool                      error;
         bool                      errorNotified;
@@ -209,6 +210,7 @@
     sp<Surface>       mAppSegmentSurface;
     bool              mAppSegmentBufferAcquired;
     size_t            mAppSegmentMaxSize;
+    CameraMetadata    mStaticInfo;
 
     int               mMainImageStreamId, mMainImageSurfaceId;
     sp<Surface>       mMainImageSurface;
diff --git a/services/camera/libcameraservice/utils/ExifUtils.cpp b/services/camera/libcameraservice/utils/ExifUtils.cpp
index a4027cc..4dea8b5 100644
--- a/services/camera/libcameraservice/utils/ExifUtils.cpp
+++ b/services/camera/libcameraservice/utils/ExifUtils.cpp
@@ -58,79 +58,59 @@
 
     // set all known fields from a metadata structure
     virtual bool setFromMetadata(const CameraMetadata& metadata,
+            const CameraMetadata& staticInfo,
             const size_t imageWidth,
             const size_t imageHeight);
 
     // sets the len aperture.
     // Returns false if memory allocation fails.
-    virtual bool setAperture(uint32_t numerator, uint32_t denominator);
-
-    // sets the value of brightness.
-    // Returns false if memory allocation fails.
-    virtual bool setBrightness(int32_t numerator, int32_t denominator);
+    virtual bool setAperture(float aperture);
 
     // sets the color space.
     // Returns false if memory allocation fails.
     virtual bool setColorSpace(uint16_t color_space);
 
-    // sets the information to compressed data.
-    // Returns false if memory allocation fails.
-    virtual bool setComponentsConfiguration(const std::string& components_configuration);
-
-    // sets the compression scheme used for the image data.
-    // Returns false if memory allocation fails.
-    virtual bool setCompression(uint16_t compression);
-
-    // sets image contrast.
-    // Returns false if memory allocation fails.
-    virtual bool setContrast(uint16_t contrast);
-
     // sets the date and time of image last modified. It takes local time. The
     // name of the tag is DateTime in IFD0.
     // Returns false if memory allocation fails.
     virtual bool setDateTime(const struct tm& t);
 
-    // sets the image description.
-    // Returns false if memory allocation fails.
-    virtual bool setDescription(const std::string& description);
-
     // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
     // was not used.
     // Returns false if memory allocation fails.
-    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
+    virtual bool setDigitalZoomRatio(
+            uint32_t crop_width, uint32_t crop_height,
+            uint32_t sensor_width, uint32_t sensor_height);
 
-    // sets the exposure bias.
+    // Sets the exposure bias.
     // Returns false if memory allocation fails.
-    virtual bool setExposureBias(int32_t numerator, int32_t denominator);
+    virtual bool setExposureBias(int32_t ev,
+            uint32_t ev_step_numerator, uint32_t ev_step_denominator);
 
     // sets the exposure mode set when the image was shot.
     // Returns false if memory allocation fails.
-    virtual bool setExposureMode(uint16_t exposure_mode);
-
-    // sets the program used by the camera to set exposure when the picture is
-    // taken.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureProgram(uint16_t exposure_program);
+    virtual bool setExposureMode(uint8_t exposure_mode);
 
     // sets the exposure time, given in seconds.
     // Returns false if memory allocation fails.
-    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
+    virtual bool setExposureTime(float exposure_time);
 
     // sets the status of flash.
     // Returns false if memory allocation fails.
-    virtual bool setFlash(uint16_t flash);
+    virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode);
 
     // sets the F number.
     // Returns false if memory allocation fails.
-    virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
+    virtual bool setFNumber(float f_number);
 
     // sets the focal length of lens used to take the image in millimeters.
     // Returns false if memory allocation fails.
-    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
+    virtual bool setFocalLength(float focal_length);
 
-    // sets the degree of overall image gain adjustment.
+    // sets the focal length of lens for 35mm film used to take the image in millimeters.
     // Returns false if memory allocation fails.
-    virtual bool setGainControl(uint16_t gain_control);
+    virtual bool setFocalLengthIn35mmFilm(float focal_length,
+            float sensor_size_x, float sensor_size_y);
 
     // sets the altitude in meters.
     // Returns false if memory allocation fails.
@@ -164,45 +144,21 @@
     // Returns false if memory allocation fails.
     virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
 
-    // sets the kind of light source.
-    // Returns false if memory allocation fails.
-    virtual bool setLightSource(uint16_t light_source);
-
     // sets the smallest F number of the lens.
     // Returns false if memory allocation fails.
-    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
-
-    // sets the metering mode.
-    // Returns false if memory allocation fails.
-    virtual bool setMeteringMode(uint16_t metering_mode);
+    virtual bool setMaxAperture(float aperture);
 
     // sets image orientation.
     // Returns false if memory allocation fails.
     virtual bool setOrientation(uint16_t orientation);
 
-    // sets the unit for measuring XResolution and YResolution.
-    // Returns false if memory allocation fails.
-    virtual bool setResolutionUnit(uint16_t resolution_unit);
-
-    // sets image saturation.
-    // Returns false if memory allocation fails.
-    virtual bool setSaturation(uint16_t saturation);
-
-    // sets the type of scene that was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setSceneCaptureType(uint16_t type);
-
-    // sets image sharpness.
-    // Returns false if memory allocation fails.
-    virtual bool setSharpness(uint16_t sharpness);
-
     // sets the shutter speed.
     // Returns false if memory allocation fails.
-    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
+    virtual bool setShutterSpeed(float exposure_time);
 
     // sets the distance to the subject, given in meters.
     // Returns false if memory allocation fails.
-    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
+    virtual bool setSubjectDistance(float diopters);
 
     // sets the fractions of seconds for the <DateTime> tag.
     // Returns false if memory allocation fails.
@@ -210,28 +166,7 @@
 
     // sets the white balance mode set when the image was shot.
     // Returns false if memory allocation fails.
-    virtual bool setWhiteBalance(uint16_t white_balance);
-
-    // sets the number of pixels per resolution unit in the image width.
-    // Returns false if memory allocation fails.
-    virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
-
-    // sets the position of chrominance components in relation to the luminance
-    // component.
-    // Returns false if memory allocation fails.
-    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
-
-    // sets the number of pixels per resolution unit in the image length.
-    // Returns false if memory allocation fails.
-    virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
-
-    // sets the manufacturer of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setMake(const std::string& make);
-
-    // sets the model number of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setModel(const std::string& model);
+    virtual bool setWhiteBalance(uint8_t white_balance);
 
     // Generates APP1 segment.
     // Returns false if generating APP1 segment fails.
@@ -280,6 +215,10 @@
     virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
             const std::string& buffer, const std::string& msg);
 
+    float convertToApex(float val) {
+        return 2.0f * log2f(val);
+    }
+
     // Destroys the buffer of APP1 segment if exists.
     virtual void destroyApp1();
 
@@ -291,6 +230,8 @@
     // The length of |app1_buffer_|.
     unsigned int app1_length_;
 
+    // How precise the float-to-rational conversion for EXIF tags would be.
+    const static int kRationalPrecision = 10000;
 };
 
 #define SET_SHORT(ifd, tag, value)                      \
@@ -373,13 +314,11 @@
     return true;
 }
 
-bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
+bool ExifUtilsImpl::setAperture(float aperture) {
+    float apexValue = convertToApex(aperture);
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
+            static_cast<uint32_t>(std::round(apexValue * kRationalPrecision)),
+            kRationalPrecision);
     return true;
 }
 
@@ -388,23 +327,6 @@
     return true;
 }
 
-bool ExifUtilsImpl::setComponentsConfiguration(
-        const std::string& components_configuration) {
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
-            EXIF_FORMAT_UNDEFINED, components_configuration);
-    return true;
-}
-
-bool ExifUtilsImpl::setCompression(uint16_t compression) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
-    return true;
-}
-
-bool ExifUtilsImpl::setContrast(uint16_t contrast) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
-    return true;
-}
-
 bool ExifUtilsImpl::setDateTime(const struct tm& t) {
     // The length is 20 bytes including NULL for termination in Exif standard.
     char str[20];
@@ -421,53 +343,111 @@
     return true;
 }
 
-bool ExifUtilsImpl::setDescription(const std::string& description) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
+bool ExifUtilsImpl::setDigitalZoomRatio(
+        uint32_t crop_width, uint32_t crop_height,
+        uint32_t sensor_width, uint32_t sensor_height) {
+    float zoomRatioX = (crop_width == 0) ? 1.0 : 1.0 * sensor_width / crop_width;
+    float zoomRatioY = (crop_height == 0) ? 1.0 : 1.0 * sensor_height / crop_height;
+    float zoomRatio = std::max(zoomRatioX, zoomRatioY);
+    const static float noZoomThreshold = 1.02f;
+
+    if (zoomRatio <= noZoomThreshold) {
+        SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, 0, 1);
+    } else {
+        SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
+                static_cast<uint32_t>(std::round(zoomRatio * kRationalPrecision)),
+                kRationalPrecision);
+    }
     return true;
 }
 
-bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
+bool ExifUtilsImpl::setExposureMode(uint8_t exposure_mode) {
+    uint16_t exposureMode = (exposure_mode == ANDROID_CONTROL_AE_MODE_OFF) ? 1 : 0;
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposureMode);
     return true;
 }
 
-bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
+bool ExifUtilsImpl::setExposureTime(float exposure_time) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
+            static_cast<uint32_t>(std::round(exposure_time * kRationalPrecision)),
+            kRationalPrecision);
     return true;
 }
 
-bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
-    return true;
-}
+bool ExifUtilsImpl::setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) {
+    // EXIF_TAG_FLASH bits layout per EXIF standard:
+    // Bit 0:    0 - did not fire
+    //           1 - fired
+    // Bit 1-2:  status of return light
+    // Bit 3-4:  0 - unknown
+    //           1 - compulsory flash firing
+    //           2 - compulsory flash suppression
+    //           3 - auto mode
+    // Bit 5:    0 - flash function present
+    //           1 - no flash function
+    // Bit 6:    0 - no red-eye reduction mode or unknown
+    //           1 - red-eye reduction supported
+    uint16_t flash = 0x20;
 
-bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
-    return true;
-}
+    if (flash_available == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+        flash = 0x00;
 
-bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
-    return true;
-}
+        if (flash_state == ANDROID_FLASH_STATE_FIRED) {
+            flash |= 0x1;
+        }
+        if (ae_mode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
+            flash |= 0x40;
+        }
 
-bool ExifUtilsImpl::setFlash(uint16_t flash) {
+        uint16_t flashMode = 0;
+        switch (ae_mode) {
+            case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
+            case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
+               flashMode = 3; // AUTO
+               break;
+            case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+            case ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
+               flashMode = 1; // ON
+               break;
+            case ANDROID_CONTROL_AE_MODE_OFF:
+            case ANDROID_CONTROL_AE_MODE_ON:
+               flashMode = 2; // OFF
+               break;
+            default:
+               flashMode = 0; // UNKNOWN
+               break;
+        }
+        flash |= (flashMode << 3);
+    }
     SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
     return true;
 }
 
-bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
+bool ExifUtilsImpl::setFNumber(float f_number) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
+            static_cast<uint32_t>(std::round(f_number * kRationalPrecision)),
+            kRationalPrecision);
     return true;
 }
 
-bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
+bool ExifUtilsImpl::setFocalLength(float focal_length) {
+    uint32_t numerator = static_cast<uint32_t>(std::round(focal_length * kRationalPrecision));
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, kRationalPrecision);
     return true;
 }
 
-bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
+bool ExifUtilsImpl::setFocalLengthIn35mmFilm(
+        float focal_length, float sensor_size_x, float sensor_size_y) {
+    static const float filmDiagonal = 43.27; // diagonal of 35mm film
+    static const float minSensorDiagonal = 0.01;
+    float sensorDiagonal = std::sqrt(
+            sensor_size_x * sensor_size_x + sensor_size_y * sensor_size_y);
+    sensorDiagonal = std::max(sensorDiagonal, minSensorDiagonal);
+    float focalLength35mmFilm = std::round(focal_length * filmDiagonal / sensorDiagonal);
+    focalLength35mmFilm = std::min(1.0f * 65535, focalLength35mmFilm);
+
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
+            static_cast<uint16_t>(focalLength35mmFilm));
     return true;
 }
 
@@ -614,18 +594,18 @@
     return true;
 }
 
-bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
+bool ExifUtilsImpl::setMaxAperture(float aperture) {
+    float maxAperture = convertToApex(aperture);
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
+            static_cast<uint32_t>(std::round(maxAperture * kRationalPrecision)),
+            kRationalPrecision);
     return true;
 }
 
-bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
+bool ExifUtilsImpl::setExposureBias(int32_t ev,
+        uint32_t ev_step_numerator, uint32_t ev_step_denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
+            ev * ev_step_numerator, ev_step_denominator);
     return true;
 }
 
@@ -658,33 +638,36 @@
     return true;
 }
 
-bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
+bool ExifUtilsImpl::setShutterSpeed(float exposure_time) {
+    float shutterSpeed = -log2f(exposure_time);
+    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
+            static_cast<uint32_t>(shutterSpeed * kRationalPrecision), kRationalPrecision);
     return true;
 }
 
-bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
-    return true;
-}
+bool ExifUtilsImpl::setSubjectDistance(float diopters) {
+    const static float kInfinityDiopters = 1.0e-6;
+    uint32_t numerator, denominator;
+    uint16_t distanceRange;
+    if (diopters > kInfinityDiopters) {
+        float focusDistance = 1.0f / diopters;
+        numerator = static_cast<uint32_t>(std::round(focusDistance * kRationalPrecision));
+        denominator = kRationalPrecision;
 
-bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
-    return true;
-}
-
-bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
-    return true;
-}
-
-bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
+        if (focusDistance < 1.0f) {
+            distanceRange = 1; // Macro
+        } else if (focusDistance < 3.0f) {
+            distanceRange = 2; // Close
+        } else {
+            distanceRange = 3; // Distant
+        }
+    } else {
+        numerator = 0xFFFFFFFF;
+        denominator = 1;
+        distanceRange = 3; // Distant
+    }
     SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE, distanceRange);
     return true;
 }
 
@@ -695,23 +678,9 @@
     return true;
 }
 
-bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
-    return true;
-}
-
-bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
-    return true;
-}
-
-bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
+bool ExifUtilsImpl::setWhiteBalance(uint8_t white_balance) {
+    uint16_t whiteBalance = (white_balance == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, whiteBalance);
     return true;
 }
 
@@ -748,16 +717,6 @@
     return true;
 }
 
-bool ExifUtilsImpl::setMake(const std::string& make) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
-    return true;
-}
-
-bool ExifUtilsImpl::setModel(const std::string& model) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
-    return true;
-}
-
 void ExifUtilsImpl::reset() {
     destroyApp1();
     if (exif_data_) {
@@ -898,9 +857,8 @@
 }
 
 bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
+        const CameraMetadata& staticInfo,
         const size_t imageWidth, const size_t imageHeight) {
-    // How precise the float-to-rational conversion for EXIF tags would be.
-    constexpr int kRationalPrecision = 10000;
     if (!setImageWidth(imageWidth) ||
             !setImageHeight(imageHeight)) {
         ALOGE("%s: setting image resolution failed.", __FUNCTION__);
@@ -921,15 +879,37 @@
     if (entry.count) {
         focal_length = entry.data.f[0];
 
-        if (!setFocalLength(
-                static_cast<uint32_t>(focal_length * kRationalPrecision), kRationalPrecision)) {
+        if (!setFocalLength(focal_length)) {
             ALOGE("%s: setting focal length failed.", __FUNCTION__);
             return false;
         }
+
+        camera_metadata_ro_entry sensorSizeEntry =
+                staticInfo.find(ANDROID_SENSOR_INFO_PHYSICAL_SIZE);
+        if (sensorSizeEntry.count == 2) {
+            if (!setFocalLengthIn35mmFilm(
+                    focal_length, sensorSizeEntry.data.f[0], sensorSizeEntry.data.f[1])) {
+                ALOGE("%s: setting focal length in 35mm failed.", __FUNCTION__);
+                return false;
+            }
+        }
     } else {
         ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
     }
 
+    if (metadata.exists(ANDROID_SCALER_CROP_REGION) &&
+            staticInfo.exists(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE)) {
+        entry = metadata.find(ANDROID_SCALER_CROP_REGION);
+        camera_metadata_ro_entry activeArrayEntry =
+                staticInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+        if (!setDigitalZoomRatio(entry.data.i32[2], entry.data.i32[3],
+                activeArrayEntry.data.i32[2], activeArrayEntry.data.i32[3])) {
+            ALOGE("%s: setting digital zoom ratio failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
     if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
         entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
         if (entry.count < 3) {
@@ -973,6 +953,18 @@
         }
     }
 
+    if (staticInfo.exists(ANDROID_CONTROL_AE_COMPENSATION_STEP) &&
+            metadata.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
+        entry = metadata.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION);
+        camera_metadata_ro_entry stepEntry =
+                staticInfo.find(ANDROID_CONTROL_AE_COMPENSATION_STEP);
+        if (!setExposureBias(entry.data.i32[0], stepEntry.data.r[0].numerator,
+                stepEntry.data.r[0].denominator)) {
+            ALOGE("%s: setting exposure bias failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
     if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
         entry = metadata.find(ANDROID_JPEG_ORIENTATION);
         if (!setOrientation(entry.data.i32[0])) {
@@ -983,50 +975,97 @@
 
     if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
         entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
-        // int64_t of nanoseconds
-        if (!setExposureTime(entry.data.i64[0],1000000000u)) {
+        float exposure_time = 1.0f * entry.data.i64[0] / 1e9;
+        if (!setExposureTime(exposure_time)) {
             ALOGE("%s: setting exposure time failed.", __FUNCTION__);
             return false;
         }
+
+        if (!setShutterSpeed(exposure_time)) {
+            ALOGE("%s: setting shutter speed failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
+        entry = metadata.find(ANDROID_LENS_FOCUS_DISTANCE);
+        if (!setSubjectDistance(entry.data.f[0])) {
+            ALOGE("%s: setting subject distance failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_SENSOR_SENSITIVITY)) {
+        entry = metadata.find(ANDROID_SENSOR_SENSITIVITY);
+        int32_t iso = entry.data.i32[0];
+        camera_metadata_ro_entry postRawSensEntry =
+                metadata.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+        if (postRawSensEntry.count > 0) {
+            iso = iso * postRawSensEntry.data.i32[0] / 100;
+        }
+
+        if (!setIsoSpeedRating(static_cast<uint16_t>(iso))) {
+            ALOGE("%s: setting iso rating failed.", __FUNCTION__);
+            return false;
+        }
     }
 
     if (metadata.exists(ANDROID_LENS_APERTURE)) {
-        const int kAperturePrecision = 10000;
         entry = metadata.find(ANDROID_LENS_APERTURE);
-        if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
+        if (!setFNumber(entry.data.f[0])) {
             ALOGE("%s: setting F number failed.", __FUNCTION__);
             return false;
         }
+        if (!setAperture(entry.data.f[0])) {
+            ALOGE("%s: setting aperture failed.", __FUNCTION__);
+            return false;
+        }
     }
 
-    if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
-        entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
-        if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
-            const uint32_t kNoFlashFunction = 0x20;
-            if (!setFlash(kNoFlashFunction)) {
-                ALOGE("%s: setting flash failed.", __FUNCTION__);
-                return false;
-            }
-        } else {
-            ALOGE("%s: Unsupported flash info: %d",__FUNCTION__, entry.data.u8[0]);
+    static const uint16_t kSRGBColorSpace = 1;
+    if (!setColorSpace(kSRGBColorSpace)) {
+        ALOGE("%s: setting color space failed.", __FUNCTION__);
+        return false;
+    }
+
+    if (staticInfo.exists(ANDROID_LENS_INFO_AVAILABLE_APERTURES)) {
+        entry = staticInfo.find(ANDROID_LENS_INFO_AVAILABLE_APERTURES);
+        if (!setMaxAperture(entry.data.f[0])) {
+            ALOGE("%s: setting max aperture failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (staticInfo.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
+        entry = staticInfo.find(ANDROID_FLASH_INFO_AVAILABLE);
+        camera_metadata_ro_entry flashStateEntry = metadata.find(ANDROID_FLASH_STATE);
+        camera_metadata_ro_entry aeModeEntry = metadata.find(ANDROID_CONTROL_AE_MODE);
+        uint8_t flashState = flashStateEntry.count > 0 ?
+                flashStateEntry.data.u8[0] : ANDROID_FLASH_STATE_UNAVAILABLE;
+        uint8_t aeMode = aeModeEntry.count > 0 ?
+                aeModeEntry.data.u8[0] : ANDROID_CONTROL_AE_MODE_OFF;
+
+        if (!setFlash(entry.data.u8[0], flashState, aeMode)) {
+            ALOGE("%s: setting flash failed.", __FUNCTION__);
             return false;
         }
     }
 
     if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
         entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
-        if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
-            const uint16_t kAutoWhiteBalance = 0;
-            if (!setWhiteBalance(kAutoWhiteBalance)) {
-                ALOGE("%s: setting white balance failed.", __FUNCTION__);
-                return false;
-            }
-        } else {
-            ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
+        if (!setWhiteBalance(entry.data.u8[0])) {
+            ALOGE("%s: setting white balance failed.", __FUNCTION__);
             return false;
         }
     }
 
+    if (metadata.exists(ANDROID_CONTROL_AE_MODE)) {
+        entry = metadata.find(ANDROID_CONTROL_AE_MODE);
+        if (!setExposureMode(entry.data.u8[0])) {
+            ALOGE("%s: setting exposure mode failed.", __FUNCTION__);
+            return false;
+        }
+    }
     if (time_available) {
         char str[4];
         if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
diff --git a/services/camera/libcameraservice/utils/ExifUtils.h b/services/camera/libcameraservice/utils/ExifUtils.h
index 8ccdd8f..c78bab9 100644
--- a/services/camera/libcameraservice/utils/ExifUtils.h
+++ b/services/camera/libcameraservice/utils/ExifUtils.h
@@ -52,78 +52,57 @@
 
     // Set all known fields from a metadata structure
     virtual bool setFromMetadata(const CameraMetadata& metadata,
+            const CameraMetadata& staticInfo,
             const size_t imageWidth, const size_t imageHeight) = 0;
 
     // Sets the len aperture.
     // Returns false if memory allocation fails.
-    virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setAperture(float aperture) = 0;
 
-    // Sets the value of brightness.
-    // Returns false if memory allocation fails.
-    virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
-
-    // Sets the color space.
+    // sets the color space.
     // Returns false if memory allocation fails.
     virtual bool setColorSpace(uint16_t color_space) = 0;
 
-    // Sets the information to compressed data.
-    // Returns false if memory allocation fails.
-    virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
-
-    // Sets the compression scheme used for the image data.
-    // Returns false if memory allocation fails.
-    virtual bool setCompression(uint16_t compression) = 0;
-
-    // Sets image contrast.
-    // Returns false if memory allocation fails.
-    virtual bool setContrast(uint16_t contrast) = 0;
-
     // Sets the date and time of image last modified. It takes local time. The
     // name of the tag is DateTime in IFD0.
     // Returns false if memory allocation fails.
     virtual bool setDateTime(const struct tm& t) = 0;
 
-    // Sets the image description.
-    // Returns false if memory allocation fails.
-    virtual bool setDescription(const std::string& description) = 0;
-
     // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
     // was not used.
     // Returns false if memory allocation fails.
-    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setDigitalZoomRatio(uint32_t crop_width, uint32_t crop_height,
+            uint32_t sensor_width, uint32_t sensor_height) = 0;
 
     // Sets the exposure bias.
     // Returns false if memory allocation fails.
-    virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
+    virtual bool setExposureBias(int32_t ev,
+            uint32_t ev_step_numerator, uint32_t ev_step_denominator) = 0;
 
     // Sets the exposure mode set when the image was shot.
     // Returns false if memory allocation fails.
-    virtual bool setExposureMode(uint16_t exposure_mode) = 0;
-
-    // Sets the program used by the camera to set exposure when the picture is
-    // taken.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureProgram(uint16_t exposure_program) = 0;
+    virtual bool setExposureMode(uint8_t exposure_mode) = 0;
 
     // Sets the exposure time, given in seconds.
     // Returns false if memory allocation fails.
-    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setExposureTime(float exposure_time) = 0;
 
     // Sets the status of flash.
     // Returns false if memory allocation fails.
-    virtual bool setFlash(uint16_t flash) = 0;
+    virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) = 0;
 
     // Sets the F number.
     // Returns false if memory allocation fails.
-    virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setFNumber(float f_number) = 0;
 
     // Sets the focal length of lens used to take the image in millimeters.
     // Returns false if memory allocation fails.
-    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setFocalLength(float focal_length) = 0;
 
-    // Sets the degree of overall image gain adjustment.
+    // Sets the focal length of lens for 35mm film used to take the image in millimeters.
     // Returns false if memory allocation fails.
-    virtual bool setGainControl(uint16_t gain_control) = 0;
+    virtual bool setFocalLengthIn35mmFilm(float focal_length,
+            float sensor_size_x, float sensor_size_y) = 0;
 
     // Sets the altitude in meters.
     // Returns false if memory allocation fails.
@@ -157,45 +136,21 @@
     // Returns false if memory allocation fails.
     virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
 
-    // Sets the kind of light source.
-    // Returns false if memory allocation fails.
-    virtual bool setLightSource(uint16_t light_source) = 0;
-
     // Sets the smallest F number of the lens.
     // Returns false if memory allocation fails.
-    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the metering mode.
-    // Returns false if memory allocation fails.
-    virtual bool setMeteringMode(uint16_t metering_mode) = 0;
+    virtual bool setMaxAperture(float aperture) = 0;
 
     // Sets image orientation.
     // Returns false if memory allocation fails.
     virtual bool setOrientation(uint16_t orientation) = 0;
 
-    // Sets the unit for measuring XResolution and YResolution.
-    // Returns false if memory allocation fails.
-    virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
-
-    // Sets image saturation.
-    // Returns false if memory allocation fails.
-    virtual bool setSaturation(uint16_t saturation) = 0;
-
-    // Sets the type of scene that was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setSceneCaptureType(uint16_t type) = 0;
-
-    // Sets image sharpness.
-    // Returns false if memory allocation fails.
-    virtual bool setSharpness(uint16_t sharpness) = 0;
-
     // Sets the shutter speed.
     // Returns false if memory allocation fails.
-    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
+    virtual bool setShutterSpeed(float exposure_time) = 0;
 
     // Sets the distance to the subject, given in meters.
     // Returns false if memory allocation fails.
-    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
+    virtual bool setSubjectDistance(float diopters) = 0;
 
     // Sets the fractions of seconds for the <DateTime> tag.
     // Returns false if memory allocation fails.
@@ -203,28 +158,7 @@
 
     // Sets the white balance mode set when the image was shot.
     // Returns false if memory allocation fails.
-    virtual bool setWhiteBalance(uint16_t white_balance) = 0;
-
-    // Sets the number of pixels per resolution unit in the image width.
-    // Returns false if memory allocation fails.
-    virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the position of chrominance components in relation to the luminance
-    // component.
-    // Returns false if memory allocation fails.
-    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
-
-    // Sets the number of pixels per resolution unit in the image length.
-    // Returns false if memory allocation fails.
-    virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the manufacturer of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setMake(const std::string& make) = 0;
-
-    // Sets the model number of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setModel(const std::string& model) = 0;
+    virtual bool setWhiteBalance(uint8_t white_blanace) = 0;
 
     // Generates APP1 segment.
     // Returns false if generating APP1 segment fails.
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 9bdd4c8..3870a11 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -58,8 +58,4 @@
 getdents64: 1
 getrandom: 1
 
-# Used by UBSan diagnostic messages
-readlink: 1
-open: 1
-
 @include /system/etc/seccomp_policy/crash_dump.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index a1ef16f..845f84b 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -67,8 +67,4 @@
 getpid: 1
 gettid: 1
 
-# Used by UBSan diagnostic messages
-readlink: 1
-open: 1
-
 @include /system/etc/seccomp_policy/crash_dump.x86.policy