Merge "Fix base class of WifiHidlEnvironment_1_2" into pi-dev
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 69f8535..fd785df 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -53,6 +53,7 @@
         camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
         mDevice(device),
         mDeviceVersion(device->common.version),
+        mFreeBufEarly(shouldFreeBufEarly()),
         mIsAELockAvailable(false),
         mDerivePostRawSensKey(false),
         mNumPartialResults(1),
@@ -129,6 +130,10 @@
     return false;
 }
 
+bool CameraDeviceSession::shouldFreeBufEarly() {
+    return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
+}
+
 CameraDeviceSession::~CameraDeviceSession() {
     if (!isClosed()) {
         ALOGE("CameraDeviceSession deleted before close!");
@@ -887,6 +892,24 @@
         (*streams)[i] = &mStreamMap[id];
     }
 
+    if (mFreeBufEarly) {
+        // Remove buffers of deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                cleanupBuffersLocked(id);
+            }
+        }
+    }
+
     return true;
 }
 
@@ -908,7 +931,9 @@
             // Unmap all buffers of deleted stream
             // in case the configuration call succeeds and HAL
             // is able to release the corresponding resources too.
-            cleanupBuffersLocked(id);
+            if (!mFreeBufEarly) {
+                cleanupBuffersLocked(id);
+            }
             it = mStreamMap.erase(it);
         } else {
             ++it;
@@ -927,6 +952,27 @@
     mResultBatcher.setBatchedStreams(mVideoStreamIds);
 }
 
+
+void CameraDeviceSession::postProcessConfigurationFailureLocked(
+        const StreamConfiguration& requestedConfiguration) {
+    if (mFreeBufEarly) {
+        // Re-build the buf cache entry for deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+            }
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::configureStreams(
         const StreamConfiguration& requestedConfiguration,
         ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
@@ -979,6 +1025,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index af90e5a..bcee259 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -120,6 +120,8 @@
             hidl_vec<camera3_stream_t*> *streams /*out*/);
     void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
 
+    void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration);
+
 protected:
 
     // protecting mClosed/mDisconnected/mInitFail
@@ -142,6 +144,7 @@
 
     camera3_device_t* mDevice;
     const uint32_t mDeviceVersion;
+    const bool mFreeBufEarly;
     bool mIsAELockAvailable;
     bool mDerivePostRawSensKey;
     uint32_t mNumPartialResults;
@@ -293,6 +296,8 @@
 
     bool initialize();
 
+    static bool shouldFreeBufEarly();
+
     Status initStatus() const;
 
     // Validate and import request's input buffer and acquire fence
diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp
index d36e9ed..60174fb 100644
--- a/camera/device/3.3/default/CameraDeviceSession.cpp
+++ b/camera/device/3.3/default/CameraDeviceSession.cpp
@@ -92,6 +92,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index 6a18161..f2e031c 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -154,6 +154,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked_3_4(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked_3_4(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
@@ -215,6 +217,23 @@
         (*streams)[i] = &mStreamMap[id];
     }
 
+    if (mFreeBufEarly) {
+        // Remove buffers of deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.v3_2.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                cleanupBuffersLocked(id);
+            }
+        }
+    }
     return true;
 }
 
@@ -236,7 +255,9 @@
             // Unmap all buffers of deleted stream
             // in case the configuration call succeeds and HAL
             // is able to release the corresponding resources too.
-            cleanupBuffersLocked(id);
+            if (!mFreeBufEarly) {
+                cleanupBuffersLocked(id);
+            }
             it = mStreamMap.erase(it);
         } else {
             ++it;
@@ -255,6 +276,26 @@
     mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
 }
 
