diff --git a/capture_service/device_mgr.cc b/capture_service/device_mgr.cc index d96edb02d..56b4fe92f 100644 --- a/capture_service/device_mgr.cc +++ b/capture_service/device_mgr.cc @@ -43,6 +43,22 @@ namespace Dive namespace { +void RestoreSetting(const AdbSession &adb, + const std::string &name_space, + const std::string &setting, + const std::string &value) +{ + if (!value.empty() && value != "null") + { + adb.Run(absl::StrFormat("shell settings put %s %s %s", name_space, setting, value)) + .IgnoreError(); + } + else + { + adb.Run(absl::StrFormat("shell settings delete %s %s", name_space, setting)).IgnoreError(); + } +} + std::string GetPythonPath() { std::string python_path; @@ -425,6 +441,30 @@ absl::Status AndroidDevice::Init() } LOGD("is_adreno_gpu: %d\n", m_dev_info.m_is_adreno_gpu); + res = Adb().RunAndGetResult("shell settings get global development_settings_enabled"); + if (res.ok()) + { + m_original_state.m_development_settings_enabled = std::string( + absl::StripAsciiWhitespace(*res)); + } + res = Adb().RunAndGetResult("shell settings get global stay_on_while_plugged_in"); + if (res.ok()) + { + m_original_state.m_stay_on_while_plugged_in = std::string(absl::StripAsciiWhitespace(*res)); + } + res = Adb().RunAndGetResult("shell settings get system screen_off_timeout"); + if (res.ok()) + { + m_original_state.m_screen_off_timeout = std::string(absl::StripAsciiWhitespace(*res)); + } + res = Adb().RunAndGetResult("shell settings get system doff_screen_timeout_ms"); + if (res.ok()) + { + m_original_state.m_doff_screen_timeout_ms = std::string(absl::StripAsciiWhitespace(*res)); + } + + SetEnableScreenAlwaysOn(true); + if (absl::Status ret = CheckAbi(); !ret.ok()) { return ret; @@ -457,7 +497,6 @@ absl::Status AndroidDevice::CheckAbi() installed_abi); return absl::FailedPreconditionError(err_msg); } - return absl::OkStatus(); } @@ -632,6 +671,8 @@ absl::Status AndroidDevice::CleanupDevice() Dive::kLogPrefixCleanup, m_serial.c_str()); + SetEnableScreenAlwaysOn(false); + UnpinGpuClock().IgnoreError(); Adb().Run("shell setprop compositor.high_priority 1").IgnoreError(); @@ -800,6 +841,69 @@ absl::Status AndroidDevice::SetupApp(const std::string &command, return m_app->Setup(); } +void AndroidDevice::SetEnableScreenAlwaysOn(bool enable_screen_always_on) +{ + if (enable_screen_always_on) + { + Adb().Run("shell settings put global development_settings_enabled 1").IgnoreError(); + Adb().Run("shell settings put global stay_on_while_plugged_in 7").IgnoreError(); + Adb().Run("shell settings put system screen_off_timeout 600000").IgnoreError(); + Adb().Run("shell settings put system doff_screen_timeout_ms 0").IgnoreError(); + Adb().Run("shell input keyevent KEYCODE_WAKEUP").IgnoreError(); + } + else + { + RestoreSetting(Adb(), + "global", + "development_settings_enabled", + m_original_state.m_development_settings_enabled); + RestoreSetting(Adb(), + "global", + "stay_on_while_plugged_in", + m_original_state.m_stay_on_while_plugged_in); + RestoreSetting(Adb(), + "system", + "screen_off_timeout", + m_original_state.m_screen_off_timeout); + RestoreSetting(Adb(), + "system", + "doff_screen_timeout_ms", + m_original_state.m_doff_screen_timeout_ms); + } +} + +absl::StatusOr AndroidDevice::IsScreenOn() const +{ + absl::StatusOr output_or = Adb().RunAndGetResult( + "shell dumpsys display | grep -E 'mScreenState'"); + if (!output_or.ok()) + { + return output_or.status(); + } + const std::string &output = *output_or; + std::vector lines = absl::StrSplit(output, '\n', absl::SkipEmpty()); + for (const auto &line : lines) + { + if (absl::StrContains(line, "mScreenState=")) + { + std::vector parts = absl::StrSplit(line, '='); + if (parts.size() == 2) + { + std::string state = std::string(absl::StripAsciiWhitespace(parts[1])); + if (state == "ON") + { + return true; + } + if (state == "OFF") + { + return false; + } + } + } + } + return absl::InternalError(absl::StrFormat("Failed to parse screen state: %s", output)); +} + absl::Status AndroidDevice::CleanupApp() { m_app = nullptr; @@ -810,6 +914,11 @@ absl::Status AndroidDevice::StartApp() { if (m_app) { + absl::StatusOr screen_on_status = IsScreenOn(); + if (!screen_on_status.ok() || !*screen_on_status) + { + LOGE("Screen is not on, Dive might not work as expected"); + } return m_app->Start(); } return absl::OkStatus(); @@ -988,7 +1097,6 @@ absl::Status DeviceManager::RunReplayGfxrScript(const GfxrReplaySettings &settin }); LOGD("RunReplayGfxrScript(): SETUP\n"); std::filesystem::path parse_remote_capture = settings.remote_capture_path; - // These are only used if kPm4Dump std::string dump_pm4_file_name = parse_remote_capture.stem().string() + ".rd"; std::string remote_pm4_path = absl::StrFormat("%s/%s", @@ -1149,6 +1257,12 @@ absl::Status DeviceManager::RunReplayProfilingBinary(const GfxrReplaySettings &s adb.Run(clean_cmd).IgnoreError(); }); + absl::StatusOr screen_on_status = m_device->IsScreenOn(); + if (!screen_on_status.ok() || !*screen_on_status) + { + LOGE("Screen is not on, Dive might not work as expected"); + } + std::string binary_path_on_device = absl::StrFormat("%s/%s", remote_profiling_dir, kProfilingPluginName); @@ -1276,6 +1390,11 @@ absl::Status DeviceManager::RunReplayApk(const GfxrReplaySettings &settings) con // Wake up the screen. RETURN_IF_ERROR(adb.Run("shell input keyevent KEYCODE_WAKEUP")); + absl::StatusOr screen_on_status = m_device->IsScreenOn(); + if (!screen_on_status.ok() || !*screen_on_status) + { + LOGE("Screen is not on, Dive might not work as expected"); + } LOGD("RunReplayApk(): Starting replay\n"); absl::Status ret_run; diff --git a/capture_service/device_mgr.h b/capture_service/device_mgr.h index 52d4a5a12..f18120ed2 100644 --- a/capture_service/device_mgr.h +++ b/capture_service/device_mgr.h @@ -58,6 +58,10 @@ struct DeviceState std::string m_enforce; bool m_root_access_requested = false; bool m_is_root_shell = false; + std::string m_development_settings_enabled; + std::string m_stay_on_while_plugged_in; + std::string m_screen_off_timeout; + std::string m_doff_screen_timeout_ms; }; enum class GfxrReplayOptions @@ -184,6 +188,9 @@ class AndroidDevice // Triggers a screenshot and saves it to the specified path. absl::Status TriggerScreenCapture(const std::filesystem::path &on_device_screenshot_dir); + void SetEnableScreenAlwaysOn(bool enable_screen_always_on); + absl::StatusOr IsScreenOn() const; + private: // The ABI must be consistent between the connected device and the Dive device libraries absl::Status CheckAbi();