Merge "sdm: Teardown CWB during power off sequence for external display" into display.lnx.9.0.r1-rel
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index e64c704..79ec0c7 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -4223,10 +4223,10 @@
 int HWCSession::WaitForCommitDone(hwc2_display_t display, int client_id) {
   shared_ptr<Fence> retire_fence = nullptr;
   int timeout_ms = -1;
+  callbacks_.Refresh(display);
   {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
     DLOGI("Acquired lock for client %d display %" PRIu64, client_id, display);
-    callbacks_.Refresh(display);
     clients_waiting_for_commit_[display].set(client_id);
     locker_[display].Wait();
     if (commit_error_[display] != 0) {
@@ -4407,7 +4407,6 @@
       DLOGW("Target display %d is not ready", disp_id);
       return -ENODEV;
     }
-    tui_state_transition_[disp_id] = true;
   }
 
   return 0;
@@ -4427,11 +4426,6 @@
     return -ENOTSUP;
   }
 
-  if (!tui_state_transition_[disp_id]) {
-    DLOGE("Display %d tui transition state is not valid.", disp_id);
-    return -EINVAL;
-  }
-
   {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_[target_display]);
     hwc_display_[target_display]->SetIdleTimeoutMs(idle_time_active_ms_, idle_time_inactive_ms_);
@@ -4466,7 +4460,6 @@
       DLOGW("Target display %d is not ready", disp_id);
       return -ENODEV;
     }
-    tui_state_transition_[disp_id] = false;
   }
 
   return TUITransitionUnPrepare(disp_id);
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index cefdf3b..8886246 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -720,7 +720,6 @@
   bool async_power_mode_triggered_ = false;
   bool async_vds_creation_ = false;
   bool power_state_transition_[HWCCallbacks::kNumDisplays] = {};
-  bool tui_state_transition_[HWCCallbacks::kNumDisplays] = {};
   std::bitset<HWCCallbacks::kNumDisplays> display_ready_;
   bool secure_session_active_ = false;
   bool is_idle_time_up_ = false;
diff --git a/composer/service.cpp b/composer/service.cpp
index de8c0f5..9adede5 100644
--- a/composer/service.cpp
+++ b/composer/service.cpp
@@ -26,6 +26,39 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+/*
+Changes from Qualcomm Innovation Center are provided under the following license:
+Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted (subject to the limitations in the
+disclaimer below) provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Qualcomm Innovation Center, Inc. nor the
+      names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior
+      written permission.
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -33,6 +66,7 @@
 
 #include "DisplayConfigAIDL.h"
 #include "QtiComposer.h"
+#include "hwc_debugger.h"
 
 using aidl::vendor::qti::hardware::display::config::DisplayConfigAIDL;
 using android::ProcessState;
@@ -46,11 +80,18 @@
 int main(int, char **) {
   ALOGI("Creating Display HW Composer HAL");
 
+  int composer_thread_count = 8;
+  sdm::HWCDebugHandler::Get()->GetProperty(COMPOSER_THREAD_COUNT, &composer_thread_count);
+  if (composer_thread_count < 4 || composer_thread_count > 15) {
+    composer_thread_count = 4;
+  }
+  ALOGI("composer_thread_count: %d", composer_thread_count);
+
   // TODO(user): double-check for SCHED_FIFO logic
   // the conventional HAL might start binder services
   ProcessState::initWithDriver("/dev/vndbinder");
   sp<ProcessState> ps(ProcessState::self());
-  ps->setThreadPoolMaxThreadCount(4);
+  ps->setThreadPoolMaxThreadCount(composer_thread_count);
   ps->startThreadPool();
   ALOGI("ProcessState initialization completed");
 
@@ -73,7 +114,7 @@
   }
 
   ALOGI("Configuring RPC threadpool");
-  configureRpcThreadpool(4, true /*callerWillJoin*/);
+  configureRpcThreadpool(composer_thread_count, true /*callerWillJoin*/);
   ALOGI("Configuring RPC threadpool...done!");
 
   ALOGI("Registering Display HW Composer HAL as a service");
diff --git a/composer/vendor.qti.hardware.display.composer-service.rc b/composer/vendor.qti.hardware.display.composer-service.rc
index 96e080d..7513fd6 100644
--- a/composer/vendor.qti.hardware.display.composer-service.rc
+++ b/composer/vendor.qti.hardware.display.composer-service.rc
@@ -4,5 +4,6 @@
     group graphics drmrpc
     capabilities SYS_NICE
     onrestart restart surfaceflinger
