composer: avoid handling pending power mode for disconnected displays
For pluggable displays, check if the underlying display is
disconnected before handling pending power states as part of
secure session exit.
CRs-Fixed: 3325948
Change-Id: I1c18aebb8f65ddf54f650a2ab90c85d812933daa
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 75144f7..f2f0244 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -3719,23 +3719,69 @@
Fence::Wait(retire_fence);
+ SCOPE_LOCK(pluggable_handler_lock_);
+ HWDisplaysInfo hw_displays_info = {};
+ DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
+ if (error != kErrorNone) {
+ DLOGE("Failed to get connected display list. Error = %d", error);
+ return;
+ }
+
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1;
display < HWCCallbacks::kNumDisplays; display++) {
- if (display != active_builtin_disp_id) {
- Locker::ScopeLock lock_d(locker_[display]);
- if (pending_power_mode_[display] && hwc_display_[display]) {
- HWC2::Error error =
- hwc_display_[display]->SetPowerMode(hwc_display_[display]->GetPendingPowerMode(), false);
- if (HWC2::Error::None == error) {
- pending_power_mode_[display] = false;
- hwc_display_[display]->ClearPendingPowerMode();
- pending_refresh_.set(UINT32(HWC_DISPLAY_PRIMARY));
- } else {
- DLOGE("SetDisplayStatus error = %d (%s)", error, to_string(error).c_str());
+ if (display == active_builtin_disp_id) {
+ continue;
+ }
+
+ Locker::ScopeLock lock_d(locker_[display]);
+ if (!pending_power_mode_[display] || !hwc_display_[display]) {
+ continue;
+ }
+
+ // check if a pluggable display which is in pending power state is already disconnected.
+ // In such cases, avoid powering up the display. It will be disconnected as part of
+ // HandlePendingHotplug.
+ bool disconnected = false;
+ hwc2_display_t client_id;
+ sdm::DisplayType disp_type;
+ for (auto &map_info : map_info_pluggable_) {
+ if (display != map_info.client_id) {
+ continue;
+ }
+
+ for (auto &iter : hw_displays_info) {
+ auto &info = iter.second;
+ if (info.display_id == map_info.sdm_id && !info.is_connected) {
+ disconnected = true;
+ break;
}
}
+ client_id = map_info.client_id;
+ disp_type = map_info.disp_type;
+ break;
+ }
+
+ if (disconnected) {
+ continue;
+ }
+
+ HWC2::PowerMode pending_mode = hwc_display_[display]->GetPendingPowerMode();
+
+ if (pending_mode == HWC2::PowerMode::Off || pending_mode == HWC2::PowerMode::DozeSuspend) {
+ map_active_displays_.erase(display);
+ } else {
+ map_active_displays_.insert(std::make_pair(client_id, disp_type));
+ }
+ HWC2::Error error = hwc_display_[display]->SetPowerMode(pending_mode, false);
+ if (HWC2::Error::None == error) {
+ pending_power_mode_[display] = false;
+ hwc_display_[display]->ClearPendingPowerMode();
+ pending_refresh_.set(UINT32(HWC_DISPLAY_PRIMARY));
+ } else {
+ DLOGE("SetDisplayStatus error = %d (%s)", error, to_string(error).c_str());
}
}
+
secure_session_active_ = false;
}