+void CameraDeviceSession::postProcessConfigurationFailureLocked_3_4(
+        const StreamConfiguration& requestedConfiguration) {
+    if (mFreeBufEarly) {
+        // Re-build the buf cache entry for deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.v3_2.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+            }
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::processCaptureRequest_3_4(
         const hidl_vec<V3_4::CaptureRequest>& requests,
         const hidl_vec<V3_2::BufferCache>& cachesToRemove,
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index 5d6a112..fdc8a5a 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -84,6 +84,8 @@
             camera3_stream_configuration_t *stream_list /*out*/,
             hidl_vec<camera3_stream_t*> *streams /*out*/);
     void postProcessConfigurationLocked_3_4(const StreamConfiguration& requestedConfiguration);
+    void postProcessConfigurationFailureLocked_3_4(
+            const StreamConfiguration& requestedConfiguration);
 
     Return<void> processCaptureRequest_3_4(
             const hidl_vec<V3_4::CaptureRequest>& requests,
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index ccb51ec..6124264 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -308,7 +308,7 @@
 
     expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id));
 
-    EXPECT_GE(att_keymaster_version, 3U);
+    EXPECT_EQ(att_keymaster_version, 4U);
     EXPECT_EQ(security_level, att_keymaster_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 24d9944..3499762 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -779,20 +779,27 @@
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
 
-    /* Setting to carrier restriction needs some time */
-    updateSimCardStatus();
-    auto startTime = std::chrono::system_clock::now();
-    while (cardStatus.cardState != CardState::RESTRICTED &&
-           std::chrono::duration_cast<chrono::seconds>(std::chrono::system_clock::now() - startTime)
-                   .count() < 10) {
-        /* Set 2 seconds as interval to check card status */
-        sleep(2);
+    if (radioRsp->rspInfo.error == RadioError::NONE) {
+        /* Setting to carrier restriction needs some time */
         updateSimCardStatus();
+        auto startTime = std::chrono::system_clock::now();
+        while (cardStatus.cardState != CardState::RESTRICTED &&
+               std::chrono::duration_cast<chrono::seconds>(std::chrono::system_clock::now() -
+                                                           startTime)
+                       .count() < 10) {
+            /* Set 2 seconds as interval to check card status */
+            sleep(2);
+            updateSimCardStatus();
+        }
+        EXPECT_EQ(CardState::RESTRICTED, cardStatus.cardState);
     }
-    EXPECT_EQ(CardState::RESTRICTED, cardStatus.cardState);
     sleep(10);
 
-    /* Reset back to no carrier restriction */
+    /** 
+     * Another test case of the API to cover to allow carrier.
+     * If the API is supported, this is also used to reset to no carrier restriction
+     * status for cardStatus. 
+     */
     memset(&carriers, 0, sizeof(carriers));
     carriers.allowedCarriers.resize(0);
     carriers.excludedCarriers.resize(0);
@@ -808,18 +815,21 @@
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
 
-    /* Resetting back to no carrier restriction needs some time */
-    updateSimCardStatus();
-    startTime = std::chrono::system_clock::now();
-    while (cardStatus.cardState == CardState::RESTRICTED &&
-           std::chrono::duration_cast<chrono::seconds>(std::chrono::system_clock::now() - startTime)
-                   .count() < 10) {
-        /* Set 2 seconds as interval to check card status */
-        sleep(2);
+    if (radioRsp->rspInfo.error == RadioError::NONE) {
+        /* Resetting back to no carrier restriction needs some time */
         updateSimCardStatus();
+        auto startTime = std::chrono::system_clock::now();
+        while (cardStatus.cardState == CardState::RESTRICTED &&
+               std::chrono::duration_cast<chrono::seconds>(std::chrono::system_clock::now() -
+                                                           startTime)
+                       .count() < 10) {
+            /* Set 2 seconds as interval to check card status */
+            sleep(2);
+            updateSimCardStatus();
+        }
+        EXPECT_NE(CardState::RESTRICTED, cardStatus.cardState);
+        sleep(10);
     }
-    EXPECT_NE(CardState::RESTRICTED, cardStatus.cardState);
-    sleep(10);
 }
 
 /*
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index a9865e5..3510163 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -48,8 +48,11 @@
         // error for now. This should be fixed correctly, possibly in a future version of the hal
         // (b/110421924). This is being allowed because some vendors do not support
         // this request on dual sim devices.
+        // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do not support the
+        // required manual GSM search functionality. This is tracked in b/112206766.
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
-                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
+                                      RadioError::OPERATION_NOT_ALLOWED}));
     }
 }
 
@@ -317,7 +320,9 @@
         .type = ScanType::ONE_SHOT,
         .interval = 60,
         .specifiers = {specifier},
-        .maxSearchTime = 600,
+        // Some vendor may not support max search time of 360s.
+        // This issue is tracked in b/112205669.
+        .maxSearchTime = 300,
         .incrementalResults = false,
         .incrementalResultsPeriodicity = 10};
 
@@ -333,8 +338,9 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
                                      {RadioError::NONE, RadioError::SIM_ABSENT}));
     } else if (cardStatus.base.cardState == CardState::PRESENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
-                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
 }
 
@@ -353,7 +359,9 @@
         .type = ScanType::ONE_SHOT,
         .interval = 60,
         .specifiers = {specifier},
-        .maxSearchTime = 600,
+        // Some vendor may not support max search time of 360s.
+        // This issue is tracked in b/112205669.
+        .maxSearchTime = 300,
         .incrementalResults = false,
         .incrementalResultsPeriodicity = 10,
         .mccMncs = {"310410"}};
@@ -370,8 +378,9 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
                                      {RadioError::NONE, RadioError::SIM_ABSENT}));
     } else if (cardStatus.base.cardState == CardState::PRESENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
-                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_2->rspInfo.error,
+            {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
 }
 
@@ -650,9 +659,8 @@
     if (cardStatus.base.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(
             radioRsp_v1_2->rspInfo.error,
-            {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
-             RadioError::INVALID_ARGUMENTS, RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW,
-             RadioError::REQUEST_NOT_SUPPORTED}));
+            {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+             RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW, RadioError::REQUEST_NOT_SUPPORTED}));
     } else if (cardStatus.base.cardState == CardState::PRESENT) {
         ASSERT_TRUE(CheckAnyOfErrors(
             radioRsp_v1_2->rspInfo.error,