+    onrestart restart feature_enabler_client
     socket pps stream 0660 system system
     writepid /dev/cpuset/system-background/tasks
diff --git a/include/display_properties.h b/include/display_properties.h
index 80197b2..219c8c4 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -74,6 +74,7 @@
 #define EXTERNAL_ACTION_SAFE_HEIGHT_PROP     DISPLAY_PROP("external_action_safe_height")
 #define FB_WIDTH_PROP                        DISPLAY_PROP("fb_width")
 #define FB_HEIGHT_PROP                       DISPLAY_PROP("fb_height")
+#define COMPOSER_THREAD_COUNT                DISPLAY_PROP("composer_thread_count")
 #define DISABLE_METADATA_DYNAMIC_FPS_PROP    DISPLAY_PROP("disable_metadata_dynamic_fps")
 #define DISABLE_SKIP_VALIDATE_PROP           DISPLAY_PROP("disable_skip_validate")
 #define DISABLE_DESTINATION_SCALER_PROP      DISPLAY_PROP("disable_dest_scaler")
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index cc6fffd..9a6f476 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -3807,12 +3807,12 @@
     SetPendingPowerState(state);
   }
 
+  comp_manager_->HandleSecureEvent(display_comp_ctx_, secure_event);
   err = hw_intf_->HandleSecureEvent(secure_event, cached_qos_data_);
   if (err != kErrorNone) {
     return err;
   }
 
-  comp_manager_->HandleSecureEvent(display_comp_ctx_, secure_event);
   secure_event_ = secure_event;
   if (secure_event == kTUITransitionEnd) {
     DisplayState pending_state;
diff --git a/services/config/src/device_impl.cpp b/services/config/src/device_impl.cpp
index 8c32a89..39bb02d 100644
--- a/services/config/src/device_impl.cpp
+++ b/services/config/src/device_impl.cpp
@@ -146,17 +146,9 @@
 
 void DeviceImpl::serviceDied(uint64_t client_handle,
                              const android::wp<::android::hidl::base::V1_0::IBase>& callback) {
-  std::lock_guard<std::shared_mutex> exclusive_lock(shared_mutex_);
   std::lock_guard<std::recursive_mutex> lock(death_service_mutex_);
-  auto itr = display_config_map_.find(client_handle);
-  std::shared_ptr<DeviceClientContext> client = itr->second;
-  if (client != NULL) {
-    ConfigInterface *intf = client->GetDeviceConfigIntf();
-    intf_->UnRegisterClientContext(intf);
-    client.reset();
+  pending_display_config_.push_back(client_handle);
     ALOGW("Client id:%lu service died", client_handle);
-    display_config_map_.erase(itr);
-  }
 }
 
 DeviceImpl::DeviceClientContext::DeviceClientContext(
@@ -899,12 +891,24 @@
 Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
                                  const ByteStream &input_params, const HandleStream &input_handles,
                                  perform_cb _hidl_cb) {
-  std::shared_lock<std::shared_mutex> shared_lock(shared_mutex_);
   int32_t error = 0;
   std::shared_ptr<DeviceClientContext> client = nullptr;
 
   {
     std::lock_guard<std::recursive_mutex> lock(death_service_mutex_);
+    for (auto& pending_client_handle : pending_display_config_) {
+      auto itr = display_config_map_.find(pending_client_handle);
+      std::shared_ptr<DeviceClientContext> pending_client = itr->second;
+      if (pending_client != NULL) {
+        ConfigInterface *pending_intf = pending_client->GetDeviceConfigIntf();
+        intf_->UnRegisterClientContext(pending_intf);
+        pending_client.reset();
+        ALOGI("clear old client id:%lu ", pending_client_handle);
+      }
+      display_config_map_.erase(itr);
+    }
+    pending_display_config_.clear();
+
     auto itr = display_config_map_.find(client_handle);
     if (itr == display_config_map_.end()) {
       error = -EINVAL;
diff --git a/services/config/src/device_impl.h b/services/config/src/device_impl.h
index c89be31..dd0e536 100644
--- a/services/config/src/device_impl.h
+++ b/services/config/src/device_impl.h
@@ -179,9 +179,9 @@
 
   ClientContext *intf_ = nullptr;
   std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
+  std::vector<uint64_t> pending_display_config_;
   uint64_t client_id_ = 0;
   std::recursive_mutex death_service_mutex_;
-  std::shared_mutex shared_mutex_;
   static DeviceImpl *device_obj_;
   static std::mutex device_lock_;
 };